diff --git a/features/shell.feature b/features/shell.feature index d5595506..6cf104ce 100644 --- a/features/shell.feature +++ b/features/shell.feature @@ -77,3 +77,39 @@ Feature: WordPress REPL """ history: -1: invalid option """ + + Scenario: Shell with hook parameter + Given a WP install + And a session file: + """ + did_action('init'); + """ + + When I run `wp shell --basic --hook=init < session` + Then STDOUT should contain: + """ + int(1) + """ + + Scenario: Shell with hook parameter using plugins_loaded hook + Given a WP install + And a session file: + """ + did_action('plugins_loaded'); + """ + + When I run `wp shell --basic --hook=plugins_loaded < session` + Then STDOUT should contain: + """ + int(1) + """ + + Scenario: Shell with hook parameter for hook that hasn't fired + Given a WP install + + When I try `wp shell --basic --hook=shutdown < /dev/null` + Then STDERR should contain: + """ + Error: The 'shutdown' hook has not fired yet + """ + And the return code should be 1 diff --git a/src/Shell_Command.php b/src/Shell_Command.php index edd2c611..7c89a7b2 100644 --- a/src/Shell_Command.php +++ b/src/Shell_Command.php @@ -19,14 +19,57 @@ class Shell_Command extends WP_CLI_Command { * : Force the use of WP-CLI's built-in PHP REPL, even if the Boris or * PsySH PHP REPLs are available. * + * [--hook=] + * : Ensure that a specific WordPress action hook has fired before starting the shell. + * This validates that the preconditions associated with that hook are met. + * Only hooks that have already been triggered can be used (e.g., init, plugins_loaded, wp_loaded). + * --- + * default: '' + * --- + * * ## EXAMPLES * * # Call get_bloginfo() to get the name of the site. * $ wp shell * wp> get_bloginfo( 'name' ); * => string(6) "WP-CLI" + * + * # Start a shell, ensuring the 'init' hook has already fired. + * $ wp shell --hook=init */ public function __invoke( $_, $assoc_args ) { + $hook = Utils\get_flag_value( $assoc_args, 'hook', '' ); + + // No hook specified, start immediately. + if ( ! $hook ) { + $this->start_shell( $assoc_args ); + return; + } + + // Check if the hook has already fired. + if ( did_action( $hook ) ) { + // Hook already fired, start the shell immediately. + $this->start_shell( $assoc_args ); + return; + } + + // Hook hasn't fired yet. + WP_CLI::error( + sprintf( + "The '%s' hook has not fired yet. " . + 'The shell command runs after WordPress is loaded, so only hooks that have already been triggered can be used. ' . + 'Common hooks that are available include: init, plugins_loaded, wp_loaded.', + $hook + ) + ); + } + + /** + * Start the shell REPL. + * + * @param array $assoc_args Associative arguments. + */ + private function start_shell( $assoc_args ) { $class = WP_CLI\Shell\REPL::class; $implementations = array(