From 3bd980a8e370fd7a29f997a1b0d4ddc58bde9a42 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 2 Nov 2025 17:04:54 +0000 Subject: [PATCH 01/15] Initial plan From a44033d36478f367e581022f959d8ad46f3f6830 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 2 Nov 2025 17:12:47 +0000 Subject: [PATCH 02/15] Add --format flag support to language update commands Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- src/Core_Language_Command.php | 13 ++++++- src/Plugin_Language_Command.php | 13 ++++++- src/Theme_Language_Command.php | 13 ++++++- src/WP_CLI/CommandWithTranslation.php | 55 ++++++++++++++++++++------- 4 files changed, 78 insertions(+), 16 deletions(-) diff --git a/src/Core_Language_Command.php b/src/Core_Language_Command.php index c1b01af1..573b9bac 100644 --- a/src/Core_Language_Command.php +++ b/src/Core_Language_Command.php @@ -339,6 +339,17 @@ public function uninstall( $args ) { * [--dry-run] * : Preview which translations would be updated. * + * [--format=] + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - json + * - summary + * --- + * * ## EXAMPLES * * # Update installed core languages packs. @@ -351,7 +362,7 @@ public function uninstall( $args ) { * @subcommand update * * @param string[] $args Positional arguments. - * @param array{'dry-run'?: bool} $assoc_args Associative arguments. + * @param array{'dry-run'?: bool, format?: string} $assoc_args Associative arguments. */ public function update( $args, $assoc_args ) { // phpcs:ignore Generic.CodeAnalysis.UselessOverridingMethod.Found -- Overruling the documentation, so not useless ;-). parent::update( $args, $assoc_args ); diff --git a/src/Plugin_Language_Command.php b/src/Plugin_Language_Command.php index 532e5110..1d3cf2a3 100644 --- a/src/Plugin_Language_Command.php +++ b/src/Plugin_Language_Command.php @@ -588,6 +588,17 @@ public function uninstall( $args, $assoc_args ) { * [--dry-run] * : Preview which translations would be updated. * + * [--format=] + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - json + * - summary + * --- + * * ## EXAMPLES * * # Update all installed language packs for all plugins. @@ -600,7 +611,7 @@ public function uninstall( $args, $assoc_args ) { * @subcommand update * * @param string[] $args Positional arguments. - * @param array{'dry-run'?: bool, all?: bool} $assoc_args Associative arguments. + * @param array{'dry-run'?: bool, all?: bool, format?: string} $assoc_args Associative arguments. */ public function update( $args, $assoc_args ) { $all = \WP_CLI\Utils\get_flag_value( $assoc_args, 'all', false ); diff --git a/src/Theme_Language_Command.php b/src/Theme_Language_Command.php index a9589627..d17246bc 100644 --- a/src/Theme_Language_Command.php +++ b/src/Theme_Language_Command.php @@ -607,6 +607,17 @@ public function uninstall( $args, $assoc_args ) { * [--dry-run] * : Preview which translations would be updated. * + * [--format=] + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - json + * - summary + * --- + * * ## EXAMPLES * * # Update all installed language packs for all themes. @@ -619,7 +630,7 @@ public function uninstall( $args, $assoc_args ) { * @subcommand update * * @param string[] $args Positional arguments. - * @param array{'dry-run'?: bool, all?: bool} $assoc_args Associative arguments. + * @param array{'dry-run'?: bool, all?: bool, format?: string} $assoc_args Associative arguments. */ public function update( $args, $assoc_args ) { $all = \WP_CLI\Utils\get_flag_value( $assoc_args, 'all', false ); diff --git a/src/WP_CLI/CommandWithTranslation.php b/src/WP_CLI/CommandWithTranslation.php index c273dc8e..0c8157e5 100644 --- a/src/WP_CLI/CommandWithTranslation.php +++ b/src/WP_CLI/CommandWithTranslation.php @@ -26,7 +26,7 @@ protected function sort_translations_callback( $a, $b ) { * Updates installed languages for the current object type. * * @param string[] $args Positional arguments. - * @param array{'dry-run'?: bool, all?: bool} $assoc_args Associative arguments. + * @param array{'dry-run'?: bool, all?: bool, format?: string} $assoc_args Associative arguments. */ public function update( $args, $assoc_args ) { $updates = $this->get_translation_updates(); @@ -41,9 +41,17 @@ public function update( $args, $assoc_args ) { $args = array( null ); // Used for core. } - $upgrader = 'WP_CLI\\LanguagePackUpgrader'; - $results = array(); - $num_to_update = 0; + $format = Utils\get_flag_value( $assoc_args, 'format' ); + + if ( $format && in_array( $format, array( 'json', 'csv' ), true ) ) { + $logger = new \WP_CLI\Loggers\Quiet(); + WP_CLI::set_logger( $logger ); + } + + $upgrader = 'WP_CLI\\LanguagePackUpgrader'; + $results = array(); + $results_data = array(); + $num_to_update = 0; foreach ( $args as $slug ) { // Gets a list of all languages. @@ -118,6 +126,16 @@ public function update( $args, $assoc_args ) { $result = $upgrader_instance->upgrade( $update ); $results[] = $result; + + // Capture data for formatted output. + if ( $format ) { + $slug_key = 'core' === $obj_type ? 'version' : 'slug'; + $results_data[] = array( + $slug_key => isset( $update->slug ) ? $update->slug : $update->Version, + 'language' => $update->language, + 'status' => $result ? 'updated' : 'failed', + ); + } } } } @@ -126,21 +144,32 @@ public function update( $args, $assoc_args ) { if ( Utils\get_flag_value( $assoc_args, 'dry-run' ) ) { $update_count = count( $updates ); - WP_CLI::line( - sprintf( - 'Found %d translation %s that would be processed:', - $update_count, - WP_CLI\Utils\pluralize( 'update', $update_count ) - ) - ); - - Utils\format_items( 'table', $updates, array( 'Type', 'Name', 'Version', 'Language' ) ); + if ( $format ) { + Utils\format_items( $format, $updates, array( 'Type', 'Name', 'Version', 'Language' ) ); + } else { + WP_CLI::line( + sprintf( + 'Found %d translation %s that would be processed:', + $update_count, + WP_CLI\Utils\pluralize( 'update', $update_count ) + ) + ); + + Utils\format_items( 'table', $updates, array( 'Type', 'Name', 'Version', 'Language' ) ); + } return; } $num_updated = count( array_filter( $results ) ); + // Format output if --format is specified. + if ( $format && 'summary' !== $format ) { + $obj_type = rtrim( $this->obj_type, 's' ); + $slug_key = 'core' === $obj_type ? 'version' : 'slug'; + Utils\format_items( $format, $results_data, array( $slug_key, 'language', 'status' ) ); + } + $line = sprintf( "Updated $num_updated/$num_to_update %s.", WP_CLI\Utils\pluralize( 'translation', $num_updated ) ); if ( $num_to_update === $num_updated ) { From 4594dcbf14c959e0bd174a69cd9abf0c93d9b861 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 2 Nov 2025 17:16:03 +0000 Subject: [PATCH 03/15] Add tests for --format flag in update commands Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- features/language-core.feature | 29 ++++++++++++++++++++++++ features/language-plugin.feature | 39 ++++++++++++++++++++++++++++++++ features/language-theme.feature | 38 +++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+) diff --git a/features/language-core.feature b/features/language-core.feature index 4fe8e115..f50e4677 100644 --- a/features/language-core.feature +++ b/features/language-core.feature @@ -476,3 +476,32 @@ Feature: Manage core translation files for a WordPress install | en_US | active | | nl_NL | installed | And STDERR should be empty + + @require-wp-4.0 + Scenario: Core translation update with format flag + Given a WP install + And an empty cache + + When I run `wp language core update --format=json` + Then STDOUT should be: + """ + [] + """ + And STDERR should contain: + """ + Success: Translations are up to date. + """ + + When I run `wp language core update --format=csv` + Then STDOUT should be empty + And STDERR should contain: + """ + Success: Translations are up to date. + """ + + When I run `wp language core update --format=summary` + Then STDOUT should be empty + And STDERR should contain: + """ + Success: Translations are up to date. + """ diff --git a/features/language-plugin.feature b/features/language-plugin.feature index a94e9636..3c4ad14c 100644 --- a/features/language-plugin.feature +++ b/features/language-plugin.feature @@ -444,3 +444,42 @@ Feature: Manage plugin translation files for a WordPress install | akismet | en_US | active | | akismet | nl_NL | installed | And STDERR should be empty + + @require-wp-4.0 + Scenario: Plugin translation update with format flag + Given a WP install + And a wp-content/plugins/test-plugin/test-plugin.php file: + """ + Date: Sun, 2 Nov 2025 17:17:02 +0000 Subject: [PATCH 04/15] Fix format output for empty update results Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- src/WP_CLI/CommandWithTranslation.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/WP_CLI/CommandWithTranslation.php b/src/WP_CLI/CommandWithTranslation.php index 0c8157e5..35bc81c2 100644 --- a/src/WP_CLI/CommandWithTranslation.php +++ b/src/WP_CLI/CommandWithTranslation.php @@ -30,8 +30,12 @@ protected function sort_translations_callback( $a, $b ) { */ public function update( $args, $assoc_args ) { $updates = $this->get_translation_updates(); + $format = Utils\get_flag_value( $assoc_args, 'format' ); if ( empty( $updates ) ) { + if ( $format && in_array( $format, array( 'json', 'csv' ), true ) ) { + Utils\format_items( $format, array(), array() ); + } WP_CLI::success( 'Translations are up to date.' ); return; @@ -41,8 +45,6 @@ public function update( $args, $assoc_args ) { $args = array( null ); // Used for core. } - $format = Utils\get_flag_value( $assoc_args, 'format' ); - if ( $format && in_array( $format, array( 'json', 'csv' ), true ) ) { $logger = new \WP_CLI\Loggers\Quiet(); WP_CLI::set_logger( $logger ); From 2ec032e44788f11dfe4a153c47ad78fdde29af4e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 2 Nov 2025 17:22:21 +0000 Subject: [PATCH 05/15] Refactor update method to avoid code duplication and fix slug key logic Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- src/WP_CLI/CommandWithTranslation.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/WP_CLI/CommandWithTranslation.php b/src/WP_CLI/CommandWithTranslation.php index 35bc81c2..bc81904a 100644 --- a/src/WP_CLI/CommandWithTranslation.php +++ b/src/WP_CLI/CommandWithTranslation.php @@ -54,6 +54,8 @@ public function update( $args, $assoc_args ) { $results = array(); $results_data = array(); $num_to_update = 0; + $obj_type = rtrim( $this->obj_type, 's' ); + $slug_key = 'core' === $obj_type ? 'version' : 'slug'; foreach ( $args as $slug ) { // Gets a list of all languages. @@ -106,7 +108,6 @@ public function update( $args, $assoc_args ) { $updates_per_type[ $update->type ][] = $update; } - $obj_type = rtrim( $this->obj_type, 's' ); $available_updates = isset( $updates_per_type[ $obj_type ] ) ? $updates_per_type[ $obj_type ] : null; if ( ! is_array( $available_updates ) ) { @@ -131,9 +132,9 @@ public function update( $args, $assoc_args ) { // Capture data for formatted output. if ( $format ) { - $slug_key = 'core' === $obj_type ? 'version' : 'slug'; + $slug_value = 'core' === $obj_type ? $update->Version : $update->slug; $results_data[] = array( - $slug_key => isset( $update->slug ) ? $update->slug : $update->Version, + $slug_key => $slug_value, 'language' => $update->language, 'status' => $result ? 'updated' : 'failed', ); @@ -167,8 +168,6 @@ public function update( $args, $assoc_args ) { // Format output if --format is specified. if ( $format && 'summary' !== $format ) { - $obj_type = rtrim( $this->obj_type, 's' ); - $slug_key = 'core' === $obj_type ? 'version' : 'slug'; Utils\format_items( $format, $results_data, array( $slug_key, 'language', 'status' ) ); } From 75f704d85d193818379cdd0486ae1a4720119fe8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 2 Nov 2025 17:24:06 +0000 Subject: [PATCH 06/15] Optimize data collection to skip summary format Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- src/WP_CLI/CommandWithTranslation.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/WP_CLI/CommandWithTranslation.php b/src/WP_CLI/CommandWithTranslation.php index bc81904a..ca99bf65 100644 --- a/src/WP_CLI/CommandWithTranslation.php +++ b/src/WP_CLI/CommandWithTranslation.php @@ -130,8 +130,8 @@ public function update( $args, $assoc_args ) { $results[] = $result; - // Capture data for formatted output. - if ( $format ) { + // Capture data for formatted output (skip for summary format). + if ( $format && 'summary' !== $format ) { $slug_value = 'core' === $obj_type ? $update->Version : $update->slug; $results_data[] = array( $slug_key => $slug_value, From 7978aadc0ef84ffc64f424fc40230c7bc50afac3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 2 Nov 2025 17:26:39 +0000 Subject: [PATCH 07/15] Use WP_CLI::log instead of WP_CLI::line for proper quiet logger support Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- src/WP_CLI/CommandWithTranslation.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WP_CLI/CommandWithTranslation.php b/src/WP_CLI/CommandWithTranslation.php index ca99bf65..1c50d9eb 100644 --- a/src/WP_CLI/CommandWithTranslation.php +++ b/src/WP_CLI/CommandWithTranslation.php @@ -119,7 +119,7 @@ public function update( $args, $assoc_args ) { if ( ! Utils\get_flag_value( $assoc_args, 'dry-run' ) ) { // Update translations. foreach ( $available_updates as $update ) { - WP_CLI::line( "Updating '{$update->Language}' translation for {$update->Name} {$update->Version}..." ); + WP_CLI::log( "Updating '{$update->Language}' translation for {$update->Name} {$update->Version}..." ); /** * @var \WP_CLI\LanguagePackUpgrader $upgrader_instance From c62f5738c625150eea542e7d964d2a9ece4436df Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 2 Nov 2025 17:28:15 +0000 Subject: [PATCH 08/15] Improve maintainability by using slug_key variable consistently Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- src/WP_CLI/CommandWithTranslation.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WP_CLI/CommandWithTranslation.php b/src/WP_CLI/CommandWithTranslation.php index 1c50d9eb..9e6ec0f9 100644 --- a/src/WP_CLI/CommandWithTranslation.php +++ b/src/WP_CLI/CommandWithTranslation.php @@ -132,7 +132,7 @@ public function update( $args, $assoc_args ) { // Capture data for formatted output (skip for summary format). if ( $format && 'summary' !== $format ) { - $slug_value = 'core' === $obj_type ? $update->Version : $update->slug; + $slug_value = 'version' === $slug_key ? $update->Version : $update->slug; $results_data[] = array( $slug_key => $slug_value, 'language' => $update->language, From e0157bf63b4abf14aa52185e6b650e47203e9b44 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 3 Nov 2025 08:33:51 +0000 Subject: [PATCH 09/15] Fix format output to suppress success message and use standard test fixtures Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- features/language-core.feature | 15 +++------------ features/language-plugin.feature | 27 +++++---------------------- features/language-theme.feature | 26 +++++--------------------- src/WP_CLI/CommandWithTranslation.php | 9 ++++++--- 4 files changed, 19 insertions(+), 58 deletions(-) diff --git a/features/language-core.feature b/features/language-core.feature index f50e4677..3cae6c14 100644 --- a/features/language-core.feature +++ b/features/language-core.feature @@ -487,21 +487,12 @@ Feature: Manage core translation files for a WordPress install """ [] """ - And STDERR should contain: - """ - Success: Translations are up to date. - """ + And STDERR should be empty When I run `wp language core update --format=csv` Then STDOUT should be empty - And STDERR should contain: - """ - Success: Translations are up to date. - """ + And STDERR should be empty When I run `wp language core update --format=summary` Then STDOUT should be empty - And STDERR should contain: - """ - Success: Translations are up to date. - """ + And STDERR should be empty diff --git a/features/language-plugin.feature b/features/language-plugin.feature index 3c4ad14c..6b4e6d32 100644 --- a/features/language-plugin.feature +++ b/features/language-plugin.feature @@ -448,38 +448,21 @@ Feature: Manage plugin translation files for a WordPress install @require-wp-4.0 Scenario: Plugin translation update with format flag Given a WP install - And a wp-content/plugins/test-plugin/test-plugin.php file: - """ - Date: Mon, 3 Nov 2025 08:55:18 +0000 Subject: [PATCH 10/15] Show success message only for summary format and add tests with actual updates Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- features/language-core.feature | 5 ++- features/language-plugin.feature | 53 +++++++++++++++++++++++++++ features/language-theme.feature | 53 +++++++++++++++++++++++++++ src/WP_CLI/CommandWithTranslation.php | 26 +++++++------ 4 files changed, 124 insertions(+), 13 deletions(-) diff --git a/features/language-core.feature b/features/language-core.feature index 3cae6c14..3ebdee33 100644 --- a/features/language-core.feature +++ b/features/language-core.feature @@ -495,4 +495,7 @@ Feature: Manage core translation files for a WordPress install When I run `wp language core update --format=summary` Then STDOUT should be empty - And STDERR should be empty + And STDERR should contain: + """ + Success: Translations are up to date. + """ diff --git a/features/language-plugin.feature b/features/language-plugin.feature index 6b4e6d32..13b32b4e 100644 --- a/features/language-plugin.feature +++ b/features/language-plugin.feature @@ -465,4 +465,57 @@ Feature: Manage plugin translation files for a WordPress install When I run `wp language plugin update --all --format=summary` Then STDOUT should be empty + And STDERR should contain: + """ + Success: Translations are up to date. + """ + + @require-wp-4.0 + Scenario: Plugin translation update with format flag and actual updates + Given a WP install + And an empty cache + + When I run `wp plugin install akismet --version=3.2 --force` + Then STDERR should be empty + + When I run `wp language plugin install akismet de_DE` + Then STDERR should be empty + + When I run `wp plugin install akismet --version=4.0 --force` + And I run `wp language plugin list akismet --fields=plugin,language,update,status` + Then STDOUT should be a table containing rows: + | plugin | language | update | status | + | akismet | de_DE | available | installed | + + When I run `wp language plugin update akismet --format=json` + Then STDOUT should be JSON containing: + """ + [{"slug":"akismet","language":"de_DE","status":"updated"}] + """ And STDERR should be empty + + When I run `wp plugin install akismet --version=3.2 --force` + And I run `wp language plugin install akismet de_DE --force` + And I run `wp plugin install akismet --version=4.0 --force` + + When I run `wp language plugin update akismet --format=csv` + Then STDOUT should contain: + """ + slug,language,status + """ + And STDOUT should contain: + """ + akismet,de_DE,updated + """ + And STDERR should be empty + + When I run `wp plugin install akismet --version=3.2 --force` + And I run `wp language plugin install akismet de_DE --force` + And I run `wp plugin install akismet --version=4.0 --force` + + When I run `wp language plugin update akismet --format=summary` + Then STDOUT should be empty + And STDERR should contain: + """ + Success: Updated 1/1 translation. + """ diff --git a/features/language-theme.feature b/features/language-theme.feature index ce6e7568..e455e085 100644 --- a/features/language-theme.feature +++ b/features/language-theme.feature @@ -349,4 +349,57 @@ Feature: Manage theme translation files for a WordPress install When I run `wp language theme update --all --format=summary` Then STDOUT should be empty + And STDERR should contain: + """ + Success: Translations are up to date. + """ + + @require-wp-4.0 + Scenario: Theme translation update with format flag and actual updates + Given a WP install + And an empty cache + + When I run `wp theme install twentyfifteen --version=2.0 --force` + Then STDERR should be empty + + When I run `wp language theme install twentyfifteen de_DE` + Then STDERR should be empty + + When I run `wp theme install twentyfifteen --version=2.5 --force` + And I run `wp language theme list twentyfifteen --fields=theme,language,update,status` + Then STDOUT should be a table containing rows: + | theme | language | update | status | + | twentyfifteen | de_DE | available | installed | + + When I run `wp language theme update twentyfifteen --format=json` + Then STDOUT should be JSON containing: + """ + [{"slug":"twentyfifteen","language":"de_DE","status":"updated"}] + """ + And STDERR should be empty + + When I run `wp theme install twentyfifteen --version=2.0 --force` + And I run `wp language theme install twentyfifteen de_DE --force` + And I run `wp theme install twentyfifteen --version=2.5 --force` + + When I run `wp language theme update twentyfifteen --format=csv` + Then STDOUT should contain: + """ + slug,language,status + """ + And STDOUT should contain: + """ + twentyfifteen,de_DE,updated + """ And STDERR should be empty + + When I run `wp theme install twentyfifteen --version=2.0 --force` + And I run `wp language theme install twentyfifteen de_DE --force` + And I run `wp theme install twentyfifteen --version=2.5 --force` + + When I run `wp language theme update twentyfifteen --format=summary` + Then STDOUT should be empty + And STDERR should contain: + """ + Success: Updated 1/1 translation. + """ diff --git a/src/WP_CLI/CommandWithTranslation.php b/src/WP_CLI/CommandWithTranslation.php index 04e48c1d..cf192509 100644 --- a/src/WP_CLI/CommandWithTranslation.php +++ b/src/WP_CLI/CommandWithTranslation.php @@ -33,11 +33,11 @@ public function update( $args, $assoc_args ) { $format = Utils\get_flag_value( $assoc_args, 'format' ); if ( empty( $updates ) ) { - if ( $format ) { - if ( in_array( $format, array( 'json', 'csv' ), true ) ) { - Utils\format_items( $format, array(), array() ); - } - } else { + if ( $format && in_array( $format, array( 'json', 'csv' ), true ) ) { + Utils\format_items( $format, array(), array() ); + } + + if ( ! $format || 'summary' === $format ) { WP_CLI::success( 'Translations are up to date.' ); } @@ -174,14 +174,16 @@ public function update( $args, $assoc_args ) { Utils\format_items( $format, $results_data, array( $slug_key, 'language', 'status' ) ); } - $line = sprintf( "Updated $num_updated/$num_to_update %s.", WP_CLI\Utils\pluralize( 'translation', $num_updated ) ); + if ( ! $format || 'summary' === $format ) { + $line = sprintf( "Updated $num_updated/$num_to_update %s.", WP_CLI\Utils\pluralize( 'translation', $num_updated ) ); - if ( $num_to_update === $num_updated ) { - WP_CLI::success( $line ); - } elseif ( $num_updated > 0 ) { - WP_CLI::warning( $line ); - } else { - WP_CLI::error( $line ); + if ( $num_to_update === $num_updated ) { + WP_CLI::success( $line ); + } elseif ( $num_updated > 0 ) { + WP_CLI::warning( $line ); + } else { + WP_CLI::error( $line ); + } } } From fd5a46439bd38269ba0ed9e7c0180830825eeb55 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 3 Nov 2025 09:45:09 +0000 Subject: [PATCH 11/15] Fix test expectations and remove invalid --force flag from language install commands Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- features/language-core.feature | 4 ++-- features/language-plugin.feature | 22 ++++++++++------------ features/language-theme.feature | 22 ++++++++++------------ 3 files changed, 22 insertions(+), 26 deletions(-) diff --git a/features/language-core.feature b/features/language-core.feature index 3ebdee33..86944a2a 100644 --- a/features/language-core.feature +++ b/features/language-core.feature @@ -494,8 +494,8 @@ Feature: Manage core translation files for a WordPress install And STDERR should be empty When I run `wp language core update --format=summary` - Then STDOUT should be empty - And STDERR should contain: + Then STDOUT should contain: """ Success: Translations are up to date. """ + And STDERR should be empty diff --git a/features/language-plugin.feature b/features/language-plugin.feature index 13b32b4e..0ca38f5b 100644 --- a/features/language-plugin.feature +++ b/features/language-plugin.feature @@ -464,11 +464,11 @@ Feature: Manage plugin translation files for a WordPress install And STDERR should be empty When I run `wp language plugin update --all --format=summary` - Then STDOUT should be empty - And STDERR should contain: + Then STDOUT should contain: """ Success: Translations are up to date. """ + And STDERR should be empty @require-wp-4.0 Scenario: Plugin translation update with format flag and actual updates @@ -484,8 +484,8 @@ Feature: Manage plugin translation files for a WordPress install When I run `wp plugin install akismet --version=4.0 --force` And I run `wp language plugin list akismet --fields=plugin,language,update,status` Then STDOUT should be a table containing rows: - | plugin | language | update | status | - | akismet | de_DE | available | installed | + | plugin | language | update | status | + | akismet | de_DE | available | installed | When I run `wp language plugin update akismet --format=json` Then STDOUT should be JSON containing: @@ -495,10 +495,9 @@ Feature: Manage plugin translation files for a WordPress install And STDERR should be empty When I run `wp plugin install akismet --version=3.2 --force` - And I run `wp language plugin install akismet de_DE --force` + And I run `wp language plugin install akismet de_DE` And I run `wp plugin install akismet --version=4.0 --force` - - When I run `wp language plugin update akismet --format=csv` + And I run `wp language plugin update akismet --format=csv` Then STDOUT should contain: """ slug,language,status @@ -510,12 +509,11 @@ Feature: Manage plugin translation files for a WordPress install And STDERR should be empty When I run `wp plugin install akismet --version=3.2 --force` - And I run `wp language plugin install akismet de_DE --force` + And I run `wp language plugin install akismet de_DE` And I run `wp plugin install akismet --version=4.0 --force` - - When I run `wp language plugin update akismet --format=summary` - Then STDOUT should be empty - And STDERR should contain: + And I run `wp language plugin update akismet --format=summary` + Then STDOUT should contain: """ Success: Updated 1/1 translation. """ + And STDERR should be empty diff --git a/features/language-theme.feature b/features/language-theme.feature index e455e085..9891b052 100644 --- a/features/language-theme.feature +++ b/features/language-theme.feature @@ -348,11 +348,11 @@ Feature: Manage theme translation files for a WordPress install And STDERR should be empty When I run `wp language theme update --all --format=summary` - Then STDOUT should be empty - And STDERR should contain: + Then STDOUT should contain: """ Success: Translations are up to date. """ + And STDERR should be empty @require-wp-4.0 Scenario: Theme translation update with format flag and actual updates @@ -368,8 +368,8 @@ Feature: Manage theme translation files for a WordPress install When I run `wp theme install twentyfifteen --version=2.5 --force` And I run `wp language theme list twentyfifteen --fields=theme,language,update,status` Then STDOUT should be a table containing rows: - | theme | language | update | status | - | twentyfifteen | de_DE | available | installed | + | theme | language | update | status | + | twentyfifteen | de_DE | available | installed | When I run `wp language theme update twentyfifteen --format=json` Then STDOUT should be JSON containing: @@ -379,10 +379,9 @@ Feature: Manage theme translation files for a WordPress install And STDERR should be empty When I run `wp theme install twentyfifteen --version=2.0 --force` - And I run `wp language theme install twentyfifteen de_DE --force` + And I run `wp language theme install twentyfifteen de_DE` And I run `wp theme install twentyfifteen --version=2.5 --force` - - When I run `wp language theme update twentyfifteen --format=csv` + And I run `wp language theme update twentyfifteen --format=csv` Then STDOUT should contain: """ slug,language,status @@ -394,12 +393,11 @@ Feature: Manage theme translation files for a WordPress install And STDERR should be empty When I run `wp theme install twentyfifteen --version=2.0 --force` - And I run `wp language theme install twentyfifteen de_DE --force` + And I run `wp language theme install twentyfifteen de_DE` And I run `wp theme install twentyfifteen --version=2.5 --force` - - When I run `wp language theme update twentyfifteen --format=summary` - Then STDOUT should be empty - And STDERR should contain: + And I run `wp language theme update twentyfifteen --format=summary` + Then STDOUT should contain: """ Success: Updated 1/1 translation. """ + And STDERR should be empty From 374d75ee23a9dfaa9937f0c6c14a9ada7ee419e1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 3 Nov 2025 12:36:12 +0000 Subject: [PATCH 12/15] Fix format handling to show success messages for table format Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- src/WP_CLI/CommandWithTranslation.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/WP_CLI/CommandWithTranslation.php b/src/WP_CLI/CommandWithTranslation.php index cf192509..e41a6a5c 100644 --- a/src/WP_CLI/CommandWithTranslation.php +++ b/src/WP_CLI/CommandWithTranslation.php @@ -37,7 +37,7 @@ public function update( $args, $assoc_args ) { Utils\format_items( $format, array(), array() ); } - if ( ! $format || 'summary' === $format ) { + if ( ! $format || in_array( $format, array( 'table', 'summary' ), true ) ) { WP_CLI::success( 'Translations are up to date.' ); } @@ -174,7 +174,7 @@ public function update( $args, $assoc_args ) { Utils\format_items( $format, $results_data, array( $slug_key, 'language', 'status' ) ); } - if ( ! $format || 'summary' === $format ) { + if ( ! $format || in_array( $format, array( 'table', 'summary' ), true ) ) { $line = sprintf( "Updated $num_updated/$num_to_update %s.", WP_CLI\Utils\pluralize( 'translation', $num_updated ) ); if ( $num_to_update === $num_updated ) { From 1e612fbfbed0cf0963b93477d380ad0344748a32 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 3 Nov 2025 13:10:07 +0000 Subject: [PATCH 13/15] Uninstall language before reinstalling to ensure updates are triggered Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- features/language-plugin.feature | 6 ++++-- features/language-theme.feature | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/features/language-plugin.feature b/features/language-plugin.feature index 0ca38f5b..31b0e6f7 100644 --- a/features/language-plugin.feature +++ b/features/language-plugin.feature @@ -494,7 +494,8 @@ Feature: Manage plugin translation files for a WordPress install """ And STDERR should be empty - When I run `wp plugin install akismet --version=3.2 --force` + When I run `wp language plugin uninstall akismet de_DE` + And I run `wp plugin install akismet --version=3.2 --force` And I run `wp language plugin install akismet de_DE` And I run `wp plugin install akismet --version=4.0 --force` And I run `wp language plugin update akismet --format=csv` @@ -508,7 +509,8 @@ Feature: Manage plugin translation files for a WordPress install """ And STDERR should be empty - When I run `wp plugin install akismet --version=3.2 --force` + When I run `wp language plugin uninstall akismet de_DE` + And I run `wp plugin install akismet --version=3.2 --force` And I run `wp language plugin install akismet de_DE` And I run `wp plugin install akismet --version=4.0 --force` And I run `wp language plugin update akismet --format=summary` diff --git a/features/language-theme.feature b/features/language-theme.feature index 9891b052..005df259 100644 --- a/features/language-theme.feature +++ b/features/language-theme.feature @@ -378,7 +378,8 @@ Feature: Manage theme translation files for a WordPress install """ And STDERR should be empty - When I run `wp theme install twentyfifteen --version=2.0 --force` + When I run `wp language theme uninstall twentyfifteen de_DE` + And I run `wp theme install twentyfifteen --version=2.0 --force` And I run `wp language theme install twentyfifteen de_DE` And I run `wp theme install twentyfifteen --version=2.5 --force` And I run `wp language theme update twentyfifteen --format=csv` @@ -392,7 +393,8 @@ Feature: Manage theme translation files for a WordPress install """ And STDERR should be empty - When I run `wp theme install twentyfifteen --version=2.0 --force` + When I run `wp language theme uninstall twentyfifteen de_DE` + And I run `wp theme install twentyfifteen --version=2.0 --force` And I run `wp language theme install twentyfifteen de_DE` And I run `wp theme install twentyfifteen --version=2.5 --force` And I run `wp language theme update twentyfifteen --format=summary` From ef8e06f492d73dbfd230685a8ffa707991fe6a68 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 3 Nov 2025 13:29:51 +0000 Subject: [PATCH 14/15] Fix dry-run output to show message for table/summary formats and fix theme test Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- features/language-theme.feature | 2 +- src/WP_CLI/CommandWithTranslation.php | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/features/language-theme.feature b/features/language-theme.feature index 005df259..285864f1 100644 --- a/features/language-theme.feature +++ b/features/language-theme.feature @@ -334,7 +334,7 @@ Feature: Manage theme translation files for a WordPress install Given a WP install When I try `wp theme install twentyten` - Then STDERR should be empty + Then STDOUT should not be empty When I run `wp language theme update twentyten --format=json` Then STDOUT should be: diff --git a/src/WP_CLI/CommandWithTranslation.php b/src/WP_CLI/CommandWithTranslation.php index e41a6a5c..308528f4 100644 --- a/src/WP_CLI/CommandWithTranslation.php +++ b/src/WP_CLI/CommandWithTranslation.php @@ -150,9 +150,11 @@ public function update( $args, $assoc_args ) { if ( Utils\get_flag_value( $assoc_args, 'dry-run' ) ) { $update_count = count( $updates ); - if ( $format ) { + if ( $format && ! in_array( $format, array( 'table', 'summary' ), true ) ) { + // For json/csv formats, just output the formatted data without the message Utils\format_items( $format, $updates, array( 'Type', 'Name', 'Version', 'Language' ) ); } else { + // For table/summary/no format, show the message and table WP_CLI::line( sprintf( 'Found %d translation %s that would be processed:', From 683e5b9d5ff4798618639bc152abaa48823986db Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Mon, 3 Nov 2025 14:49:23 +0100 Subject: [PATCH 15/15] Lint fixes --- src/WP_CLI/CommandWithTranslation.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/WP_CLI/CommandWithTranslation.php b/src/WP_CLI/CommandWithTranslation.php index 308528f4..f4638543 100644 --- a/src/WP_CLI/CommandWithTranslation.php +++ b/src/WP_CLI/CommandWithTranslation.php @@ -36,7 +36,7 @@ public function update( $args, $assoc_args ) { if ( $format && in_array( $format, array( 'json', 'csv' ), true ) ) { Utils\format_items( $format, array(), array() ); } - + if ( ! $format || in_array( $format, array( 'table', 'summary' ), true ) ) { WP_CLI::success( 'Translations are up to date.' ); } @@ -53,12 +53,12 @@ public function update( $args, $assoc_args ) { WP_CLI::set_logger( $logger ); } - $upgrader = 'WP_CLI\\LanguagePackUpgrader'; - $results = array(); - $results_data = array(); - $num_to_update = 0; - $obj_type = rtrim( $this->obj_type, 's' ); - $slug_key = 'core' === $obj_type ? 'version' : 'slug'; + $upgrader = 'WP_CLI\\LanguagePackUpgrader'; + $results = array(); + $results_data = array(); + $num_to_update = 0; + $obj_type = rtrim( $this->obj_type, 's' ); + $slug_key = 'core' === $obj_type ? 'version' : 'slug'; foreach ( $args as $slug ) { // Gets a list of all languages. @@ -135,7 +135,7 @@ public function update( $args, $assoc_args ) { // Capture data for formatted output (skip for summary format). if ( $format && 'summary' !== $format ) { - $slug_value = 'version' === $slug_key ? $update->Version : $update->slug; + $slug_value = 'version' === $slug_key ? $update->Version : $update->slug; $results_data[] = array( $slug_key => $slug_value, 'language' => $update->language,