---
layout: post
author: danielbachhuber
title: Version 0.23.0 released
---

It's hard to believe the last WP-CLI 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](https://wp-cli.org/package-index/) 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](https://wp-cli.org/docs/commands-cookbook/) to learn more.
* All of the wiki pages moved to a [documentation portal on the website](https://wp-cli.org/docs/), including new pages documenting [internal APIs](https://wp-cli.org/docs/internal-api/) you can use in your own commands. Pull requests encouraged.

Now that I've given away all of the surprises, 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](http://runcommand.io/) as the name for my new WP-CLI venture. [Sign up for email updates](http://runcommand.io/) on the website, or follow [@runcommand](https://twitter.com/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](https://wp-cli.org/blog/how-wp-cli-loads-wordpress.html)), 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](https://github.com/wp-cli/wp-cli/pull/2486).

Want to help fix this? Refill your cup of coffee and dive into [#34936](https://core.trac.wordpress.org/ticket/34936) on WordPress Trac.

### Install community commands from the Package Index

Consider the following situation ([#2523](https://github.com/wp-cli/wp-cli/issues/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](https://github.com/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](https://wp-cli.org/package-index/), a directory of community-maintained WP-CLI packages. Browse available packages to install with `wp package browse` ([doc](https://wp-cli.org/commands/package/browse/)). Once you've found the solution you're looking for, install it with `wp package install` ([doc](https://wp-cli.org/commands/package/install/)):

    $ 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 http://wordpress-develop.dev/ for unused themes...
    Checking http://wordpress-develop.dev/foo/ 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 beta feature at this time. You may run into [one of the open issues](https://github.com/wp-cli/wp-cli/issues?q=is%3Aopen+sort%3Aupdated-desc+label%3Acommand%3Apackage), 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](https://github.com/wp-cli/wp-cli/pull/2442), [#2460](https://github.com/wp-cli/wp-cli/pull/2460), [#2491](https://github.com/wp-cli/wp-cli/pull/2491), [#2512](https://github.com/wp-cli/wp-cli/pull/2512), [#2514](https://github.com/wp-cli/wp-cli/pull/2514), [#2533](https://github.com/wp-cli/wp-cli/pull/2533), [#2534](https://github.com/wp-cli/wp-cli/pull/2534), [#2537](https://github.com/wp-cli/wp-cli/pull/2537), [#2540](https://github.com/wp-cli/wp-cli/pull/2540), [#2543](https://github.com/wp-cli/wp-cli/pull/2543), [#2546](https://github.com/wp-cli/wp-cli/pull/2546), [#2547](https://github.com/wp-cli/wp-cli/pull/2547), [#2555](https://github.com/wp-cli/wp-cli/pull/2555), [#2561](https://github.com/wp-cli/wp-cli/pull/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](https://wp-cli.org/docs/internal-api/wp-cli-add-command/)) 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](https://github.com/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_CLI\Fetchers\User;
    	$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](https://github.com/runcommand/hook)):

    WP_CLI::add_command( 'hook', $hook_command, array(
    	'shortdesc' => 'List callbacks registered to a given action or filter.',
    	'synopsis' => array(
    		array(
    			'name'        => 'hook',
    			'type'        => 'positional',
    			'description' => 'The key for the action or filter.',
    		),
    		array(
    			'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](https://wp-cli.org/docs/commands-cookbook/) for a deep dive into command registration. Relevant pull requests for these improvements to `WP_CLI::add_command()` include [#2373](https://github.com/wp-cli/wp-cli/pull/2373), [#2389](https://github.com/wp-cli/wp-cli/pull/2389), [#2398](https://github.com/wp-cli/wp-cli/pull/2398), [#2409](https://github.com/wp-cli/wp-cli/pull/2409), [#2556](https://github.com/wp-cli/wp-cli/pull/2556), [#2559](https://github.com/wp-cli/wp-cli/pull/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](https://wp-cli.org/docs/) on the website. I spent time cleaning up the pages as I moved them over; hopefully you find the new [commands cookbook](https://wp-cli.org/docs/commands-cookbook/) quite helpful.
* Internal APIs you can use in your own commands are now [publicly documented](https://wp-cli.org/docs/internal-api/). The internal API pages are generated from the codebase, which should greatly help maintenance efforts.
* On each command page, there's a "Github 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](https://github.com/wp-cli/wp-cli/issues?q=is%3Aopen+label%3Acommand%3Apackage+sort%3Aupdated-desc) 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](https://github.com/wp-cli/wp-cli/pull/2454), [#2487](https://github.com/wp-cli/wp-cli/pull/2487), [#2494](https://github.com/wp-cli/wp-cli/pull/2494), [#2499](https://github.com/wp-cli/wp-cli/pull/2499), [#2507](https://github.com/wp-cli/wp-cli/pull/2507), [#2513](https://github.com/wp-cli/wp-cli/pull/2513), [#2515](https://github.com/wp-cli/wp-cli/pull/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 release.

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](https://github.com/wp-cli/wp-cli/pull/2536) and [#2538](https://github.com/wp-cli/wp-cli/pull/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](https://github.com/wp-cli/wp-cli/pull/2370), [#2387](https://github.com/wp-cli/wp-cli/pull/2387)].
* Prevents dupe builds with Travis default settings in `wp scaffold plugin-tests` [[#2377](https://github.com/wp-cli/wp-cli/pull/2377)].
* Generate comments for a specific post with `wp comment generate --post_id=<post-id>` [[#2388](https://github.com/wp-cli/wp-cli/pull/2388)].
* Cleans up files from the prior version when using `wp core (update|download) --force` [[#2382](https://github.com/wp-cli/wp-cli/pull/2382), [#2406](https://github.com/wp-cli/wp-cli/pull/2406), [#2413](https://github.com/wp-cli/wp-cli/pull/2413), [#2432](https://github.com/wp-cli/wp-cli/pull/2432)].
* Adds a timer to individual events in `wp cron event run` [[#2437](https://github.com/wp-cli/wp-cli/pull/2437)].
* Introduces `wp term meta` for managing term meta [[#2444](https://github.com/wp-cli/wp-cli/pull/2444)].
* Adds CSV and JSON output format to `wp (theme|plugin) update` [[#2452](https://github.com/wp-cli/wp-cli/pull/2452)].
* Verifies MD5 hash of downloaded archive file with `wp core download` [[#2461](https://github.com/wp-cli/wp-cli/pull/2461)]
* Entirely avoids loading WordPress in `wp core verify-checksums` [[#2459](https://github.com/wp-cli/wp-cli/pull/2459)].
* Supports emptying term meta with `wp site empty` [[#2506](https://github.com/wp-cli/wp-cli/pull/2506)].
* Adds WP REST API registration args to `scaffold (post-type|taxonomy)` [[#2551](https://github.com/wp-cli/wp-cli/pull/2551)].
* Adds documentation to `test-sample.php` and `bootstrap.php` when running `wp scaffold plugin-tests` [[#2577](https://github.com/wp-cli/wp-cli/pull/2577), [#2578](https://github.com/wp-cli/wp-cli/pull/2578)].

Framework enhancements:

* Switches `WP_CLI::confirm()` to automatically lowercase the response, permitting use of `Y` or `y` [[#2366](https://github.com/wp-cli/wp-cli/pull/2366)].
* Adds `(before|after)_wp(_config)_load` hooks in WP load process, permitting code injected via `--require` to make modifications during the bootstrap process [[#2375](https://github.com/wp-cli/wp-cli/pull/2375)].
* Adds `.editorconfig` to project root based on WordPress Coding Standards [[#2395](https://github.com/wp-cli/wp-cli/pull/2395)].
* Encodes `WP_Error` data as JSON in `WP_CLI::error_to_string()` so that the data is actually human-readable [[#2397](https://github.com/wp-cli/wp-cli/pull/2397)].
* Supports custom exit codes in `WP_CLI::error()` [[#2440](https://github.com/wp-cli/wp-cli/pull/2440)].
* Introduces `--format=yaml` for easily displaying data as YAML [[#2453](https://github.com/wp-cli/wp-cli/pull/2453)].
* Supports config deep merging and inheritance [[#2496](https://github.com/wp-cli/wp-cli/pull/2496)].
* Updates Composer dependencies [[#2554](https://github.com/wp-cli/wp-cli/pull/2554)]

Bug fixes across the board:

* In `bin/install-wp-tests.sh`, don't cd in `WP_TESTS_DIR` before dowloading and setting up `wp-tests-config.php` [[#2371](https://github.com/wp-cli/wp-cli/pull/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 UX to appear again [[#2400](https://github.com/wp-cli/wp-cli/pull/2400)].
* Removes unnecessary `exit` on premature success for `wp theme activate` [[#2412](https://github.com/wp-cli/wp-cli/pull/2412)].
* Checks if a taxonomy exists before listing its terms [[#2414](https://github.com/wp-cli/wp-cli/pull/2414)].
* When trying to update a version of core that doesn't exist, check the HTTP response code before trying to unzip an invalid archive [[#2368](https://github.com/wp-cli/wp-cli/pull/2368)].
* Fixes use of `wp server` when the PHP binary contains spaces [[#2422](https://github.com/wp-cli/wp-cli/pull/2422)].
* Respects `--skip_comments` flag for `wp export`, which has been broken for quite a while [[#2427](https://github.com/wp-cli/wp-cli/pull/2427)]
* Persists IPTC data in `wp media import` when missing a title or caption; removes extension from default title [[#2438](https://github.com/wp-cli/wp-cli/pull/2438), [#2466](https://github.com/wp-cli/wp-cli/pull/2466)].
* Disables check translation updates when updating themes or plugins [[#2439](https://github.com/wp-cli/wp-cli/pull/2439)].
* Corrects parameter sequence order when creating a new user on multisite [[#2443](https://github.com/wp-cli/wp-cli/pull/2443)].
* Disables automatic colorization when `--format=table` [[#2458](https://github.com/wp-cli/wp-cli/pull/2458)].
* Uses core's version check API for finding updates, which gives us exact URLs to download offers [[#2469](https://github.com/wp-cli/wp-cli/pull/2469)].
* Uses more robust failed download checking in `wp cli update` [[#2488](https://github.com/wp-cli/wp-cli/pull/2488)].
* Runs help early for `wp core` commands used when core isn't yet installed [[#2497](https://github.com/wp-cli/wp-cli/pull/2497)].
* Fixes formatting of GLOBAL PARAMETERS when command has subcommands [[#2516](https://github.com/wp-cli/wp-cli/pull/2516)].
* Properly handles multi-column keys in `wp search-replace` [[#2531](https://github.com/wp-cli/wp-cli/pull/2531)].
* Uses correct path to autoloader when WP-CLI is installed to a parent Composer project [[#2550](https://github.com/wp-cli/wp-cli/pull/2550)].
* Properly passes `wp plugin search` fields to `plugins_api()` request; adds `page` parameter [[#2570](https://github.com/wp-cli/wp-cli/pull/2570), [#2571](https://github.com/wp-cli/wp-cli/pull/2571)].
* Add `parent` as a potential status in `wp theme status` [[#2573](https://github.com/wp-cli/wp-cli/pull/2573)]

Contributors to this release: [anantshri](https://github.com/anantshri), [danielbachhuber](https://github.com/danielbachhuber), [edueo](https://github.com/edueo), [GaryJones](https://github.com/GaryJones), [gilbitron](https://github.com/gilbitron), [hina](https://github.com/hina), [hinoue-work](https://github.com/hinoue-work), [jacobischwartz](https://github.com/jacobischwartz), [marco-c](https://github.com/marco-c), [markjaquith](https://github.com/markjaquith), [markkimsal](https://github.com/markkimsal), [mbovel](https://github.com/mbovel), [ottok](https://github.com/ottok), [rodrigoprimo](https://github.com/rodrigoprimo), [sourcerer-mike](https://github.com/sourcerer-mike), [staude](https://github.com/staude), [szepeviktor](https://github.com/szepeviktor), [za-creature](https://github.com/za-creature)

You can browse the full list of [resolved issues](https://github.com/wp-cli/wp-cli/issues?q=milestone%3A0.23.0+is%3Aclosed) on GitHub.
