compared with
Current by Torio Farazdagi
on Apr 18, 2012 15:52.

Key
This line was removed.
This word was removed. This word was added.
This line was added.

Changes (101)

View Page History
h2. Overview
<h2>Overview</h2>

This document covers general questions for {{Zend\Tool}} refactoring and applicability of {{Zend_Tool}} infrastructure in context of ZF2.
<p>This document covers general questions for <code>Zend\Tool</code> refactoring and applicability of <code>Zend_Tool</code> infrastructure in context of ZF2.</p>

<p>It also discusses the need for default providers (in ZF1 defined in {{Zend_Tool_Framework_System_Provider}}) <code>Zend_Tool_Framework_System_Provider</code>) and more importantly default code generating providers (defined in {{Zend_Tool_Project_Provider}}). <code>Zend_Tool_Project_Provider</code>).</p>


h2. Goals
<h2>Goals</h2>

<ul>
* Define <li>Define what parts of {{Zend\Tool\*}} <code>Zend\Tool*</code> ecosystem is reusable in context of ZF2 (what have been already refactored, what need to be removed)</li>
* Understand the need or the lack of support for code generating capabilities previously available in {{Zend\Tool\Project}} (but not limited to them)
<li>Understand the need or the lack of support for code generating capabilities previously available via <code>Zend\Tool\Project</code> (but not limited to them)</li>
</ul>

h2. Requirements

h3. Zend\Tool\Framework
<h2>Requirements</h2>

* *MUST* be simplified
* All low-level components not _directly_ involved in exposing providers' functionality *MUST* be either factored out or removed
* *MUST* integrate more tightly with {{Zend\Console}} (instead of custom CLI implementation)
<h3>Zend\Tool\Framework</h3>

<ul>
<li><strong>MUST</strong> be simplified</li>
<li>All low-level components not <em>directly</em> involved in exposing providers' functionality <strong>MUST</strong> be either factored out or removed</li>
<li><strong>MUST</strong> integrate more tightly with <code>Zend\Console</code> (instead of custom CLI implementation)</li>
</ul>

h3. zf2.php
* *MUST* co-exist w/o conflicts with ZF1 {{zf.php}} tool
* *MUST* support shared ZF2 installations (where ZF installed on some common path)
* *SHOULD* be able to create [ZendSkeletonApplication|https://github.com/zendframework/ZendSkeletonApplication] - allowing to quick start _quickly_
* *SHOULD* provide functionality on par with previous {{zf.php}} tool
* *SHOULD* expose providers previously found in {{Zend\Tool\Project}}

h3. Zend\Tool\Project:

* No need to have it in framework's core, _providers_ *SHOULD* be moved to separate module ([ZendToolProviders|https://github.com/farazdagi/ZendToolProviders] during first implementation phase)
* *MUST* be simplified, just set of generators/providers easily consumable by {{zf2.php}} tool
* *SHOULD NOT* be stateful
** Contrary to what is said in [docs|http://framework.zend.com/manual/1.11/en/zend.tool.project.introduction.html], when adding new action to existing controller no state is necessary - reflection capabilities of {{Zend\Code}} component should be enough.
** General {{modus operandi}} should be KISS
<h3>zf2.php </h3>
<ul>
<li><strong>MUST</strong> co-exist w/o conflicts with ZF1 <code>zf.php</code> tool</li>
<li><strong>MUST</strong> support shared ZF2 installations (where ZF installed on some common path)</li>
<li><strong>SHOULD</strong> be able to create <a href="https://github.com/zendframework/ZendSkeletonApplication">ZendSkeletonApplication</a> - allowing to quick start <em>quickly</em></li>
<li><strong>SHOULD</strong> provide functionality on par with previous <code>zf.php</code> tool</li>
<li><strong>SHOULD</strong> expose providers previously found in <code>Zend\Tool\Project</code></li>
</ul>

h2. Current Status of Components

At the moment {{Zend\Tool}} component and all of its sub-components were removed from master branch.
<h3>Zend\Tool\Project:</h3>

Partially, some functionality like one provided by {{Zend\Tool\Client}} is now available as a part of {{Zend\Console}} component (being developed).
<ul>
<li>No need to have it in framework's core, <em>providers</em> <strong>SHOULD</strong> be moved to separate module (<a href="https://github.com/farazdagi/ZendToolProviders">ZendToolProviders</a> during first implementation phase)</li>
<li><strong>MUST</strong> be simplified, just set of generators/providers easily consumable by <code>zf2.php</code> tool</li>
<li><strong>SHOULD NOT</strong> be stateful
<ul>
<li>Contrary to what is said in <a href="http://framework.zend.com/manual/1.11/en/zend.tool.project.introduction.html">docs</a>, when adding new action to existing controller no state is necessary - reflection capabilities of <code>Zend\Code</code> component should be enough.</li>
<li>General <code>modus operandi</code> should be KISS</li>
</ul>
</li>
</ul>

Number of components originally found in {{Zend_Tool}} clearly smell of over-engineering: {{Zend\Tool\Framework\Registry}}, providers having state, client data storage capabilities, CLI client implementation itself.
All these components either do not belong to the problem domain, or we have that domain defined very broadly.

So, the aim is to utilize previously created code, but the whole architecture should be more simple, decoupled and have fewer layers.
<h2>Current Status of Components</h2>

h2. Proposal
<p>At the moment <code>Zend\Tool</code> component and all of its sub-components were removed from master branch.</p>

Instead of having {{Zend\Tool\Framework}} + {{Zend\Tool\Project}} + {{bin/zf.php}} infrastructure will be amended to:
<p>Partially, some functionality like one provided by <code>Zend\Tool\Client</code> is now available as a part of <code>Zend\Console</code> component (being developed).</p>

* have way more simple {{Zend\Tool}} component
* have {{ZendToolProviders}} ZF2 module. It will contain set of default providers (providers found in {{Zend\Tool\Framework\System\Provider}}).
* providers found in found in {{Zend\Tool\Framework\System\Provider}}, should remain w/i framework's core, so that they are available w/o {{ZentToolProviders}} module installation.
* {{Zend\Tool\Project\Provider}} will be moved into {{ZendToolProviders}} module sub-module.
* {{zf2.php}} will be a rewrite of {{zf.php}} utilizing {{Zend\Console}}
<p>Number of components originally found in <code>Zend_Tool</code> clearly smell of over-engineering: <code>Zend\Tool\Framework\Registry</code>, providers having state, client data storage capabilities, CLI client implementation itself. <br />
All these components either do not belong to the problem domain, or we have that domain defined very broadly.</p>

<p>So, the aim is to utilize previously created code, but the whole architecture should be more simple, decoupled and have fewer layers.</p>

h3. Zend\Tool Component
<h2>Proposal</h2>

Primary responsibility will be to aid 3rd party modules having console routes defined.
<p>Instead of having <code>Zend\Tool\Framework</code> + <code>Zend\Tool\Project</code> + <code>bin/zf.php</code> infrastructure will be amended to:</p>

While {{Zend\Tool\Framework}} was full-fledged framework, {{Zend\Tool}} in ZF2 will be a more light-weight solution delegating all the leg-work to 3rd party modules (with default providers being part of [ZendTool|https://github.com/farazdagi/ZendTool] module).
<ul>
<li>have way more simple <code>Zend\Tool</code> component</li>
<li>have <code>ZendToolProviders</code> ZF2 module. It will contain set of default providers (providers found in <code>Zend\Tool\Project\Provider</code>).</li>
<li>providers found in <code>Zend\Tool\Framework\System\Provider</code> should remain w/i framework's core, so that they are available w/o <code>ZentToolProviders</code> module installation.</li>
<li><code>zf2.php</code> will be a rewrite of <code>zf.php</code> utilizing <code>Zend\Console</code></li>
</ul>

A good example of what might go into {{Zend\Tool}} component are marker interfaces, like {{Provider}} and {{Pretandable}} (aka dry-run) allowing to have framework defined standards for concrete providers.

h3. ZendToolProviders module

* Will contain all basic code generation functionality, including:
** modules
** controllers
** actions
** views
** unit tests
** form
** style and script assets (this can go to separate assetic module of course)
* It is probably good idea to have better integration for ORM entities (so that forms might be generated from them). This is a serious question though, requiring serious consideration.
* Will play nicely with 3rd party console-enabled modules
* {{Zend\Code}} will be used for both parsing/scanning and code generation (where necessary)
* It will be _standard_ ZF2 module, to be installed into {{vendor}} folder
<h3>Zend\Tool Component</h3>

{{Zend\Tool\Project}}
<p>Primary responsibility will be to provide utility functionality to any console-enabled modules.</p>

* No special treatment of projects, except for probably namespacing generators (to distinguish btw standard providers and imported)
* Providers will be reworked to take into account changes occurred in {{Zend\Code}} and {{Zend\Console}}
<p>While <code>Zend\Tool\Framework</code> was full-fledged framework, <code>Zend\Tool</code> in ZF2 will be a more light-weight solution delegating all of the leg-work to providers modules.</p>

h3. bin/zf2.php
<p>A good example of what might go into <code>Zend\Tool</code> component are marker interfaces, like <code>Provider</code> and <code>Pretandable</code> (aka dry-run). This will allow to have framework-defined standards for concrete providers.</p>

* It will heavily depend on [Zend\Console component|https://github.com/Thinkscape/zf2/tree/feature/console/library/Zend/Console] developed by [~joust]
* *MUST* be able to detect whether it is being run from ZF2 application, and if so detect available console-enabled modules
* *SHOULD* support both Active and Passive Generators
* *MUST* allow 3rd party plugin generators (so be extensible, 3rd party modules should be able to register with the tool and their providers become immediately available)
* {{zf2.php}} *IS NOT* 1:1 conversion of previous zf.php capabilities
* *MUST* support full scaffold generation (with separetely runnable steps - like controller creation, view creation etc)
<h3>ZendToolProviders module</h3>

<ul>
<li>We may pick another name, I am not particularly good at naming</li>
<li>Will contain all basic code generation functionality, including:
<ul>
<li>modules</li>
<li>controllers</li>
<li>actions</li>
<li>views</li>
<li>unit tests</li>
<li>form</li>
<li>style and script assets (these can go into separate assetic module of course)</li>
</ul>
</li>
<li>It is probably good idea to have better integration for ORM entities (so that forms might be generated from them). This is a serious question though, requiring serious consideration.</li>
<li>Will play nicely with 3rd party console-enabled modules</li>
<li><code>Zend\Code</code> will be used for both parsing/scanning and code generation (where necessary)</li>
<li>It will be <em>standard</em> ZF2 module, to be installed into <code>vendor</code> folder</li>
</ul>

h2. Functional Segmentation

Very important issue is functionality segmentation: for ex, Doctrine2 migrations or schema handling module may (and probably should) define its own providers.
The aim is to standardize the way providers are created, and provide single point of access via which those providers will be used: that's via {{zf2}} script.
<p><code>Zend\Tool\Project</code></p>

So, with wise utilization of refactored {{Zend\Tool}} (which will allow to mark classes semantically) + generic {{zf2.php}} script (which will rely on conventional [Zend\Mvc\ConsoleApplication|http://framework.zend.com/wiki/display/ZFDEV2/RFC+-+Console+2.0]) we should be able to expose all console-enabled controllers easily.
<ul>
<li>No special treatment of projects, except for probably namespacing generators (to distinguish btw standard providers and imported)</li>
<li>Providers will be reworked to take into account changes occurred in <code>Zend\Code</code> and <code>Zend\Console</code></li>
</ul>

h2. Active vs Passive Generators

Ideally, both passive, and [active|http://c2.com/cgi/wiki?ActiveCodeGeneration] code generation should be supported.
<h3>bin/zf2.php</h3>

While passive code generation - where generated code is to be additionally edited by programmer - saves lots of typing, active generation will support on-fly or triggered re-compilation of artifacts/assets.
<ul>
<li>It will heavily depend on <a href="https://github.com/Thinkscape/zf2/tree/feature/console/library/Zend/Console">Zend\Console component</a> developed by <ac:link><ri:user ri:username="joust" /></ac:link></li>
<li><strong>MUST</strong> be able to detect whether it is being run from ZF2 application, and if so detect available console-enabled modules</li>
<li><strong>SHOULD</strong> support both Active and Passive Generators</li>
<li><strong>MUST</strong> allow 3rd party plugin generators (so be extensible, 3rd party modules should be able to register with the tool and their providers become immediately available)</li>
<li><code>zf2.php</code> <strong>IS NOT</strong> 1:1 conversion of previous zf.php capabilities</li>
<li><strong>MUST</strong> support full scaffold generation (with separetely runnable steps - like controller creation, view creation etc)</li>
</ul>

With this in mind, the primary focus of the module *SHOULD* be CLI-tool, and not the web-based interface (à la Yii's [Gii|http://www.yiiframework.com/doc/guide/1.1/en/topics.gii] tool).

As module will be depended on {{Zend\Console}} which by itself is a good abstraction layer between framework's core and the rest of the world, extending code generator to support web-based interface should be relatively easy task. This is _beyond_ the scope of current document though.

h2. Installation
<h2>Functional Segmentation</h2>

{{bin/zf2.php}} tool will be available whenever ZF itself is available (being a part of installation).
<p>Very important issue is separation by responsibility: for ex, Doctrine2 migrations or schema handling module may (and probably should) define its own providers. <br />
The aim is to standardize the way providers are created, and provide single point of access via which those providers will be used: that's via <code>zf2</code> script.</p>

System providers (like {{zf2 show version}}) will be available w/o any further configuration.
<p>So, with wise utilization of refactored <code>Zend\Tool</code> (which will allow to mark classes semantically) + generic <code>zf2.php</code> script (which will rely on conventional <a href="http://framework.zend.com/wiki/display/ZFDEV2/RFC+-+Console+2.0">Zend\Mvc\ConsoleApplication</a>) we should be able to expose all console-enabled controllers easily.</p>

Code generators will be available on per project basis, and installable as any other ZF2 module i.e. {{ZendToolProviders}} module goes to {{vendor}} folder.
<h2>Active vs Passive Generators</h2>

h2. ZF1 Compatibility
<p>Ideally, both passive, and <a href="http://c2.com/cgi/wiki?ActiveCodeGeneration">active</a> code generation should be supported. </p>

{{zf2.php}} tool:
* *SHOULD* provide similar features original {{zf1.php}} provided (so that there's no huge learning curve)
* *SHOULD NOT* be aware of ZF1, meaning code generators will be ZF2-compatible ONLY
* *MAY* provide (out-of-box) some {{migration}} provider set, helping automating ZF1->ZF2 migrations.
<p>While passive code generation - where generated code is to be additionally edited by programmer - saves lots of typing, active generation will support on-fly or triggered re-compilation of artifacts/assets.</p>

h2. zf2.php and module installation
<p>With this in mind, the primary focus of the module <strong>SHOULD</strong> be CLI-tool, and not the web-based interface (&agrave; la Yii's <a href="http://www.yiiframework.com/doc/guide/1.1/en/topics.gii">Gii</a> tool).</p>

Good stress test for the whole idea of having descrete modules for different provider sets is module [installation and distribution|http://framework.zend.com/wiki/display/ZFDEV2/RFC+-+Module+Installation+and+Distribution].
<p>As module will be depended on <code>Zend\Console</code> which by itself is a good abstraction layer between framework's core and the rest of the world, extending code generator to support web-based interface should be relatively easy task. This is <em>beyond</em> the scope of current document though.</p>

It is expected that {{zf2.php}} is capable of installing/updating modules, so here is the question to anyone who have spent some brain-power analyzing best ways to install modules:
Will it be feasible to create some {{ZendToolModuleManager}} module, which will be exposed via proposed {{zf2.php}} tool?
<h2>Installation</h2>

h2. Roadmap
<p><code>bin/zf2.php</code> tool will be available whenever ZF itself is available (being a part of installation).</p>

* After gathering some input to confirm that whole idea is sane, first step will be to implement {{zf2.php}} tool
* Once done, {{Zend\Tool\Project\Provider}} need to be migrated to [ZendToolProviders|https://github.com/farazdagi/ZendToolProviders] repo
* Some docs on how to expose zf2 console-enabled controllers, so that any other modules may be updated:
** Module management
** Assets management
** Doctrine2 integration (both schema and migrations tools)
<p>System providers (like <code>zf2 show version</code>) will be available w/o any further configuration.</p>

NB: All development should be in sync with {{Zend\Console}} component - which is currently being updated.
<p>Code generators will be available on per project basis, and installable as any other ZF2 module i.e. <code>ZendToolProviders</code> module goes to <code>vendor</code> folder.</p>

<h2>ZF1 Compatibility</h2>

h2. Alternatives
<p><code>zf2.php</code> tool:</p>
<ul>
<li><strong>SHOULD</strong> provide similar features original <code>zf1.php</code> provided (so that there's no huge learning curve)</li>
<li><strong>SHOULD NOT</strong> be aware of ZF1, meaning code generators will be ZF2-compatible ONLY</li>
<li><strong>MAY</strong> provide (out-of-box) some <code>migration</code> provider set, helping automating ZF1-&gt;ZF2 migrations.</li>
</ul>

When considering whether we need support for scaffolding/code generation it is worth looking at how others have tackles the same problem:

- RoR has amazingly complete CLI tools (including code generators), Symfony2 follows the suit.
- Django provides great admin application, but no code generation per se (although admin app + ModelForm + generic views still allow you to keep dev. process pretty DRY)
- Yii has web-based generator (with preview), plus deprecated CLI tool
- CakePHP has very rich CLI tools, including code generation, schema management, and i18n
<h2>zf2.php and module installation</h2>

h2. References
<p>Good stress test for the whole idea of having separate modules for different sets of providers is module <a href="http://framework.zend.com/wiki/display/ZFDEV2/RFC+-+Module+Installation+and+Distribution">installation and distribution</a>.</p>

[Zend Tool Docs for ZF1|http://framework.zend.com/manual/en/zend.tool.project.html]
[Artur Bodera's Console Sandbox on GitHub|https://github.com/Thinkscape/zf2-console-sandbox]
[ZendToolProviders|https://github.com/farazdagi/ZendToolProviders]
[RFC Zend\Console 2.0|http://framework.zend.com/wiki/display/ZFDEV2/RFC+-+Console+2.0]
<p>It is expected that <code>zf2.php</code> is capable of installing/updating modules, so here is the question to anyone who have spent some brain-power analyzing best ways to install modules:<br />
Will it be feasible to create some <code>ZendToolModuleManager</code> module, which will be exposed via proposed <code>zf2.php</code> tool?</p>

<p>Will it be too much to ask end-user to install some standard modules in addition to core libs, to utilize framework in a more pleasant way?</p>

<h2>Roadmap</h2>

<ul>
<li>After gathering some input to confirm that the whole idea is sane, first step will be to implement <code>zf2.php</code> tool</li>
<li>Once done, <code>Zend\Tool\Project\Provider</code> need to be migrated to <a href="https://github.com/farazdagi/ZendToolProviders">ZendToolProviders</a> repo</li>
<li>Some docs on how to expose zf2 console-enabled controllers, so that any other modules may be updated:
<ul>
<li>Module management</li>
<li>Assets management</li>
<li>Doctrine2 integration (both schema and migrations tools)</li>
</ul>
</li>
</ul>


<p>NB: All development should be in sync with <code>Zend\Console</code> component - which is currently being updated.</p>


<h2>Alternatives</h2>

<p>When considering whether we need support for scaffolding/code generation it is worth looking at how others have tackled the same problem:</p>

<ul class="alternate">
<li>RoR has amazingly complete CLI tools (including code generators), Symfony2 follows the suit.</li>
<li>Django provides great admin application, but no code generation per se (although admin app + ModelForm + generic views still allow you to keep dev. process pretty DRY)</li>
<li>Yii has web-based generator (with preview), plus deprecated CLI tool</li>
<li>CakePHP has very rich CLI tools, including code generation, schema management, and i18n</li>
</ul>


<h2>References</h2>

<p><a href="http://framework.zend.com/manual/en/zend.tool.project.html">Zend Tool Docs for ZF1</a><br />
<a href="https://github.com/Thinkscape/zf2-console-sandbox">Artur Bodera's Console Sandbox on GitHub</a><br />
<a href="https://github.com/farazdagi/ZendToolProviders">ZendToolProviders</a><br />
<a href="http://framework.zend.com/wiki/display/ZFDEV2/RFC+-+Console+2.0">RFC Zend\Console 2.0</a></p>