Version 0.23.0 released

It’s hard to believe the last WP-CLIWP-CLI WP-CLI is the Command Line Interface for WordPress, used to do administrative and development tasks in a programmatic way. The project page is release was only two months ago because this is the longest release post I’ve ever written. My apologies in advance.

If you don’t make it all of the way through, here’s what you absolutely need to know about WP-CLI v0.23.0:

  • This release includes WordPress 4.5 compatibility. Older WP-CLI versions are incompatible with WordPress 4.5. If you’re planning to use WordPress 4.5 in the future, you’ll need to upgrade before you do.
  • You can now browse available packages with wp package browse, and install them with wp package install. Try wp package install runcommand/db-ack.
  • There are many new tools for registering commands. Ain’t no more need to extend WP_CLI_Command. See the commands cookbook to learn more.
  • All of the wiki pages moved to a documentation portal on the website, including new pages documenting internal APIs you can use in your own commands. Pull requests encouraged.

Now that I’ve given away all of the surpises, let’s get on with the release post.

Oh darn, I forgot two more things:

  • For those using the Phar file, which should be most of you, WP-CLI now automatically checks for updates, and will prompt you to update as applicable. It even works for those using the nightly build. This behavior is configurable, see below.
  • I’ve settled on runcommand as the name for my new WP-CLI venture. Sign up for email updates on the website, or follow @runcommand on Twitter.

And now, the release post.

WordPress 4.5 compatibility

WordPress 4.5 loads yet another file in wp-settings.php. Because WP-CLI has a custom wp-settings-cli.php (background), WP-CLI v0.23.0 is the only release compatible with WordPress 4.5.

Importantly, due to the nature of these changes, WP-CLI versions prior to 0.23.0 will be incompatible with WordPress 4.5.

Inspect the nature of the change in this pull request.

Want to help fix this? Refill your cup of coffee and dive into #34936 on WordPress TracTrac Trac is the place where contributors create issues for bugs or feature requests much like GitHub.

Install community commands from the Package Index

Consider the following situation (#2523):

Using the theme list command without --url parameter shows if a theme is enabled for the network and active in the default site.

If you pass the --url of a site of the network, this command shows if a theme is active in that site.

But I can’t find a way to list which themes are inactive in every site of the network so I can safely disable and delete them, and i’d love to have this feature

If you had to complete this task using the WordPress network admin, it would take you hours, if not days. Simply writing the WP-CLI command for this issue took me only 3 minutes (runcommand/find-unused-themes). WP-CLI is genuinely the fastest interface to manage WordPress.

WP-CLI also generally follows the 80/20 rule when deciding whether to introduce a new feature. If the feature could be useful to most people, then maybe; otherwise, probably not. Those 20% shouldn’t be left with the short stick though, particularly when it comes to the really helpful commands.

Today, I’m proud to reintroduce the Package Index, a directory of community-maintained WP-CLI packages. Browse available packages to install with wp package browse (doc). Once you’ve found the solution you’re looking for, install it with wp package install (doc):

$ wp package install runcommand/find-unused-themes
Installing runcommand/find-unused-themes (dev-master)
Updating /home/vagrant/.wp-cli/packages/composer.json to require the package...
Using Composer to install the package...
Loading composer repositories with package information
Updating dependencies
Analyzed 2223 packages to resolve dependencies
Analyzed 29243 rules to resolve dependencies
 - Installing package
Writing lock file
Generating autoload files
Success: Package installed successfully.
$ wp find-unused-themes
Checking for unused themes...
Checking for unused themes...
| name           | version |
| default        | 1.7.2   |
| mystore        | 1.0.6   |
| p2             | 1.5.5   |
| twentyeleven   | 2.3     |
| twentyfourteen | 1.6     |
| twentyten      | 2.1     |
| twentythirteen | 1.8     |
| twentytwelve   | 1.9     |

Pretty cool, huh? Consider WP-CLI’s package management to be a betaBeta A pre-release of software that is given out to a large group of users to trial under real conditions. Beta versions have gone through alpha testing in-house and are generally fairly close in look, feel and function to the final product; however, design changes often occur as part of the process. feature at this time. You may run into one of the open issues, or find a bug that hasn’t been reported yet. If you’re keen to take a deep dive into Composer’s internals, helping to improve wp package would be a great way to start.

Relevant pull requests for wp package include #2442, #2460, #2491, #2512, #2514, #2533, #2534, #2537, #2540, #2543, #2546, #2547, #2555, #2561

Register more commands

Ever wonder why, when writing your own command, you had to extend WP_CLI_Command? Well, you didn’t need to, actually.

In fact, WP_CLI::add_command() (doc) now supports registering any arbitrary callable as a WP-CLI command. For instance, here’s a closure command to reset the passwords of one or more users (runcommand/reset-passwords):

 * Reset passwords for one or more WordPress users.
 * <user>...
 * : Specify one or more user logins or IDs.
$reset_password_command = function( $args ) {
    $fetcher = new WP_CLIFetchersUser;
    $users = $fetcher->get_many( $args );
    foreach( $users as $user ) {
        wp_update_user( array( 'ID' => $user->ID, 'user_pass' => wp_generate_password() ) );
        WP_CLI::log( "Reset password for {$user->user_login}." );
    WP_CLI::success( 'Passwords reset.' );
WP_CLI::add_command( 'user reset-passwords', $reset_password_command );

Want to reuse argument definition between commands? You can now register command synopsis as the third argument to WP_CLI::add_command() (runcommand/hook):

WP_CLI::add_command( 'hook', $hook_command, array(
    'shortdesc' => 'List callbacks registered to a given action or filter.',
    'synopsis' => array(
            'name'        => 'hook',
            'type'        => 'positional',
            'description' => 'The key for the action or filter.',
            'name'        => 'format',
            'type'        => 'assoc',
            'description' => 'List callbacks as a table, JSON, or CSV.',
            'optional'    => true,
            'options'     => array( 'table', 'json', 'csv' ),
            'default'     => 'table',
) );

Note the default argument attribute for format. WP-CLI accepts default and options as a part of argument registration to make it easier to process user input within your command. These attributes can be also defined in the callable’s PHPDoc:

 * List callbacks registered to a given action or filter.
 * <hook>
 * : The key for the action or filter.
 * [--format=<format>]
 * : List callbacks as a table, JSON or CSV.
 * ---
 * options:
 *   - table
 *   - json
 *   - csv
 * default: table
 * ---
$hook_command = function( $args, $assoc_args ) {

Check out the commands cookbook for a deep dive into command registration. Relevant pull requests for these improvements to WP_CLI::add_command() include #2373, #2389, #2398, #2409, #2556, #2559.

More, better, easier to find documentation

It’s actually hard to imagine how people got around previously. Here’s what’s changed in documentationland:

  • The wiki has been reincarnated as the documentation portal on the website. I spent time cleaning up the pages as I moved them over; hopefully you find the new commands cookbook quite helpful.
  • Internal APIs you can use in your own commands are now publicly documented. The internal APIAPI An API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways. pages are generated from the codebase, which should greatly help maintenance efforts.
  • On each command page, there’s a “GithubGitHub GitHub is a website that offers online implementation of git repositories that can easily be shared, copied and modified by other developers. Public repositories are free to host, private repositories require a paid subscription. GitHub introduced the concept of the ‘pull request’ where code changes done in branches by contributors can be reviewed and discussed before being merged be the repository owner. issues” link to make it easier to find both open and closed issues for a given command. For instance, here are all of the outstanding issues for wp package and its subcommands. Keep in mind this isn’t necessarily exact, because I didn’t go back through and label all issues of all time. This feature will become more useful as time goes forward.

Relevant pull requests include #2454, #2487, #2494, #2499, #2507, #2513, #2515.

Automatic update checks

For those using WP-CLI as a Phar file, which should be most of you, version 0.23.0 and later will automatically check for updates. If an update is found, you’ll be prompted to install it.

Automatic update checks even work for those using the nightly build! Use wp cli update --nightly to get back on the nightly track after each major releaseMajor Release A set of releases or versions having the same major version number may be collectively referred to as “X.Y” -- for example version 5.2.x to refer to versions 5.2, 5.2.1, and all other versions in the 5.2. (five dot two dot) branch of that software. Major Releases often are the introduction of new major features and functionality..

By default, the automatic update check will run once a day for users with a writable WP-CLI Phar file. Distribution file or directory not writable? Then the check won’t run. Automatic update checks are triggered when a user, not a script, runs wp help <some-command>. This frequency can be configured with the WP_CLI_AUTO_CHECK_UPDATE_DAYS environment variable, or disabled entirely with the WP_CLI_DISABLE_AUTO_CHECK_UPDATE environment variable.

Relevant pull requests for this feature includes #2536 and #2538.

Everything else in 0.23.0

Command improvements:

  • Better performance for wp (user|post) list --format=count by only fetching the data we need [#2370, #2387].
  • Prevents dupe builds with Travis default settings in wp scaffold plugin-tests [#2377].
  • Generate comments for a specific post with wp comment generate --post_id=<post-id> [#2388].
  • Cleans up files from the prior version when using wp core (update|download) --force [#2382, #2406, #2413, #2432].
  • Adds a timer to individual events in wp cron event run [#2437].
  • Introduces wp term meta for managing term metaMeta Meta is a term that refers to the inside workings of a group. For us, this is the team that works on internal WordPress sites like WordCamp Central and Make WordPress. [#2444].
  • Adds CSV and JSONJSON JSON, or JavaScript Object Notation, is a minimal, readable format for structuring data. It is used primarily to transmit data between a server and web application, as an alternative to XML. output format to wp (theme|plugin) update [#2452].
  • Verifies MD5 hash of downloaded archive file with wp core download [#2461]
  • Entirely avoids loading WordPress in wp core verify-checksums [#2459].
  • Supports emptying term meta with wp site empty [#2506].
  • Adds WP REST APIREST API The REST API is an acronym for the RESTful Application Program Interface (API) that uses HTTP requests to GET, PUT, POST and DELETE data. It is how the front end of an application (think “phone app” or “website”) can communicate with the data store (think “database” or “file system”) registration args to scaffold (post-type|taxonomy) [#2551].
  • Adds documentation to test-sample.php and bootstrap.php when running wp scaffold plugin-tests [#2577, #2578].

Framework enhancements:

  • Switches WP_CLI::confirm() to automatically lowercase the response, permitting use of Y or y [#2366].
  • Adds (before|after)_wp(_config)_load hooksHooks In WordPress theme and development, hooks are functions that can be applied to an action or a Filter in WordPress. Actions are functions performed when a certain event occurs in WordPress. Filters allow you to modify certain functions. Arguments used to hook both filters and actions look the same. in WP load process, permitting code injected via --require to make modifications during the bootstrap process [#2375].
  • Adds .editorconfig to project root based on WordPress Coding StandardsWordPress Coding Standards The Accessibility, PHP, JavaScript, CSS, HTML, etc. coding standards as published in the WordPress Coding Standards Handbook. May also refer to The collection of PHP_CodeSniffer rules (sniffs) used to format and validate PHP code developed for WordPress according to the PHP coding standards. [#2395].
  • Encodes WP_Error data as JSON in WP_CLI::error_to_string() so that the data is actually human-readable [#2397].
  • Supports custom exit codes in WP_CLI::error() [#2440].
  • Introduces --format=yaml for easily displaying data as YAML [#2453].
  • Supports config deep merging and inheritance [#2496].
  • Updates Composer dependencies [#2554]

Bug fixes across the board:

  • In bin/, don’t cd in WP_TESTS_DIR before dowloading and setting up wp-tests-config.php [#2371].
  • When using --prompt, now only prompts for the first command in the execution thread. Previously, any use of WP_CLI::run_command() within a command would cause the prompting UXUX UX is an acronym for User Experience - the way the user uses the UI. Think ‘what they are doing’ and less about how they do it. to appear again [#2400].
  • Removes unnecessary exit on premature success for wp theme activate [#2412].
  • Checks if a taxonomyTaxonomy A taxonomy is a way to group things together. In WordPress, some common taxonomies are category, link, tag, or post format. exists before listing its terms [#2414].
  • When trying to update a version of coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. that doesn’t exist, check the HTTPHTTP HTTP is an acronym for Hyper Text Transfer Protocol. HTTP is the underlying protocol used by the World Wide Web and this protocol defines how messages are formatted and transmitted, and what actions Web servers and browsers should take in response to various commands. response code before trying to unzip an invalid archive [#2368].
  • Fixes use of wp server when the PHPPHP PHP (recursive acronym for PHP: Hypertext Preprocessor) is a widely-used open source general-purpose scripting language that is especially suited for web development and can be embedded into HTML. binary contains spaces [#2422].
  • Respects --skip_comments flag for wp export, which has been broken for quite a while [#2427]
  • Persists IPTC data in wp media import when missing a title or caption; removes extension from default title [#2438, #2466].
  • Disables check translation updates when updating themes or plugins [#2439].
  • Corrects parameter sequence order when creating a new user on multisiteMultisite Multisite is a WordPress feature which allows users to create a network of sites on a single WordPress installation. Available since WordPress version 3.0, Multisite is a continuation of WPMU or WordPress Multiuser project. WordPress MultiUser project was discontinued and its features were included into WordPress core. [#2443].
  • Disables automatic colorization when --format=table [#2458].
  • Uses core’s version check API for finding updates, which gives us exact URLs to download offers [#2469].
  • Uses more robust failed download checking in wp cli update [#2488].
  • Runs help early for wp core commands used when core isn’t yet installed [#2497].
  • Fixes formatting of GLOBAL PARAMETERS when command has subcommands [#2516].
  • Properly handles multi-column keys in wp search-replace [#2531].
  • Uses correct path to autoloader when WP-CLI is installed to a parent Composer project [#2550].
  • Properly passes wp plugin search fields to plugins_api() request; adds page parameter [#2570, #2571].
  • Add parent as a potential status in wp theme status [#2573]

Contributors to this release: anantshri, danielbachhuber, edueo, GaryJones, gilbitron, hina, hinoue-work, jacobischwartz, marco-c, markjaquith, markkimsal, mbovel, ottok, rodrigoprimo, sourcerer-mike, staude, szepeviktor, za-creature

You can browse the full list of resolved issues on Github.