Skip to content

Commit 90aa6bc

Browse files
committed
Merge branch 'main' into copilot/support-restarting-shell
2 parents 58d4632 + de92dc6 commit 90aa6bc

4 files changed

Lines changed: 94 additions & 1 deletion

File tree

.github/workflows/code-quality.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ on:
66
branches:
77
- main
88
- master
9+
schedule:
10+
- cron: '17 2 * * *' # Run every day on a seemly random time.
911

1012
jobs:
1113
code-quality:

README.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Quick links: [Using](#using) | [Installing](#installing) | [Contributing](#contr
1010
## Using
1111

1212
~~~
13-
wp shell [--basic]
13+
wp shell [--basic] [--hook=<hook>]
1414
~~~
1515

1616
`wp shell` allows you to evaluate PHP statements and expressions
@@ -25,13 +25,24 @@ that you can use within a WordPress plugin, for example.
2525
Force the use of WP-CLI's built-in PHP REPL, even if the Boris or
2626
PsySH PHP REPLs are available.
2727

28+
[--hook=<hook>]
29+
Ensure that a specific WordPress action hook has fired before starting the shell.
30+
This validates that the preconditions associated with that hook are met.
31+
Only hooks that have already been triggered can be used (e.g., init, plugins_loaded, wp_loaded).
32+
---
33+
default: ''
34+
---
35+
2836
**EXAMPLES**
2937

3038
# Call get_bloginfo() to get the name of the site.
3139
$ wp shell
3240
wp> get_bloginfo( 'name' );
3341
=> string(6) "WP-CLI"
3442

43+
# Start a shell, ensuring the 'init' hook has already fired.
44+
$ wp shell --hook=init
45+
3546
## Installing
3647

3748
This package is included with WP-CLI itself, no additional installation necessary.

features/shell.feature

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,39 @@ Feature: WordPress REPL
114114
"""
115115
history: -1: invalid option
116116
"""
117+
118+
Scenario: Shell with hook parameter
119+
Given a WP install
120+
And a session file:
121+
"""
122+
did_action('init');
123+
"""
124+
125+
When I run `wp shell --basic --hook=init < session`
126+
Then STDOUT should contain:
127+
"""
128+
int(1)
129+
"""
130+
131+
Scenario: Shell with hook parameter using plugins_loaded hook
132+
Given a WP install
133+
And a session file:
134+
"""
135+
did_action('plugins_loaded');
136+
"""
137+
138+
When I run `wp shell --basic --hook=plugins_loaded < session`
139+
Then STDOUT should contain:
140+
"""
141+
int(1)
142+
"""
143+
144+
Scenario: Shell with hook parameter for hook that hasn't fired
145+
Given a WP install
146+
147+
When I try `wp shell --basic --hook=shutdown < /dev/null`
148+
Then STDERR should contain:
149+
"""
150+
Error: The 'shutdown' hook has not fired yet
151+
"""
152+
And the return code should be 1

src/Shell_Command.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ class Shell_Command extends WP_CLI_Command {
2828
* : Watch a file or directory for changes and automatically restart the shell.
2929
* Only works with the built-in REPL (--basic).
3030
*
31+
* [--hook=<hook>]
32+
* : Ensure that a specific WordPress action hook has fired before starting the shell.
33+
* This validates that the preconditions associated with that hook are met.
34+
* Only hooks that have already been triggered can be used (e.g., init, plugins_loaded, wp_loaded).
35+
* ---
36+
* default: ''
37+
* ---
38+
*
3139
* ## EXAMPLES
3240
*
3341
* # Call get_bloginfo() to get the name of the site.
@@ -47,8 +55,12 @@ class Shell_Command extends WP_CLI_Command {
4755
* Detected changes in wp-content/plugins/my-plugin, restarting shell...
4856
* wp>
4957
*
58+
* # Start a shell, ensuring the 'init' hook has already fired.
59+
* $ wp shell --hook=init
60+
*
5061
* @param string[] $_ Positional arguments. Unused.
5162
* @param array{basic?: bool, watch?: string} $assoc_args Associative arguments.
63+
5264
*/
5365
public function __invoke( $_, $assoc_args ) {
5466
$watch_path = Utils\get_flag_value( $assoc_args, 'watch', false );
@@ -58,6 +70,38 @@ public function __invoke( $_, $assoc_args ) {
5870
$assoc_args['basic'] = true;
5971
}
6072

73+
$hook = Utils\get_flag_value( $assoc_args, 'hook', '' );
74+
75+
// No hook specified, start immediately.
76+
if ( ! $hook ) {
77+
$this->start_shell( $assoc_args );
78+
return;
79+
}
80+
81+
// Check if the hook has already fired.
82+
if ( did_action( $hook ) ) {
83+
// Hook already fired, start the shell immediately.
84+
$this->start_shell( $assoc_args );
85+
return;
86+
}
87+
88+
// Hook hasn't fired yet.
89+
WP_CLI::error(
90+
sprintf(
91+
"The '%s' hook has not fired yet. " .
92+
'The shell command runs after WordPress is loaded, so only hooks that have already been triggered can be used. ' .
93+
'Common hooks that are available include: init, plugins_loaded, wp_loaded.',
94+
$hook
95+
)
96+
);
97+
}
98+
99+
/**
100+
* Start the shell REPL.
101+
*
102+
* @param array<string,bool|string> $assoc_args Associative arguments.
103+
*/
104+
private function start_shell( $assoc_args ) {
61105
$class = WP_CLI\Shell\REPL::class;
62106

63107
$implementations = array(

0 commit comments

Comments
 (0)