Managing WordPress Dev Environments With WP-CLI and Robo

Automating repetitive tasks is one of the best ways to save time in your development workflow. In my day to day work as a plugin developer, I often have to reset the database, reinstall a specific version of WordPress, install one or more plugins, and update the settings. This quickly gets tiresome, so it’s a natural fit for automation. In this article, I’ll show you how I use WP-CLI in combination with Robo to automate the tasks needed to manage my WordPress development environment.

The WordPress command line tool, WP-CLI, is a great start to speeding up your workflow. If you’re not familiar with it, I highly recommend reading one of our many blog posts. Our installation guide is a great starting point, laying out how to install it on your OS, set up tab completion, and create a configuration file.

Robo is an open source modern task runner used by a number of projects including Drush and Codeception.

Robo is similar to Gulp and Grunt, but using PHP rather than JavaScript.

The idea is that you can create nifty little commands like this:

The Robo task runner makes it easy to document the commands you create by adding DocBlock comments to your commands, so you can provide help for future versions of yourself:

Asking for more info about a specific command:

I’ve created some powerful commands with Robo that I use every day to manage my WordPress development environment. In this article, I’m going to share these commands with you and provide an introduction to Robo commands along the way.

Robo Simplifies Command Line PHP

Let’s check the rear view mirror just a bit. Writing command-line PHP commands is certainly not new. It’s always been possible to just run a PHP script from the command line like this:

And PHP has been available as a command line environment in most *NIX environments for as long as I can remember. Adding the PHP shebang will work in most environments that have the PHP interpreter installed.

Which makes it possible to execute the script from the command line without specifying that it should be parsed by PHP (or including the .php file extension):

The downside of running raw PHP scripts from the command line is that there’s quite a lot of overhead for input and output to take care of in each script. The process of accepting arguments from the command line, and then outputting the messages to the command line is a bit cumbersome and doesn’t feel very flexible.

Robo sets out to make it easier to write command line PHP by taking care of a lot of the standard “plumbing” that most scripts need. This lets you focus on the core functionality of your scripts.

Installing Robo

You’ll need to install Robo before we can get started. I keep Robo installed globally on my machine, so I’ve installed it like this:

But as with anything installed via Composer, you can keep it as a project dependency if you’re more comfortable with that. Alternatively, the GitHub has instructions on installing it by downloading robo.phar.

Your First Command

First, we need to initialize Robo in the project folder:

This really just creates a new RoboFile.php in your folder with the following content:

To add our first command, we just add a public method:

As you can probably guess, the above method creates the command hello and simply outputs a message on the screen.

Parsing Arguments

Just adding that method like we did above is a great way to show one of the more important reasons why I like Robo, namely parsing command line arguments.

To show you what I mean, let’s try to run this command:

Aha! Robo gives me an error message because the hello command actually expects a $world parameter and then proceeds to write out the full usage syntax for the command.

Let’s change the method a bit and make the parameter optional:

…and now let’s run it again:

That’s better! By making the parameter optional, Robo now happily executes our method even without passing an argument. We’ve also seen that we can pass a simple argument and an argument within quotes and it just works.

If you ever spent any time writing argument checking logic for a command line script you probably realize why this is a nice feature. It just takes a lot of pain away.

The example hello command uses one single positional argument. Robo also supports using flags and named arguments by creating an array argument with some default values.

Let’s modify the function further to optionally print out some additional characters:

This will tell Robo that we may optionally pass in named arguments using double dashes:

Input and Output

We’ve also already seen an example using IO. The say() function of the Robo task object simply outputs a string back to the user. There is also an ask() function that lets you ask the user for input:

Robo uses Symfony Console for creating user interactions. This means that besides the two simple say() and ask() functions, we have access to any function from Symfony Console, like table():

Pretty cool, eh?

Great Helpers

Another reason to like Robo is that it has built-in support for many common tasks that makes it easier to write understandable code, even if you’re coming back to it 3 months later. Let’s have a look at how Robo helps with writing very clean code for some pretty standard tasks:

All of the above is possible using normal PHP and the exec() function, but that quite often becomes a hopeless exercise of trying to glue command strings together and correctly escaping arguments without messing things up too badly.

Besides the examples above, there is also similar support for Git, Subversion, Rsync, Bower, Gulp, Docker, NPM, and other tools often used in development environments.

Benefits of Robo

Taken together, Robo makes creating command line scripts a lot easier and the end result is usually a lot more semantically appealing than plain PHP.

I find that scripts for Robo end up being easier to read and understand compared with pure PHP scripts, because so much of the command line boilerplate stuff is hidden inside Robo itself. Personally, I can look at my own code after a few months and honestly wonder who wrote it, so anything that helps me write clear, readable code is a welcome addition in my tool belt.

Maintaining WordPress With Robo

The rest of this article assumes that you are somewhat familiar with WP-CLI, using Composer, and working with the command line.

The Important Files

There are four important files in this setup. I will cover each one of them throughout this post:

My Environment

Just to set the stage for the rest of this article, I’m going to quickly describe how my local development environment is set up. This is a simplified version of how I’ve organized things on disk:

The src folder is where everything development related is stored and the devenv folder holds files specific to the actual runtime environment. Since I usually have more than one WordPress environment running at the same time, each WordPress installation has its own sub folder, named wordpress-dev and wordpress-test in this example.

Each of the plugins I work on sits in a separate folder per plugin.

In the real world, I have multiple devenv folders so that I can keep my work for Delicious Brains separate from various side projects, but that’s not relevant for this article.

Database User

To make everything work I’ve also created local databases for each of the WordPress installations in my local MySQL installation and there’s a database user, aptly named wordpress, with the correct access to those databases. The exact details of the databases as well as the user credentials are stored in the wp-cli.yml file.

Web Server

I’m using nginx as my local web server, but you will find that Apache2 works just as well. My nginx config is set up so that http://www.wordpress-dev.local and http://www.wordpress-test.local point to the two WordPress folders mentioned above.

Taking Care of Dependencies

To make my Robo scripts more flexible, I’m using some additional functionality installed via Composer, specifically the Symfony Yaml parser. Since RoboFile.php is really just a normal PHP file, I’m free to include any libraries I want and I naturally use Composer to do that. The composer.json file for this project looks like this:

If you copy that, don’t forget to actually install the library using composer update.

Leveraging wp-cli.yml

When working with WP-CLI, you can make life a lot simpler by using a configuration file such as wp-cli.yml. I use the WP-CLI configuration file for two main reasons: aliases and setting up defaults for various subcommands.

What Is an Alias in WP-CLI?

At its core, a WP-CLI alias is just a label in the config file that lets you override some of the defaults.

The most common usage of aliases is probably to override the default path so that each alias points to a separate WordPress installation. Since each WordPress installation keeps its own configuration file with database credentials, the alias used this way also represents a separate database. An alias in the WP-CLI configuration file can override the url, path, user, ssh, and http settings, but it can’t override default values for subcommands.

Creating an additional WordPress environment named @test allows me to run WP-CLI commands like this:

Command Defaults

If you haven’t tried this before, setting up default parameters for subcommands is super handy. For instance, when you create a new WordPress configuration file using the config create command, you need to specify at least three parameters every time:

If you ever get tired of typing this, you can stick the parameters into a wp-cli.yml file:

Once you’ve done that, you can just use wp config create and it will pick up the right parameters from your wp-cli.yml file.

Unfortunately it’s not possible to set up different command defaults for different aliases. This was actually one of the reasons I started looking at Robo for more automation.

My WP-CLI config file looks like this:

With just this configuration file in place, I’m able to run common commands without having to specify the individual parameters every time:

As WP-CLI picks up most of the parameters from the configuration file, I don’t have to type out all the command line parameters like --dbuserand --admin_email that I would normally have to.

Note that in the last example above I provided the title parameter separately. This is because I want the site title to be different in the test environment, but it’s not possible to override this parameter using an alias.

Creating Custom Robo Commands

Setting up a fresh WordPress installation is almost never enough. Usually there are one or more plugins that need to be installed and activated and quite often a few settings to fix up here and there.

Even with a carefully written WP-CLI configuration file, I’d still end up with a long string of commands if I want to reset my WordPress environment and get everything ready. I often did sequences like this over and over again:

Even when taking full advantage of the WP-CLI config file, this is a lot of typing. To avoid typing this over and over again and also getting it wrong every now and then, I created two specialized commands using Robo to do it for me:

Since the WP-CLI subcommand default parameters don’t extend to different command-line environments, we can use Robo to kill that bird with the same stone. Let’s see how.

Command Configuration

Our first stop is to have a look at the Robo configuration file I’ve created for this. It’s written in YAML, which should make it fairly straightforward to understand and extend. I’ll go over each section as we get to the command that uses it:

Each WordPress environment is identified using a wordpress-$env key. Each key can hold several configuration values.

The reset Command

The first command is reset. It’s used from the command line like this:

The first thing this command does is to delete all existing files and folders in the target WordPress installation directory and reset the configured WordPress database.

Then, the reset command uses the WP-CLI commands core download, config create and one of core install or core multisite-install depending on the --multi option.

To the largest extent possible, this uses the command parameter defaults located in the wp-cli.yml file. The reason for this is that those defaults are also helpful when running WP-CLI directly without the Robo wrapper. But as discussed above, in some cases it’s just not possible.

Therefore the robo.yml config file offers the possibility to specify overrides for the defaults in wp-cli.yml. For example, when installing the @test environment we want to override the parameters for the core install parameter --title. We can do that by adding the following in robo.yml:

The syntax here is quite easy: the CLI command name (spaces replaced with dashes) as the key and one subkey for each named parameter. The above example would generate the following extra parameter to the core install cli command:

Post-Install Steps

Each environment key in the config file can optionally specify an array with post-install steps. This is simply a list of bash commands that are executed when the WordPress installation is done. For added flexibility, a few string replacements are made before the command is executed:

String Replaced with
$cwd The current working directory
$path The path of the target WordPress installation
$wp The wp-cli command, including the alias prefix, i.e., wp @test
~ (tilde symbol) The HOME directory of the current user

So a post-install step of ln -s $cwd/../plugin1 $path/wp-content/plugins/ would create a symlink from one of my plugins folders to the plugins subfolder in the target WordPress install.

The profile Command

The profile command is quite similar to the post-install steps, but its intended use is to run a set of commands on an existing WordPress installation. Let’s say that you have a very plain development environment that you do most of your work in. However, sometimes you need to install the WooCommerce plugin and do some basic setup for it. This is what the profile command is for. It can be used like this:

The sample robo.yml file above has a WooCommerce profile. Applying that profile will:

Using different profiles is quite useful. I spend most of my days working on the WP Offload Media plugin and I often need to import lots of images to the WordPress media library. WP-CLI has a really convenient command for this:

Since I often forget a lot of stuff in general and long path names in particular, I find it easier to remember:

Here’s another example. I’ve been working on a particular GitHub issue where we’re trying to fix a compatibility issue between our plugin and another popular WordPress plugin. When I work on that issue, I need to install that plugin and set a config value in wp-config.php. So I created a profile for it:

Now I can get my environment ready to go in one step, just robo profile issue2530.

Just like the post-install steps in the reset command, each row in the profiles definition is really just a separate bash command. You could use it to launch separate scripts, delete files, or whatever you fancy. It’s also quite possible to shoot yourself in the foot, so tread carefully.

The Source

If any of the above sounds interesting to try out, here’s the RoboFile that I’m using for all of the above stuff, feel free to use it to get started with managing WordPress using Robo.

Wrapping Up

In development, repetitive tasks tend to go with the territory. I can’t see a way of doing away with them completely, but automating as many of them as possible really helps you to get as much real work done with the time available.

Automating some of those tasks with the combination of WP-CLI and Robo that I’ve outlined here has saved time for me every single day as a plugin developer. I could never go back to doing these things manually again.

What tools do you use for automating the most tedious parts of your development workflow? Let me know in the comments.

This content was originally published here.

Sign Up for Updates and Special Offers

Jeff Kerby

CEO | KERBCO Web Services