 Okay, I think we can get started Welcome everyone This is writing command line tools for Drupal 8 modules Thanks for coming Just want to introduce our speakers today Greg Anderson from Pantheon he's the open-source developer there Jesus Manuel Olivas Drupal 8 solutions engineer at FFW Myself an open-source developer Moshe Weitzman longtime Drupal contributor and Darrell Norris a Drupal engineer with Hewlett Packard Enterprise Okay We're talking about command line tools and how you write your commands for your Drupal 8 modules The goal of us as command line developers Or command line framework developers is that it should be easy for you to write your commands They should be brief. They should be simple And you should have access to the parts of Drupal in the parts of the command line runner Easy and familiar access to those parts of the system a little bit about the agenda today You're gonna learn about symphony console commands and about new innovation in Drush called annotated commands Which is new for Drush 8 and Drush 9? policy files for ways you can adapt other people's commands output formatting command discovery and Configuration of commands and generation of different parts of your Drupal modules and commands Want to just briefly summarize some really recent changes in Drush We started in the Drush 8 and Drush 9 Branches to support symphony console commands Okay, so you can write straight Console commands and run them via Drush will show up in Drush help and all of the arguments and options will be shown there And we'll be passed through Okay As a layer on top of that you can run you can write annotated commands for your modules And we'll show you more about that later And finally the very familiar drush.ink files Command files are still possible with Drush 8, but we have deprecated and won't Run them for much longer in Drush 9 Okay, so that's that's where the Drush system is right now We have representatives from both the console project and the Drush project here And just want to kind of give people an orientation about some of the differences between our two projects On the Drush side on the left-hand side We're working with annotated commands show that they're short and readable and optimized for those things The Drupal console systems optimizing for straight symphony console command class usage And so everything you learn from the symphony documentation Will work fine for Drupal console commands I think I'll hand this over now The symphony console provides a life cycle flow for method execution so you can have configure methods You can have initialize you can have Interact and execute so interact is the place where you ask questions to the user You know when you are is the place where you have to play for you know This is you want to do this you want to this other you want to do something else and Execute part is the method where you put your logic Well, we should mean execute your logic But I mean the best practice to do this is to take all that logic and put into a service and inject the service into your command Just do the couple components and make easier to update and maintain and those commands are Registering to application object and this is the one who takes care of executing those commands All right, so the slide shows symphony console command command that has configure execute and demo as Jesus said and all of this Works equally well in drush and Drupal console now as of the recent changes we've made on the drush branches but we've also started experimenting with a new way to configure your commands called annotated commands and This style actually started in WPC li where they used annotations to describe The parameters and the help text and it all came together as one easy to read unit It was really nice development experience So that that was adopted by terminus and there's also something called the robo PHP task runner that's adopted this and now we're also Bringing this into drush so as an experimental feature And so I'll emphasize that for Drupal 8 module writers We're recommending that you stick with straight symphony console commands But if you'd like to experiment with this or if you'd like to make internal commands Then go ahead and this first slide shows an example of An annotated symphony console command Annotated command is a new class that extends the symphony console command So everything you see here is exactly like the symphony console commands you're used to using except that we have replaced the configure method with a Doc a php doc block comment that shows you what the command name is What the arguments are and the defaults and things of that nature? And this is all used to generate the help text So it now has shortened your command a little bit You can actually take this one step further and rather than using a symphony console command You can use what we call a command handler And a command handler is just a plain old class. It doesn't have to extend from anything but it is a class so it can participate in dependency injection as we'll see later and The methods of this class can be annotated with a command annotation that names what the command should be and then the command runner drush takes care of Processing the inputs from the command line and passing them in to the parameters of your function And once again the help text is all generated for you. So you just have this really short canonical easy to read File evangelizing this upstream and symphony We don't really know whether they like it or not here that interacts or integrates with annotated commands This is something that has been in drush for a while, but we're bringing it forward to the object-oriented world again, we're in Experimental testing pipeline starts with the validate step Then your command is executed and after your command execution happens the results from the command goes through the processing pipeline I'm not going to talk a lot about Robo PHP here, but I will mention that in drush 9 We are basing a runner on Robo, so if you return a Robo collection of tasks, then those tasks will all be run as part of the pipeline And the reason that's cool and interesting is that each stage of the processing pipeline Can be affected by hooks that you add with annotated methods. I'll show you Next so in the process phase you could add additional tasks that run whenever someone else's command runs such as SQL sync or or whatever and Robo provides a rollback mechanism So if one of the tasks fails then all of the tasks that were added have a chance to roll back And that just keeps the process altered it goes through a formatting engine So here's a quick you just put this in any command file that's located anywhere The drush finds command files you put a hook annotation on it and in this particular example I'm showing you the command hook, which is the name or an ordinary Tag it with this hook your method will be called With the console command event parameter and you can manipulate it any way that you would for those of you Who aren't gives you methods that allow you to change the options or select a different command That's going to run or just stop the command from running all together or whatever you need to do and of course This feature being part of symphony. There are other ways you can inject this interface using the symphony APIs but this is a much cleaner and simpler thing in Drush a lot of people have made use of we have an examples folder that shows you how to do something with a Policy you just take that policy you copy it to your home drush folder add whatever code you want and then you can do things like stop people from shooting themselves when they try to Sql sync to their production database or just you know, what whatever Policy controls you want to put in so we're trying to keep that equally simple But also make it possible to integrate with any symphony command that output formats It's wonderful to have a command line tool that gives you lots of information about the deep in terms of your Drupal site But if you're using a command line tool chances are really good You might be sending that data somewhere else. You might be in bash. You might be typing it to something else that might be or said or split or whatever Different tools take different formats. So since Drush 5 and Drush 8 and Drush 9 with annotations so This is an example only showing the fusions here in addition to your other command annotations You can just add annotations and say what the field labels are and the neat thing is down at the bottom You have a regular PHP returns annotation so the Whole system looks at this return annotation. It knows what data type your command is returning and from that It can infer which output formats are available So when you run the help command, it'll say aha You are doing the row of fields and I know how to take row of fields and turn that into a table So I'm going to do table as one of your Options as an output for matter if you look at the method body here You can see that the output data then is just a simple array Each element of the array is a row and each row has Elements that are the various cells on that row and then down at the bottom We wrap it in a row of fields object, which is nothing more than a PHP array object So it behaves like the array that it wraps, but so we know what's going on So you can see an example of what a format table looks like this is just a normal symphony table object That formats the data and on the right. I've shown you the same output Formatted in yaml. So it looks just like the array function was returning It gets even cooler than that though because it's also possible when you're doing table formatting to select which fields you want So here the example it's using the human visible labels Three and one and put them in the reverse order So it selects and re-orders the tables and whatever order you want to show them in some commands In drush have very very long tables with lots of fields and only a few of those are showed by default But you can select which ones you want to see On the right. We've just made it one step for it better now in drush 8 and drush 9 It's never worked before but you can now mix your table selections and your output formatter So first you select fields three and one then you format it as jason And you see only the fields you selected in the jason format We have a whole pile of output formatters just available for your use So as a command writer, you don't have to think about formats at all I showed you this as an attachment to annotation commands obviously all of these functionalities have You know classes and methods as a normal API and we're going to be working After this session to roll this feature into Drupal console so that you'll be able to take advantage of Output formats in your console commands as well So in symphony console, they have this thing called the symphony style Which is very similar to what we're talking about which is the auto format Which allows you to provide you a way to input and output Input data and output messages And I'll ask you to ask questions and you can also provide default values for example Yes, or no, you can also provide an array. We're just gonna provide you different type of choices working user can choose and also they can select it by pressing the arrow You can also display this data Very similar what he showed but the difference in here is gonna be that you're gonna have to erase one for the header and one for the roles You can you can also take advantage of this symphony style by By outputting a verbose way to display messages. You can display warnings match as success messages Listing and errors and with different colors To me no Yeah, discovery So another new innovation that is very new and most of you probably haven't seen yet because this is literally only within the past couple of weeks is We're changing the way the command discovery is done for modules commands in both Drush and So our friend Larry Garfield says outside of a factory access to the dependency injection container It's almost always a bug and you see this all over the place Where someone will go just to deepen some field and it'll grab the container from a static method And that's often necessary because you're dealing with legacy code, but you'd rather not do that whenever possible you would like to have your Dependencies cleanly injected from the container at construction time and Drupal 8 has a whole System designed to make this cool and awesome and wouldn't be cool and awesome if you could take advantage of that in your commands To so that your commands didn't have to go and route through the Drupal system to pull out all of the different depending if you go into your modules Services.yml file you can now declare all of your command classes as services and since these are services They can take part in the regular symphony dependency injection and get all of the different pieces They need injected into their constructor in this example I'm showing you the services.yml from a patch that I submitted to the default content module and this patch runs on both symphony console and Drush and what it does is The default content has defined its own service You can see at the top the default content manager where they do all of their work and now we have three commands Three command line commands and each of those take that content management manager object as a Parameter that's injected into their constructor From that tag search for all of the services that are tagged as console commands We instantiate those and when we instantiate them they get injected properly So it's all clean and modern An advantage of doing something like this is we save a lot of I mean we improve the discovery method So instead of filing searching for the file system for commands We use the this little tag that you can see here like something like console command This we find by that tag on the container and we discover those commands on this register on the system So any new module adding new commands register of services will be automatically discovered by the tool This is working. I think so Finalizing what rappers mentioned the same discovery method is using in the projects. Let's jump into the some configuration and generation and Same as triple eight triple console provides a Possibility force to scribe to certain events. So we have events for running before the command gets executed While the command is executed or at the very end so we can use those methods for different things in this particular case we can use before the Command execution so we can ask for a configuration. So we provide configuration files that you can put in different places and Based on the file is stored. It will take some it will gain based on that So you have can have configuration files globally in your home directory. This is one place You can have configurations file set in the root of your triple side. So you can have some And based on that configuration you can set you can stop commands to be executed Let's say we have a command for you have a lot of generators in triple console And you don't want you don't want to run those generators in production So you can stop for loading those commands just by changing the configuration Let's say we might be have we are handling a project using Composer Which is the way to go so you can set default options in that configuration to force all of your download commands and Download add a module so for use Composer instead of going to Drupal.org and download that file for you If you pass that option that console Composer in that configuration will force to do Composer and Eventually will download for it there from the package is and also will update your Composer JSON file And you can when do more things with that like probably before command execution you can add messages for I mean for the user output. We use that a lot of the generators to tell you which file were generated Let's jump into automate command execution Us I mean we as well as as you can I mean the event listeners for command execution command execution Drupal console provide a chain command. This chain command allowed you to read a Jamal file definition as you can see here or you can set different commands to be executed You can set those commands and you can also set the options you want to use So basically you can create your own recipes of commands to automate your all of your process You can have something like I want to in this case what is happening is I want to run site new Which is basically will download in Drupal for you then is I'm setting the argument in this case and this Drupal 8.dev which it means I want to use this directory to download my project and Instead of passing a version so you don't have to force this to a specific version You can say something like latest equals to true Which it means all we'll get downloaded latest version for you and you can do this for every single command I mean Drupal single console single command and as well in the final section You can see where we are running the site install command in this case You can see this little or running strange signs there like where the db type and db host is so those are placeholders So you can set placeholders and you can either set default values for those placeholders passing in line We have two different types of placeholders the ones you see with a person sign It means that could be passed online or use a default value if you don't set a You don't pass a value via inline command execution You will throw an interaction question for you What's the value you want to assign to this specific placeholder? And once you set up that value for the placeholder you will set to the command option or argument Which is just linked to and their last one who's in the dollar sign in this case As you can see is a different this is is different So this is door sign not person sign that one will allow you to read environment variables You might be you might be don't want to put your credentials in your configuration in the system So you can put those values on the environment system and you can use a chain command Make takes care of the automation of installing Drupal and ring those values for the system and On the right side we can see the differences. So again the person sign it means as you can provide a default You can set inline or if it's not it will ask you for you the other one The value is always required if not will throw an exception and the value must be preset via the environment part And you might be asking when you can start writing more select commands with triple console. You can do it now You can do it by using this generate command command So we basically provide you with a command to generate commands This is an example of how this command should run something like Drupal generate command And you can either Let this command run in your interactive mode and asking you question Oh, if you want to save time because I mean this tool is kind of do it for doing something like that to save your time So you can focus in what you what's really important for it for your project or your organization You can set all the values in like something like in this case module example I want to make the class the common class called something like awesome command And I want to this command to be awesome It means the class name is what we have as awesome command But the command name how will be listed in your in your system when you do something like Drupal list for listing the commands This is the name that we showed that's awesome, and you can take advantage of the Injected services remember what Greg was mentioning about about or commands both system system register those commands services is gonna take advantage of the Injecting services from the container. So this is the option you will use to inject those services So you can pass the services name here on the dash to a service option to inject those and this generator Will take care of getting those those for you and inject it in your command if you run this from interactive mode What it happens it will get it will discover all those all those services from the Drupal site that you are working with And we'll list it for you using this symphony style that Drupal was mentioning And you will be able to use error keys to select those from the system You will select one or many as you want and finally you see that no interaction mean option It means I don't want this command to do any interaction in this particular case you can do either no interaction or in our interactive and I'll recommend you if you don't know which options to pass when running commands instead of instead of doing trying to I mean Trying to guess which options are you can either go dash dash help or you can run the command and pass Pass the option dash dash generate inline And that will be output at the very end of the command execution the inner representation of that command for you If you want to add a command to a Jamo file in order to use the chain command You can do the same thing execute a command and do something like dash dash generate chain And that will that will output for you the you know the Jamo definition that we can see here for your command and Finally in order to those commands you don't have to worry about where those commands are if you run the chain command The system automatically will discover those for you We have specific places like your home directory the module the module directory and the system that default site I mean root directory and those commands will be discovered for them So in closing I just like to say that you know the drush team and the Drupal console team have been working together trying to Unify our efforts and reduce the amount of duplicate maintenance we need to do and Try to figure out where we can share functionality as best we can so immediately after the session in room 292 we're going to have a bop on command lines where we invite you all to come and ask all of your questions and provide suggestions or feature requests for the future and Of course, don't forget the general sprints that are going on all weekend And finally if you have any technical questions about things that you were That you've seen today in this presentation. We're going to be opening up the mic right now But leave any of your questions about you know the future or what we've decided for the boss because you know We're still working on that and so the answers to those types of questions are gonna be more complicated Nope, no, I'll refer you to question. There might be a switch on there that you can turn on Yeah I was curious what the status right now of the 9x branch of drush like is it for develop for developers now? Can you use it on a site? well, the 9x branch is in development and Typically the drush maintainers use master every day for their work the way it's working right now The 9x branch is using all of the old legacy drush dot ink commands unless you Specifically address one of the newer commands and the newer commands have colons and then there's only a few of the newer commands That's very very new branch You know, it's basically usable, but you're gonna have a much rockier ride on the 9x slash master branch We are maintaining the 8x branch and so, you know only stable bug fixes and things of that nature will go back there So we really recommend most people check out 8x or a stable tag Right, so related with that my second question is that the goal is to get rid of the drush dot ink support in 9x That's right. Okay, so you have a lot of time with 8x because You know Drupal 7 is going to be around for a long time because with the new architecture of Drupal 8 It's going to be a while before Drupal needs to go to Drupal 9 And so the fact that Drupal 8 is going to last a long time means that Drupal 7 is going to last a long time So Drupal 8 will be around to support Drupal 7 so this gives you a lot of time to work in the 8x branch and Convert your module commands for Drupal 8 into symphony console commands so that by the time we actually EOL the drush 8 branch you should all be over I hope I see a lot of you in the bath after this. Thank you very much for coming So we have a few stickers if you want to put several self We all love stickers