WP-CLI v2.12.0 Release Notes


A new release of WP-CLI, WP-CLI v2.12.0, is now available. For this release, we had 68 contributors collaborate to get 382 pull requests merged. 

As always, big thanks to the WP-CLI sponsors that make the continued maintenance possible.

This release includes numerous bug fixes and compatibility improvements, but we still could teach WP-CLI a few new tricks which I’ll highlight below. As always, you can also skip directly to the detailed changelog if you prefer.

If you already use WP-CLI, updating is as simple as wp cli update. Else, check out our website for recommended installation methods.

Pluck & patch commands for caches and transients

The cache and transient commands have now also learned the subtle art of plucking and patching. This means that you can directly manipulate individual entries in an array of values that these commands let you manage.

Here’s an example of how such an operation can look and how it compare to the regular cache/transient operations:

# Transient structure
# 'some_key' => ['foo' => ['bar' => 'baz']]

# Retrieve the transient value
$ wp transient get some_key --format=json
{'foo':{'bar':'baz'}}

# Retrieve the value of the foo => bar subkey
$ wp transient pluck some_key foo bar
baz

# Replace baz with bazzer
$ wp transient patch update some_key foo bar bazzer
Success: Updated transient 'some_key'.

Post lists can now handle complex query flags

When using post list, you can now use JSON notation to provide complex query arguments to the --tax_query, --meta_query and --post_date fields.

$ wp post list --field=post_title --date_query='{"before":{"year":"2024"}}
+--------------------------+
| post_title               |
+--------------------------+
| My year in review - 2021 |
| My year in review - 2022 |
| My year in review - 2023 |
+--------------------------+

$ wp post list --field=post_title --tax_query='[{"taxonomy":"category","field":"slug","terms":"first-category"}]'
...

$ wp post list --field=post_title --meta_query='[{"key":"key2","value":"value2b"}]'
...

Post meta can be forced to only return a single value

The post meta get command now has a --single flag defaulting to true which can be negated with --no-single. This flag tells WordPress whether to only return a single value or all existing values for a given key.

# Create a post meta key for post with ID 123 that has multiple values
$ wp post meta add 123 my_meta_key value_1
$ wp post meta add 123 my_meta_key value_2
$ wp post meta add 123 my_meta_key value_4

# Retrieve a single value
$ wp post meta get 123 my_meta_key --single
value_1

# Retrieve all values
$ wp post meta get 123 my_meta_key --no-single --format=json
["value_1","value_2","value_3"]

Exclude files on core checksum verification

When running a core checksum verification, you can exclude one or more files from the checksum verification with the new --exclude=<files> flag, which takes a comma-separated list of filepaths relative to the current root.

# Make a change to the README file in the WordPress core root folder
$ echo "nonsense" > readme.html

# Run the core checksum verification
$ wp core verify-checksums --exclude='readme.html'
Success: WordPress installation verifies against checksums.

Respect requires and requires_php tags for plugins and themes

The plugin and theme commands now understand and respect the requires and requires_php header tags when trying ot install or update extensions. A new state unavailable has been introduced to denote the updates that are newer that your current installation but for which your site does not fulfill the requirements.

This also adds new fields requires and requires_php which are displayed if they contain relevant information and otherwise hidden by default.

$ wp plugin list
+----------------+----------+-------------+---------+----------------+-------------+----------+--------------+
| name           | status   | update      | version | update_version | auto_update | requires | requires_php |
+----------------+----------+-------------+---------+----------------+-------------+----------+--------------+
| akismet        | inactive | available   | 5.1     | 5.3.5          | off         | 5.8      | 5.6.20       |
| edit-flow      | inactive | none        | 0.9.9   |                | off         | 6.0      | 8.0          |
| wp-super-cache | inactive | unavailable | 1.9.4   | 1.12.4         | off         | 6.5      | 7.0          |
+----------------+----------+-------------+---------+----------------+-------------+----------+--------------+

$ wp plugin update wp-super-cache
Warning: wp-super-cache: This update requires WordPress version 6.5, but the version installed is 6.2.
Error: No plugins updated.

More control over make-json generation

The make-json command was made more powerful again. You can not only set a custom text domain to be used, you can also define the file extension to parse.

# Use a custom text domain
$ wp i18n make-json foo-theme --domain=my-custom-domain
Success: Created 1 file.

# Include typescript files
$ wp i18n make-json foo-theme --extensions=".ts, .tsx"
Success: Created 2 files.

Force update checks on plugin|theme list

When displaying the list of plugins or themes, WP-CLI now always ensures you get fresh data. No need to manually clear transients anymore! The existing --skip-update-check flag can be used to prevent this behavior.

# Clears any update transients to trigger an update check and display results
$ wp plugin list --fields=name,status,update --force-check
+-------------+----------+--------+
| name        | status   | update |
+-------------+----------+--------+
| hello-dolly | inactive | none   |
+-------------+----------+--------+

PHP 8.4 Compatiblity

WP-CLI is now fully compatible with PHP 8.4. This has required quite a bit of trickery and hacks to maintain compatibility with our current minimum of PHP 5.6+ at the same time. With the next release, we’ll bump the minimum PHP version to 7.2.24+, which will allow us to get rid of all these workarounds again.

Detailed Change Log

wp-cli/wp-cli-bundle

  • Fix Phar path resolution with renamed binaries [#752]
  • Deployment: Fix FILENAME env var [#696]
  • Address deprecation warnings in Behat tests [#663]

wp-cli/wp-cli

  • Replace duplicate-post plugin with debug-bar in feature tests [#6091]
  • Use forked mustache library [#6090]
  • Escape CSV output [#6089]
  • Make sure existing esc_like() takes precedence [#6088]
  • Set display_errors to stderr (lowercase) instead of STDERR [#6084]
  • Fix update step for nightlies [#6075]
  • Detect MariaDB vs MySQL [#6072]
  • Update WP-CLI update message [#6071]
  • Add WP_CLI_REQUIRE environment variable for including extra PHP files [#6070]
  • Remove array_column() compatibility function [#6068]
  • Support multiple files in WP_CLI_EARLY_REQUIRE [#6065]
  • Properly create missing WP-CLI configuration file when needed [#6062]
  • Improve command suggestions for taxonomies and post types [#6059]
  • Fix undefined variable issue [#6058]
  • Pass working-directory and stdin to docker scheme [#5974] & [#6057]
  • Add test for line breaks in table view [#6055]
  • Ensure code after wp-settings.php call is loaded [#6042]
  • Allow collecting PHPUnit coverage [#6041]
  • don’t forcefully exec() docker version [#6040]
  • Improve regular expression for detecting wp-settings.php [#6039]
  • Check PHP version requirement in update check [#6037]
  • Add hook to http_request() utility function [#6036]
  • Add PHPDoc for cmd_starts_with() method [#6034]
  • Update expected error message in unit tests [#6032]
  • Update outdated AJAX documentation link [#6031]
  • Add global documentation [#6017]
  • Allow remote binary customization [#6013]
  • Add configurable user agent to WP-CLI to detect in firewall logs [#5998]
  • Convert PHPUnit deprecations into exceptions [#5994]
  • Remove unused automerge workflow [#5992]
  • Fix CSV escaping deprecation notices [#5991]
  • Check for root earlier [#5987]
  • Remove use of E_STRICT for wp_debug_mode() [#5986]
  • Fix deprecation notices for ReflectionProperty::setValue() [#5984]
  • Fix “missing return type” deprecation warnings in WP_CLI\Iterators\CSV [#5983]
  • Fix implicitly nullable parameters [#5982]
  • Update Requests to v2.0.12 [#5981]
  • Update log and warning logger functions comment according to the actual functionality [#5979]
  • Add defaults and accepted values for runcommand() options in documentation [#5953]

wp-cli/handbook

  • Update documentation to include new WP_CLI_SSH_BINARY value [#559]
  • Add documentation for newly supported ENV vars [#556]
  • Update URL for True-False Hosting [#553]

wp-cli/cache-command

  • Fix expired transients tests [#104]
  • Allow manually dispatching tests workflow [#99]
  • Make transient test more robust against added transients by core [#98]
  • Add pluck & patch commands for caches and transients [#89]

wp-cli/checksum-command

  • Add blank space when trimming the version [#130]
  • Add --exclude argument for verifying checksums [#123]
  • Remove unused variable [#134]
  • Don’t check missing files [#131]

wp-cli/config-command

  • Don’t require file to be writable for config has [#187]
  • Suppress output of eval(get_wp_config_code) preventing errors printing twice [#188]

wp-cli/core-command

  • Fix flaky tests due to changing download URL [#277]
  • Allow installing major version with trailing zero [#276]
  • Use existing WpOrgApi helper class [#283]
  • Add doc comment for $insecure [#281]
  • Host shouldn’t include http:// [#279]

wp-cli/cron-command

  • Harden test checking for log file [#111]

wp-cli/db-command

  • Correct error message in db search for --format=count [#267]
  • Update db search documentation [#265]
  • Add --add-drop-table to export command options [#263]
  • Improve MariaDB detection/compatibility [#280]
  • Add affected rows count for queries that can modify data in db query [#277]
  • Don’t hardcode MySQL command names [#275]

wp-cli/entity-command

  • Add missing options header in signup list command [#508]
  • Ensure user update returns non-zero exit code for invalid users [#527]
  • Make term-migrate test more robust [#524]
  • Add a flag for getting post meta as a single value or not [#523]
  • Add JSON input support for tax_query and meta_query [#522]
  • Add JSON input support for date_query argument [#520]
  • wp option – new autoload values in autoload filter [#515]
  • Return a proper WP_Error object when failing to update a comment [#514]
  • Add test cases asserting post/term update error exit codes [#513]
  • Safeguard remove cap from collisions with roles [#530]

wp-cli/export-command

  • Use get_post_stati() instead of get_post_statuses() to support all registered post statuses in export [#121]

wp-cli/extension-command

  • Use strpos() instead of str_contains() in get_wporg_data() function [#432]
  • Don’t use transient values when doing plugin|theme list [#446]
  • Fix fatal error issue in in_array() function [#445]
  • Support requires and requires_php in plugin|theme list and plugin|theme update commands [#440]
  • Update logic when deleting and uninstalling plugins [#438]
  • Check WordPress and PHP requirements before installing a theme or plugin [#436]
  • Add --force-check flag to wp plugin list and wp theme list. [#426]
  • Cache certain GitHub URLs [#385]

wp-cli/i18n-command

  • Convert PHPUnit deprecations to exceptions [#413]
  • make-pot: scan any theme.json file in any level [#424]
  • Add ability to pass extensions to make-json command [#439]
  • Update schema fallback files [#431]
  • make-json: Add new --domain argument [#430]
  • update-po: merge X-Domain header [#429]
  • Add php-format and js-format flags [#428]

wp-cli/language-command

  • Mention site switch-language in readme [#159]
  • Allow filtering languages by multiple statuses [#162]

wp-cli/php-cli-tools

  • Example code: remove use of E_STRICT [#175]
  • Fix implicitly nullable parameters [#173]
  • Replace tabs in tables with 4 spaces [#181]
  • Properly handle line breaks in column value [#179]
  • Support line breaks and tab replacement in tabular table values [#182]
  • Fix removal of trailing tab / whitespace in tabular table [#184]
  • Avoid deprecation warnings in newer PHP [#185]

wp-cli/rewrite-command

  • Improve warning message in rewrite flush [#69]

wp-cli/scaffold-command

  • Convert PHPUnit deprecations to exceptions [#348]
  • Add dependency checks and error handling for svn and download tools [#345]
  • Accept Bitbucket as valid CI in scaffold plugin [#340]
  • Update Bitbucket CI [#339]
  • Update templates for child theme scaffolding [#342]
  • Update custom post type and taxonomy scaffolding [#341]
  • Update GitLab CI configuration file [#338]
  • Remove grunt from plugin scaffolding [#337]

wp-cli/shell-command

  • Add missing do construct [#68]

wp-cli/wp-config-transformer

  • Add read-only option for WPConfigTransformer [#54]
  • Add a branch-alias for dev-main [#55]
  • Deletion of constants deletes more lines than expected [#53]

Contributors

@9ete, @amirhmoradi, @baizmandesign, @benjaminprojas, @BhargavBhandari90, @cliffordp, @daalderp, @dac514, @danielbachhuber, @dd32, @dkoston, @dlind1, @drzraf, @elenachavdarova, @ernilambar, @gedex, @gitlost, @greatislander, @herregroen, @i-am-chitti, @iDschepe, @imrraaj, @itsmekopila, @janw-me, @jenkoian, @jkrrv, @jrfnl, @karthick-murugan, @l3ku, @localheinz, @marksabbath, @matiasbenedetto, @matzeeable, @meszarosrob, @michaelw85, @michaelzangl, @mostafasoufi, @mrsdizzie, @oandregal, @ocean90, @ouikhuan, @PARTHVATALIYA, @pbiron, @peterwilsoncc, @petitphp, @pfefferle, @pmbaldha, @ponsfrilus, @pwtyler, @ramonjd, @rodrigoprimo, @Roy-Orbison, @saas786, @sabithahmd, @sdnunca, @shendy-a8c, @shreya0204, @siliconforks, @strarsis, @swissspidy, @todeveni, @Tug, @tyrann0us, @wojsmol, @wpeople-dev, @WPprodigy, @yousan

#release, #v2-12-0