From dec35ffc45ae83c0fd6143df045a6291e6489d88 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 4 Feb 2026 16:29:33 +0000 Subject: [PATCH 1/5] Initial plan From 62abd24ba3b53b8e7867c521857651d24407ecc6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 4 Feb 2026 16:38:28 +0000 Subject: [PATCH 2/5] Add --force flag to plugin activate and wire it up with plugin install Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- src/Plugin_Command.php | 27 +++++++++++++++++++++++---- src/WP_CLI/CommandWithUpgrade.php | 13 +++++++++++-- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/Plugin_Command.php b/src/Plugin_Command.php index c257debb..2d571d40 100644 --- a/src/Plugin_Command.php +++ b/src/Plugin_Command.php @@ -321,6 +321,9 @@ protected function get_all_items() { * [--network] * : If set, the plugin will be activated for the entire multisite network. * + * [--force] + * : If set, the plugin activation hooks will be run even if the plugin is already active. + * * ## EXAMPLES * * # Activate plugin @@ -345,6 +348,11 @@ protected function get_all_items() { * Plugin 'buddypress' network activated. * Success: Activated 2 of 2 plugins. * + * # Force re-running activation hooks for an already active plugin. + * $ wp plugin activate hello --force + * Plugin 'hello' activated. + * Success: Activated 1 of 1 plugins. + * * @param array $args * @param array $assoc_args */ @@ -352,6 +360,7 @@ public function activate( $args, $assoc_args = [] ) { $network_wide = Utils\get_flag_value( $assoc_args, 'network', false ); $all = Utils\get_flag_value( $assoc_args, 'all', false ); $all_exclude = Utils\get_flag_value( $assoc_args, 'exclude', '' ); + $force = Utils\get_flag_value( $assoc_args, 'force', false ); /** * @var string $all_exclude @@ -379,13 +388,23 @@ public function activate( $args, $assoc_args = [] ) { } // Network-active is the highest level of activation status. if ( 'active-network' === $status ) { - WP_CLI::warning( "Plugin '{$plugin->name}' is already network active." ); - continue; + // If force flag is set, deactivate and reactivate to run activation hooks. + if ( $force ) { + deactivate_plugins( $plugin->file, false, true ); + } else { + WP_CLI::warning( "Plugin '{$plugin->name}' is already network active." ); + continue; + } } // Don't reactivate active plugins, but do let them become network-active. if ( ! $network_wide && 'active' === $status ) { - WP_CLI::warning( "Plugin '{$plugin->name}' is already active." ); - continue; + // If force flag is set, deactivate and reactivate to run activation hooks. + if ( $force ) { + deactivate_plugins( $plugin->file, false, false ); + } else { + WP_CLI::warning( "Plugin '{$plugin->name}' is already active." ); + continue; + } } // Plugins need to be deactivated before being network activated. diff --git a/src/WP_CLI/CommandWithUpgrade.php b/src/WP_CLI/CommandWithUpgrade.php index 52f9f5bf..12d17f27 100755 --- a/src/WP_CLI/CommandWithUpgrade.php +++ b/src/WP_CLI/CommandWithUpgrade.php @@ -314,14 +314,23 @@ public function install( $args, $assoc_args ) { if ( true === $allow_activation && count( $extension ) > 0 ) { $this->chained_command = true; + $force = Utils\get_flag_value( $assoc_args, 'force', false ); if ( Utils\get_flag_value( $assoc_args, 'activate-network' ) ) { WP_CLI::log( "Network-activating '$slug'..." ); - $this->activate( array( $slug ), array( 'network' => true ) ); + $activate_args = array( 'network' => true ); + if ( $force ) { + $activate_args['force'] = true; + } + $this->activate( array( $slug ), $activate_args ); } if ( Utils\get_flag_value( $assoc_args, 'activate' ) ) { WP_CLI::log( "Activating '$slug'..." ); - $this->activate( array( $slug ) ); + $activate_args = array(); + if ( $force ) { + $activate_args['force'] = true; + } + $this->activate( array( $slug ), $activate_args ); } $this->chained_command = false; } From 22f703d3dc2e740842acfc896fd4fb4e168d055b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 4 Feb 2026 16:40:00 +0000 Subject: [PATCH 3/5] Add tests for --force flag with plugin activate and install Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- features/plugin-activate.feature | 44 +++++++++++++++++++++++++ features/plugin-install.feature | 56 ++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) diff --git a/features/plugin-activate.feature b/features/plugin-activate.feature index a479e801..6d0e250c 100644 --- a/features/plugin-activate.feature +++ b/features/plugin-activate.feature @@ -177,3 +177,47 @@ Feature: Activate WordPress plugins Debug (plugin): Unexpected output: Unexpected output from plugin activation """ And the return code should be 1 + + Scenario: Force activate an already active plugin to re-run activation hooks + Given a wp-content/plugins/force-test.php file: + """ + Date: Wed, 4 Feb 2026 16:42:43 +0000 Subject: [PATCH 4/5] Address code review feedback - improve documentation and add error suppression in tests Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- features/plugin-activate.feature | 2 +- features/plugin-install.feature | 2 +- src/Plugin_Command.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/features/plugin-activate.feature b/features/plugin-activate.feature index 6d0e250c..1ca93c0a 100644 --- a/features/plugin-activate.feature +++ b/features/plugin-activate.feature @@ -189,7 +189,7 @@ Feature: Activate WordPress plugins */ register_activation_hook( __FILE__, function() { - file_put_contents( WP_CONTENT_DIR . '/activation-test.txt', 'Activation hook was run' ); + @file_put_contents( WP_CONTENT_DIR . '/activation-test.txt', 'Activation hook was run' ); }); """ diff --git a/features/plugin-install.feature b/features/plugin-install.feature index 25c1caa8..6097d67d 100644 --- a/features/plugin-install.feature +++ b/features/plugin-install.feature @@ -319,7 +319,7 @@ Feature: Install WordPress plugins */ register_activation_hook( __FILE__, function() { - file_put_contents( WP_CONTENT_DIR . '/install-activation-test.txt', 'Activation hook was run' ); + @file_put_contents( WP_CONTENT_DIR . '/install-activation-test.txt', 'Activation hook was run' ); }); """ diff --git a/src/Plugin_Command.php b/src/Plugin_Command.php index 2d571d40..022e1bad 100644 --- a/src/Plugin_Command.php +++ b/src/Plugin_Command.php @@ -322,7 +322,7 @@ protected function get_all_items() { * : If set, the plugin will be activated for the entire multisite network. * * [--force] - * : If set, the plugin activation hooks will be run even if the plugin is already active. + * : If set, deactivates and reactivates the plugin to re-run activation hooks, even if already active. * * ## EXAMPLES * From 5b4b9e83568f8580c9549221612cc318d096dff5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 4 Feb 2026 19:26:14 +0000 Subject: [PATCH 5/5] Fix failing tests - correct expected output and use zip for install test Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- features/plugin-activate.feature | 8 ++++++-- features/plugin-install.feature | 11 +++++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/features/plugin-activate.feature b/features/plugin-activate.feature index 1ca93c0a..62326bbd 100644 --- a/features/plugin-activate.feature +++ b/features/plugin-activate.feature @@ -206,11 +206,15 @@ Feature: Activate WordPress plugins # Try activating without --force (should skip) When I try `wp plugin activate force-test` - Then STDERR should be: + Then STDERR should contain: """ Warning: Plugin 'force-test' is already active. - Error: No plugins activated. """ + And STDOUT should be: + """ + Success: Plugin already activated. + """ + And the return code should be 0 And the wp-content/activation-test.txt file should not exist # Now try with --force (should re-run activation hooks) diff --git a/features/plugin-install.feature b/features/plugin-install.feature index 6097d67d..2c9247d9 100644 --- a/features/plugin-install.feature +++ b/features/plugin-install.feature @@ -308,7 +308,7 @@ Feature: Install WordPress plugins Scenario: Force reinstall and activate an already active plugin to re-run activation hooks Given a WP install - And a wp-content/plugins/install-force-test.php file: + And a wp-content/plugins/install-force-test/install-force-test.php file: """