Drush for Developers, 2nd Edition
This book review was published by Slashdot, .
As with any content management system, building a website using Drupal typically requires extensive use of its administrative interface, as one navigates through its menus, fills out its forms, and reads the admin pages and notifications — or barely skims them, as they have likely been seen by the site builder countless times before. With the aim of avoiding this tedium, speeding up the process, and making it more programmatic, members of the Drupal community created a "shell" program, Drush, which allows one to perform most of these tasks on the command line. At this time, there is only one current print book that covers this tool, Drush for Developers, Second Edition, which is ostensibly an update of its predecessor, Drush User's Guide.
Both editions were written by Juampy Novillo Requena, although in the transition from the first edition to the second, both the author's name and the book title were changed. The most recent edition's title seems redundant, because of course such a book is going to be "for developers"; after all, who but Drupal developers would have an interest in Drush? The edition under review was published on 29 January 2015 by Packt Publishing, under the ISBN 978-1784393786. (My thanks to the publisher for a review copy.) At 180 pages, this edition is longer than its predecessor, but still a manageable size. Its content is divided among half a dozen chapters. Anyone interested in learning more about the book may wish to visit the publisher's website, which provides a brief description of the book, the table of contents, free sample content (Chapter 3), and the source code files.
The first chapter begins by presenting a brief comparison of the steps needed to run database updates on a Drupal website, using the GUI versus using Drush. As expected, the latter requires fewer steps. The author then discusses the prerequisites for installing Drush in a Linux or OS X environment. For Windows, the given download URL, http://www.drush.org/drush_windows_installer, is incorrect and should instead be http://drush.readthedocs.org/en/master/install/#windows-zip-package. The author states that "the installer installs an older version of Drush", but actually the installer has disappeared from its former locations. Fortunately, the current Windows archive file has the latest version as of this writing, 7.0.0-alpha7. This version is more recent than the alpha5 used in the book, but the commands and their options seem identical. On the other hand, it is a large archive file containing the Drush application files, Msys, PHP, and parts of PEAR and Symfony's YAML — but no helpful installer. The chapter continues with explication of Drush command invocation, arguments, options, aliases, and context. The only apparent blemish is that the variable name "site-name" (page 14) should instead read "site_name".
After this introductory material, one would expect the next chapter or so to explain and illustrate the details of Drush commands frequently used by site developers, such as those for installing, enabling, and updating modules and themes. Instead, the author jumps far ahead to much more advanced topics (more on this below). In the case of the second chapter, the goal is to learn how to synchronize code, database configuration, and content among different server environments, including capturing database configuration settings in files so they can be version controlled in Git. This is arguably worthwhile knowledge, but certainly not what the average reader would expect so early in the book.
Readers attempting to follow and replicate the demonstrations in the book, may become frustrated with the pitfalls in the second chapter — such as the instances where it does not provide all the needed instructions, or they don't match the example code. When readers starting from scratch encounter the Drush script (page 23), they may be tempted to try it right away on their own test sites, but this would be ill-advised because the first command will fail until the Registry Rebuild command is installed (later in the chapter), and the fourth command will fail if the chosen website does not have the Features module already installed and enabled. When learning about database updates, the reader is instructed to create a new Boolean field, but only later learns that the test website should have contained nodes of the "Basic Page" content type. When readers learn these things the hard way, they must circle back and redo steps or, even worse, try to revert the state of files or the database.
The mymodule custom module found in the downloadable archive does not match what the reader will need on page 30, so she will need to modify mymodule.install to match that listed in the book, and also presumably comment out the last two lines in mymodule.info related to the Features module — but not the first two, because that would result in worse problems later. This initial code should have been included in the downloadable archive. Before running the command
drush --verbose updatedb, should she have enabled the mymodule custom module? Apparently so, since the expected output includes "Executing mymodule_update_7100", but when I tried it, the provided module's update hook was not recognized as a database update, using Drush or the admin interface (update.php). On page 32, the reader is told to download and enable the Features module, but that must have been done already because the mymodule module required it earlier. Lastly, the book's preface states that PHP version 5.2 (or higher) would be sufficient, but 5.5 is needed, otherwise a fatal PHP error is generated by the empty() call on line 29 of the "7101" example code.
The third chapter covers the use of Drush for running and monitoring a variety of tasks in a Drupal website, such as updating the database or reindexing the searchable content in Apache Solr. The author begins by briefly describing the uses for the cron utility, and some advantages of executing it from Drush. A technique shown for preventing Drupal from running cron automatically, is to set the cron_safe_threshold variable to 0, export it to code (as a Features module), and then deploy it to the target environments. The author also demonstrates how to use Jenkins in conjunction with Drush to periodically run and monitor cron jobs. As an example of running a task without using cron, a Feeds importer is set up to work with Drush, using a custom module and a Drush command to trigger the Feeds importer. It's not mentioned in the book, but for the importer, in the settings for the node processor, be sure to assign the bundle, otherwise there will be EntityMalformedException errors; also, map the essential feed and node elements, otherwise the nodes created will be empty.
The book then explores a number of topics that are somewhat related to one another: how to use Drush and the Drupal Batch API to run time-consuming tasks so as to avoid PHP and database limits of memory and time; how to run PHP code after Drupal has been bootstrapped; how to best log messages using the drush_log() function; how to capture Drush output in a file; how to implement your own logging mechanism by overriding the Drush default logging function; and how to run Drush commands in the background. Despite the complexity of the processing implemented in this chapter, readers should encounter few problems trying it out. For the
drush php-eval commands, Windows command line users will need to replace the single quotes with double quotes. In the section titled "The php-script command", two of the three "php-eval" terms should instead read "php-script" (page 65).
Debugging and error handling are addressed in detail in the fourth chapter: how to validate user input values and Drush command line options prior to passing them to a command's callback; how to define custom validation within a command; how to discover all of the available hooks for any given Drush command; utilizing the Devel module, how to discover all of the Drupal modules that use a given hook, and how to find the location of a given function or class method. In the midst of all this, readers get a detailed tour of the steps that Drush executes when bootstrapping Drupal. Readers should note that, as with the second chapter, some of the code in the downloadable archive does not match the initial code presented in the text, but rather its final state. As readers may have been seen in earlier chapters, the "-- verbose" versions of the Drush commands can produce a lot more informational output than what is presented in the text, including the MySQL commands (that may be a consequence of, in this case, the Windows command line). In the case of
drush --debug testhooks, the output is remarkably different, but at least all of the commands are executed.
The penultimate chapter explores techniques for leveraging Drush to better manage Drupal websites on local and remote servers, utilizing site aliases. Developers will undoubtedly be intrigued if not thrilled with the possibilities of being able to execute Drush, Linux, and MySQL commands within remote environments from the local command line. The only questionable aspect is that in the first chapter it is claimed that one "does not even have to open an SSH connection" to perform these feats of digital derring-do, and yet all of them presented in this chapter seem to depend upon an SSH connection — if not explicitly on the command line, then at least established and used in the background by Drush. Nonetheless, the potential power of using Drush in this manner is clearly significant for Drupal site builders and maintainers, and thus the author wisely shows how to avoid inadvertently corrupting the files or database of a target installation.
The final chapter blends and builds upon most if not all of the topics addressed in the earlier chapters, to show how Drush can be used to set up an effective development workflow for teams building Drupal websites. To this end, the author demonstrates how to move Drush commands out of a project's web document root, and how to use Drupal Boilerplate to achieve this and more. The instructions employ wget to download Boilerplate, but other readers as well may encounter an error of wget not being able to verify github.com's certificate. Readers learn how to use Jenkins to synchronize the Drupal files and databases in disparate environments, how to use Drush commands to improve database synchronization and sanitization, and how to prevent inadvertently emailing production addresses.
Like seemingly any Packt Publishing book, this one has plenty of errata relative to its length: "OSX" (page 9; should read "OS X"), "an input data" (page 14; should read "an input datum"), "inform [Drush] where" (page 19), "Dated" (page 21; should read "It is dated"), "sites/all/drush/command[s]" (page 28), "type Page" (page 29; should read "type Basic Page"), "PHP.ini" (page 34; should read "php.ini"), "cover [the] Queue API" (page 58), "context" (page 66; probably should read "content"), "run[ning]" (page 66), "straight brackets" (page 68; just "brackets"), "thanks to [']allow-additional-options'" (page 83), "require [the] minimum" (page 94), "a valid Drupal's root directory" (page 94; no "'s"), "point [to] our local Drupal project" (page 117), "logged as message" (page 120), "our the $HOME path" (page 139), "password;." (page 149), and "offers [a] hook" (ditto). Some of the phrasing is odd, e.g., "output can be logged in to" (page 34), "tasks running at cron" (page 52), and "equals to 1" (page 61). Some of the sentences are incomplete, e.g., "Importing configuration into the database." (page 34). Fortunately, none of the narrative is incomprehensible, and it is generally smoother in this edition than in the first.
The structure of this book is more logical than that of its predecessor. As Drupal expert Mike Anello correctly pointed out in his review of the first edition, "the book could have easily been improved by splitting out various sections of chapters into their own stand-alone chapters." The same criticism still holds true for this second edition, particularly the third chapter, though to a much lesser extent overall.
As with most if not all titles offered by Packt Publishing, this book's chapters are lengthened with summaries, none of which serve any useful purpose, since they repeat what was presented just pages earlier, but do not include enough detail to be of any value.
One major problem with the book is that it is billed as a second edition to the earlier user guide, which covered introductory and intermediate topics; yet this second edition does not, and instead is almost entirely devoted to advanced topics. In fact, much of the material is preparatory for the final chapter, on utilizing Drush to improve a team's project workflow. This is not made clear to the prospective buyer. This is truly a new book, and not an update of the first edition. Furthermore, it is more focused on specific uses of Drush.
Whether this book could be recommended to any potential reader, depends upon what that individual is hoping to learn. For anyone who wishes full coverage of the beginner and intermediate topics of Drush, this book would be completely inappropriate, and the individual would be best pointed to the Drush documentation. On the other hand, the book would be much better suited for a Drupal developer looking to improve his or her understanding of using Drush for managing database configuration and other topics related to project workflow, particularly in team settings — in which case it could be extremely valuable.