From 61c5e1f0b8fd0900328c6b85c641e3384985fa15 Mon Sep 17 00:00:00 2001
From: Christopher Allford <6451942+ObliviousHarmony@users.noreply.github.com>
Date: Mon, 23 May 2022 15:50:57 -0700
Subject: [PATCH] Env: Fixed `run` Argument Passing (#41179)
* Fixed `run` Argument Passing
By enabling the `unknown-options-as-args` parser
option, any options passed to the command that
are not registered will be given to the command
as arguments. This lets us pass them to the
container without quoting them.
Note: --help and --version can't be passed since they
aren't unknown. This is probably fine though and we
can handle that using quotes when necessary.
* Documented Quotes Behavior
Since we no longer require the quotes, this
commit updates the documentation to
explain what cases they are required to
be used. This will keep it from being a
surprise if a command does not behave as
expected.
* Added Changelog Entry
---
packages/env/CHANGELOG.md | 2 ++
packages/env/README.md | 24 +++++++++++-------------
packages/env/lib/cli.js | 7 ++++++-
packages/env/test/cli.js | 16 ++++++++++++++++
4 files changed, 35 insertions(+), 14 deletions(-)
diff --git a/packages/env/CHANGELOG.md b/packages/env/CHANGELOG.md
index 998c788851a3e0..281d7261f04c4f 100644
--- a/packages/env/CHANGELOG.md
+++ b/packages/env/CHANGELOG.md
@@ -1,6 +1,8 @@
## Unreleased
+### Enhancement
+- Removed the need for quotation marks when passing options to `wp-env run`.
## 4.7.0 (2022-05-18)
diff --git a/packages/env/README.md b/packages/env/README.md
index 5a9e7302d6a2f8..25836f74aa6916 100644
--- a/packages/env/README.md
+++ b/packages/env/README.md
@@ -300,21 +300,23 @@ Positionals:
The run command can be used to open shell sessions or invoke WP-CLI commands.
-To run a WP-CLI command that includes optional arguments, enclose the WP-CLI command in quotation marks; otherwise, the optional arguments are ignored. This is because flags are normally passed to `wp-env` itself, meaning that the flags are not considered part of the argument that specifies the WP-CLI command. With quotation marks, `wp-env` considers everything inside quotation marks the WP-CLI command argument.
+In some cases, `wp-env` may consume options that you are attempting to pass to
+the container. This happens with options that `wp-env` has already declared,
+such as `--debug`, `--help`, and `--version`. When this happens, you should fall
+back to using quotation marks; `wp-env` considers everything inside the
+quotation marks to be command argument.
-For example, to list cron schedules with optional arguments that specify the fields returned and the format of the output:
+For example, to ask `WP-CLI` for its help text:
```sh
-wp-env run cli "wp cron schedule list --fields=name --format=csv"
+wp-env run cli "wp --help"
```
-Without the quotation marks, WP-CLI lists the schedule in its default format, ignoring the `fields` and `format` arguments.
+Without the quotation marks, `wp-env` will print its own help text instead of
+passing it to the container. If you experience any problems where the command
+is not being passed correctly, fall back to using quotation marks.
-Note that quotation marks are not required for a WP-CLI command that excludes optional arguments, although it does not hurt to include them. For example, the following command syntaxes return identical results: `wp-env run cli "wp cron schedule list"` or `wp-env run cli wp cron schedule list`.
-
-For more information about all the available commands, see [WP-CLI Commands](https://developer.wordpress.org/cli/commands/).
-
```sh
wp-env run [command..]
@@ -323,11 +325,7 @@ Runs an arbitrary command in one of the underlying Docker containers. The
"development", "tests", or "cli". To run a wp-cli command, use the "cli" or
"tests-cli" service. You can also use this command to open shell sessions like
bash and the WordPress shell in the WordPress instance. For example, `wp-env run
-cli bash` will open bash in the development WordPress instance. When using long
-commands with arguments and quotation marks, you need to wrap the "command"
-param in quotation marks. For example: `wp-env run tests-cli "wp post create
---post_type=page --post_title='Test'"` will create a post on the tests WordPress
-instance.
+cli bash` will open bash in the development WordPress instance.
Positionals:
container The container to run the command on. [string] [required]
diff --git a/packages/env/lib/cli.js b/packages/env/lib/cli.js
index 37b260838c7c99..3ff31e85d5f452 100644
--- a/packages/env/lib/cli.js
+++ b/packages/env/lib/cli.js
@@ -92,6 +92,10 @@ module.exports = function cli() {
default: false,
} );
+ // Make sure any unknown arguments are passed to the command as arguments.
+ // This allows options to be passed to "run" without being quoted.
+ yargs.parserConfiguration( { 'unknown-options-as-args': true } );
+
yargs.command(
'start',
wpGreen(
@@ -171,7 +175,7 @@ module.exports = function cli() {
describe: 'The container to run the command on.',
} );
args.positional( 'command', {
- type: 'string',
+ type: 'array',
describe: 'The command to run.',
} );
},
@@ -189,6 +193,7 @@ module.exports = function cli() {
'$0 run tests-cli bash',
'Open a bash session in the WordPress tests instance.'
);
+
yargs.command(
'destroy',
wpRed(
diff --git a/packages/env/test/cli.js b/packages/env/test/cli.js
index 207323ab02bd57..9319750518095f 100644
--- a/packages/env/test/cli.js
+++ b/packages/env/test/cli.js
@@ -18,6 +18,7 @@ jest.mock( '../lib/env', () => ( {
start: jest.fn( Promise.resolve.bind( Promise ) ),
stop: jest.fn( Promise.resolve.bind( Promise ) ),
clean: jest.fn( Promise.resolve.bind( Promise ) ),
+ run: jest.fn( Promise.resolve.bind( Promise ) ),
ValidationError: jest.requireActual( '../lib/env' ).ValidationError,
} ) );
@@ -61,6 +62,21 @@ describe( 'env cli', () => {
expect( spinner.text ).toBe( '' );
} );
+ it( 'parses run commands without arguments.', () => {
+ cli().parse( [ 'run', 'tests-wordpress', 'test' ] );
+ const { container, command, spinner } = env.run.mock.calls[ 0 ][ 0 ];
+ expect( container ).toBe( 'tests-wordpress' );
+ expect( command ).toStrictEqual( [ 'test' ] );
+ expect( spinner.text ).toBe( '' );
+ } );
+ it( 'parses run commands with variadic arguments.', () => {
+ cli().parse( [ 'run', 'tests-wordpress', 'test', 'test1', '--test2' ] );
+ const { container, command, spinner } = env.run.mock.calls[ 0 ][ 0 ];
+ expect( container ).toBe( 'tests-wordpress' );
+ expect( command ).toStrictEqual( [ 'test', 'test1', '--test2' ] );
+ expect( spinner.text ).toBe( '' );
+ } );
+
it( 'handles successful commands with messages.', async () => {
env.start.mockResolvedValueOnce( 'success message' );
cli().parse( [ 'start' ] );