diff --git a/features/shell.feature b/features/shell.feature index dfb63c44..a60c17d3 100644 --- a/features/shell.feature +++ b/features/shell.feature @@ -3,8 +3,12 @@ Feature: WordPress REPL Scenario: Blank session Given a WP install - When I run `wp shell < /dev/null` - And I run `wp shell --basic < /dev/null` + And an empty_session file: + """ + """ + + When I run `wp shell < empty_session` + And I run `wp shell --basic < empty_session` Then STDOUT should be empty Scenario: Persistent environment @@ -252,7 +256,11 @@ Feature: WordPress REPL 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` + And an empty_session file: + """ + """ + + When I try `wp shell --basic --hook=shutdown < empty_session` Then STDERR should contain: """ Error: The 'shutdown' hook has not fired yet diff --git a/src/WP_CLI/Shell/REPL.php b/src/WP_CLI/Shell/REPL.php index 5dcff93b..69bf04b5 100644 --- a/src/WP_CLI/Shell/REPL.php +++ b/src/WP_CLI/Shell/REPL.php @@ -176,10 +176,12 @@ private function prompt() { } private static function create_prompt_cmd( $prompt, $history_path ) { - $prompt = escapeshellarg( $prompt ); - $history_path = escapeshellarg( $history_path ); + $is_windows = \WP_CLI\Utils\is_windows(); + if ( getenv( 'WP_CLI_CUSTOM_SHELL' ) ) { $shell_binary = (string) getenv( 'WP_CLI_CUSTOM_SHELL' ); + } elseif ( $is_windows ) { + $shell_binary = 'powershell.exe'; } elseif ( is_file( '/bin/bash' ) && is_readable( '/bin/bash' ) ) { // Prefer /bin/bash when available since we use bash-specific commands. $shell_binary = '/bin/bash'; @@ -191,10 +193,24 @@ private static function create_prompt_cmd( $prompt, $history_path ) { $shell_binary = 'bash'; } + $is_powershell = $is_windows && 'powershell.exe' === $shell_binary; + + if ( $is_powershell ) { + // PowerShell uses ` (backtick) for escaping but for strings single quotes are literal. + // If prompt contains single quotes, we double them in PowerShell. + $prompt_for_ps = str_replace( "'", "''", $prompt ); + $history_path_for_ps = str_replace( "'", "''", $history_path ); + $cmd = "\$line = Read-Host -Prompt '{$prompt_for_ps}'; if ( \$line ) { Add-Content -Path '{$history_path_for_ps}' -Value \$line; } Write-Output \$line;"; + return "powershell.exe -Command \"{$cmd}\""; + } + if ( ! is_file( $shell_binary ) || ! is_readable( $shell_binary ) ) { WP_CLI::error( "The shell binary '{$shell_binary}' is not valid. You can override the shell to be used through the WP_CLI_CUSTOM_SHELL environment variable." ); } + $prompt = escapeshellarg( $prompt ); + $history_path = escapeshellarg( $history_path ); + $is_ksh = self::is_ksh_shell( $shell_binary ); $shell_binary = escapeshellarg( $shell_binary );