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

Even though WP-CLI is a mature project, we still manage to pack a great set of improvements into each release. Here's what's coming to you in v0.20.0.

### Regex, verbose search-replace

Use the `--regex` flag to `wp search-replace` to... wait for it... use regex in your search and replace operations. And, with the `--verbose` flag, you'll see each column with affected rows as the operation is performed:

    $ wp post get 1 --field=title
    Hello world
    $ wp search-replace '(Hello)\s(world)' '$2, $1' --regex --verbose
    ...
    Checking: wp_posts.post_content
    0 rows affected
    Checking: wp_posts.post_title
    1 rows affected
    Checking: wp_posts.post_excerpt
    0 rows affected
    ...
    $ wp post get 1 --field=title
    world, Hello

Note: search-replace with `--regex` is 15-20x slower than without. Make sure you plan for the performance hit in your migration plans, and use wisely.

### Major bug fix: cached partial upgrade files masquerading as full upgrades

Since v0.17.0 ([pull request](https://github.com/wp-cli/wp-cli/pull/1320)), WP-CLI mistakenly cached partial archives in a lossy manner. More specifically, a ZIP file for a partial upgrade would be cached with the same key as a ZIP file for a full upgrade. With the file incorrectly cached, subsequent full upgrades would use the cached partial upgrade archive.

If you can't immediately upgrade to v0.20.0, we've also released [v0.17.2](https://github.com/wp-cli/wp-cli/releases/tag/v0.17.2), [v0.18.1](https://github.com/wp-cli/wp-cli/releases/tag/v0.18.1), and [v0.19.3](https://github.com/wp-cli/wp-cli/releases/tag/v0.19.3) with the bug fix ([pull request](https://github.com/wp-cli/wp-cli/pull/1901)). The cache key was changed as well, so prior invalid WordPress archives are silently ignored.

Use `wp core verify-checksums` to make sure a given WordPress install has the correct copy of each file. If it doesn't verify, use `wp core download --version=$(wp core version) --force` to re-install WordPress.

### WP-API CLI

We [released v0.19.0](https://wp-cli.org/blog/version-0.19.0.html) with this statement:

> WP-API is days away from 2.0-beta1, and brings with it a powerful new interface to WordPress. In the near future, we’ll start exploring how WP-CLI can use WP-API internally. If all goes well, WP-CLI could see just one more 0.x.0 release before the big 1.0.0.

Well... it was a bold declaration. Follow [danielbachhuber/wp-rest-cli](https://github.com/danielbachhuber/wp-rest-cli) for progress on the implementation. 1.0.0 will still likely be WP-CLI based on WP-API, but it'll take a fair bit of work to get there.

### Helpful one-liners

There were a couple issues opened for "how do I do X?", which you might find helpful too:

    # List plugins on each site in a network
    wp site list --field=url | xargs -n 1 -I % wp plugin list --url=%

    # Delete inactive plugins
    wp plugin delete $(wp plugin list --status=inactive --field=name)


### Other changes in v0.20.0

Enhancements:

* The `wp server` command is bundled with WP-CLI. Use PHP's built-in web server for a specific WordPress instance.
* Keep up with the latest and greatest by using `wp cli update --nightly`. When downloading a nightly, the hash is appended to the version.
* Added a simple `wp comment generate` command.
* Cache invalidation is deferred until the end of the command when using `wp term generate`. This improves performance of the command.
* `wp term list` supports filtering by `--term_id=<term-id>`.
* Use `--start_id=<post-id>` to start `wp export` from a given post ID, or use `--post_type=<post-type>,<post-type>` to export a selection of post types.
* Throws a helpful error when an invalid `--url=<url>` is specified on multisite. Previously, WP-CLI would fail silently, leaving the user confused as to why their command wasn't running.
* Create a new role from another role with `wp role --clone=<role>`.
* Use `--format=summary` to get one-liner messages with `wp (plugin|theme) update`.
* Switched away from using `wp_download_language_pack()` so languages can be installed with the `DISALLOW_FILE_MODS` constant set.

Bug fixes:

* `wp term generate` tries to generate unique term names on subsequent executions. Previously, it would start its index at `0`, and then error for duplicate terms.
* Internalized `wp_clean_update_cache()` (used in `wp core language list` and `wp core language update`) to prevent fatals in WordPress 4.0. The function was introduced in WordPress 4.1.
* When WordPress is detected, WP-CLI will wait until WordPress is fully loaded before executing `wp help`. This means plugins which add commands to an existing namespace can have theri help docs appear.
* Corrected Travis notification syntax produced by `wp scaffold plugin-tests` command.
* Supports `Requests` installed to parent project in `WP_CLI\Utils\http_request()`
* Passes thru `--allow-root` in `cli update` to let root update WP-CLI.
* Restored apt-get tab completion after using WP-CLI tab completion.
* Permits categories to be assigned with `wp post update`.
* Prevents `wp import` from using double the memory it actually needs, and save 100s of MBs on large imports.

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

Contributors to this release: [boonebgorges](https://github.com/boonebgorges), [danielbachhuber](https://github.com/danielbachhuber), [janvoracek](https://github.com/janvoracek), [gedex](https://github.com/gedex), [johnbillion](https://github.com/johnbillion), [kdoole](https://github.com/kdoole), [marcaddeo](https://github.com/marcaddeo), [miya0001](https://github.com/miya0001), [montchr](https://github.com/montchr), [morganestes](https://github.com/morganestes), [rodrigoprimo](https://github.com/rodrigoprimo), [rmccue](https://github.com/rmccue), [scribu](https://github.com/scribu), [stevegrunwell](https://github.com/stevegrunwell), [szepeviktor](https://github.com/szepeviktor)
