-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use Symfony Console application and annotation commands in Drush #2103
Conversation
Nifty. It I like annotation classes as commands. Great checklist - lots of work to do! Maybe we should split out the major ones into their own issues and link from there. Lets use the drush9 milestone to collect such issues. This notice is noisy: |
Awesome to see this taking shape! |
You might find this useful: Drupal Console discovers commands though name conventions. DCG discovers commands using PHP reflection. There is core conversation about Symfony Console integration with some interesting points about command discovery. |
Thanks a lot for those links. Will read up on command discovery. I just played with DCG and reviewed the code. Terrific work! |
Thanks for the references; I was unaware of DCG. I am ambivalent about the DCG discovery technique vs the DrupalConsole discovery technique. Being able to use instanceof is clearly a good thing; however, DCG at its core is still using filesystem iteration to discover classes, and furthemore it instantiates classes it does not need in order to use instanceof. In the balance, I think I prefer the model that commandfiles must conform to some naming convention in their filenames, e.g. *Command.php, as DrupalConsole does. |
There should be a way to distinguish Drush commands from Drupal Console commands and other types of commands. Perhaps *DrushCommand.php or Drush/*Command.php |
Actually, it is my goal to make it possible to write a Drupal 8 module cli tool that is loadable by both DrupalConsole and Drush. So, we'll instantiate any *Command.php, but will ignore anything that is an instanceof Symfony Console. Drush will only support annotation commands (and legacy procedural Drush commands, of course); DrupalConsole will use instanceof to distinguish between annotation commands and native Drupal Console commands. I'm working on the Drupal Console PR right now; I will cross-reference here when it is ready. UPDATE: See hechoendrupal/drupal-console#2081 below. |
Converted one command as a proof-of-concept, and got the tests to pass. Still a lot of work remaining, but a good milestone. |
|
||
use Drush\Log\LogLevel; | ||
|
||
class InitCommand extends \Robo\Tasks |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see the @option
annotations below on the individual methods, but should there be an annotation on the class too for command discovery? Or are those intended to be discovered by other means?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commandfile discovery hasn't been designed yet, exactly. The basic mechanism is similar to what Drush does today: find all commandfiles, and then register all of the commands they define. Note that annotations on the class, or using instanceof are both possibilities for secondary techniques for command discovery / selection; however, there needs to be an additional initial filter function as well, as we would not want to load every class file available just to determine which are commandfiles.
DrupalConsole searches for files called *Command.php (in certain paths), and registers all of those. We should probably do something similar. Suggestions / PRs welcome.
Hooks and formatters are now working; I think the next step is to actually load a commandfile provided by a module, and see if we can make that work. n.b. Module commandfiles will invariantly given a full bootstrap. We'll support allowing global and site commands to set their bootstrap level later. |
I decided that Chi-teck was right, above; annotation commandfiles should use different filename patterns than Symfony commands. Discussion at consolidation/annotated-command#12 |
I renamed consolidation/annotation-command to consolidation/annotated-command. GitHub will automatically redirect the old links above to their new location in the new project name. |
*/ | ||
public function phpEval($php, $options = | ||
[ | ||
'format' => 'var_export', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does an annotation command specify @default-format and $options['format']? Also, I have not seen this use of use of an associative array as default value. Is that new in PHP?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I put in both @default-format and 'format' => 'var_export'
because I was experimenting; only one is needed on any given command. If you are using a Symfony Console command (whose parameters are always InputInterface, OutputInterface), then you must use @default-format.
The associative array as a default value, as far as I know, has always worked in php, but I have only verified this as far back as php 5.4. Its use in this context -- to define the default values for your options -- originated in Robo.
Going to investigate service tags, similar to what was done in an earlier Drush PR. See: tags example and the compiler pass. Actually, it looks like it won't be necessary to use a compiler pass here. (UPDATE: It was necessary to use a compiler pass here.) |
@@ -0,0 +1 @@ | |||
WootCommands.php |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this .gitignore really needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than make two copies of the same 'WootCommands', my scripts copy or symlink the Drupal 8 version into the Drupal 7 test module directory. I don't want this test artifact to be accidentally committed. It might also be a good idea to just erase the duplicate after the test runs.
I merged in #2169, so this PR now uses tagged services to find commands in Drupal 8 modules. In order for this to work, we need to create a subclass of DrupalKernel. A core patch that adds the functionality we need is here: https://www.drupal.org/node/2718933 |
4591667
to
6c09849
Compare
I squashed and rebased this with the master branch. |
Continued in #2843. |
CONTINUED IN #2175.
Setting the DRUSH_SYMFONY environment variable makes the Symfony Console Application the main command runner. Otherwise, the original Drush command dispatcher is used first, and the Symfony Console Application is used as a backup.
There's a lot of work needed here before Drush will be fully functional under the Symfony Console Application. One interesting thing about Symfony Console is that option processing is not fully done until
$application->run()
is called. This means that work like site selection must be done via event listeners.The list below enumerates what needs to be done, cross-referenced to other issues, PRs or commits that are relevant. Items that have existing code are checked off, but nothing should be considered to be "done" until reviewed, discussed and merged.
list
command shows command aliases as duplicate entries; duplicates should be hidden