 Welcome everyone to the Drush Optimizations Lab. We have two hours here learning all about Drush and development workflows and how to write commands. And so, you know, we're very excited to further along your skills with Drush. Just want you guys to take a look and review the goals that we have for the lab and make sure this is the right place for you. How to add Drush integration for contrib modules. Learning how to configure and customize Drush for your own workflow. Talk to you about some internals, especially internals that are new for Drupal 6. And, you know, we're going to have general, like, a Q&A at the end here. So, if you've been meaning to chat with the Drush maintainers, here we are and we'd love to talk to you. A little bit of housekeeping before we get into the program. If you have questions or you need help, there's two different processes for that. If you have a question for the presenter, raise your hand high and look up here towards Greg when he's presenting. If you're doing something on your machine and you run into trouble, there's lots of us here to help. Just raise your hand about halfway and start looking at one of us over here, okay? And we'll be happy to come over to your machine when we get a second and help. I'm going to have the whole panel introduce themselves now. I'll go first. My name is Moshe Weitzman. I'm the Drush maintainer. I work for Acquia as the director of research and development. I'm a long time Drupal developer as well. So why don't we start with Damien here. Yeah, I'm Damien Lee. I'm an engineer at Acquia. But I also maintain Fuse, Seedles and a few other Drush brands. Hi everyone. My name is Juan Pablo. I like to be called I like to be called Huampi. I work for Lulabot as a developer and I wrote a book on Drush a year and a half ago. My name is Jeannie Finks and I work as a, I manage a Drupal support team at Acquia. I'm based in Boston, United States. And I've been building and managing a Drupal site since 2007. And last, but not least... I work at Acquia, a Drupal gardens engineering team. And I contributed to Drupal 6, Drupal 7 core. Hi everyone. I'm Greg Anderson. I'm going to be your presenter today. I started contributing to Drush in 2009. I've been a co-maintainer since 2010. I'm the original author of some useful features like site aliases and SQL sync. So thank you all for coming to the lab today. Alright. Hope most people brought laptops. Get them out. And we're going to start using them now. If you don't have one, hopefully your neighbor can let you look on. Pair programming is definitely a great way to go. So hopefully everyone at least has a computer to look on to. Alright. I'm going to call up Greg. Let's get started. Alright. Good afternoon. It's great to see everyone here today. First of all, I want to tell you a little bit about our backup plan. I was told that we should count on the internet failing. And so I've done exactly that. If for some reason you can no longer use the internet, you can switch over to our access point which has an FSID of Drush Lab If you're hooked up to this access point, you won't have any internet whatsoever. But that's no problem because you're going to be able to pull the slides up from Drush.org flash frog. And you're also going to be able to run Drush PM download for any 7.x contrib module. Got a whole clone of Druple.org up here. So if later you're going in and you want to try the Drush command for some contrib module and it's not on your machine you can still download it. Which might happen if I mention something along the way. But I'm also hoping that many of you today have brought your own dev sites and might get into making Drush commands for the contrib modules that you already use or maintain. I'll just add that URL Drush.org flash frog. Go ahead and download that to your machines that PDF just in case it's good to have it locally. The other thing you can do is copy and paste from the demos that we have put there and the exercises we have there. So go ahead and get that. Yeah that's a great point. So the slides are available in PDF form at that URL and you'll find them at that URL both on the real internet and the fake Drush Lab internet. So go ahead and pull them down and you can follow along as we go. So I would like to make a little announcement. I think probably almost everyone in this room has probably already noticed that Drush is now on GitHub. We made this transition a little while ago just before the release of Drush 6. And I would say that overall GitHub is working pretty well for us. We were there because we were having continual frustrations with the Drupal.org module versioning scheme which makes a lot of sense for a contrib module that's tied to a given release of Drupal but didn't make a lot of sense for Drush since Drush works with multiple versions of Drupal. People were always saying which version of Drush goes with Drupal or the 8.x7.x branch doesn't work and Drupal 7 does it but they were wrong it did. So now it's just very simple. We've got right on the homepage the list of all of the branches which are now much simpler now. What version of PHP you need and what version of Drupal it works with. And this is a really good place to go if you're considering pulling master. So a lot of people ask you know is it safe to use the dev versions of Drush and most of the time it is. All of the maintainers use today's head and their day to day work. So it's not terribly unsafe for you to pull that but of course we do sometimes break head to try never to but if we do break head you can go here and see that'll say build bailing you can just not pull on that day. The 6.x branch of course is a lot safer than master anything that's stable from master that we put in we're going to backport the 6.x branch. So if you want to keep up to date you can do that of course if you're using Drupal 8 you have to be on the master branch. So the Travis integration and inline comments have been great pull requests have been great some challenges like pull requests for example makes it a little challenging when you have multiple people working on the same patch compared to Drupal.org. But you know overall it's been working out just fine. Alright as we go through the slides today you'll notice that a lot of the slides are labels with exercises. An exercise is something we're all going to do together they're all pretty simple it should just take a minute to type it in so you can see things working and understand what we're talking about it's not necessary for you to do the exercises if you don't want to but it's helpful and recommended and it'll help get you started for the lab portion at the end once the presentation is over. Other slides are labeled demo and these are things that I'm going to show you but you don't need to type them in yourself you certainly can. But if you skip it you won't fall behind. And finally near the end I have a few bonus things in the slides and these are examples that I'm not even going to show you but you can go back and try it on your own later maybe in the hands-on lab portion after the presentation or maybe later. So the presentation portion is going to go through several stages of Drush. I'm going to start off showing you how to make custom commands for Drush and even if you're an old hand at making Drush commands this should still be an interesting part for you because I'm going to introduce the new output format feature from Drush 6. Then I'm going to go through a couple of simple Drush techniques you can use that are useful and describe some ways that you can use Drush Hook and Drush configuration to make your development life a little easier. Apologize for the pause as I'm not going to get through this all. I don't keep hydrating. If you want to create a custom command for Drush it's really easy and there are tons of resources all over the place. The often overlooked Drush topic section has topics on all sorts of different things. You should always go there if you're looking for information on Drush and in particular Doc's commands and Doc's example section will show you how to write Drush commands. APRESS very kindly allowed me to put the Drush chapter of the definitive guide of Drupal 7 online as a sample chapter for free download. This is covering Drush 4 but it's actually still surprisingly relevant for even Drush 6 and Drush 7 although we've added some features the information in there is still useful. There are some Drush command file snippets. You can follow that link when you download the slides. If you're a Sublime Text 2 user a few macros will give you a skeleton that you can use to start writing a Drush command. And then we also have an example command that will show you XKCD cartoons and of course all of the Drush commands inside of the commands folder are also excellent examples that you can use to base your work on. I'm not going to show you any of that. You can find it later but I am going to show you the new Drushify tool. This is a simple code generator that you can run on the command line and it will very quickly throw together a little Drush command for your module. So first I'm going to show you an XKCD example and hopefully you have the slides downloaded if you want to be a smart guy or gal and run this yourself. There we go. So the XKCD command I ran it. It looked up some metadata on the internet or the fake internet actually and it pulled up this little XKCD cartoon. Now I'm showing you this not only to show you how cool Drush commands are but I also wanted to show you this particular cartoon. Maybe you've seen it before. If you're an XKCD command fan it talks about how long people spend building tools versus how much time it really saves them. It's sort of a humorous piece. We all are very interested in efficient processes and sometimes we spend more time being efficient than it's really worth. So we're asking is it worth it? And the graph is completely accurate in terms of there's a one to one mapping between time spent and time saved but he really kind of sells short the idea of modernizing and making your life more efficient with tooling because of many reasons. One thing is that the time you save doesn't just pay back to you. It pays back to the whole community especially in Drupal where your Drush commands can go into Contrib and they can go into your Contrib module and then other people who are using that module will also save a ton of time by being able to do things with your module on the command line. A side benefit of having Drush commands just beyond the efficiency is it makes great sample code for people learning about how your module works because there's a very regular template for Drush commands. You can go in and say hey here's a Drush command that adds a new foo and you can look at the implementation of that and there's the API for creating foos and if you need to put that into your module file instead of calling it from Drush it's easy for you to do that. And finally not all time is created equal and if it's the end of the day and there's an emergency and you just need to get something done and you can do it in two minutes with the Drush command and it would have taken you 30 minutes without well you're probably going to value those 25 minutes you saved a lot higher than if it happened in a non-critical time. So I just wanted to go over all of that to encourage everyone here. If you're in this lab I'm sure you're really interested in automation. I want to tell you that there's benefits to that beyond the obvious. Back to the slides. You can look at the setup later. The XKPD command is in the example folder which is a search by default. You can either copy it over or put it in your dashi. Okay, so we have now reached our first exercise. I'm going to do a demo for you of the Drushify command but if you're fast you can run the whole demo and be done with it before I even finish describing it that quick. So the first step to just go to your command line and type Drush Hello this is your control to prove that I'm not pulling a fast one on you. I didn't write the Drush command in master and sneak it in so that could pull it. You should get an error that says the Drush command hello could not be found. So the next step is to type in Drush DL Drushify and that will automatically go out to Drupal.org either on the real internet or the fake internet and download this tool and it automatically puts it in your home.drush folder where Drush can find it and it automatically clears the Drush command cache. You always have to say Drush CC Drush doesn't do anything that modifies the commands but if you're using a Drush command to add your Drush command it will do that for you. So after you downloaded Drushify just type in Drush Drushify Hello. What this will do is it says we want to make a new command file called Hello and there's an invisible second parameter here which is the name of the command that you want to create. If you give your command a name it names it the same thing as your command file. So this is going to make a command file named Hello with a Hello command in it. If you are successful in doing that you can then type Drush Hello again and it should give you a little message that says not just Hello World but it gives you a whole table of Hello World in different languages and they did that so that we could demonstrate output formats. Does anyone have that running yet? Yep okay cool. So I'm going to do it quickly for those who don't have laptops or those in our studio audience. Oh I think I forgot to erase my Hello command. Oh good I did remember to erase it. Oh yeah and there's one more feature of Drushify that I forgot to mention before you notice that it just opened up an editor that has the command that it just created in the editor because unless you're actually writing the Hello World command you're probably going to want to edit the command right away. So you can just scroll on down to the command implementation here which is Drush Hello and you can change the implementation from Hello World to whatever you want to write and we'll return to this demo a little later. Oh alright question for me? Yes. Oh the Drushify command is an external Drush command. It's on Drupal.org as a contrib module. So that's why you had that step to download it because it's not part of Drush. And it works with Drush 5, it works with Drush 6, it works with Drush 7. If you run it with Drush 6 or later you get output formats. If you run it with Drush 5 it just works with Hello World with no table because Drush 5 doesn't support output formats. So basics of output formatting in the past if you wanted to produce output with a Drush command you would just print it. Oh and I've got a self bug here. There's actually a Drush print command that you should use instead of the PHP print command. I apologize for that. In Drush 6 instead of printing your output you should return it. And when you return a data structure from a primary Drush command hook in Drush 6 or later. Greg can I pause you for one second. For people who are still on the Drushify example, don't do this from inside of a Drupal site. Because you're trying to create a command and it won't work from inside the Drupal site. So go CD out of Drupal and do Drushify Hello and then it will write out a file and then you will have the command available to you. That's a really good point. If you're inside a Drush command and you say Drushify Hello it's going to look for a module named Hello and it says no module found. This Drushify command is all of two weeks old so it's not very happy in terms of error correction. But besides CDing out of your Drupal site another thing you can do is you can say Drush at none Drushify because the none site alias will tell Drush to ignore the CWD and act as if you are outside of a Drush context. And then you can write a Drush extension that's not part of a module. If Drushify sees that you're creating a command file when you're not inside of a Drupal root then it creates something inside of your home.drush folder which should be Drushify does. It should work with Drushify. Oh to open the editor. Okay so I only tested with like 5x and 6x and master. Okay 5x8 and up is a requirement for Drushify. Great. Alright are we ready to go on? Yeah so if you return data Drush is going to render it for you now. Yes. Oh I'm sorry I didn't realize I was drifting away from it. Is that better? Oh okay yeah the question was more of a comment. The Drushify command only works with 5x8 and higher. If you use a really old version of Drush it doesn't have a utility function that I'm using and it gives you an error message. Okay so the next thing we're going to talk about is the format option. Drush provides many built in formatters that work with all Drush core commands that produce formatted output. There are array formatters and an array formatter can take any array and print it out no matter what its structure is. So there are examples of this are like var export and printar and yaml and json. Drush does all of these by default. So in the old days when you were using a Drush command and you used dash dash pipe to get machine parts of output you only had one choice and different commands would make a different choice about what output format to use. But now you can specify dash dash format and see your output all sorts of different ways. There are also lists with various separators so it's really easy to make a comma separated list or a space separated list and tables as we saw with the Drushify command can be easily formatted from a relatively complex, convenient for machines two dimensional array into something that's readable for humans. So commands return data and formatters render them. So you can follow along with this. We're just going to run the Drush hello command which uses output formatters and we're going to format it in different ways. So first we'll do var export. Do you want the terminal larger? Sorry? And higher. Move the terminal higher okay. I don't want to type clear because it's going to drift to the bottom so I want to make the terminal smaller so the bottom is actually visible. How's that? Can you see the bottom now? Good? Reasonable? Okay format equals var export. This is your most useful format as a developer because this will show you the data structures exactly as the Drush command returned it. And of course you've already seen the output without any formatter. You can see how it takes this array and prints it in a table. But if you don't want to see it in PHP you can also see it in JSON or YAML. All sorts of useful stuff. Again if anyone wants help we have lots of people up here. If your hello command isn't working we're happy to help you get that working. Okay so if you're following along open up the file that Drushify opened for you and scroll through the file until you get to the command record. If you're defining an output format for your command the first thing you need to do is specify what the default and pipe format should be and that's done in a very straight forward way. The pipe format is following along in the footsteps of Drush5 and earlier the dash dash pipe command option that I mentioned earlier in Drush5 and earlier will output code in a machine parsable format and that flag is still available in Drush6 or later. So your output format just needs to say by default what format is best for your command when someone uses dash dash pipe. The next thing that you need to specify is the output data type and here we've picked format table. There are a number of available output data types. A format table is what we just saw with the hello world command. It's an array of arrays with rows and columns. Format list is a simple one dimensional array that might be an associative array with keys or just might be a keyless array and a format single means simply a single string. Then there's also one funny data type if you want to say that your data structure is just weird and it's not usable by any of these other commands or sorry format types but you do want to be able to format it with their export YAML, JSON and so on and so forth. Then you just set the output format type to true which somewhat regrettably is how you get into the situation. But the reason for this is if you don't specify the output format at all then you're just telling Drush that you can't predict what your output is going to look like and the user is then allowed to select any format or some of which might give you runtime errors that can't render the output the command produced. So the reason that we specify our output formats by type instead of just listing all of the formats that our command supports is that Drush allows you to add more output formatters. Like at the moment there's no XML output formatter but you could write one in a Drush extension and register it with Drush and say that it will accept any of these data types and then a user will be able to say 1.9 equals XML and that will work with all of the commands that have declared that they work with that data type. A little tiny bit more work for you but it gives us a more flexible system for adding unanticipated data types. Drush also does a lot of nice work for you in terms of managing fields and we'll see this in some of the demos that are coming up. In order to do this all you need to do is specify your field labels and your field default. The field labels is just an often very very long list that maps from the machine readable ID for your column or field to the human readable string that you want to appear in the text output. And a field's default lists which fields should actually appear in the output. Sometimes your command produces tons and tons and tons of data in the array which is useful for machines that are calling it but you don't want to see all of that data by default. And we'll see how this works in some of the following slides. So I'm just going to demo this quickly if you want to follow along you may. So the first thing I'm going to do is use the dash dash fields command to specify that I only want to see the message field. And you can see there that it just shaves off the language or if I tell it that I want to see the language field it shaves off the message or we can reverse the order and say I want to see the message first and the language second. If you want you can also shave off the field labels and keep the data the same. So for example if you run drush status and ask for just the drush configuration line then you will see this big list of files that drush loaded for your configuration. But if you wanted to parse this output then you might want to add in a field labels equals zero. So if you just set this to zero instead of listing the fields you want to say you know I don't want to see any of the field labels and then the field labels go away. Now you have a space delimited list of file paths and you can parse that nicely. Moving along here is a mapping that shows the thing I was describing earlier. Here is your field label that maps from language to language and message to message and if your command results outputs an array of rows each row having columns that are tagged with this machine key then you can see that the data from the command output up here is in the body of the table and the fields from the field labels clearly enough shows up at the top. That's fairly straightforward. So here's our next exercise. We are going to see how these commands that I just showed you work in practice by adding an extra field into the hello output. Select that so that I can quickly come on over here and paste in English for the first one easy. Let me see if I got that wrong. Finally the all important thing on is plh in case your user absolutely has to know ISO code. If we run address hello you will notice that the output hasn't changed. Go on to the next example to explain why that is. I haven't defined these fields and since the field's not defined Drush is going to ignore it. So now I'm going to go ahead and say that the code label is the ISO 639-2 language code and that is up here in the command record so we are going to paste that into the field label section inside of your output format and we are also going to modify field default. Let's not modify field default yet run address hello and see what it does. So there we go. We've defined what the label looks like but the output is still the same because our default field does not include output. So now I'm going to come on over here to the field default and say in addition to lang and message we are also going to put in code. Save that and then when I run address hello again now you can see that it's added one more field. Oh I need to move my terminal over. There you go. That's better. Is that clear? Yeah so that left most column there is new that just finally showed up after those steps. So you should see the ISO 392 column here if you successfully added things. So hopefully you have the slides that you can see but here on the screen is that big enough? I can make that a little bigger. And for those of us who walked in a little later after the start and some of the other resources for this session can be found at drush.org slash prog. And I guess this just highlights the fact that drush commands often have more fields available to you than what are shown when you run the command by default. So if you go look at the help for the command you'll often see the additional fields that you can request if you want to. So I'm going to move on to the drush technique section. The first thing I want to show you is hopefully a lot of you are already using this feature. It's the ever-useful drush quick drive. So I'm going to move on to the drush technique section. The first thing I want to show you is hopefully a lot of you are already using this feature. This is the ever-useful drush quick Drupal command. And this one command will fire up a complete Drupal site for you for your testing pleasure. The first argument is the name of the folder that you want your Drupal site to be written into. And following the first argument is just of modules that you would like to download and enable at the same time that you're installing the site. So for this exercise I'd strongly recommend that you include Devel. If you don't include that, some of the later stuff won't work. Auge and CCK are what I recommend, but if you're feeling wild and crazy you can pick some different modules that you want. Or if you feel like it, even though I labeled this an exercise instead of a demo, if you've brought your own Drupal site, this is actually an optional exercise, so you can choose to just use the one you've already bought. Brought. Yes. Yeah, no, I got it. Sorry, I'll repeat the question. So the question is, can you get rid of this extra schlock that drush makes? Because it makes a very long name for the root folder, and then inside that it makes a folder named Drupal. So the answer to the first half of that question is that the first argument, if you specify a first argument here, then you won't get that very long name folder. It'll instead be named prod. And I don't have, as Moshe mentioned, sometimes the option lists for drush commands or drush fields are really, really long. I don't have all of the site install or QD options summarized. We can look for that during the lab, but off the top of my head, I don't think you can get rid of that Drupal folder. For my part, I really like to have that folder there. I don't call it Drupal. I call it HT docs. And usually the root folder I name after my site. And the reason I do that is that I'm still checking in my whole Drupal site into Git for revision control. And so having one extra folder that's outside of the Drupal site allows me to check in assets that don't belong inside the Drupal root. Now if QD and SI do not have an option to get rid of that field, that second folder, I think that's an excellent feature request. And patches are welcome. If you're really nice, someone might even write it for you. But I could imagine an option where you give it the name that you want that folder to be, or you set it to zero following the Drush convention if you just want it to go away. It would be easy to add that feature, but I don't think anyone's written that yet. So the next thing I wanted to mention, if you're running QD and you do not have SQLite installed on your computer, then you can, instead of using SQLite, specify the specific database that you would like to use. And hopefully you have some SQL database on your computer, I guess, that everyone at Drupalcon must. So if you're not using SQLite, then you have to create the database yourself with my SQL admin. There are some Drush commands like SQLsync that will create DB as a service, but QD currently is not one of them. That would be another good feature request. So I'm going to just quickly fire off this command. If you run QD and you get an error about the run server part not working, it means that your PHP is not quite set up enough to use run server, but your Drupal site is functional. You just can't look at it through a web browser. It'll function in Drush. That's right. The comment from the field was there's a no server option that you can skip the run server part with. It is a harmless error though. If everything is running correctly, it should take you all the way through the install process. We had a funny little feature request in the Drush issue Q once about this message that says, this takes a few seconds and our contributor said that maybe it should say something like, you know, this takes an extortably long or go get a coffee or something like that. But I timed this and if you're running the same one that I am, it only takes about a minute to go through the whole thing. Now, minutes are really a long time in a presentation or if you're sitting in a lab wondering if it's going to work or not, but it's really not that much time out of your life. So just let this run in the background and eventually if your run server is set up, you will get a browser window that will open up. And this browser window is also going to show up on my system. It may or may not interfere with my presentation. But if I'm suddenly interrupted by a Drupal site, it's just our exercise working correctly. So if you're not finished with this exercise yet or if it's still spinning, don't worry about it. Just put that terminal session aside and open up another one who we're actually going to use this example Drupal site way at the end when we're doing the open collaboration. We won't use it during the other parts. We may use it in a demo though, so keep it handy. Oh, here it is. See, I mean it can go by pretty fast when you're gathering. So the site install command just finished on my computer and you can now see that I named my site Prague. So Drupal cleverly tells me welcome to Prague and I now have a site with AUG, CCK, and Devel that's all ready to go. We'll come back to that later. So the next thing I want to show you is Drush FN hook. So if you're following along, you'll need your site. So be sure to change your working directory to the site that you just created which should be in a folder called Prague slash Drupal, that's your Drupal root as we discussed in the previous question, and then we're going to run Drush FN hook menu. This is a really super useful command provided by Devel which we cleverly just downloaded. So I'm changing my Drupal root into the site that I just created and now I'm going to type Drush FN hook menu and now Drush is going to go and look at all of the enabled modules in that Drupal site and it's going to give me a really long list of all of the modules that enable or that implement the menu hook and I'm going to just arbitrarily say I would like to see AUG's implementation of hook menu and my font is big so it kind of overflowed. You can see here's the implementation of AUG menu and it also shows you the comment that appears in the source code before the function definition, the file name that the function definition appears in which no surprise is a .module file and it also shows you which lines it appears on. Yes. Can we split this output into pages? Sure. We can pipe it through more and drum roll. Oh, darn it. No, you can't. Well, not really. It's not really an impossibility control C on out of here. This is a good segue into my next demo. You can see here that it told me hook menu is called AUG menu. We pretty much all know that already but if you didn't, there it is, you can see it. Now instead of using fn hook, we're going to come on over here. Can you read that if I don't full screen it? We're going to use fn view instead of fn hook and this will do the same thing but we give it exactly the file or the function that we want to see say drush fn hook AUG menu. Sorry trying to type the right command but somehow my fingers had other ideas. Okay, and there we get the same output and now the problem with fn hook is that it had interactive output which got in the way of more but since we're using fn view here we can pipe it through more and you get a pager. There are some drush commands like drush topic that will do a pager for you and so that would be a good feature request. We could add that to drush or to actually to develop. You'll have to track down the develop maintainer and ask him. And another really cool function that I like is drush ev which just or php eval it's the full name of the command and this function just runs a little snippet of php but of course it does a full boot strap of your Drupal site first. So this is a handy way to find out if there's some function. I forgot to escape out of this again. Okay, here we go. Escape. I'm going to select this so I can run it. If you found some function and you're curious how it works I'm going to run this on the sample site first just so you can see it's going to bootstrap the site. Oh, yeah, no wonder it got strange output. Thank you. Drush ev this command. If I found this function called drush get entity groups and I want to know what it returns then I can just use ev to find it. Now of course drush is not a replacement for your full IDE to let you do full source code debugging but sometimes you just want to see really quickly what the function is and you don't want to have to open up the window and set your break point and run your command in the context of the debugger. So it's the right tools for the right time. If you run this command and you're following along and you run it on the site you just built it's going to produce no output because of course you don't have any groups and you don't have any memberships. But I have another site so I'm just showing you here that ev of this function does in fact return an interest spring structure and you can see there's a node in there and there's an associate of array that goes from a 2 to a 252 and if you use this in conjunction with reading source code it'll give you some insights into how this function works because you can see it's output. Yeah, that's a very good question I typed return and then I called to the function you could also do a printar or a print or a var export and that would work the same way but now the ev command supports formatters and the nice thing about this if I say print you get only what the command prints but if I run it with return then I can use a format equal to json and if you for some reason want to see your array in json then you don't have to type out json decode or json encode I mean. Again, there's many different ways to do things they're all going to work out pretty well but the right tool for the right time I find that drush ev can be really useful. You can just skip the other demo you don't really need to see the output of node load. Alright, so next up I'm going to show some interesting little drush hooks that will help you optimize different steps that you do frequently drush has a very complicated working system that allows you to modify the way a command works either by doing something before the command executes or after the command executes and true to the Drupal pattern the way that you hook functions is that you carefully compose a function name that matches the pattern and it has your command file name inside of the pattern and also has the name of the function that you'd like to hook and sometimes it's hard to figure out exactly what pattern you should use if you want to write a hook for some new drush command. So a useful way to figure out what your hooks are is to use the dash dash show invoke global function and this is going to print out all of the hooks for all of the drush command files for the command that you run and in this particular example I'm interested in only the hooks that have to do with my new hello command so I'm going to redirect standard error to standard output and pipe that through grep hello let's see what that looks like there it is with color disabled for some reason the next hook that I want to show is the post pm enable hook and this is a really useful hook to patch into if you have a contrib module that has external libraries and if you're using a module that needs some other library then you have to read the project page and it says go to this website and download this tarabile and find the right folder to uncompress it and this is a bunch of additional steps that your user has to do before you can start using your module there's quite a few modules that implement a post enable hook and it automatically develops one example of it when you enable the develop module it automatically runs a download function to go and get the fire core php extension and it extracts it in the right place so when you're using the drushify command to create a new command template it's automatically going to put one of these post enable hooks as just a hint that you should really think about implementing one of these if you have external libraries that need to be downloaded if you don't have any external libraries you can just of course delete this function next up is the sync enable hook inside of the drush examples folder there's a command file called syncenable.drush.inc and if you'd like to use this feature all you have to do is copy that example command file over to your dot drush folder in your home directory if you do this then there are going to be additional options available after SQL sync and one of those options is dash dash enable which takes a list of modules to enable another example is dash dash disable which takes a list of modules that you'd like to disable and if you take these features and combine it with drush site aliases and the command specific feature you can make yourself a little record that says whenever this alias is the target of an sql sync command then I want to use the enable option to enable develop and state file proxy and then sync enable also has a permissions setting feature so you can tell it that I want access develop information to always be enabled so this way if you sync from your live site to your dev site then you don't have to go through the steps of saying oh my gosh I forgot to do something obvious like enable the access develop information and that's why I can't see the tabs in my debugging which is very useful to not have to continue to remember the same thing again and again so this has been in the drush examples folder for a long time so as an aside a couple of times people have asked me about the sync enable hook and say well can I also set variables every time I sql sync my site and the answer to that is no that feature isn't there and it wouldn't be difficult to add it but there's no point in adding it because the better way to do that is to just use the drupal function to put overrides inside of your settings php file and then those are always there and you don't need to worry about changing the database every time you sql sync it. So the next hook I wanted to talk about was the sanitize hook sql sync has a feature you can pass sanitize and it'll do its best to clean up any user data that may be sensitive but drush is extensible so if there are contrib modules that may add additional tables that might contain sensitive information like social security numbers or bank account numbers or missile launching codes or something like that then you can add your own hook that will clear out the fields of the tables that you add and it's really easy to use all you have to do is generate some sql that you want to run on a sanitize operation and register a post sync op by calling this drush api function and then your cleanup function will happen at the end of the sanitize yes you have to put this hook into your drush.ink file inside of your module so you can use drushify with your module name to make a basic template and then you can fill this hook in and add your particular sanitization so then drush will find your command file and clear out that information so finally I'm going to go through some drush configuration things you can do to make your life easier quickly drush configuration files are just php code so you can run any command that you want when you're setting up your function the one example I'm showing here we call the grayside function because grayside contributed this to the drush queue and we put it into the examples folder and we run get rev parse to find the root of your get directory and then we set options config, options include, and options alias pass and you can of course do a subset of these to tell drush that I would like to look for commands in this location aliases in this location or I'd like to source this specific drush rc every time drush loads up and I also want to call out this new drush feature if you treat this option like an array and append something to it then it will add on to the configuration that drush provides by default to adding an additional path or an additional file if you get rid of the array and just assign a string to this function that will blow away the array that's already there and then the paths that drush adds by default will be overwritten so if you don't want to search these standard locations you can get rid of them so just to add on to that the usefulness of this grayside example is that a team of developers can share get configuration or sorry drush configuration in aliases just by creating a drush folder at the top of your get repo and all the commands and aliases you put in there are going to be shared by everyone just when they get pulled so it's a great way for teams to share their drush stuff, command files, aliases, and configuration you can also do your configuration based on location this is a little example of something that I do in my drush configuration I check to see if my current network gateway is the gateway that my company has set up and if it is then I set a context that says that I'm inside of my company's intranet and I use that context later inside of my aliases file so if I'm inside sorry if I'm not inside of my company network then I add additional ssh options to add a proxy command to send all of my ssh connections through a bastion server so the result of this is when I union this in with the parent directive on one of my aliases then that says that this internal machine is internal to my company and if I'm sitting outside of my company then my ssh's to this machine will all go through this intermediate bastion which is pretty cool because it means I can use drush commands on a site alias and they work exactly the same whether I'm inside or outside of the firewall because I've provided these instructions on how to tunnel around through the firewall and I actually use this for non-drupal purposes drush has an ssh command and it has an rsync command and both of these commands recognize the ssh options that I set here so I can ssh into a specific work machine or rsync into a deep folder of a work machine and I can just refer to its name by its drush alias and this is a pretty handy technique someone pointed out to me earlier that I should be using IP instead of route but I didn't have time to change my example so here's a bonus example you can also make yourself a little shell alias an example that comes from the drush examples folder a certain anonymous drush contributor made an editorial comment that in the case of the examples folder was limited only to overlay and dashboard so the alias took out overlay and dashboard now you may or may not think that overlay and dashboard suck and in my case I don't particularly like tool bar or shortcut I prefer admin menu I don't really think they suck but I just think that there's other contrib modules that work better for me and since the unsuck command was there already I just piggybacked on top of that so now if I go into a drupal site then I can just type drush unsuck and it's going to strip out the stuff I don't like and put in the admin menu and I say I can find my admin pages again so I just never got used to those other things I'm sure some people like them but the point is if you make this little command then it's fast for you to set up your preferences and there's lots of ways you can do this you can set up features or whatever but it's the right command for the right tool for the right time that is pretty much the conclusion of the main content of the presentation part today and so now I'm going to in this next couple of slides I'm going to start talking about some things such as some contrib module statistics that can slide into our post presentation activities and you know break up into groups or work independently I'm going to have a number of choices for things to do but first I wanted to point out that when I cloned Drupal.org 7x modules I found out that at the time I did it anyway there were 5,495 of them another interesting thing about that is I read a really recent Drupal Planet post that says that there were 7,200 some of them not too many weeks need to go by before this number grows fairly substantially but of these many modules that exist on Drupal.org only 429 of them have a drush.ink file it's a little more than 5% so one of the things I'm hoping today is that we can start getting this percentage up a little bit of those 427 27 of them have a post-pm enable hook I think that's pretty impressive that's pretty appreciable but it would be even cooler if that number was higher because I think there are more than 27 contrib modules that have external libraries and getting back to our XKPD cartoon from the beginning you could save a lot of time for a lot of people if you just implement one of these because you as a module maintainer know exactly what the library is and exactly where it goes your users take quite a few minutes to read through your documentation and figure that out and finally of the 7,495 modules that I downloaded only one of them had a sanitize hook which is too bad and I really wish that I had a prize to give out today so I would like to give a prize to the person who could say which module implements a sanitize hook I don't have any prizes do you have any takers anyone guess sorry migrate not migrate good choice brush itself okay not a module you almost got the I wasn't thinking of that prize anymore so the one and only one module that implements the sanitize hook is the paranoia module and the reason that's really ironic is that paranoia only sanitizes core fields so we made this hook and zero contrib modules decided to sanitize their private fields and I think that's because basically nobody knows about the sanitize hook so I'm hoping that maybe today some of the people present will say gee I know of some private fields in database tables of contrib modules that I use or maintain and maybe add one of these because they're pretty quick to add and the huge advantage of adding one of these is if you want to sanitize your Drupal site you don't really have a good way of knowing what your contrib modules are adding in the way of user sensitive information so finally of the top 100 downloaded modules according to Drupal.org 35 of them have a Drushink file that's great that's up to 35% way more than 5% but it still means that there's 65 modules that don't have a Drush.ink so perhaps some of these might be just APIE like jQuery update probably doesn't need one so some of these can be filtered out is not important but still there's a lot of examples here if you're looking for inspiration of something to experiment with maybe pull something off of this list but it doesn't have to come from this list if you brought a site today to enhance some module that has some tasks that you do frequently you'd like to automate. Another thing that you can do is work through the bonus exercise that follows in the slides I'm not going to do that up here because I figured that then this would turn into a two hour presentation and that would be brutal for you and for me so we're not going to do that but the information is available in the slides and it's easy to step through. And those slides once again are at drush.org slash prog you can download all the slides including the bonus slides and work through them right now and we're here to help. Yeah and I was just too jet lagged to have the bright idea to put the slides linked from my session page but I'm going to do that right after the session so if you forget drush.org prog but if you do you can go back to the session page and shortly I'll have a link from there as well. And so finally after today I'd like to call on everyone to participate. One of the great things about Drupal is how active all of the queues are and you know drush is no exception we've got our issue queue on github which is active today and contribute additional features bug fixes or feature requests and for support we've migrated support over to stack exchange and we've got a link to this right on the project page in the readme file too. So if you have a question or you want to help answer questions just head on over to stack exchange. So I'm just going to zip through the slides so you can see what's here in case you want to do it. In the bonus materials I've used drushify to make an example cck command called create content type and then I just show how you can modify the command record information that drushify creates for you to have information that's relevant to your command and then I said since what I want to do is programmatically create a content type for cck I went out to the internet and on google I typed drupal 7 programmatically create cck content type and I found a whole bunch of pages that all pretty much did the same thing so I took one of those and I pasted it into the implementation instead of what drushify gave me and I ran it and it did something and then I went through and I changed it to look at the command line options instead of the hard coded stuff and I made a drush command in almost no time at all so if you want to step through those steps while there are people here to help you with them you're welcome to do that or do your own modules or we could also get up into discussion groups if you have anything that you'd like to talk about in terms of drush futures or implementation just find one of us and we can get something going so if you have any suggestions yes yes let's repeat I'll repeat the question so yeah that's actually a complicated question what are the advantages of using drushmake or the post-pm-enable hook so I think the main use of make is to download all of the source code for a site the next step would be to install the site typically after a make so that's very early on in a site's life cycle when you're using make when you're using make-enable it can be a site that is a day or 3 years old or 10 years old you're enabling a new module and you just want a library to come along for the ride that's the typical use case for pm-enable if you're using make on a site that's been around for a long time you're in sort of a team developer workflow and it's a little bit of a specialized use case I think when you're in that use case using make for that is fine I think there is some overlap but I think the pm-enable case is kind of like the common man lots of people do it lots of times and the make case is very special developer team kind of thing I want to add something to that too because a year or two ago I got into this idea where there was actually a couple blog articles about you know every Drupal site is an install profile it's like yeah that's a great idea so the first thing I'm going to do when I make a new Drupal site is I'm going to make an install profile and I'm going to type in all of the modules I need and I felt so accomplished and rigorous doing this and then I also found that my productivity fell down to like by a factor of 10 I'm like oh my god I can't I can't deal with this so what I did was I switched back to the DL and enable workflow and the last site that sort of worked for me then I wrote a code generator that made an install profile out of a running site and that works for Drupal 7 and it doesn't have the template files for Drupal 6 which is why for more than a year it hasn't been committed it was more than a year in the Drush queue and it recently moved over to the module builder queue the maintainer there said hey I'll take this when we closed all of the old Drush issues so after this conference I'll probably work on that and then there's also you know Moshe's answer was best it's pragmatic but I also want to give a really niggling answer and that is inside of Drush make there was an idea for modules to provide their own make files and yeah and you did that okay there's a huge issue and I can't even get into the issues in the issue about why it's not very convenient for a module to do this and one of the reasons is if you don't want it then you have to put in what I call a don't hurt me flag you know I'd rather say you know if I want something then add it in and you know for the record we do have a don't hurt me flag and the PM enable thing well but yeah as Moshe said it's the right tool for the right situation and make is a good way to do that as well yes it shouldn't okay yeah let me answer the question for the question is it would there be a conflict if you added a post enable hook is that going to screw up your install profile and the answer is no because when you run the install profile it doesn't use Drush to enable the module so the Drush post enable hook is only going to run when you PM enable from Drush it's not going to run if you enable from the UI or from an install profile any more Q and yeah if you yeah if you turn it on with features using Drush then you're also not using PN enable and you do not automatically download the library you know I'd have to look at the implementation to say why because I don't know about the implementation of features if it calls invoke or whatever maybe I'm even wrong maybe it does do it yes the model is that the maintainer picks the version that's best but if there's multiple versions that might be relevant to the users of that module you can use the Drush help alter hook to add a flag and then they could specify the version that they wanted in a flag to PM enable or you could even go so far as to call Drush choice from inside of your hook and prompt the user for which one they wanted I would tend to discourage interactive input inside of PM enable it wasn't expected it is an option if you want that any more questions all right well I bet a couple of us will be in the back of the room if anyone wants to get a little circle together and do a quick Drush buff we're happy to do that kind of discussion thing a bunch of us will be walking around helping you get through these slides helping you get through your own Drush commands also and definitely do give us feedback okay and this is our first time doing a Drush lab with this many people trying to figure out the right experience level and the right activities so if you've got constructive criticism or suggestions about how we might structure it differently next time let us know