Version 1.5.0 released

It’s release day again!

We’re excited to bring you WP-CLI v1.5.0, with a total of 279 merged pull requests since v1.4.1 in November 2017.

This release was led by the tireless Martin Burke (@gitlost), who made sure no bug went unsquashed and no edge case untested.

New committer

  • Pascal (@swissspidy) lives in Zurich, Switzerland. Amongst other contributions, he’s been doing the hard work on the embed family of commands.

Plugin checksum verification

WP-CLI can now verify the integrity of your installed plugins through the new plugin verify-checksums command (in addition to the already existing core verify-checksums command). [#15], [#26]

# Verify the files of all installed plugins against their official checksums.
$ wp plugin verify-checksums --all
| plugin_name | file          | message                 |
| gutenberg   | backdoor.php  | File was added          |
| gutenberg   | gutenberg.php | Checksum does not match |
Error: Only verified 1 of 2 plugins (1 failed).

Note: This is a first iteration on this functionality, and it still comes with a few limitations:

  • It only works for plugins that are hosted in the official plugin repository.
  • It only works for recent versions of these plugins, as we haven’t yet rolled out code on the backend to retroactively generate the checksums for older versions.

Please keep these limitations in mind when you plan on using this new command.

As we will further iterate on this project to allow verification of all free themes from the themes repository, and later hopefully also third-party plugins/themes, we welcome any and all feedback to the current implementation.

WordPress config file manipulations

Managing your wp-config.php file just got a whole lot easier! Not only did we improve the config get and included both a config has and a filterable config list command… No, we finally bring you full WordPress Config file manipulation with the new config set and config delete commands. [#42], [#44]

# Get the table_prefix as defined in wp-config.php file.
$ wp config get table_prefix

# Check whether the DB_PASSWORD constant exists in the wp-config.php file.
$ wp config has DB_PASSWORD
(return exit code)

# List only database user and password from wp-config.php file.
$ wp config list DB_USER DB_PASSWORD --strict
| key         | value | type     |
| DB_USER     | root  | constant |
| DB_PASSWORD | root  | constant |

Big thanks to @fjarrett for the awesome work on the wp-cli/wp-config-transformer package that powers the changes to wp-config.php.

oEmbed management

The new embed command allows you to inspect and manipulate the oEmbed object, for instance you can clear the cached values for a particular post with

$ wp embed cache clear 123
Success: Cleared oEmbed cache.

or reset the cached values with

$ wp embed cache trigger 123
Success: Caching triggered!

You can find out what the embed HTML is for a URL with fetch:

$ wp embed fetch

or look at exactly what the provider is returning by using the --raw option:

$ wp embed fetch --raw
{"height":295,"thumbnail_height":360,"provider_name":"YouTube","provider_url":"https:\/\/\/","author_name":"RickAstleyVEVO","width":525,"version":"1.0","thumbnail_width":480,"author_url":"https:\/\/\/user\/RickAstleyVEVO","html":"<iframe width=\"525\" height=\"295\" src=\"https:\/\/\/embed\/dQw4w9WgXcQ?feature=oembed\" frameborder=\"0\" allow=\"autoplay; encrypted-media\" allowfullscreen><\/iframe>","title":"Rick Astley - Never Gonna Give You Up","thumbnail_url":"https:\/\/\/vi\/dQw4w9WgXcQ\/hqdefault.jpg","type":"video"}

And lots more!

Array argument support (post meta for now)

The --meta_input option of the post create and post update commands now accepts JSON-formatted arrays, so you can add or update your post and its meta in one go:

$ wp post create --post_title='Title' --post_content='Content.' --meta_input='{"key1":"value1","key2":"value2"}
Success: Created post 123.

A great time saver, as you’d previously have to run three separate commands to get the same result.

This rather innocuous change means we can finally accept associative arrays as parameter arguments, through the use of this JSON syntax. The --meta_input parameter is probably just the first of many more to come. Let us know if you can think of other potential use cases for this syntax.

Everything else in v1.5.0

Backward Compatibility breaks

Please note that a framework change [#4624] alters the behavior of table filter arguments to the db search, db tables and search-replace commands.

The table filter arguments now:

  • Respect registered wpdb tables when given a table filter and not given the --all-tables-with-prefix or the --all-tables option.
  • Do not ignore the --scope option when given the --network option.
  • Tables are always returned in sorted order.

Also note that option list no longer shows transients by default [#127].

New and notable

  • user reset-password: Resets a user’s password [#119].
  • Command descriptions now follow the WordPress norm and use the third person singular, thanks DrewAPicture !

Command improvements

  • cli info:
    • Displays OS & shell information [#4604], [#4610].
  • core download:
    • Skips cache also when ZIP URL is 'http://' to nightly build [#44].
  • core update:
    • Ignores SSL trigger_error in WP get_core_checksums() [#48].
    • Strips wp-content/ using ZipArchive to always allow --skip-content [#59].
  • core verify-checksums
    • Warns when files prefixed with wp- are included in WordPress root [#28].
  • db *:
    • Uses new after_wp_config_load hook for early invocation of db commands [#57].
  • db check/cli/create/drop/export/import/optimize/query/repair/reset:
    • Adds --dbuser and --dbpass options to all the heightened privilege commands, and extra arguments option to check, optimize and repair [#75].
  • db search:
    • NOTE: See Backward Compatibility breaks above on treatment of table filter arguments [#4624].
  • db size:
    • Ensures default value of --size_format=<format> argument is always bytes [#69].
    • Includes support for TB and GB database size formats [#81].
  • db tables:
    • NOTE: See Backward Compatibility breaks above on treatment of table filter arguments [#4624].
  • export:
    • Adds --with_attachments option to force including attachments when --post__in has been specified. [#16].
  • media image-size:
    • Adds size ratio to output [#58], [#59].
  • media regenerate:
    • Does not throw PHP warning if no sizes metadata [#61].
  • option get:
    • Display error message if option doesn’t exist [#126].
  • option list:
    • Defaults to not showing transients [#127].
  • package *:
    • Caters for mixed-case package names [#49], [#50].
    • Adds GITHUB_TOKEN and COMPOSER_AUTH handling [#47].
  • package browse/list:
    • Catches exception if browsing/listing packages and Composer can’t access a repository [#60].
  • package install/uninstall:
    • Reverts composer.json on memory limit error [#64].
  • package install:
    • Retrieves package name from correct branch [#65].
  • plugin install:
    • Uses the Github project name as the plugin directory for Github archive URLs [#81]
  • post create/update:
    • Adds the ability to add multiple metadata by passing JSON-formatted arrays to --meta_input [#133], [#138].
  • post create:
    • Accepts category slugs in --post_category and checks if incorrect ids or slugs given [#129].
  • post delete:
    • Corrects delete message [#124].
  • post generate:
    • Adds support for generating a specific post_title [#94].
  • scaffold block:
    • Scaffolds a basic Gutenberg block for a plugin or theme [#96].
    • Adds inline documentation based on the Gutenberg Handbook, generates style.css, supports latest supportsHtml API, WordPress Coding Standards fixes [#107].
    • Updates PHP template to latest recommended method [#111].
  • scaffold child-theme:
    • Generates WordPress Coding Standards compliant code [#117].
  • scaffold plugin:
    • Adds a default task to scaffolded Gruntfile.js [#87].
    • Generates WordPress Coding Standards compliant code [#120].
  • scaffold plugin-tests:
    • Uses Composer to determine which PHPUnit version to install, instead of keying off Travis environment variable [#75].
    • Adds XML declaration to phpunit.xml.dist [#78].
    • Uses updated error message in bootstrap.php [#90].
    • Removes Composer vendor directory from Travis CI cache [#99].
  • scaffold post-type:
    • Trims dashicon- from dashicon argument to prevent duplicated string [#70].
    • Refreshes scaffolded post type labels [#84].
    • Generates WordPress Coding Standards compliant code [#110].
  • scaffold taxonomy:
    • Adds term_updated_messages to scaffolded taxonomies [#82].
    • Generates WordPress Coding Standards compliant code [#112].
  • scaffold theme-tests:
    • Adds theme_root filter to tests/bootstrap.php to make sure theme’s functions.php gets loaded [#116].
  • search-replace:
    • NOTE: See Backward Compatibility breaks above on treatment of table filter arguments [#4624].
    • Adds --skip-tables=<tables> argument to exclude specific tables [#48].
    • Disables report tables without index when using --report-change-only [#54].
    • General improvements to reporting, including disabling table display when no tables to output [#57].
    • Fixes not quoting non-integer primary keys [#59], [#63].
  • user remove-caps:
    • Errors if the cap doesn’t exist or is inherited from a role [#125].

Framework enhancements

  • Improves warning when can’t create cache directory [#4456].
  • Allows method @when to override class @when [#4458].
  • Pulls links from help texts into footnotes [#4465].
  • Implements command namespaces [#4470].
  • Generates get_site_url() without set_url_scheme() [#4473].
  • Introduces new after_wp_config_load hook (used to invoke wp db * early) [#4488].
  • Gets the hostname automatically with vagrant ssh-config [#4495].
  • Indicates other WP installs in db when install isn’t found [#4476].
  • Permits use of php7.1-mysql in Debian build [#4511].
  • Supports 'longdesc' as command argument when registering a command [#4513], [#4636].
  • Improves Extractor error messages [#4510].
  • Runs wp cache flush and wp search-replace on multisite even when site isn’t found [#4527].
  • Fixes prompting on Windows git/cygwin bash [#4547].
  • Doesn’t show 'sitecategories' table unless global terms are enabled [#4552].
  • Ensures late-registered registered commands appear in usage [#4564].
  • Improves Windows compatibility on invoking a proc and using [#4572], [#4595].
  • Uses a softer PHP requirement in RPM build [#4571].
  • Only provides dictionary-based suggestions if they produce valid options [#4590].
  • Adds interval argument to make_progress_bar() [#4603].
  • Adds Utils\esc_like() polyfill of wpdb version [#4612].
  • Deals correctly with wildcards in wp_get_table_names() (see Backward Compatibility breaks above) [#4624].
  • Adds shell array parsing helper [#4623], [#4635].
  • Checks for readability of WordPress core files [#4626].
  • Adds some more suggestions for mistyped arguments [#4577].

Contributors to this release (39 total)
ahmadawais, BhargavBhandari90, danielbachhuber, davidbhayes, DrewAPicture, drzrafecotechie, emgk, eriktorsner, fjarrett, gitlost, grantpalin, gziolo, inetbiz, kirtangajjar, LC43, lukecav, marcochiesi, marksabbath, miya0001, mm-pagely, neonardo1, ntwb, ocean90, playmonorkialashaki, runofthemill, ryotsun, sagarprajapati, schlessera, Shelob9, ssnepenthe, swissspidy, szepeviktor, terriann, thrijith, vbaranovskiy-plesk, vigilanteweb, websupporter

#cli, #release, #v1-5-0

Minor programming notes

Quick announcement before things totally shut down for the holidays:

  • Martin Burke (@gitlost) will be taking the Release Lead role for WP-CLI v1.5.0, due out on January 30th. He’ll be making sure all of the i’s are dotted and t’s are crossed before the version is tagged and deployed.
  • Alain will continue on as maintainer in a supporting role to Martin, helping out on a day to day basis with triaging the deluge of issues and pull requests.
  • I (Daniel) will be stepping away from day to day maintenance of WP-CLI, but will be around to support Martin and Alain as needed.

But why? Is this the end of the world?

My goal is, and always has been, long-term stability and quality for WP-CLI. I want WP-CLI to be software you can depend on for years, not months.

Part of longevity is consistent baseline investment into maintenance, with occasional bursts of new feature development. But longevity is also the human capacity around the project, of which I cannot be the bus factor. Stepping away creates space for others to step up.

Martin and Alain are very intelligent individuals. I trust they’ll do a great job.

Are you planning to come back?

We’re trialing this through the release of v1.5.0, and will reassess after that point.

I’m personally looking forward to: 1) taking a true mental break (my first WP-CLI PR was September 2012), and 2) submitting pull requests to WP-CLI as a contributor again.

If you’ve been hesitant to contribute to WP-CLI, now’s your time to dive in and help out. I’m sure Martin and Alain would love your enthusiasm 🙂

Live long and prosper!

Call for action – Help us test Checksum Verification

We’ve been working on building a first usable implementation of the plugin checksum verification project. Now we need your help to test the current implementation.

Implementation Details

The infrastructure now calculates MD5 and SHA-256 checksums for all plugin files and stores them in a publically accessible way. You can find a specification of the current endpoint to retrieve the checksums here.

The wp checksum plugin command we’ve built goes through some or all of the plugins installed on a machine, downloads the checksums for each plugin, and then verifies the downloaded checksums against freshly generated ones.

We now need help testing this command to make sure we weed out all edge cases and that its output serves all expected scripting requirements.

Right now, the output on STDOUT will provide you with a list of checksum mismatches or added/removed files. STDERR will contain warnings about skipped plugins. The exit code will return 0 if all compared checksums were valid, and 1 otherwise. Any feedback on whether that is a good approach, or on alternative approaches for the output are welcome!

Let us know as well when a plugin’s checksums is not found that you would expect to be found in the official plugin repository. Note: Right now, only the checksums for the latest versions of every plugin have been calculated, older versions will be added later.

How To Test

The implemented command can be found in the plugin-checksums branch of the wp-cli/checksum-command repository.

You can easily install the version to test through the following command:

wp package install wp-cli/checksum-command:dev-plugin-checksums

To get back to the stable bundled command later on, just type the following command:

wp package uninstall wp-cli/checksum-command

The easiest way to run the test is to enter the root folder of an existing WordPress site and run the following command:

wp checksum plugin --all

The command supports several formats, like JSON or CSV, which you can generate through the --format=<format> parameter.

Note: the output will be most useful right now if all plugins are up-to-date (as older checksums have not been calculated yet), so you might want to run a wp plugin update --all against local sites you test. Obviously, don’t do this without backups on production sites.

Please report any feedback or issues you find in the GitHub issue tracker of the checksum command.

Timing for v1.5.0 and v2.0.0

A heads up on some upcoming scheduled changes:

  • WP-CLI v1.5.0 is slated to be released on Tuesday, January 30th. This will be the last release in the v1.x series, unless some critical issue necessitates a v1.5.1.
  • WP-CLI v2.x will require PHP 5.4 and higher. Given current release cadence, v2.0.0 could be released in the May timeframe.

Why? Travis CI is ending support of PHP 5.3 testing (targeting early April). I’m not very keen to invest time into some alternate CI system solely for those still running PHP 5.3.

If you manage WordPress installs for others and don’t already have systems for helping them safely update PHP, you should take the time in 2018 to develop said systems.

Good issues for new and existing contributors

Want to submit your first pull request to WP-CLI? We’ve identified a few good first issues for you to get your feet wet:

If you’ve contributed to WP-CLI before, here are some reasonably well-defined issues we’d like to see pull requests for:

Read through the contributing guide for details on how to get started. Feel free to ask questions on the specific issue, or join us in the #cli channel with any questions you might have.

Version 1.4.1 released

Gosh darn those pesky bugs.

WP-CLI v1.4.1 fixes a few annoying regressions introduced in v1.4.0:

  • Strips Composer autoload of PHPCS references to prevent PHP notices in Phar build [#4477].
  • plugin status: Colorizes and adds a legend to listed drop-ins to prevent PHP notice [#62].
  • search-replace: Uses $wpdb->remove_placeholder_escape() when exporting in WP 4.8.3 and greater [#43].

Want to help us catch these bugs earlier? Run wp cli update --nightly in your local and staging environments to use the latest and greatest.

Contributors to this release (3 total): danielbachhubergitlost, mullnerz

What do you wish `wp scaffold` could do for you?

wp scaffold * presents a series of commands to help you quickly get up and running with your development project:

  • wp scaffold plugin generates a basic plugin, complete with unit tests.
  • wp scaffold post-type produces a full custom post type, with all of the different arguments you can change.
  • etc.

We’d like to make it even better! To help guide your feedback:

  • What basic code do you find yourself copy and pasting between WordPress projects?
  • Of the existing commands, are there ways you’d like to improve upon them?
  • What boilerplate/scaffolded code do you find most helpful in the other open source projects you use?

Consider this an open thread: we welcome all the ideas you have.

Version 1.4.0 released

Happy release day!

We’re excited to bring you WP-CLI v1.4.0. In just two short months, we’ve merged 308 pull requests from 42 contributors.

New faces

You may have noticed a few new faces around the project. This is our motley crew of committers:

  • Martin (@gitlost) lives in Dublin, Ireland. Check out his work with wp db search and wp search-replace --log (see below).
  • Siddharth (@Sidsector9) resides in Pune, India. His enhancements to wp doctor and wp profile will be available soon in a release near you.
  • Takayuki (@miya0001) is based out of Kyoto, Japan. He’s been making numerous improvements across the entire project; you never know what his next pull request will fix.

They’ve already had an amazing impact on the project. Please pass along your thanks when you have the chance.

Log search-replace transformations

If you’ve ever wanted to see what transformations are taking place with wp search-replace, now you can!

Use wp search-replace --log to display transformations as they happen, or wp search-replace --log=transformations.log to save the transformations to a file [#35, #39]:

$ wp search-replace 'http://' 'https://' --log
| Table      | Column       | Replacements | Type |
| wp_options | option_value | 3            | PHP  |
Success: Made 3 replacements.

It’s even more beautiful in color. Check out this asciicinema video for the full glory.

Note: wp search-replace is much slower when logging transformations, so please use it wisely.

See registered image sizes

Does uploading a new image take forever? You might have too many registered image sizes!

Both themes and plugins make use of add_image_size() [ref] to define names for image sizes they expect to use in templating. For each registered image size with a hard crop, WordPress has to create the cropped version on upload. With dozens of image sizes, uploading an image can take tens of seconds.

Use wp media image-size to see all of the image sizes registered to WordPress [#36, #37, #39, #49]:

$ wp media image-size --format=count

55 is too many!

Everything else in v1.4.0

New and notable

  • wp cli has-command: Detect whether a command is registered [#4349].
  • wp site (mature|unmature|public|unpublic): Manage mature and public status of a site [#63].
  • wp * (pluck|patch): Fetch and modify serialized data in options and meta [#24, #65].
  • wp user (spam|unspam): Mark a user as spam or not spam [#74, #86, #90].

Command improvements

  • comment list:
    • Improves performance of --format=count [#64].
  • core download:
    • Use --skip-content to download WordPress without default themes/plugins (US locale only) [#37, #40, #41].
  • core update:
    • Makes use of halt_on_error to catch error and release lock [#38].
  • db export:
    • Includes Y-m-d in default export file name [#36].
  • db search:
    • Caters for reserved word column/table names [#40].
    • Changes default delimiter to chr(1) [#46].
    • Fixes match in non-regex case [#45].
    • Lessens context duplication by shortening and appending context if it overlaps with the next match [#55].
    • Avoids displaying default delimiter on regex fail in db search [#56].
  • export:
    • Adds --stdout to write WXR to STDOUT [#13].
    • Adds --max_file_size=-1 to avoid splitting export files [#12, #21].
    • Adds --max_num_posts=<num> to limit number of posts in an export file [#15].
  • import:
    • Avoids use of GLOB_BRACE for compatibility with Alpine Linux [#14].
  • media import:
    • Properly handles query strings on image import to prevent security error [#35].
    • Adds --preserve-filetime argument to support persisting file modification time [#42].
  • media regenerate:
    • Skips non-thumbnailed PDFs & other images rather than fail [#48].
  • package browse:
    • Adds deprecation notice [#36].
  • package install:
    • Supports package names that differ from repository names [#31].
  • package (install|uninstall):
    • Only includes Composer return code when it’s set [#40].
  • package uninstall:
    • Removes repository entry when uninstalling [#37].
  • plugin install:
    • Skips renaming ZIPs coming from a GitHub archive release/tag [#45].
  • plugin list:
    • Wraps all uses of get_plugins() with the all_plugins filter [#31].
    • Includes dropins like object-cache.php when listing installed plugins [#55].
  • plugin search:
    • Only displays pagination message when --format=table [#56].
  • scaffold child-theme:
    • Transforms spaces to underscores when scaffolding a child theme [#40].
  • scaffold plugin:
    • Adds package-lock.json, yarn.lock to distignore template [#57].
  • scaffold plugin-tests:
    • Uses $TMPDIR in bin/ to allow temp directory override [#39].
    • Uses latest branch for test library in bin/, and always gets the latest major release when 2 digit WP versions are used [#35].
    • Removes XDebug in scaffolded .travis.yml to improve performance [#49].
    • Improves error message when phpunit is run before bin/ [#55].
    • Shows progress when invoking phpcs [#64].
    • Adds PHP 7.0 and 7.1 to scaffolded GitLab configuration [#68].
  • scaffold (post-type|taxonomy):
    • Enhances pluralization by internalizing Doctrine library [#54, #58, #59].
  • search-replace:
    • Adds esc_sql_ident() function to escape column/table names [#23].
    • Adds --regex-delimiter argument and validation for the --regex-flags argument [#28, #29, #30].
    • Adds --report flag so report can be suppressed with --no-report; --report-changed-only flag option to only report changed fields [#32].
    • Avoids displaying default delimiter on regex failure [#40].
  • site delete:
    • Prevent deleting the root site on multisite, which WordPress core doesn’t permit [#73].
  • user import-csv:
    • Permits importing CSV from STDIN [#100].

Framework enhancements

  • Brings codebase inline with WordPress Coding Standards while narrowly avoiding committer mutiny [#4058].
  • Improves AutoloadSplitter regexes [#4422].
  • Add skips argument to WP_CLI\Utils\report_batch_operation_results() [#4429].
  • Provides dictionary-based suggestions for common misspellings [#4392].
  • Introduces new ‘halt_on_error’ to overload exit in WP_CLI\Utils\http_request() [#4383].
  • When extracting, fails back to tar xz when PharData throws an Exception [#4371].
  • Adds support for running commands over vagrant ssh [#4348].
  • Supports upper- and lowercase ‘Y’ when prompting a flag [#4334].
  • Gives suggestions when exiting early on wp help [#4266, #4303].

Contributors to this release (42 total): aaemnnosttv, AaronRutley, ako80218, anhskohbo, atimmer, BhargavBhandari90, danielbachhuber, desrosj, diggy, domantasg, drzraf, eliseferguson, ethanclevenger91, Flimm, fumikito, GaryJones, gitlost, goldenapples, hearvox, Ippey, javorszky, jdub233, johnbillion, kurudrive, Lewiscowles1986, mimosafa, mitchelldmiller, mitraval192, miya0001, n8finch, nameherocom, nextgenthemes, ryotsun, schlessera, shadyvb, Sidsector9, stevegrunwell, szepeviktor, takezou, Umangvaghela, waviaei, wp-make-coffee

WP Plugin & Theme Checksums Project – Update

The WordPress Plugin & Theme Checksums Project has been kicked off!

Here’s a quick run-down of the current state of affairs:

  • The server side of the development will be managed in, whereas the consuming client code development will be managed in for now.
  • Project collaboration and coordination will happen in a dedicated #cli-checksums channel (not created yet, WIP:
  • It now looks like the most promising approach is to directly build the checksum generation into the existing .org infrastructure, as the code that is generating the ZIP downloads can easily be extended to generate and store the checksums at the same time. @dd32 is currently working on proof-of-concepts to evaluate the best approach for this in
  • The current timeline for following through with the project is:
    • Planning phase: Oct 3 – Oct 24
    • Implementation phase: Oct 25 – Nov 14
    • Integration phase: Nov 15 – Nov 22
  • Several companies have offered to support this project with development time or other help, and are already invested in differing degrees: DreamHostPagely, Plesk, Savvii.

UPDATE (Oct. 17th): We opted to keep project collaboration and coordination in the general #cli channel for now, instead of in a dedicated channel.


Daniel likes these issues

WP-CLI’s next release, v1.4.0, is just around the corner: Tuesday, October 17th. If you’ve contributed to WP-CLI before, here are a few moderately advanced issues I’d love to see fixed in the next release:

Read through the contributing guide for a refresher on the process. Feel free to ask questions on the specific issue, or join us in the #cli channel with any questions you might have.