From 0d505a415a85de140485cde5f779bf1a87ad4835 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 11:57:42 +0000 Subject: [PATCH 1/7] Initial plan From 72504256200d00158b828290c11ab3a7a1e4b28b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 12:03:59 +0000 Subject: [PATCH 2/7] Add test for PHP binary path with spaces and apply fix to CLI_Command Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- features/cli.feature | 24 + .../wp-cli/php/commands/src/CLI_Command.php | 805 ++++++++++++++++++ 2 files changed, 829 insertions(+) create mode 100644 vendor/wp-cli/wp-cli/php/commands/src/CLI_Command.php diff --git a/features/cli.feature b/features/cli.feature index a444c2c4c..87cf49b29 100644 --- a/features/cli.feature +++ b/features/cli.feature @@ -173,3 +173,27 @@ Feature: `wp cli` tasks """ WP-CLI {UPDATE_VERSION} """ + + @github-api + Scenario: Update command works with PHP binary path containing spaces + Given an empty directory + And a new Phar with version "0.0.0" + + # Create a directory with spaces and a PHP wrapper + When I run `mkdir -p "php with spaces/bin"` + And I run `printf '#!/bin/bash\nexec php "$@"' > "php with spaces/bin/php"` + And I run `chmod +x "php with spaces/bin/php"` + Then the return code should be 0 + + # Test that the update command works when PHP_BINARY has spaces + When I run `PHP_BINARY="$PWD/php with spaces/bin/php" "$PWD/php with spaces/bin/php" {PHAR_PATH} cli update --yes` + Then STDOUT should contain: + """ + sha512 hash verified: + """ + And STDOUT should contain: + """ + Success: + """ + And STDERR should be empty + And the return code should be 0 diff --git a/vendor/wp-cli/wp-cli/php/commands/src/CLI_Command.php b/vendor/wp-cli/wp-cli/php/commands/src/CLI_Command.php new file mode 100644 index 000000000..70ec7faef --- /dev/null +++ b/vendor/wp-cli/wp-cli/php/commands/src/CLI_Command.php @@ -0,0 +1,805 @@ +} + * + * @phpstan-type UpdateOffer array{version: string, update_type: string, package_url: string, status: string, requires_php: string} + */ +class CLI_Command extends WP_CLI_Command { + + private function command_to_array( $command ) { + $dump = [ + 'name' => $command->get_name(), + 'description' => $command->get_shortdesc(), + 'longdesc' => $command->get_longdesc(), + 'hook' => $command->get_hook(), + ]; + + $alias = $command->get_alias(); + if ( $alias ) { + $dump['alias'] = $alias; + } + + foreach ( $command->get_subcommands() as $subcommand ) { + $dump['subcommands'][] = $this->command_to_array( $subcommand ); + } + + if ( empty( $dump['subcommands'] ) ) { + $dump['synopsis'] = (string) $command->get_synopsis(); + } + + return $dump; + } + + /** + * Prints WP-CLI version. + * + * ## EXAMPLES + * + * # Display CLI version. + * $ wp cli version + * WP-CLI 0.24.1 + */ + public function version() { + WP_CLI::line( 'WP-CLI ' . WP_CLI_VERSION ); + } + + /** + * Prints various details about the WP-CLI environment. + * + * Helpful for diagnostic purposes, this command shares: + * + * * OS information. + * * Shell information. + * * PHP binary used. + * * PHP binary version. + * * php.ini configuration file used (which is typically different than web). + * * WP-CLI root dir: where WP-CLI is installed (if non-Phar install). + * * WP-CLI global config: where the global config YAML file is located. + * * WP-CLI project config: where the project config YAML file is located. + * * WP-CLI version: currently installed version. + * + * See [config docs](https://make.wordpress.org/cli/handbook/references/config/) for more details on global + * and project config YAML files. + * + * ## OPTIONS + * + * [--format=] + * : Render output in a particular format. + * --- + * default: list + * options: + * - list + * - json + * --- + * + * ## EXAMPLES + * + * # Display various data about the CLI environment. + * $ wp cli info + * OS: Linux 4.10.0-42-generic #46~16.04.1-Ubuntu SMP Mon Dec 4 15:57:59 UTC 2017 x86_64 + * Shell: /usr/bin/zsh + * PHP binary: /usr/bin/php + * PHP version: 7.1.12-1+ubuntu16.04.1+deb.sury.org+1 + * php.ini used: /etc/php/7.1/cli/php.ini + * WP-CLI root dir: phar://wp-cli.phar + * WP-CLI packages dir: /home/person/.wp-cli/packages/ + * WP-CLI global config: + * WP-CLI project config: + * WP-CLI version: 1.5.0 + * + * @param string[] $args Positional arguments. Unused. + * @param array{format: string} $assoc_args Associative arguments. + */ + public function info( $args, $assoc_args ) { + $system_os = sprintf( + '%s %s %s %s', + php_uname( 's' ), + php_uname( 'r' ), + php_uname( 'v' ), + php_uname( 'm' ) + ); + + $shell = getenv( 'SHELL' ); + if ( ! $shell && Utils\is_windows() ) { + $shell = getenv( 'ComSpec' ); + } + + $php_bin = Utils\get_php_binary(); + + $runner = WP_CLI::get_runner(); + + $packages_dir = $runner->get_packages_dir_path(); + if ( ! is_dir( $packages_dir ) ) { + $packages_dir = null; + } + + if ( Utils\get_flag_value( $assoc_args, 'format' ) === 'json' ) { + $info = [ + 'system_os' => $system_os, + 'shell' => $shell, + 'php_binary_path' => $php_bin, + 'php_version' => PHP_VERSION, + 'php_ini_used' => get_cfg_var( 'cfg_file_path' ), + 'mysql_binary_path' => Utils\get_mysql_binary_path(), + 'mysql_version' => Utils\get_mysql_version(), + 'sql_modes' => Utils\get_sql_modes(), + 'wp_cli_dir_path' => WP_CLI_ROOT, + 'wp_cli_vendor_path' => WP_CLI_VENDOR_DIR, + 'wp_cli_phar_path' => defined( 'WP_CLI_PHAR_PATH' ) ? WP_CLI_PHAR_PATH : '', + 'wp_cli_packages_dir_path' => $packages_dir, + 'wp_cli_cache_dir_path' => Utils\get_cache_dir(), + 'global_config_path' => $runner->global_config_path, + 'project_config_path' => $runner->project_config_path, + 'wp_cli_version' => WP_CLI_VERSION, + ]; + + WP_CLI::line( (string) json_encode( $info ) ); + } else { + /** + * @var string $cfg_file_path + */ + $cfg_file_path = get_cfg_var( 'cfg_file_path' ); + WP_CLI::line( "OS:\t" . $system_os ); + WP_CLI::line( "Shell:\t" . $shell ); + WP_CLI::line( "PHP binary:\t" . $php_bin ); + WP_CLI::line( "PHP version:\t" . PHP_VERSION ); + WP_CLI::line( "php.ini used:\t" . $cfg_file_path ); + WP_CLI::line( "MySQL binary:\t" . Utils\get_mysql_binary_path() ); + WP_CLI::line( "MySQL version:\t" . Utils\get_mysql_version() ); + WP_CLI::line( "SQL modes:\t" . implode( ',', Utils\get_sql_modes() ) ); + WP_CLI::line( "WP-CLI root dir:\t" . WP_CLI_ROOT ); + WP_CLI::line( "WP-CLI vendor dir:\t" . WP_CLI_VENDOR_DIR ); + WP_CLI::line( "WP_CLI phar path:\t" . ( defined( 'WP_CLI_PHAR_PATH' ) ? WP_CLI_PHAR_PATH : '' ) ); + WP_CLI::line( "WP-CLI packages dir:\t" . $packages_dir ); + WP_CLI::line( "WP-CLI cache dir:\t" . Utils\get_cache_dir() ); + WP_CLI::line( "WP-CLI global config:\t" . $runner->global_config_path ); + WP_CLI::line( "WP-CLI project config:\t" . $runner->project_config_path ); + WP_CLI::line( "WP-CLI version:\t" . WP_CLI_VERSION ); + } + } + + /** + * Checks to see if there is a newer version of WP-CLI available. + * + * Queries the GitHub releases API. Returns available versions if there are + * updates available, or success message if using the latest release. + * + * ## OPTIONS + * + * [--patch] + * : Only list patch updates. + * + * [--minor] + * : Only list minor updates. + * + * [--major] + * : Only list major updates. + * + * [--field=] + * : Prints the value of a single field for each update. + * + * [--fields=] + * : Limit the output to specific object fields. Defaults to version,update_type,package_url,status,requires_php. + * + * [--format=] + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - json + * - count + * - yaml + * --- + * + * ## EXAMPLES + * + * # Check for update. + * $ wp cli check-update + * Success: WP-CLI is at the latest version. + * + * # Check for update and new version is available. + * $ wp cli check-update + * +---------+-------------+-------------------------------------------------------------------------------+ + * | version | update_type | package_url | + * +---------+-------------+-------------------------------------------------------------------------------+ + * | 0.24.1 | patch | https://github.com/wp-cli/wp-cli/releases/download/v0.24.1/wp-cli-0.24.1.phar | + * +---------+-------------+-------------------------------------------------------------------------------+ + * + * @subcommand check-update + * + * @param string[] $args Positional arguments. Unused. + * @param array{patch?: bool, minor?: bool, major?: bool, field?: string, fields?: string, format: string} $assoc_args Associative arguments. + */ + public function check_update( $args, $assoc_args ) { + $updates = $this->get_updates( $assoc_args ); + + if ( $updates ) { + $formatter = new Formatter( + $assoc_args, + [ 'version', 'update_type', 'package_url', 'status', 'requires_php' ] + ); + $formatter->display_items( $updates ); + } elseif ( empty( $assoc_args['format'] ) || 'table' === $assoc_args['format'] ) { + $update_type = $this->get_update_type_str( $assoc_args ); + WP_CLI::success( "WP-CLI is at the latest{$update_type}version." ); + } + } + + /** + * Updates WP-CLI to the latest release. + * + * Default behavior is to check the releases API for the newest stable + * version, and prompt if one is available. + * + * Use `--stable` to install or reinstall the latest stable version. + * + * Use `--nightly` to install the latest built version of the master branch. + * While not recommended for production, nightly contains the latest and + * greatest, and should be stable enough for development and staging + * environments. + * + * Only works for the Phar installation mechanism. + * + * ## OPTIONS + * + * [--patch] + * : Only perform patch updates. + * + * [--minor] + * : Only perform minor updates. + * + * [--major] + * : Only perform major updates. + * + * [--stable] + * : Update to the latest stable release. Skips update check. + * + * [--nightly] + * : Update to the latest built version of the master branch. Potentially unstable. + * + * [--yes] + * : Do not prompt for confirmation. + * + * [--insecure] + * : Retry without certificate validation if TLS handshake fails. Note: This makes the request vulnerable to a MITM attack. + * + * ## EXAMPLES + * + * # Update CLI. + * $ wp cli update + * You are currently using WP-CLI version 0.24.0. Would you like to update to 0.24.1? [y/n] y + * Downloading from https://github.com/wp-cli/wp-cli/releases/download/v0.24.1/wp-cli-0.24.1.phar... + * New version works. Proceeding to replace. + * Success: Updated WP-CLI to 0.24.1. + * + * @param string[] $args Positional arguments. Unused. + * @param array{patch?: bool, minor?: bool, major?: bool, stable?: bool, nightly?: bool, yes?: bool, insecure?: bool} $assoc_args Associative arguments. + */ + public function update( $args, $assoc_args ) { + if ( ! Utils\inside_phar() ) { + WP_CLI::error( 'You can only self-update Phar files.' ); + } + + $old_phar = (string) realpath( $_SERVER['argv'][0] ); + + if ( ! is_writable( $old_phar ) ) { + WP_CLI::error( sprintf( '%s is not writable by current user.', $old_phar ) ); + } elseif ( ! is_writable( dirname( $old_phar ) ) ) { + WP_CLI::error( sprintf( '%s is not writable by current user.', dirname( $old_phar ) ) ); + } + + if ( Utils\get_flag_value( $assoc_args, 'nightly' ) ) { + WP_CLI::confirm( sprintf( 'You are currently using WP-CLI version %s. Would you like to update to the latest nightly version?', WP_CLI_VERSION ), $assoc_args ); + $download_url = 'https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli-nightly.phar'; + $md5_url = 'https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli-nightly.phar.md5'; + $sha512_url = 'https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli-nightly.phar.sha512'; + } elseif ( Utils\get_flag_value( $assoc_args, 'stable' ) ) { + WP_CLI::confirm( sprintf( 'You are currently using WP-CLI version %s. Would you like to update to the latest stable release?', WP_CLI_VERSION ), $assoc_args ); + $download_url = 'https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar'; + $md5_url = 'https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar.md5'; + $sha512_url = 'https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar.sha512'; + } else { + + $updates = $this->get_updates( $assoc_args ); + + /** + * @phpstan-var UpdateOffer|null $newest + */ + $newest = $this->array_find( + $updates, + static function ( $update ) { + return 'available' === $update['status']; + } + ); + + if ( ! $newest ) { + $update_type = $this->get_update_type_str( $assoc_args ); + WP_CLI::success( "WP-CLI is at the latest{$update_type}version." ); + return; + } + + WP_CLI::confirm( sprintf( 'You have version %s. Would you like to update to %s?', WP_CLI_VERSION, $newest['version'] ), $assoc_args ); + + $download_url = $newest['package_url']; + $md5_url = str_replace( '.phar', '.phar.md5', $download_url ); + $sha512_url = str_replace( '.phar', '.phar.sha512', $download_url ); + } + + WP_CLI::log( sprintf( 'Downloading from %s...', $download_url ) ); + + $temp = Utils\get_temp_dir() . uniqid( 'wp_', true ) . '.phar'; + + $headers = []; + $options = [ + 'timeout' => 600, // 10 minutes ought to be enough for everybody. + 'filename' => $temp, + 'insecure' => (bool) Utils\get_flag_value( $assoc_args, 'insecure', false ), + ]; + + Utils\http_request( 'GET', $download_url, null, $headers, $options ); + + unset( $options['filename'] ); + + $this->validate_hashes( $temp, $sha512_url, $md5_url ); + + $allow_root = WP_CLI::get_runner()->config['allow-root'] ? '--allow-root' : ''; + $php_binary = Utils\get_php_binary(); + $process = Process::create( Utils\esc_cmd( '%s %s --info %s', $php_binary, $temp, $allow_root ) ); + $result = $process->run(); + if ( 0 !== $result->return_code || false === stripos( $result->stdout, 'WP-CLI version' ) ) { + $multi_line = explode( PHP_EOL, $result->stderr ); + WP_CLI::error_multi_line( $multi_line ); + WP_CLI::error( 'The downloaded PHAR is broken, try running wp cli update again.' ); + } + + WP_CLI::log( 'New version works. Proceeding to replace.' ); + + $mode = fileperms( $old_phar ) & 511; + + if ( false === chmod( $temp, $mode ) ) { + WP_CLI::error( sprintf( 'Cannot chmod %s.', $temp ) ); + } + + class_exists( '\cli\Colors' ); // This autoloads \cli\Colors - after we move the file we no longer have access to this class. + + if ( false === rename( $temp, $old_phar ) ) { + WP_CLI::error( sprintf( 'Cannot move %s to %s', $temp, $old_phar ) ); + } + + if ( Utils\get_flag_value( $assoc_args, 'nightly', false ) ) { + $updated_version = 'the latest nightly release'; + } elseif ( Utils\get_flag_value( $assoc_args, 'stable', false ) ) { + $updated_version = 'the latest stable release'; + } else { + $updated_version = isset( $newest['version'] ) ? $newest['version'] : ''; + } + WP_CLI::success( sprintf( 'Updated WP-CLI to %s.', $updated_version ) ); + } + + /** + * @param string $file Release file path. + * @param string $sha512_url URL to sha512 hash. + * @param string $md5_url URL to md5 hash. + * + * @throws \WP_CLI\ExitException + */ + private function validate_hashes( $file, $sha512_url, $md5_url ): void { + $algos = [ + 'sha512' => $sha512_url, + 'md5' => $md5_url, + ]; + + foreach ( $algos as $algo => $url ) { + $response = Utils\http_request( 'GET', $url ); + if ( '20' !== substr( (string) $response->status_code, 0, 2 ) ) { + WP_CLI::log( "Couldn't access $algo hash for release (HTTP code {$response->status_code})." ); + continue; + } + + $file_hash = hash_file( $algo, $file ); + + $release_hash = trim( $response->body ); + if ( $file_hash === $release_hash ) { + WP_CLI::log( "$algo hash verified: $release_hash" ); + return; + } else { + WP_CLI::error( "$algo hash for download ($file_hash) is different than the release hash ($release_hash)." ); + } + } + + WP_CLI::error( 'Release hash verification failed.' ); + } + + /** + * Returns update information. + */ + private function get_updates( $assoc_args ) { + $url = 'https://api.github.com/repos/wp-cli/wp-cli/releases?per_page=100'; + + $options = [ + 'timeout' => 30, + 'insecure' => (bool) Utils\get_flag_value( $assoc_args, 'insecure', false ), + ]; + + $headers = [ + 'Accept' => 'application/json', + ]; + + $github_token = getenv( 'GITHUB_TOKEN' ); + if ( false !== $github_token ) { + $headers['Authorization'] = 'token ' . $github_token; + } + + $response = Utils\http_request( 'GET', $url, null, $headers, $options ); + + if ( ! $response->success || 200 !== $response->status_code ) { + WP_CLI::error( sprintf( 'Failed to get latest version (HTTP code %d).', $response->status_code ) ); + } + + /** + * @phpstan-var GitHubRelease[] $release_data + */ + $release_data = json_decode( $response->body, false ); + + $updates = [ + 'major' => false, + 'minor' => false, + 'patch' => false, + ]; + + $updates_unavailable = []; + + foreach ( $release_data as $release ) { + + // Get rid of leading "v" if there is one set. + $release_version = $release->tag_name; + if ( 'v' === substr( $release_version, 0, 1 ) ) { + $release_version = ltrim( $release_version, 'v' ); + } + + $update_type = Utils\get_named_sem_ver( $release_version, WP_CLI_VERSION ); + + if ( ! $update_type ) { + continue; + } + + // Release is older than one we already have on file. + if ( ! empty( $updates[ $update_type ] ) && ! Comparator::greaterThan( $release_version, $updates[ $update_type ]['version'] ) ) { + continue; + } + + $package_url = null; + + /** + * WP-CLI manifest.json data. + * + * @var object{requires_php?: string}|null $manifest_data + */ + $manifest_data = null; + + foreach ( $release->assets as $asset ) { + if ( ! isset( $asset->browser_download_url ) ) { + continue; + } + + if ( substr( $asset->browser_download_url, - strlen( '.phar' ) ) === '.phar' ) { + $package_url = $asset->browser_download_url; + } + + // The manifest.json file, if it exists, contains information about PHP version requirements and similar. + if ( substr( $asset->browser_download_url, - strlen( 'manifest.json' ) ) === 'manifest.json' ) { + $response = Utils\http_request( 'GET', $asset->browser_download_url, null, $headers, $options ); + + if ( $response->success ) { + /** + * WP-CLI manifest.json data. + * + * @var object{requires_php?: string}|null $manifest_data + */ + $manifest_data = json_decode( $response->body, false ); + } + } + } + + if ( ! $package_url ) { + continue; + } + + // Release requires a newer version of PHP. + if ( + isset( $manifest_data->requires_php ) && + ! Comparator::greaterThanOrEqualTo( PHP_VERSION, $manifest_data->requires_php ) + ) { + $updates_unavailable[] = [ + 'version' => $release_version, + 'update_type' => $update_type, + 'package_url' => $release->assets[0]->browser_download_url, + 'status' => 'unavailable', + 'requires_php' => $manifest_data->requires_php, + ]; + } else { + $updates[ $update_type ] = [ + 'version' => $release_version, + 'update_type' => $update_type, + 'package_url' => $release->assets[0]->browser_download_url, + 'status' => 'available', + 'requires_php' => isset( $manifest_data->requires_php ) ? $manifest_data->requires_php : '', + ]; + } + } + + foreach ( $updates as $type => $value ) { + if ( empty( $value ) ) { + unset( $updates[ $type ] ); + } + } + + foreach ( [ 'major', 'minor', 'patch' ] as $type ) { + if ( true === Utils\get_flag_value( $assoc_args, $type ) ) { + return ! empty( $updates[ $type ] ) ? [ $updates[ $type ] ] : false; + } + } + + if ( empty( $updates ) && preg_match( '#-alpha-(.+)$#', WP_CLI_VERSION, $matches ) ) { + $version_url = 'https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/NIGHTLY_VERSION'; + $response = Utils\http_request( 'GET', $version_url, null, [], $options ); + if ( ! $response->success || 200 !== $response->status_code ) { + WP_CLI::error( sprintf( 'Failed to get current nightly version (HTTP code %d)', $response->status_code ) ); + } + $nightly_version = trim( $response->body ); + + if ( WP_CLI_VERSION !== $nightly_version ) { + $manifest_data = null; + + // The manifest.json file, if it exists, contains information about PHP version requirements and similar. + $response = Utils\http_request( 'GET', 'https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli-nightly.manifest.json', null, $headers, $options ); + + if ( $response->success ) { + /** + * WP-CLI manifest.json data. + * + * @var object{requires_php?: string}|null $manifest_data + */ + $manifest_data = json_decode( $response->body ); + } + + // Release requires a newer version of PHP. + if ( + isset( $manifest_data->requires_php ) && + ! Comparator::greaterThanOrEqualTo( PHP_VERSION, $manifest_data->requires_php ) + ) { + $updates_unavailable[] = [ + 'version' => $nightly_version, + 'update_type' => 'nightly', + 'package_url' => 'https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli-nightly.phar', + 'status' => 'unavailable', + 'requires_php' => $manifest_data->requires_php, + ]; + } else { + $updates['nightly'] = [ + 'version' => $nightly_version, + 'update_type' => 'nightly', + 'package_url' => 'https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli-nightly.phar', + 'status' => 'available', + 'requires_php' => isset( $manifest_data->requires_php ) ? $manifest_data->requires_php : '', + ]; + } + } + } + + return array_merge( $updates_unavailable, array_values( $updates ) ); + } + + /** + * Returns the the first element of the passed array for which the + * callback returns true. + * + * Polyfill for the `array_find()` function introduced in PHP 8.3. + * + * @param array $arr Array to search. + * @param callable $callback The callback function for each element in the array. + * @return mixed First array element for which the callback returns true, null otherwise. + */ + private function array_find( $arr, $callback ) { + if ( function_exists( '\array_find' ) ) { + // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.array_findFound + return \array_find( $arr, $callback ); + } + + foreach ( $arr as $key => $value ) { + if ( $callback( $value, $key ) ) { + return $value; + } + } + + return null; + } + + /** + * Dumps the list of global parameters, as JSON or in var_export format. + * + * ## OPTIONS + * + * [--with-values] + * : Display current values also. + * + * [--format=] + * : Render output in a particular format. + * --- + * default: json + * options: + * - var_export + * - json + * --- + * + * ## EXAMPLES + * + * # Dump the list of global parameters. + * $ wp cli param-dump --format=var_export + * array ( + * 'path' => + * array ( + * 'runtime' => '=', + * 'file' => '', + * 'synopsis' => '', + * 'default' => NULL, + * 'multiple' => false, + * 'desc' => 'Path to the WordPress files.', + * ), + * 'url' => + * array ( + * + * @subcommand param-dump + */ + public function param_dump( $_, $assoc_args ) { + $spec = WP_CLI::get_configurator()->get_spec(); + + if ( Utils\get_flag_value( $assoc_args, 'with-values' ) ) { + $config = WP_CLI::get_configurator()->to_array(); + // Copy current config values to $spec. + foreach ( $spec as $key => $value ) { + $current = null; + if ( isset( $config[0][ $key ] ) ) { + $current = $config[0][ $key ]; + } + $spec[ $key ]['current'] = $current; + } + } + + if ( 'var_export' === Utils\get_flag_value( $assoc_args, 'format' ) ) { + var_export( $spec ); + } else { + echo json_encode( $spec ); + } + } + + /** + * Dumps the list of installed commands, as JSON. + * + * ## EXAMPLES + * + * # Dump the list of installed commands. + * $ wp cli cmd-dump + * {"name":"wp","description":"Manage WordPress through the command-line.","longdesc":"\n\n## GLOBAL PARAMETERS\n\n --path=\n Path to the WordPress files.\n\n --ssh=\n Perform operation against a remote server over SSH (or a container using scheme of "docker" or "docker-compose").\n\n --url=\n Pretend request came from given URL. In multisite, this argument is how the target site is specified. \n\n --user=\n + * + * @subcommand cmd-dump + */ + public function cmd_dump() { + echo json_encode( $this->command_to_array( WP_CLI::get_root_command() ) ); + } + + /** + * Generates tab completion strings. + * + * ## OPTIONS + * + * --line= + * : The current command line to be executed. + * + * --point= + * : The index to the current cursor position relative to the beginning of the command. + * + * ## EXAMPLES + * + * # Generate tab completion strings. + * $ wp cli completions --line='wp eva' --point=100 + * eval + * eval-file + */ + public function completions( $_, $assoc_args ) { + $line = substr( $assoc_args['line'], 0, $assoc_args['point'] ); + $compl = new Completions( $line ); + $compl->render(); + } + + /** + * Get a string representing the type of update being checked for. + */ + private function get_update_type_str( $assoc_args ) { + $update_type = ' '; + foreach ( [ 'major', 'minor', 'patch' ] as $type ) { + if ( true === Utils\get_flag_value( $assoc_args, $type ) ) { + $update_type = ' ' . $type . ' '; + break; + } + } + return $update_type; + } + + /** + * Detects if a command exists + * + * This commands checks if a command is registered with WP-CLI. + * If the command is found then it returns with exit status 0. + * If the command doesn't exist, then it will exit with status 1. + * + * ## OPTIONS + * ... + * : The command + * + * ## EXAMPLES + * + * # The "site delete" command is registered. + * $ wp cli has-command "site delete" + * $ echo $? + * 0 + * + * # The "foo bar" command is not registered. + * $ wp cli has-command "foo bar" + * $ echo $? + * 1 + * + * # Install a WP-CLI package if not already installed + * $ if ! $(wp cli has-command doctor); then wp package install wp-cli/doctor-command; fi + * Installing package wp-cli/doctor-command (dev-main || dev-master || dev-trunk) + * Updating /home/person/.wp-cli/packages/composer.json to require the package... + * Using Composer to install the package... + * --- + * Success: Package installed. + * + * @subcommand has-command + * + * @when after_wp_load + */ + public function has_command( $_, $assoc_args ) { + + // If command is input as a string, then explode it into array. + $command = explode( ' ', implode( ' ', $_ ) ); + + WP_CLI::halt( is_array( WP_CLI::get_runner()->find_command_to_run( $command ) ) ? 0 : 1 ); + } +} From 6138b058b3db16632af28f223d5360d2c073cdc0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 12:05:26 +0000 Subject: [PATCH 3/7] Improve test to use WP_CLI_PHP_USED environment variable Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- features/cli.feature | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/features/cli.feature b/features/cli.feature index 87cf49b29..f18c13cda 100644 --- a/features/cli.feature +++ b/features/cli.feature @@ -181,12 +181,13 @@ Feature: `wp cli` tasks # Create a directory with spaces and a PHP wrapper When I run `mkdir -p "php with spaces/bin"` - And I run `printf '#!/bin/bash\nexec php "$@"' > "php with spaces/bin/php"` + And I run `cp "$(which php)" "php with spaces/bin/php"` And I run `chmod +x "php with spaces/bin/php"` Then the return code should be 0 - # Test that the update command works when PHP_BINARY has spaces - When I run `PHP_BINARY="$PWD/php with spaces/bin/php" "$PWD/php with spaces/bin/php" {PHAR_PATH} cli update --yes` + # Test that the update command works when WP_CLI_PHP_USED has spaces + # This simulates the scenario where PHP binary path contains spaces + When I run `WP_CLI_PHP_USED="$PWD/php with spaces/bin/php" {PHAR_PATH} cli update --yes` Then STDOUT should contain: """ sha512 hash verified: From aa3225e9506c8b8cc98ae6aa74a2afc46b0ae0ec Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Thu, 22 Jan 2026 14:20:38 +0100 Subject: [PATCH 4/7] Remove file --- .../wp-cli/php/commands/src/CLI_Command.php | 805 ------------------ 1 file changed, 805 deletions(-) delete mode 100644 vendor/wp-cli/wp-cli/php/commands/src/CLI_Command.php diff --git a/vendor/wp-cli/wp-cli/php/commands/src/CLI_Command.php b/vendor/wp-cli/wp-cli/php/commands/src/CLI_Command.php deleted file mode 100644 index 70ec7faef..000000000 --- a/vendor/wp-cli/wp-cli/php/commands/src/CLI_Command.php +++ /dev/null @@ -1,805 +0,0 @@ -} - * - * @phpstan-type UpdateOffer array{version: string, update_type: string, package_url: string, status: string, requires_php: string} - */ -class CLI_Command extends WP_CLI_Command { - - private function command_to_array( $command ) { - $dump = [ - 'name' => $command->get_name(), - 'description' => $command->get_shortdesc(), - 'longdesc' => $command->get_longdesc(), - 'hook' => $command->get_hook(), - ]; - - $alias = $command->get_alias(); - if ( $alias ) { - $dump['alias'] = $alias; - } - - foreach ( $command->get_subcommands() as $subcommand ) { - $dump['subcommands'][] = $this->command_to_array( $subcommand ); - } - - if ( empty( $dump['subcommands'] ) ) { - $dump['synopsis'] = (string) $command->get_synopsis(); - } - - return $dump; - } - - /** - * Prints WP-CLI version. - * - * ## EXAMPLES - * - * # Display CLI version. - * $ wp cli version - * WP-CLI 0.24.1 - */ - public function version() { - WP_CLI::line( 'WP-CLI ' . WP_CLI_VERSION ); - } - - /** - * Prints various details about the WP-CLI environment. - * - * Helpful for diagnostic purposes, this command shares: - * - * * OS information. - * * Shell information. - * * PHP binary used. - * * PHP binary version. - * * php.ini configuration file used (which is typically different than web). - * * WP-CLI root dir: where WP-CLI is installed (if non-Phar install). - * * WP-CLI global config: where the global config YAML file is located. - * * WP-CLI project config: where the project config YAML file is located. - * * WP-CLI version: currently installed version. - * - * See [config docs](https://make.wordpress.org/cli/handbook/references/config/) for more details on global - * and project config YAML files. - * - * ## OPTIONS - * - * [--format=] - * : Render output in a particular format. - * --- - * default: list - * options: - * - list - * - json - * --- - * - * ## EXAMPLES - * - * # Display various data about the CLI environment. - * $ wp cli info - * OS: Linux 4.10.0-42-generic #46~16.04.1-Ubuntu SMP Mon Dec 4 15:57:59 UTC 2017 x86_64 - * Shell: /usr/bin/zsh - * PHP binary: /usr/bin/php - * PHP version: 7.1.12-1+ubuntu16.04.1+deb.sury.org+1 - * php.ini used: /etc/php/7.1/cli/php.ini - * WP-CLI root dir: phar://wp-cli.phar - * WP-CLI packages dir: /home/person/.wp-cli/packages/ - * WP-CLI global config: - * WP-CLI project config: - * WP-CLI version: 1.5.0 - * - * @param string[] $args Positional arguments. Unused. - * @param array{format: string} $assoc_args Associative arguments. - */ - public function info( $args, $assoc_args ) { - $system_os = sprintf( - '%s %s %s %s', - php_uname( 's' ), - php_uname( 'r' ), - php_uname( 'v' ), - php_uname( 'm' ) - ); - - $shell = getenv( 'SHELL' ); - if ( ! $shell && Utils\is_windows() ) { - $shell = getenv( 'ComSpec' ); - } - - $php_bin = Utils\get_php_binary(); - - $runner = WP_CLI::get_runner(); - - $packages_dir = $runner->get_packages_dir_path(); - if ( ! is_dir( $packages_dir ) ) { - $packages_dir = null; - } - - if ( Utils\get_flag_value( $assoc_args, 'format' ) === 'json' ) { - $info = [ - 'system_os' => $system_os, - 'shell' => $shell, - 'php_binary_path' => $php_bin, - 'php_version' => PHP_VERSION, - 'php_ini_used' => get_cfg_var( 'cfg_file_path' ), - 'mysql_binary_path' => Utils\get_mysql_binary_path(), - 'mysql_version' => Utils\get_mysql_version(), - 'sql_modes' => Utils\get_sql_modes(), - 'wp_cli_dir_path' => WP_CLI_ROOT, - 'wp_cli_vendor_path' => WP_CLI_VENDOR_DIR, - 'wp_cli_phar_path' => defined( 'WP_CLI_PHAR_PATH' ) ? WP_CLI_PHAR_PATH : '', - 'wp_cli_packages_dir_path' => $packages_dir, - 'wp_cli_cache_dir_path' => Utils\get_cache_dir(), - 'global_config_path' => $runner->global_config_path, - 'project_config_path' => $runner->project_config_path, - 'wp_cli_version' => WP_CLI_VERSION, - ]; - - WP_CLI::line( (string) json_encode( $info ) ); - } else { - /** - * @var string $cfg_file_path - */ - $cfg_file_path = get_cfg_var( 'cfg_file_path' ); - WP_CLI::line( "OS:\t" . $system_os ); - WP_CLI::line( "Shell:\t" . $shell ); - WP_CLI::line( "PHP binary:\t" . $php_bin ); - WP_CLI::line( "PHP version:\t" . PHP_VERSION ); - WP_CLI::line( "php.ini used:\t" . $cfg_file_path ); - WP_CLI::line( "MySQL binary:\t" . Utils\get_mysql_binary_path() ); - WP_CLI::line( "MySQL version:\t" . Utils\get_mysql_version() ); - WP_CLI::line( "SQL modes:\t" . implode( ',', Utils\get_sql_modes() ) ); - WP_CLI::line( "WP-CLI root dir:\t" . WP_CLI_ROOT ); - WP_CLI::line( "WP-CLI vendor dir:\t" . WP_CLI_VENDOR_DIR ); - WP_CLI::line( "WP_CLI phar path:\t" . ( defined( 'WP_CLI_PHAR_PATH' ) ? WP_CLI_PHAR_PATH : '' ) ); - WP_CLI::line( "WP-CLI packages dir:\t" . $packages_dir ); - WP_CLI::line( "WP-CLI cache dir:\t" . Utils\get_cache_dir() ); - WP_CLI::line( "WP-CLI global config:\t" . $runner->global_config_path ); - WP_CLI::line( "WP-CLI project config:\t" . $runner->project_config_path ); - WP_CLI::line( "WP-CLI version:\t" . WP_CLI_VERSION ); - } - } - - /** - * Checks to see if there is a newer version of WP-CLI available. - * - * Queries the GitHub releases API. Returns available versions if there are - * updates available, or success message if using the latest release. - * - * ## OPTIONS - * - * [--patch] - * : Only list patch updates. - * - * [--minor] - * : Only list minor updates. - * - * [--major] - * : Only list major updates. - * - * [--field=] - * : Prints the value of a single field for each update. - * - * [--fields=] - * : Limit the output to specific object fields. Defaults to version,update_type,package_url,status,requires_php. - * - * [--format=] - * : Render output in a particular format. - * --- - * default: table - * options: - * - table - * - csv - * - json - * - count - * - yaml - * --- - * - * ## EXAMPLES - * - * # Check for update. - * $ wp cli check-update - * Success: WP-CLI is at the latest version. - * - * # Check for update and new version is available. - * $ wp cli check-update - * +---------+-------------+-------------------------------------------------------------------------------+ - * | version | update_type | package_url | - * +---------+-------------+-------------------------------------------------------------------------------+ - * | 0.24.1 | patch | https://github.com/wp-cli/wp-cli/releases/download/v0.24.1/wp-cli-0.24.1.phar | - * +---------+-------------+-------------------------------------------------------------------------------+ - * - * @subcommand check-update - * - * @param string[] $args Positional arguments. Unused. - * @param array{patch?: bool, minor?: bool, major?: bool, field?: string, fields?: string, format: string} $assoc_args Associative arguments. - */ - public function check_update( $args, $assoc_args ) { - $updates = $this->get_updates( $assoc_args ); - - if ( $updates ) { - $formatter = new Formatter( - $assoc_args, - [ 'version', 'update_type', 'package_url', 'status', 'requires_php' ] - ); - $formatter->display_items( $updates ); - } elseif ( empty( $assoc_args['format'] ) || 'table' === $assoc_args['format'] ) { - $update_type = $this->get_update_type_str( $assoc_args ); - WP_CLI::success( "WP-CLI is at the latest{$update_type}version." ); - } - } - - /** - * Updates WP-CLI to the latest release. - * - * Default behavior is to check the releases API for the newest stable - * version, and prompt if one is available. - * - * Use `--stable` to install or reinstall the latest stable version. - * - * Use `--nightly` to install the latest built version of the master branch. - * While not recommended for production, nightly contains the latest and - * greatest, and should be stable enough for development and staging - * environments. - * - * Only works for the Phar installation mechanism. - * - * ## OPTIONS - * - * [--patch] - * : Only perform patch updates. - * - * [--minor] - * : Only perform minor updates. - * - * [--major] - * : Only perform major updates. - * - * [--stable] - * : Update to the latest stable release. Skips update check. - * - * [--nightly] - * : Update to the latest built version of the master branch. Potentially unstable. - * - * [--yes] - * : Do not prompt for confirmation. - * - * [--insecure] - * : Retry without certificate validation if TLS handshake fails. Note: This makes the request vulnerable to a MITM attack. - * - * ## EXAMPLES - * - * # Update CLI. - * $ wp cli update - * You are currently using WP-CLI version 0.24.0. Would you like to update to 0.24.1? [y/n] y - * Downloading from https://github.com/wp-cli/wp-cli/releases/download/v0.24.1/wp-cli-0.24.1.phar... - * New version works. Proceeding to replace. - * Success: Updated WP-CLI to 0.24.1. - * - * @param string[] $args Positional arguments. Unused. - * @param array{patch?: bool, minor?: bool, major?: bool, stable?: bool, nightly?: bool, yes?: bool, insecure?: bool} $assoc_args Associative arguments. - */ - public function update( $args, $assoc_args ) { - if ( ! Utils\inside_phar() ) { - WP_CLI::error( 'You can only self-update Phar files.' ); - } - - $old_phar = (string) realpath( $_SERVER['argv'][0] ); - - if ( ! is_writable( $old_phar ) ) { - WP_CLI::error( sprintf( '%s is not writable by current user.', $old_phar ) ); - } elseif ( ! is_writable( dirname( $old_phar ) ) ) { - WP_CLI::error( sprintf( '%s is not writable by current user.', dirname( $old_phar ) ) ); - } - - if ( Utils\get_flag_value( $assoc_args, 'nightly' ) ) { - WP_CLI::confirm( sprintf( 'You are currently using WP-CLI version %s. Would you like to update to the latest nightly version?', WP_CLI_VERSION ), $assoc_args ); - $download_url = 'https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli-nightly.phar'; - $md5_url = 'https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli-nightly.phar.md5'; - $sha512_url = 'https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli-nightly.phar.sha512'; - } elseif ( Utils\get_flag_value( $assoc_args, 'stable' ) ) { - WP_CLI::confirm( sprintf( 'You are currently using WP-CLI version %s. Would you like to update to the latest stable release?', WP_CLI_VERSION ), $assoc_args ); - $download_url = 'https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar'; - $md5_url = 'https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar.md5'; - $sha512_url = 'https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar.sha512'; - } else { - - $updates = $this->get_updates( $assoc_args ); - - /** - * @phpstan-var UpdateOffer|null $newest - */ - $newest = $this->array_find( - $updates, - static function ( $update ) { - return 'available' === $update['status']; - } - ); - - if ( ! $newest ) { - $update_type = $this->get_update_type_str( $assoc_args ); - WP_CLI::success( "WP-CLI is at the latest{$update_type}version." ); - return; - } - - WP_CLI::confirm( sprintf( 'You have version %s. Would you like to update to %s?', WP_CLI_VERSION, $newest['version'] ), $assoc_args ); - - $download_url = $newest['package_url']; - $md5_url = str_replace( '.phar', '.phar.md5', $download_url ); - $sha512_url = str_replace( '.phar', '.phar.sha512', $download_url ); - } - - WP_CLI::log( sprintf( 'Downloading from %s...', $download_url ) ); - - $temp = Utils\get_temp_dir() . uniqid( 'wp_', true ) . '.phar'; - - $headers = []; - $options = [ - 'timeout' => 600, // 10 minutes ought to be enough for everybody. - 'filename' => $temp, - 'insecure' => (bool) Utils\get_flag_value( $assoc_args, 'insecure', false ), - ]; - - Utils\http_request( 'GET', $download_url, null, $headers, $options ); - - unset( $options['filename'] ); - - $this->validate_hashes( $temp, $sha512_url, $md5_url ); - - $allow_root = WP_CLI::get_runner()->config['allow-root'] ? '--allow-root' : ''; - $php_binary = Utils\get_php_binary(); - $process = Process::create( Utils\esc_cmd( '%s %s --info %s', $php_binary, $temp, $allow_root ) ); - $result = $process->run(); - if ( 0 !== $result->return_code || false === stripos( $result->stdout, 'WP-CLI version' ) ) { - $multi_line = explode( PHP_EOL, $result->stderr ); - WP_CLI::error_multi_line( $multi_line ); - WP_CLI::error( 'The downloaded PHAR is broken, try running wp cli update again.' ); - } - - WP_CLI::log( 'New version works. Proceeding to replace.' ); - - $mode = fileperms( $old_phar ) & 511; - - if ( false === chmod( $temp, $mode ) ) { - WP_CLI::error( sprintf( 'Cannot chmod %s.', $temp ) ); - } - - class_exists( '\cli\Colors' ); // This autoloads \cli\Colors - after we move the file we no longer have access to this class. - - if ( false === rename( $temp, $old_phar ) ) { - WP_CLI::error( sprintf( 'Cannot move %s to %s', $temp, $old_phar ) ); - } - - if ( Utils\get_flag_value( $assoc_args, 'nightly', false ) ) { - $updated_version = 'the latest nightly release'; - } elseif ( Utils\get_flag_value( $assoc_args, 'stable', false ) ) { - $updated_version = 'the latest stable release'; - } else { - $updated_version = isset( $newest['version'] ) ? $newest['version'] : ''; - } - WP_CLI::success( sprintf( 'Updated WP-CLI to %s.', $updated_version ) ); - } - - /** - * @param string $file Release file path. - * @param string $sha512_url URL to sha512 hash. - * @param string $md5_url URL to md5 hash. - * - * @throws \WP_CLI\ExitException - */ - private function validate_hashes( $file, $sha512_url, $md5_url ): void { - $algos = [ - 'sha512' => $sha512_url, - 'md5' => $md5_url, - ]; - - foreach ( $algos as $algo => $url ) { - $response = Utils\http_request( 'GET', $url ); - if ( '20' !== substr( (string) $response->status_code, 0, 2 ) ) { - WP_CLI::log( "Couldn't access $algo hash for release (HTTP code {$response->status_code})." ); - continue; - } - - $file_hash = hash_file( $algo, $file ); - - $release_hash = trim( $response->body ); - if ( $file_hash === $release_hash ) { - WP_CLI::log( "$algo hash verified: $release_hash" ); - return; - } else { - WP_CLI::error( "$algo hash for download ($file_hash) is different than the release hash ($release_hash)." ); - } - } - - WP_CLI::error( 'Release hash verification failed.' ); - } - - /** - * Returns update information. - */ - private function get_updates( $assoc_args ) { - $url = 'https://api.github.com/repos/wp-cli/wp-cli/releases?per_page=100'; - - $options = [ - 'timeout' => 30, - 'insecure' => (bool) Utils\get_flag_value( $assoc_args, 'insecure', false ), - ]; - - $headers = [ - 'Accept' => 'application/json', - ]; - - $github_token = getenv( 'GITHUB_TOKEN' ); - if ( false !== $github_token ) { - $headers['Authorization'] = 'token ' . $github_token; - } - - $response = Utils\http_request( 'GET', $url, null, $headers, $options ); - - if ( ! $response->success || 200 !== $response->status_code ) { - WP_CLI::error( sprintf( 'Failed to get latest version (HTTP code %d).', $response->status_code ) ); - } - - /** - * @phpstan-var GitHubRelease[] $release_data - */ - $release_data = json_decode( $response->body, false ); - - $updates = [ - 'major' => false, - 'minor' => false, - 'patch' => false, - ]; - - $updates_unavailable = []; - - foreach ( $release_data as $release ) { - - // Get rid of leading "v" if there is one set. - $release_version = $release->tag_name; - if ( 'v' === substr( $release_version, 0, 1 ) ) { - $release_version = ltrim( $release_version, 'v' ); - } - - $update_type = Utils\get_named_sem_ver( $release_version, WP_CLI_VERSION ); - - if ( ! $update_type ) { - continue; - } - - // Release is older than one we already have on file. - if ( ! empty( $updates[ $update_type ] ) && ! Comparator::greaterThan( $release_version, $updates[ $update_type ]['version'] ) ) { - continue; - } - - $package_url = null; - - /** - * WP-CLI manifest.json data. - * - * @var object{requires_php?: string}|null $manifest_data - */ - $manifest_data = null; - - foreach ( $release->assets as $asset ) { - if ( ! isset( $asset->browser_download_url ) ) { - continue; - } - - if ( substr( $asset->browser_download_url, - strlen( '.phar' ) ) === '.phar' ) { - $package_url = $asset->browser_download_url; - } - - // The manifest.json file, if it exists, contains information about PHP version requirements and similar. - if ( substr( $asset->browser_download_url, - strlen( 'manifest.json' ) ) === 'manifest.json' ) { - $response = Utils\http_request( 'GET', $asset->browser_download_url, null, $headers, $options ); - - if ( $response->success ) { - /** - * WP-CLI manifest.json data. - * - * @var object{requires_php?: string}|null $manifest_data - */ - $manifest_data = json_decode( $response->body, false ); - } - } - } - - if ( ! $package_url ) { - continue; - } - - // Release requires a newer version of PHP. - if ( - isset( $manifest_data->requires_php ) && - ! Comparator::greaterThanOrEqualTo( PHP_VERSION, $manifest_data->requires_php ) - ) { - $updates_unavailable[] = [ - 'version' => $release_version, - 'update_type' => $update_type, - 'package_url' => $release->assets[0]->browser_download_url, - 'status' => 'unavailable', - 'requires_php' => $manifest_data->requires_php, - ]; - } else { - $updates[ $update_type ] = [ - 'version' => $release_version, - 'update_type' => $update_type, - 'package_url' => $release->assets[0]->browser_download_url, - 'status' => 'available', - 'requires_php' => isset( $manifest_data->requires_php ) ? $manifest_data->requires_php : '', - ]; - } - } - - foreach ( $updates as $type => $value ) { - if ( empty( $value ) ) { - unset( $updates[ $type ] ); - } - } - - foreach ( [ 'major', 'minor', 'patch' ] as $type ) { - if ( true === Utils\get_flag_value( $assoc_args, $type ) ) { - return ! empty( $updates[ $type ] ) ? [ $updates[ $type ] ] : false; - } - } - - if ( empty( $updates ) && preg_match( '#-alpha-(.+)$#', WP_CLI_VERSION, $matches ) ) { - $version_url = 'https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/NIGHTLY_VERSION'; - $response = Utils\http_request( 'GET', $version_url, null, [], $options ); - if ( ! $response->success || 200 !== $response->status_code ) { - WP_CLI::error( sprintf( 'Failed to get current nightly version (HTTP code %d)', $response->status_code ) ); - } - $nightly_version = trim( $response->body ); - - if ( WP_CLI_VERSION !== $nightly_version ) { - $manifest_data = null; - - // The manifest.json file, if it exists, contains information about PHP version requirements and similar. - $response = Utils\http_request( 'GET', 'https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli-nightly.manifest.json', null, $headers, $options ); - - if ( $response->success ) { - /** - * WP-CLI manifest.json data. - * - * @var object{requires_php?: string}|null $manifest_data - */ - $manifest_data = json_decode( $response->body ); - } - - // Release requires a newer version of PHP. - if ( - isset( $manifest_data->requires_php ) && - ! Comparator::greaterThanOrEqualTo( PHP_VERSION, $manifest_data->requires_php ) - ) { - $updates_unavailable[] = [ - 'version' => $nightly_version, - 'update_type' => 'nightly', - 'package_url' => 'https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli-nightly.phar', - 'status' => 'unavailable', - 'requires_php' => $manifest_data->requires_php, - ]; - } else { - $updates['nightly'] = [ - 'version' => $nightly_version, - 'update_type' => 'nightly', - 'package_url' => 'https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli-nightly.phar', - 'status' => 'available', - 'requires_php' => isset( $manifest_data->requires_php ) ? $manifest_data->requires_php : '', - ]; - } - } - } - - return array_merge( $updates_unavailable, array_values( $updates ) ); - } - - /** - * Returns the the first element of the passed array for which the - * callback returns true. - * - * Polyfill for the `array_find()` function introduced in PHP 8.3. - * - * @param array $arr Array to search. - * @param callable $callback The callback function for each element in the array. - * @return mixed First array element for which the callback returns true, null otherwise. - */ - private function array_find( $arr, $callback ) { - if ( function_exists( '\array_find' ) ) { - // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.array_findFound - return \array_find( $arr, $callback ); - } - - foreach ( $arr as $key => $value ) { - if ( $callback( $value, $key ) ) { - return $value; - } - } - - return null; - } - - /** - * Dumps the list of global parameters, as JSON or in var_export format. - * - * ## OPTIONS - * - * [--with-values] - * : Display current values also. - * - * [--format=] - * : Render output in a particular format. - * --- - * default: json - * options: - * - var_export - * - json - * --- - * - * ## EXAMPLES - * - * # Dump the list of global parameters. - * $ wp cli param-dump --format=var_export - * array ( - * 'path' => - * array ( - * 'runtime' => '=', - * 'file' => '', - * 'synopsis' => '', - * 'default' => NULL, - * 'multiple' => false, - * 'desc' => 'Path to the WordPress files.', - * ), - * 'url' => - * array ( - * - * @subcommand param-dump - */ - public function param_dump( $_, $assoc_args ) { - $spec = WP_CLI::get_configurator()->get_spec(); - - if ( Utils\get_flag_value( $assoc_args, 'with-values' ) ) { - $config = WP_CLI::get_configurator()->to_array(); - // Copy current config values to $spec. - foreach ( $spec as $key => $value ) { - $current = null; - if ( isset( $config[0][ $key ] ) ) { - $current = $config[0][ $key ]; - } - $spec[ $key ]['current'] = $current; - } - } - - if ( 'var_export' === Utils\get_flag_value( $assoc_args, 'format' ) ) { - var_export( $spec ); - } else { - echo json_encode( $spec ); - } - } - - /** - * Dumps the list of installed commands, as JSON. - * - * ## EXAMPLES - * - * # Dump the list of installed commands. - * $ wp cli cmd-dump - * {"name":"wp","description":"Manage WordPress through the command-line.","longdesc":"\n\n## GLOBAL PARAMETERS\n\n --path=\n Path to the WordPress files.\n\n --ssh=\n Perform operation against a remote server over SSH (or a container using scheme of "docker" or "docker-compose").\n\n --url=\n Pretend request came from given URL. In multisite, this argument is how the target site is specified. \n\n --user=\n - * - * @subcommand cmd-dump - */ - public function cmd_dump() { - echo json_encode( $this->command_to_array( WP_CLI::get_root_command() ) ); - } - - /** - * Generates tab completion strings. - * - * ## OPTIONS - * - * --line= - * : The current command line to be executed. - * - * --point= - * : The index to the current cursor position relative to the beginning of the command. - * - * ## EXAMPLES - * - * # Generate tab completion strings. - * $ wp cli completions --line='wp eva' --point=100 - * eval - * eval-file - */ - public function completions( $_, $assoc_args ) { - $line = substr( $assoc_args['line'], 0, $assoc_args['point'] ); - $compl = new Completions( $line ); - $compl->render(); - } - - /** - * Get a string representing the type of update being checked for. - */ - private function get_update_type_str( $assoc_args ) { - $update_type = ' '; - foreach ( [ 'major', 'minor', 'patch' ] as $type ) { - if ( true === Utils\get_flag_value( $assoc_args, $type ) ) { - $update_type = ' ' . $type . ' '; - break; - } - } - return $update_type; - } - - /** - * Detects if a command exists - * - * This commands checks if a command is registered with WP-CLI. - * If the command is found then it returns with exit status 0. - * If the command doesn't exist, then it will exit with status 1. - * - * ## OPTIONS - * ... - * : The command - * - * ## EXAMPLES - * - * # The "site delete" command is registered. - * $ wp cli has-command "site delete" - * $ echo $? - * 0 - * - * # The "foo bar" command is not registered. - * $ wp cli has-command "foo bar" - * $ echo $? - * 1 - * - * # Install a WP-CLI package if not already installed - * $ if ! $(wp cli has-command doctor); then wp package install wp-cli/doctor-command; fi - * Installing package wp-cli/doctor-command (dev-main || dev-master || dev-trunk) - * Updating /home/person/.wp-cli/packages/composer.json to require the package... - * Using Composer to install the package... - * --- - * Success: Package installed. - * - * @subcommand has-command - * - * @when after_wp_load - */ - public function has_command( $_, $assoc_args ) { - - // If command is input as a string, then explode it into array. - $command = explode( ' ', implode( ' ', $_ ) ); - - WP_CLI::halt( is_array( WP_CLI::get_runner()->find_command_to_run( $command ) ) ? 0 : 1 ); - } -} From 3f8d7849c21c8014da978b5a8efb8485228f819e Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Thu, 22 Jan 2026 17:14:02 +0100 Subject: [PATCH 5/7] Trial --- composer.json | 8 +- composer.lock | 220 +++++++++++++++++++++++++++++--------------------- 2 files changed, 136 insertions(+), 92 deletions(-) diff --git a/composer.json b/composer.json index d3d7894de..927d2684b 100644 --- a/composer.json +++ b/composer.json @@ -36,8 +36,14 @@ "wp-cli/shell-command": "^2", "wp-cli/super-admin-command": "^2", "wp-cli/widget-command": "^2", - "wp-cli/wp-cli": "dev-main" + "wp-cli/wp-cli": "dev-testing/cli-update as 2.13" }, + "repositories": [ + { + "type": "vcs", + "url": "https://github.com/bgturner/wp-cli" + } + ], "require-dev": { "roave/security-advisories": "dev-latest", "wp-cli/wp-cli-tests": "^5" diff --git a/composer.lock b/composer.lock index aec13dadd..6c0b01816 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e80cc2bb1e43fd4585938fac48b65be7", + "content-hash": "48144632bdf92d680d7b68d50b34a687", "packages": [ { "name": "composer/ca-bundle", @@ -149,16 +149,16 @@ }, { "name": "composer/composer", - "version": "2.9.3", + "version": "2.9.4", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "fb3bee27676fd852a8a11ebbb1de19b4dada5aba" + "reference": "d4225153940b7c06f0e825195bdbdc312c67d917" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/fb3bee27676fd852a8a11ebbb1de19b4dada5aba", - "reference": "fb3bee27676fd852a8a11ebbb1de19b4dada5aba", + "url": "https://api.github.com/repos/composer/composer/zipball/d4225153940b7c06f0e825195bdbdc312c67d917", + "reference": "d4225153940b7c06f0e825195bdbdc312c67d917", "shasum": "" }, "require": { @@ -246,7 +246,7 @@ "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/composer/issues", "security": "https://github.com/composer/composer/security/policy", - "source": "https://github.com/composer/composer/tree/2.9.3" + "source": "https://github.com/composer/composer/tree/2.9.4" }, "funding": [ { @@ -258,7 +258,7 @@ "type": "github" } ], - "time": "2025-12-30T12:40:17+00:00" + "time": "2026-01-22T13:08:50+00:00" }, { "name": "composer/metadata-minifier", @@ -847,16 +847,16 @@ }, { "name": "justinrainbow/json-schema", - "version": "6.6.3", + "version": "6.6.4", "source": { "type": "git", "url": "https://github.com/jsonrainbow/json-schema.git", - "reference": "134e98916fa2f663afa623970af345cd788e8967" + "reference": "2eeb75d21cf73211335888e7f5e6fd7440723ec7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/134e98916fa2f663afa623970af345cd788e8967", - "reference": "134e98916fa2f663afa623970af345cd788e8967", + "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/2eeb75d21cf73211335888e7f5e6fd7440723ec7", + "reference": "2eeb75d21cf73211335888e7f5e6fd7440723ec7", "shasum": "" }, "require": { @@ -916,9 +916,9 @@ ], "support": { "issues": "https://github.com/jsonrainbow/json-schema/issues", - "source": "https://github.com/jsonrainbow/json-schema/tree/6.6.3" + "source": "https://github.com/jsonrainbow/json-schema/tree/6.6.4" }, - "time": "2025-12-02T10:21:33+00:00" + "time": "2025-12-19T15:01:32+00:00" }, { "name": "marc-mabe/php-enum", @@ -2676,12 +2676,12 @@ "source": { "type": "git", "url": "https://github.com/wp-cli/ability-command.git", - "reference": "4a6552fad619be502d768348a60595f9d4570b31" + "reference": "33a966a99081f4cf1b47c64d6ed7c270d1a166c3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wp-cli/ability-command/zipball/4a6552fad619be502d768348a60595f9d4570b31", - "reference": "4a6552fad619be502d768348a60595f9d4570b31", + "url": "https://api.github.com/repos/wp-cli/ability-command/zipball/33a966a99081f4cf1b47c64d6ed7c270d1a166c3", + "reference": "33a966a99081f4cf1b47c64d6ed7c270d1a166c3", "shasum": "" }, "require": { @@ -2729,7 +2729,7 @@ "issues": "https://github.com/wp-cli/ability-command/issues", "source": "https://github.com/wp-cli/ability-command/tree/main" }, - "time": "2025-12-11T18:23:26+00:00" + "time": "2026-01-21T12:28:13+00:00" }, { "name": "wp-cli/block-command", @@ -2737,12 +2737,12 @@ "source": { "type": "git", "url": "https://github.com/wp-cli/block-command.git", - "reference": "46cc3f1aec3c23a0fdd20aad38ef463218999ad5" + "reference": "1ef1b8df411bf5ca785e19418cb4fc09ba07939d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wp-cli/block-command/zipball/46cc3f1aec3c23a0fdd20aad38ef463218999ad5", - "reference": "46cc3f1aec3c23a0fdd20aad38ef463218999ad5", + "url": "https://api.github.com/repos/wp-cli/block-command/zipball/1ef1b8df411bf5ca785e19418cb4fc09ba07939d", + "reference": "1ef1b8df411bf5ca785e19418cb4fc09ba07939d", "shasum": "" }, "require": { @@ -2806,7 +2806,7 @@ "issues": "https://github.com/wp-cli/block-command/issues", "source": "https://github.com/wp-cli/block-command/tree/main" }, - "time": "2025-12-11T20:01:16+00:00" + "time": "2026-01-21T12:28:13+00:00" }, { "name": "wp-cli/cache-command", @@ -4767,23 +4767,25 @@ }, { "name": "wp-cli/wp-cli", - "version": "dev-main", + "version": "dev-testing/cli-update", "source": { "type": "git", - "url": "https://github.com/wp-cli/wp-cli.git", - "reference": "02400e30e64333935abdbf7a4f0b394bb00140ff" + "url": "https://github.com/bgturner/wp-cli.git", + "reference": "50e07d85406a74fa6faf0298fbc16ef247683313" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wp-cli/wp-cli/zipball/02400e30e64333935abdbf7a4f0b394bb00140ff", - "reference": "02400e30e64333935abdbf7a4f0b394bb00140ff", + "url": "https://api.github.com/repos/bgturner/wp-cli/zipball/50e07d85406a74fa6faf0298fbc16ef247683313", + "reference": "50e07d85406a74fa6faf0298fbc16ef247683313", "shasum": "" }, "require": { + "ext-curl": "*", "mustache/mustache": "^3.0.0", "php": ">=7.2.24 || ^8.0", + "symfony/finder": ">2.7", "wp-cli/mustangostang-spyc": "^0.6.3", - "wp-cli/php-cli-tools": "~0.12.7" + "wp-cli/php-cli-tools": "~0.12.4" }, "require-dev": { "justinrainbow/json-schema": "^6.3", @@ -4795,30 +4797,15 @@ "wp-cli/wp-cli-tests": "^5" }, "suggest": { - "ext-curl": "For better performance when making HTTP requests", "ext-readline": "Include for a better --prompt implementation", "ext-zip": "Needed to support extraction of ZIP archives when doing downloads or updates" }, - "default-branch": true, "bin": [ "bin/wp", "bin/wp.bat" ], "type": "library", "extra": { - "commands": [ - "cli", - "cli alias", - "cli cache", - "cli check-update", - "cli cmd-dump", - "cli completions", - "cli has-command", - "cli info", - "cli param-dump", - "cli update", - "cli version" - ], "branch-alias": { "dev-main": "2.13.x-dev" } @@ -4832,7 +4819,39 @@ "php/class-wp-cli-command.php" ] }, - "notification-url": "https://packagist.org/downloads/", + "scripts": { + "behat": [ + "run-behat-tests" + ], + "behat-rerun": [ + "rerun-behat-tests" + ], + "lint": [ + "run-linter-tests" + ], + "phpcs": [ + "run-phpcs-tests" + ], + "phpcbf": [ + "run-phpcbf-cleanup" + ], + "phpstan": [ + "run-phpstan-tests" + ], + "phpunit": [ + "run-php-unit-tests" + ], + "prepare-tests": [ + "install-package-tests" + ], + "test": [ + "@lint", + "@phpcs", + "@phpstan", + "@phpunit", + "@behat" + ] + }, "license": [ "MIT" ], @@ -4843,24 +4862,24 @@ "wordpress" ], "support": { - "docs": "https://make.wordpress.org/cli/handbook/", "issues": "https://github.com/wp-cli/wp-cli/issues", - "source": "https://github.com/wp-cli/wp-cli" + "source": "https://github.com/wp-cli/wp-cli", + "docs": "https://make.wordpress.org/cli/handbook/" }, - "time": "2026-01-21T14:32:26+00:00" + "time": "2025-12-02T20:12:16+00:00" }, { "name": "wp-cli/wp-config-transformer", - "version": "v1.4.3", + "version": "v1.4.4", "source": { "type": "git", "url": "https://github.com/wp-cli/wp-config-transformer.git", - "reference": "5ade4e70349a1d5cd07efc33880ceb5eebb9e9fa" + "reference": "b0fda07aac51317404f5e56dc8953ea899bc7bce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wp-cli/wp-config-transformer/zipball/5ade4e70349a1d5cd07efc33880ceb5eebb9e9fa", - "reference": "5ade4e70349a1d5cd07efc33880ceb5eebb9e9fa", + "url": "https://api.github.com/repos/wp-cli/wp-config-transformer/zipball/b0fda07aac51317404f5e56dc8953ea899bc7bce", + "reference": "b0fda07aac51317404f5e56dc8953ea899bc7bce", "shasum": "" }, "require": { @@ -4894,9 +4913,9 @@ "homepage": "https://github.com/wp-cli/wp-config-transformer", "support": { "issues": "https://github.com/wp-cli/wp-config-transformer/issues", - "source": "https://github.com/wp-cli/wp-config-transformer/tree/v1.4.3" + "source": "https://github.com/wp-cli/wp-config-transformer/tree/v1.4.4" }, - "time": "2025-11-11T13:31:09+00:00" + "time": "2026-01-22T09:07:20+00:00" } ], "packages-dev": [ @@ -6629,12 +6648,12 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "415fded4fc00cd3df267d36e384e3e7454b39c40" + "reference": "ac5d4ead2fdb4262655538ce2af46078b49015ab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/415fded4fc00cd3df267d36e384e3e7454b39c40", - "reference": "415fded4fc00cd3df267d36e384e3e7454b39c40", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/ac5d4ead2fdb4262655538ce2af46078b49015ab", + "reference": "ac5d4ead2fdb4262655538ce2af46078b49015ab", "shasum": "" }, "conflict": { @@ -6649,13 +6668,16 @@ "aimeos/ai-cms-grapesjs": ">=2021.04.1,<2021.10.8|>=2022.04.1,<2022.10.9|>=2023.04.1,<2023.10.15|>=2024.04.1,<2024.10.8|>=2025.04.1,<2025.10.2", "aimeos/ai-controller-frontend": "<2020.10.15|>=2021.04.1,<2021.10.8|>=2022.04.1,<2022.10.8|>=2023.04.1,<2023.10.9|==2024.04.1", "aimeos/aimeos-core": ">=2022.04.1,<2022.10.17|>=2023.04.1,<2023.10.17|>=2024.04.1,<2024.04.7", + "aimeos/aimeos-laravel": "==2021.10", "aimeos/aimeos-typo3": "<19.10.12|>=20,<20.10.5", "airesvsg/acf-to-rest-api": "<=3.1", "akaunting/akaunting": "<2.1.13", "akeneo/pim-community-dev": "<5.0.119|>=6,<6.0.53", - "alextselegidis/easyappointments": "<1.5.2.0-beta1", + "alextselegidis/easyappointments": "<=1.5.2", "alexusmai/laravel-file-manager": "<=3.3.1", + "algolia/algoliasearch-magento-2": "<=3.16.1|>=3.17.0.0-beta1,<=3.17.1", "alt-design/alt-redirect": "<1.6.4", + "altcha-org/altcha": "<1.3.1", "alterphp/easyadmin-extension-bundle": ">=1.2,<1.2.11|>=1.3,<1.3.1", "amazing/media2click": ">=1,<1.3.3", "ameos/ameos_tarteaucitron": "<1.2.23", @@ -6679,14 +6701,14 @@ "athlon1600/php-proxy-app": "<=3", "athlon1600/youtube-downloader": "<=4", "austintoddj/canvas": "<=3.4.2", - "auth0/auth0-php": ">=3.3,<=8.16", - "auth0/login": "<=7.18", - "auth0/symfony": "<=5.4.1", - "auth0/wordpress": "<=5.3", + "auth0/auth0-php": ">=3.3,<8.18", + "auth0/login": "<7.20", + "auth0/symfony": "<=5.5", + "auth0/wordpress": "<=5.4", "automad/automad": "<2.0.0.0-alpha5", "automattic/jetpack": "<9.8", "awesome-support/awesome-support": "<=6.0.7", - "aws/aws-sdk-php": "<3.288.1", + "aws/aws-sdk-php": "<3.368", "azuracast/azuracast": "<=0.23.1", "b13/seo_basics": "<0.8.2", "backdrop/backdrop": "<=1.32", @@ -6694,7 +6716,7 @@ "backpack/filemanager": "<2.0.2|>=3,<3.0.9", "bacula-web/bacula-web": "<9.7.1", "badaso/core": "<=2.9.11", - "bagisto/bagisto": "<=2.3.7", + "bagisto/bagisto": "<2.3.10", "barrelstrength/sprout-base-email": "<1.2.7", "barrelstrength/sprout-forms": "<3.9", "barryvdh/laravel-translation-manager": "<0.6.8", @@ -6726,7 +6748,8 @@ "bvbmedia/multishop": "<2.0.39", "bytefury/crater": "<6.0.2", "cachethq/cachet": "<2.5.1", - "cakephp/cakephp": "<3.10.3|>=4,<4.0.10|>=4.1,<4.1.4|>=4.2,<4.2.12|>=4.3,<4.3.11|>=4.4,<4.4.10", + "cadmium-org/cadmium-cms": "<=0.4.9", + "cakephp/cakephp": "<3.10.3|>=4,<4.0.10|>=4.1,<4.1.4|>=4.2,<4.2.12|>=4.3,<4.3.11|>=4.4,<4.4.10|>=5.2.10,<5.2.12|==5.3", "cakephp/database": ">=4.2,<4.2.12|>=4.3,<4.3.11|>=4.4,<4.4.10", "cardgate/magento2": "<2.0.33", "cardgate/woocommerce": "<=3.1.15", @@ -6755,7 +6778,7 @@ "codingms/modules": "<4.3.11|>=5,<5.7.4|>=6,<6.4.2|>=7,<7.5.5", "commerceteam/commerce": ">=0.9.6,<0.9.9", "components/jquery": ">=1.0.3,<3.5", - "composer/composer": "<1.10.27|>=2,<2.2.24|>=2.3,<2.7.7", + "composer/composer": "<1.10.27|>=2,<2.2.26|>=2.3,<2.9.3", "concrete5/concrete5": "<9.4.3", "concrete5/core": "<8.5.8|>=9,<9.1", "contao-components/mediaelement": ">=2.14.2,<2.21.1", @@ -6765,11 +6788,13 @@ "contao/core-bundle": "<4.13.57|>=5,<5.3.42|>=5.4,<5.6.5", "contao/listing-bundle": ">=3,<=3.5.30|>=4,<4.4.8", "contao/managed-edition": "<=1.5", + "coreshop/core-shop": "<4.1.9", "corveda/phpsandbox": "<1.3.5", "cosenary/instagram": "<=2.3", "couleurcitron/tarteaucitron-wp": "<0.3", - "craftcms/cms": "<=4.16.5|>=5,<=5.8.6", - "croogo/croogo": "<4", + "cpsit/typo3-mailqueue": "<0.4.3|>=0.5,<0.5.1", + "craftcms/cms": "<=4.16.16|>=5,<=5.8.20", + "croogo/croogo": "<=4.0.7", "cuyz/valinor": "<0.12", "czim/file-handling": "<1.5|>=2,<2.3", "czproject/git-php": "<4.0.3", @@ -6816,7 +6841,7 @@ "drupal/commerce_alphabank_redirect": "<1.0.3", "drupal/commerce_eurobank_redirect": "<2.1.1", "drupal/config_split": "<1.10|>=2,<2.0.2", - "drupal/core": ">=6,<6.38|>=7,<7.102|>=8,<10.4.9|>=10.5,<10.5.6|>=11,<11.1.9|>=11.2,<11.2.8", + "drupal/core": ">=6,<6.38|>=7,<7.103|>=8,<10.4.9|>=10.5,<10.5.6|>=11,<11.1.9|>=11.2,<11.2.8", "drupal/core-recommended": ">=7,<7.102|>=8,<10.2.11|>=10.3,<10.3.9|>=11,<11.0.8", "drupal/currency": "<3.5", "drupal/drupal": ">=5,<5.11|>=6,<6.38|>=7,<7.102|>=8,<10.2.11|>=10.3,<10.3.9|>=11,<11.0.8", @@ -6880,7 +6905,7 @@ "ezsystems/repository-forms": ">=2.3,<2.3.2.1-dev|>=2.5,<2.5.15", "ezyang/htmlpurifier": "<=4.2", "facade/ignition": "<1.16.15|>=2,<2.4.2|>=2.5,<2.5.2", - "facturascripts/facturascripts": "<=2022.08", + "facturascripts/facturascripts": "<=2025.4|==2025.11|==2025.41|==2025.43", "fastly/magento2": "<1.2.26", "feehi/cms": "<=2.1.1", "feehi/feehicms": "<=2.1.1", @@ -6905,6 +6930,7 @@ "floriangaerber/magnesium": "<0.3.1", "fluidtypo3/vhs": "<5.1.1", "fof/byobu": ">=0.3.0.0-beta2,<1.1.7", + "fof/pretty-mail": "<=1.1.2", "fof/upload": "<1.2.3", "foodcoopshop/foodcoopshop": ">=3.2,<3.6.1", "fooman/tcpdf": "<6.2.22", @@ -6930,7 +6956,7 @@ "geshi/geshi": "<=1.0.9.1", "getformwork/formwork": "<2.2", "getgrav/grav": "<1.11.0.0-beta1", - "getkirby/cms": "<3.9.8.3-dev|>=3.10,<3.10.1.2-dev|>=4,<4.7.1|>=5,<5.1.4", + "getkirby/cms": "<3.9.8.3-dev|>=3.10,<3.10.1.2-dev|>=4,<4.7.1|>=5,<=5.2.1", "getkirby/kirby": "<3.9.8.3-dev|>=3.10,<3.10.1.2-dev|>=4,<4.7.1", "getkirby/panel": "<2.5.14", "getkirby/starterkit": "<=3.7.0.2", @@ -7020,7 +7046,7 @@ "kelvinmo/simplexrd": "<3.1.1", "kevinpapst/kimai2": "<1.16.7", "khodakhah/nodcms": "<=3", - "kimai/kimai": "<=2.20.1", + "kimai/kimai": "<2.46", "kitodo/presentation": "<3.2.3|>=3.3,<3.3.4", "klaviyo/magento2-extension": ">=1,<3", "knplabs/knp-snappy": "<=1.4.2", @@ -7039,7 +7065,7 @@ "laravel/framework": "<10.48.29|>=11,<11.44.1|>=12,<12.1.1", "laravel/laravel": ">=5.4,<5.4.22", "laravel/pulse": "<1.3.1", - "laravel/reverb": "<1.4", + "laravel/reverb": "<1.7", "laravel/socialite": ">=1,<2.0.10", "latte/latte": "<2.10.8", "lavalite/cms": "<=9|==10.1", @@ -7051,11 +7077,12 @@ "leantime/leantime": "<3.3", "lexik/jwt-authentication-bundle": "<2.10.7|>=2.11,<2.11.3", "libreform/libreform": ">=2,<=2.0.8", - "librenms/librenms": "<25.11", + "librenms/librenms": "<25.12", "liftkit/database": "<2.13.2", "lightsaml/lightsaml": "<1.3.5", "limesurvey/limesurvey": "<6.5.12", "livehelperchat/livehelperchat": "<=3.91", + "livewire-filemanager/filemanager": "<=1.0.4", "livewire/livewire": "<2.12.7|>=3.0.0.0-beta1,<3.6.4", "livewire/volt": "<1.7", "lms/routes": "<2.1.1", @@ -7105,6 +7132,7 @@ "microsoft/microsoft-graph-core": "<2.0.2", "microweber/microweber": "<=2.0.19", "mikehaertl/php-shellcommand": "<1.6.1", + "mineadmin/mineadmin": "<=3.0.9", "miniorange/miniorange-saml": "<1.4.3", "mittwald/typo3_forum": "<1.2.1", "mobiledetect/mobiledetectlib": "<2.8.32", @@ -7158,7 +7186,7 @@ "october/cms": "<1.0.469|==1.0.469|==1.0.471|==1.1.1", "october/october": "<3.7.5", "october/rain": "<1.0.472|>=1.1,<1.1.2", - "october/system": "<3.7.5", + "october/system": "<=3.7.12|>=4,<=4.0.11", "oliverklee/phpunit": "<3.5.15", "omeka/omeka-s": "<4.0.3", "onelogin/php-saml": "<2.21.1|>=3,<3.8.1|>=4,<4.3.1", @@ -7185,6 +7213,7 @@ "pagekit/pagekit": "<=1.0.18", "paragonie/ecc": "<2.0.1", "paragonie/random_compat": "<2", + "paragonie/sodium_compat": "<1.24|>=2,<2.5", "passbolt/passbolt_api": "<4.6.2", "paypal/adaptivepayments-sdk-php": "<=3.9.2", "paypal/invoice-sdk-php": "<=3.9", @@ -7221,14 +7250,15 @@ "phpxmlrpc/extras": "<0.6.1", "phpxmlrpc/phpxmlrpc": "<4.9.2", "pi/pi": "<=2.5", - "pimcore/admin-ui-classic-bundle": "<1.7.6", + "pimcore/admin-ui-classic-bundle": "<=1.7.15|>=2.0.0.0-RC1-dev,<=2.2.2", "pimcore/customer-management-framework-bundle": "<4.2.1", "pimcore/data-hub": "<1.2.4", "pimcore/data-importer": "<1.8.9|>=1.9,<1.9.3", "pimcore/demo": "<10.3", "pimcore/ecommerce-framework-bundle": "<1.0.10", "pimcore/perspective-editor": "<1.5.1", - "pimcore/pimcore": "<11.5.4", + "pimcore/pimcore": "<=11.5.13|>=12.0.0.0-RC1-dev,<12.3.1", + "pimcore/web2print-tools-bundle": "<=5.2.1|>=6.0.0.0-RC1-dev,<=6.1", "piwik/piwik": "<1.11", "pixelfed/pixelfed": "<0.12.5", "plotly/plotly.js": "<2.25.2", @@ -7252,7 +7282,7 @@ "processwire/processwire": "<=3.0.246", "propel/propel": ">=2.0.0.0-alpha1,<=2.0.0.0-alpha7", "propel/propel1": ">=1,<=1.7.1", - "pterodactyl/panel": "<=1.11.10", + "pterodactyl/panel": "<1.12", "ptheofan/yii2-statemachine": ">=2.0.0.0-RC1-dev,<=2", "ptrofimov/beanstalk_console": "<1.7.14", "pubnub/pubnub": "<6.1", @@ -7270,7 +7300,7 @@ "rap2hpoutre/laravel-log-viewer": "<0.13", "react/http": ">=0.7,<1.9", "really-simple-plugins/complianz-gdpr": "<6.4.2", - "redaxo/source": "<5.20.1", + "redaxo/source": "<=5.20.1", "remdex/livehelperchat": "<4.29", "renolit/reint-downloadmanager": "<4.0.2|>=5,<5.0.1", "reportico-web/reportico": "<=8.1", @@ -7292,10 +7322,10 @@ "setasign/fpdi": "<2.6.4", "sfroemken/url_redirect": "<=1.2.1", "sheng/yiicms": "<1.2.1", - "shopware/core": "<6.6.10.9-dev|>=6.7,<6.7.4.1-dev", + "shopware/core": "<6.6.10.9-dev|>=6.7,<6.7.6.1-dev", "shopware/platform": "<6.6.10.7-dev|>=6.7,<6.7.3.1-dev", "shopware/production": "<=6.3.5.2", - "shopware/shopware": "<=5.7.17|>=6.4.6,<6.6.10.10-dev|>=6.7,<6.7.5.1-dev", + "shopware/shopware": "<=5.7.17|>=6.4.6,<6.6.10.10-dev|>=6.7,<6.7.6.1-dev", "shopware/storefront": "<6.6.10.10-dev|>=6.7,<6.7.5.1-dev", "shopxo/shopxo": "<=6.4", "showdoc/showdoc": "<2.10.4", @@ -7340,7 +7370,7 @@ "snipe/snipe-it": "<=8.3.4", "socalnick/scn-social-auth": "<1.15.2", "socialiteproviders/steam": "<1.1", - "solspace/craft-freeform": ">=5,<5.10.16", + "solspace/craft-freeform": "<4.1.29|>=5,<5.10.16", "soosyze/soosyze": "<=2", "spatie/browsershot": "<5.0.5", "spatie/image-optimizer": "<1.7.3", @@ -7429,7 +7459,7 @@ "thelia/thelia": ">=2.1,<2.1.3", "theonedemon/phpwhois": "<=4.2.5", "thinkcmf/thinkcmf": "<6.0.8", - "thorsten/phpmyfaq": "<=4.0.13", + "thorsten/phpmyfaq": "<4.0.16|>=4.1.0.0-alpha,<=4.1.0.0-beta2", "tikiwiki/tiki-manager": "<=17.1", "timber/timber": ">=0.16.6,<1.23.1|>=1.24,<1.24.1|>=2,<2.1", "tinymce/tinymce": "<7.2", @@ -7448,10 +7478,10 @@ "twbs/bootstrap": "<3.4.1|>=4,<4.3.1", "twig/twig": "<3.11.2|>=3.12,<3.14.1|>=3.16,<3.19", "typo3/cms": "<9.5.29|>=10,<10.4.35|>=11,<11.5.23|>=12,<12.2", - "typo3/cms-backend": "<4.1.14|>=4.2,<4.2.15|>=4.3,<4.3.7|>=4.4,<4.4.4|>=7,<=7.6.50|>=8,<=8.7.39|>=9,<9.5.55|>=10,<10.4.54|>=11,<11.5.48|>=12,<12.4.37|>=13,<13.4.18", + "typo3/cms-backend": "<4.1.14|>=4.2,<4.2.15|>=4.3,<4.3.7|>=4.4,<4.4.4|>=7,<=7.6.50|>=8,<=8.7.39|>=9,<9.5.55|>=10,<=10.4.54|>=11,<=11.5.48|>=12,<=12.4.40|>=13,<=13.4.22|>=14,<=14.0.1", "typo3/cms-belog": ">=10,<=10.4.47|>=11,<=11.5.41|>=12,<=12.4.24|>=13,<=13.4.2", "typo3/cms-beuser": ">=9,<9.5.55|>=10,<10.4.54|>=11,<11.5.48|>=12,<12.4.37|>=13,<13.4.18", - "typo3/cms-core": "<=8.7.56|>=9,<9.5.55|>=10,<10.4.54|>=11,<11.5.48|>=12,<12.4.37|>=13,<13.4.18", + "typo3/cms-core": "<=8.7.56|>=9,<9.5.55|>=10,<=10.4.54|>=11,<=11.5.48|>=12,<=12.4.40|>=13,<=13.4.22|>=14,<=14.0.1", "typo3/cms-dashboard": ">=10,<10.4.54|>=11,<11.5.48|>=12,<12.4.37|>=13,<13.4.18", "typo3/cms-extbase": "<6.2.24|>=7,<7.6.8|==8.1.1", "typo3/cms-extensionmanager": ">=10,<=10.4.47|>=11,<=11.5.41|>=12,<=12.4.24|>=13,<=13.4.2", @@ -7463,7 +7493,8 @@ "typo3/cms-install": "<4.1.14|>=4.2,<4.2.16|>=4.3,<4.3.9|>=4.4,<4.4.5|>=12.2,<12.4.8|==13.4.2", "typo3/cms-lowlevel": ">=11,<=11.5.41", "typo3/cms-recordlist": ">=11,<11.5.48", - "typo3/cms-recycler": ">=9,<9.5.55|>=10,<10.4.54|>=11,<11.5.48|>=12,<12.4.37|>=13,<13.4.18", + "typo3/cms-recycler": ">=9,<9.5.55|>=10,<=10.4.54|>=11,<=11.5.48|>=12,<=12.4.40|>=13,<=13.4.22|>=14,<=14.0.1", + "typo3/cms-redirects": ">=10,<=10.4.54|>=11,<=11.5.48|>=12,<=12.4.40|>=13,<=13.4.22|>=14,<=14.0.1", "typo3/cms-rte-ckeditor": ">=9.5,<9.5.42|>=10,<10.4.39|>=11,<11.5.30", "typo3/cms-scheduler": ">=11,<=11.5.41", "typo3/cms-setup": ">=9,<=9.5.50|>=10,<=10.4.49|>=11,<=11.5.43|>=12,<=12.4.30|>=13,<=13.4.11", @@ -7545,7 +7576,7 @@ "yiisoft/yii2-redis": "<2.0.20", "yikesinc/yikes-inc-easy-mailchimp-extender": "<6.8.6", "yoast-seo-for-typo3/yoast_seo": "<7.2.3", - "yourls/yourls": "<=1.8.2", + "yourls/yourls": "<=1.10.2", "yuan1994/tpadmin": "<=1.3.12", "yungifez/skuul": "<=2.6.5", "z-push/z-push-dev": "<2.7.6", @@ -7623,7 +7654,7 @@ "type": "tidelift" } ], - "time": "2025-12-11T17:09:09+00:00" + "time": "2026-01-21T17:25:15+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", @@ -9324,12 +9355,12 @@ "source": { "type": "git", "url": "https://github.com/WordPress/WordPress-Coding-Standards.git", - "reference": "7ee7992c65e0a5e114d6b6f3062a75b92dfc0c30" + "reference": "8e14560fc2363fff275838ef129147ffbc1f0a82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/7ee7992c65e0a5e114d6b6f3062a75b92dfc0c30", - "reference": "7ee7992c65e0a5e114d6b6f3062a75b92dfc0c30", + "url": "https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/8e14560fc2363fff275838ef129147ffbc1f0a82", + "reference": "8e14560fc2363fff275838ef129147ffbc1f0a82", "shasum": "" }, "require": { @@ -9383,7 +9414,7 @@ "type": "custom" } ], - "time": "2026-01-06T14:42:29+00:00" + "time": "2026-01-21T02:21:44+00:00" }, { "name": "yoast/phpunit-polyfills", @@ -9449,7 +9480,14 @@ "time": "2025-02-09T18:58:54+00:00" } ], - "aliases": [], + "aliases": [ + { + "package": "wp-cli/wp-cli", + "version": "dev-testing/cli-update", + "alias": "2.13", + "alias_normalized": "2.13.0.0" + } + ], "minimum-stability": "dev", "stability-flags": { "roave/security-advisories": 20, From 3f6b8e9367c2bb71ec70dd636c190e92183fa8d5 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Thu, 22 Jan 2026 17:30:17 +0100 Subject: [PATCH 6/7] update --- composer.lock | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/composer.lock b/composer.lock index 6c0b01816..ec97b3ef9 100644 --- a/composer.lock +++ b/composer.lock @@ -4771,21 +4771,19 @@ "source": { "type": "git", "url": "https://github.com/bgturner/wp-cli.git", - "reference": "50e07d85406a74fa6faf0298fbc16ef247683313" + "reference": "2f040b1abb2cf9fb0b08e55a51dc0a2b64f0e556" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bgturner/wp-cli/zipball/50e07d85406a74fa6faf0298fbc16ef247683313", - "reference": "50e07d85406a74fa6faf0298fbc16ef247683313", + "url": "https://api.github.com/repos/bgturner/wp-cli/zipball/2f040b1abb2cf9fb0b08e55a51dc0a2b64f0e556", + "reference": "2f040b1abb2cf9fb0b08e55a51dc0a2b64f0e556", "shasum": "" }, "require": { - "ext-curl": "*", "mustache/mustache": "^3.0.0", "php": ">=7.2.24 || ^8.0", - "symfony/finder": ">2.7", "wp-cli/mustangostang-spyc": "^0.6.3", - "wp-cli/php-cli-tools": "~0.12.4" + "wp-cli/php-cli-tools": "~0.12.7" }, "require-dev": { "justinrainbow/json-schema": "^6.3", @@ -4797,6 +4795,7 @@ "wp-cli/wp-cli-tests": "^5" }, "suggest": { + "ext-curl": "For better performance when making HTTP requests", "ext-readline": "Include for a better --prompt implementation", "ext-zip": "Needed to support extraction of ZIP archives when doing downloads or updates" }, @@ -4808,7 +4807,20 @@ "extra": { "branch-alias": { "dev-main": "2.13.x-dev" - } + }, + "commands": [ + "cli", + "cli alias", + "cli cache", + "cli check-update", + "cli cmd-dump", + "cli completions", + "cli has-command", + "cli info", + "cli param-dump", + "cli update", + "cli version" + ] }, "autoload": { "psr-0": { @@ -4866,7 +4878,7 @@ "source": "https://github.com/wp-cli/wp-cli", "docs": "https://make.wordpress.org/cli/handbook/" }, - "time": "2025-12-02T20:12:16+00:00" + "time": "2026-01-22T16:29:49+00:00" }, { "name": "wp-cli/wp-config-transformer", From 46626bfe5bc70099a03961332930460d1a24a1e5 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Thu, 22 Jan 2026 19:04:15 +0100 Subject: [PATCH 7/7] update --- composer.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/composer.lock b/composer.lock index ec97b3ef9..27c9b1f12 100644 --- a/composer.lock +++ b/composer.lock @@ -2676,12 +2676,12 @@ "source": { "type": "git", "url": "https://github.com/wp-cli/ability-command.git", - "reference": "33a966a99081f4cf1b47c64d6ed7c270d1a166c3" + "reference": "37ab40b5946a58d9c4393da0345176f96fef681d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wp-cli/ability-command/zipball/33a966a99081f4cf1b47c64d6ed7c270d1a166c3", - "reference": "33a966a99081f4cf1b47c64d6ed7c270d1a166c3", + "url": "https://api.github.com/repos/wp-cli/ability-command/zipball/37ab40b5946a58d9c4393da0345176f96fef681d", + "reference": "37ab40b5946a58d9c4393da0345176f96fef681d", "shasum": "" }, "require": { @@ -2729,7 +2729,7 @@ "issues": "https://github.com/wp-cli/ability-command/issues", "source": "https://github.com/wp-cli/ability-command/tree/main" }, - "time": "2026-01-21T12:28:13+00:00" + "time": "2026-01-22T17:20:37+00:00" }, { "name": "wp-cli/block-command", @@ -2737,12 +2737,12 @@ "source": { "type": "git", "url": "https://github.com/wp-cli/block-command.git", - "reference": "1ef1b8df411bf5ca785e19418cb4fc09ba07939d" + "reference": "9936e919cc5961710f200d59b07b3b25d5312b6e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wp-cli/block-command/zipball/1ef1b8df411bf5ca785e19418cb4fc09ba07939d", - "reference": "1ef1b8df411bf5ca785e19418cb4fc09ba07939d", + "url": "https://api.github.com/repos/wp-cli/block-command/zipball/9936e919cc5961710f200d59b07b3b25d5312b6e", + "reference": "9936e919cc5961710f200d59b07b3b25d5312b6e", "shasum": "" }, "require": { @@ -2806,7 +2806,7 @@ "issues": "https://github.com/wp-cli/block-command/issues", "source": "https://github.com/wp-cli/block-command/tree/main" }, - "time": "2026-01-21T12:28:13+00:00" + "time": "2026-01-22T17:20:39+00:00" }, { "name": "wp-cli/cache-command", @@ -4771,12 +4771,12 @@ "source": { "type": "git", "url": "https://github.com/bgturner/wp-cli.git", - "reference": "2f040b1abb2cf9fb0b08e55a51dc0a2b64f0e556" + "reference": "a40a83f766b4f39c6258a8e1db2f34216f5b627f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bgturner/wp-cli/zipball/2f040b1abb2cf9fb0b08e55a51dc0a2b64f0e556", - "reference": "2f040b1abb2cf9fb0b08e55a51dc0a2b64f0e556", + "url": "https://api.github.com/repos/bgturner/wp-cli/zipball/a40a83f766b4f39c6258a8e1db2f34216f5b627f", + "reference": "a40a83f766b4f39c6258a8e1db2f34216f5b627f", "shasum": "" }, "require": { @@ -4878,7 +4878,7 @@ "source": "https://github.com/wp-cli/wp-cli", "docs": "https://make.wordpress.org/cli/handbook/" }, - "time": "2026-01-22T16:29:49+00:00" + "time": "2026-01-22T17:49:05+00:00" }, { "name": "wp-cli/wp-config-transformer",