From 009b706ca019f02b91011021b3254646ea7a6a91 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 19 Mar 2026 18:18:49 +0000 Subject: [PATCH 1/6] Initial plan From 49e0e9a687c78dff2d568dd38c027b38f36da476 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 19 Mar 2026 18:22:33 +0000 Subject: [PATCH 2/6] Document guidelines for use of exit codes within commands Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- guides/commands-cookbook.md | 2 + references.md | 1 + references/documentation-standards.md | 35 +++++++++++ references/exit-codes.md | 83 +++++++++++++++++++++++++++ 4 files changed, 121 insertions(+) create mode 100644 references/exit-codes.md diff --git a/guides/commands-cookbook.md b/guides/commands-cookbook.md index 0d33e245..cb9c62c4 100644 --- a/guides/commands-cookbook.md +++ b/guides/commands-cookbook.md @@ -290,6 +290,8 @@ The longdesc is also displayed when calling the `help` command, for example, `wp * Hard-wrap option descriptions at **75 chars** after the colon and a space. * Hard-wrap everything else at **90 chars**. +If your command exits with non-default exit codes, document them in an `## EXIT STATUS` section placed between `## OPTIONS` and `## EXAMPLES`. See the [exit codes](https://make.wordpress.org/cli/handbook/references/exit-codes/) reference for guidelines and examples. + For more details on how you should format your command docs, please see WP-CLI's [documentation standards](https://make.wordpress.org/cli/handbook/documentation-standards/). #### Docblock tags diff --git a/references.md b/references.md index c101afde..5272f73b 100644 --- a/references.md +++ b/references.md @@ -5,6 +5,7 @@ * **[Built-in commands](https://developer.wordpress.org/cli/commands/)** - Commands included in every copy of WP-CLI. * **[Internal API](https://make.wordpress.org/cli/handbook/references/internal-api/)** - Stable utilities considered safe to use in community commands. * **[Documentation standards](https://make.wordpress.org/cli/handbook/references/documentation-standards/)** - Standards for annotating WP-CLI commands. +* **[Exit codes](https://make.wordpress.org/cli/handbook/references/exit-codes/)** - Guidelines for using and documenting exit codes in WP-CLI commands. * **[Hosting companies](https://make.wordpress.org/cli/handbook/references/hosting-companies/)** - List of hosting companies where WP-CLI is installed by default. * **[Shell friends](https://make.wordpress.org/cli/handbook/references/shell-friends/)** - Helpful shortcuts for bash and zsh. * **[Integrated tools](https://make.wordpress.org/cli/handbook/references/tools/)** - Plugins, wrappers, and other projects that integrate with WP-CLI in some form. diff --git a/references/documentation-standards.md b/references/documentation-standards.md index 3ef5d8ab..83c6d19d 100644 --- a/references/documentation-standards.md +++ b/references/documentation-standards.md @@ -110,6 +110,41 @@ Success: Switched to 'Twenty Sixteen' theme. * Roles, sidebar ID, post type key, taxonomy key must be wrapped with quotes. * Message in the context of ongoing action could end with `...`. Eg - `Downloading from https://github.com/wp-cli/wp-cli/releases/download/v0.23.1/wp-cli-0.23.1.phar...` +### Exit status annotation + +Commands that return non-default exit codes should document them in an `## EXIT STATUS` section. This makes scripting against your command predictable and allows the documentation to be generated automatically. + +``` +/** + * Checks if a given plugin is installed. + * + * ## OPTIONS + * + * + * : The plugin to check. + * + * ## EXIT STATUS + * + * Returns exit codes for the following conditions: + * + * * 0 - Plugin is installed. + * * 1 - Plugin is not installed. + * + * ## EXAMPLES + * + * # Check whether plugin is installed; exit status 0 if installed, otherwise 1 + * $ wp plugin is-installed hello + * $ echo $? + * 1 + */ +``` + +* The `## EXIT STATUS` section should appear after `## OPTIONS` and before `## EXAMPLES`. +* List each exit code as `* - .` +* Exit codes of `0` (success) and `1` (generic failure from `WP_CLI::error()`) are the default for all commands and do not need to be documented unless you want to make them explicit. + +For a complete reference of how exit codes work and when to use them, see the [exit codes](https://make.wordpress.org/cli/handbook/references/exit-codes/) reference. + ### Command parameter description If there is a set of allowed values for a command parameter, we have set special format (mostly similar to YAML) for default value and available options. diff --git a/references/exit-codes.md b/references/exit-codes.md new file mode 100644 index 00000000..7f7ac9b7 --- /dev/null +++ b/references/exit-codes.md @@ -0,0 +1,83 @@ +# Exit Codes + +WP-CLI follows widely-adopted Unix conventions for exit codes, where `0` signals success and any non-zero value signals failure. Scripts that call WP-CLI commands can inspect the exit code to determine whether to continue, retry, or abort. + +## Standard exit codes + +| Exit code | Meaning | +|:----------|:--------| +| `0` | Command completed successfully. The requested operation was performed as expected. | +| `1` | Command failed. WP-CLI could not perform the operation as expected (e.g. invalid arguments, WordPress not found, a fatal error was encountered). | + +`WP_CLI::error()` ([doc](https://make.wordpress.org/cli/handbook/references/internal-api/wp-cli-error/)) is the conventional way to report a failure and exit with code `1`. + +`WP_CLI::halt()` ([doc](https://make.wordpress.org/cli/handbook/references/internal-api/wp-cli-halt/)) can be used to exit with a specific non-zero code when the command needs to communicate a particular outcome to the calling script. + +## Using non-standard exit codes + +Some commands produce a meaningful binary result and communicate it through the exit code rather than output. For example: + +* `wp plugin is-installed ` exits with `0` if the plugin is installed, `1` if it is not. +* `wp theme is-installed ` follows the same pattern. +* `wp core is-installed` exits with `0` when WordPress is installed, `1` when it is not. + +Use a non-standard exit code when: + +1. The command result is binary (pass/fail, found/not-found) and is intended to be tested directly in a shell conditional. +2. The behavior deviates from the default `0`/`1` convention and the deviation is intentional and documented. + +Do **not** return non-zero exit codes for conditions that are informational rather than erroneous (e.g. a list command that finds no items is still a successful operation). + +## Annotating exit codes in PHPDoc + +Commands should document any non-default exit codes they produce using an `## EXIT STATUS` section in the command's longdesc. This allows the documentation to be generated automatically and gives script authors a reliable reference. + +``` +/** + * Checks if a given plugin is installed. + * + * ## OPTIONS + * + * + * : The plugin to check. + * + * ## EXIT STATUS + * + * Returns exit codes for the following conditions: + * + * * 0 - Plugin is installed. + * * 1 - Plugin is not installed. + * + * ## EXAMPLES + * + * # Check whether plugin is installed; exit status 0 if installed, otherwise 1 + * $ wp plugin is-installed hello + * $ echo $? + * 1 + */ +``` + +Exit codes of `0` (success) and `1` (generic failure via `WP_CLI::error()`) are the default for all commands and do not need to be documented in `## EXIT STATUS` unless you want to make them explicit. + +## Using exit codes in scripts + +Because WP-CLI uses standard exit codes, you can use WP-CLI commands directly in shell conditionals: + +```bash +# Check if a plugin is installed before trying to activate it +if wp plugin is-installed my-plugin; then + wp plugin activate my-plugin +else + echo "Plugin not installed" + exit 1 +fi +``` + +You can also inspect `$?` after any WP-CLI command to check whether it succeeded: + +```bash +wp core update +if [ "$?" -ne 0 ]; then + echo "Update failed" +fi +``` From 8288d81b6d2655c09207e269a6deb9d98458fa0c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 19 Mar 2026 22:45:00 +0000 Subject: [PATCH 3/6] Remove ## EXIT STATUS PHPDoc section references per review feedback Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- guides/commands-cookbook.md | 2 -- references/documentation-standards.md | 35 --------------------------- references/exit-codes.md | 31 ------------------------ 3 files changed, 68 deletions(-) diff --git a/guides/commands-cookbook.md b/guides/commands-cookbook.md index cb9c62c4..0d33e245 100644 --- a/guides/commands-cookbook.md +++ b/guides/commands-cookbook.md @@ -290,8 +290,6 @@ The longdesc is also displayed when calling the `help` command, for example, `wp * Hard-wrap option descriptions at **75 chars** after the colon and a space. * Hard-wrap everything else at **90 chars**. -If your command exits with non-default exit codes, document them in an `## EXIT STATUS` section placed between `## OPTIONS` and `## EXAMPLES`. See the [exit codes](https://make.wordpress.org/cli/handbook/references/exit-codes/) reference for guidelines and examples. - For more details on how you should format your command docs, please see WP-CLI's [documentation standards](https://make.wordpress.org/cli/handbook/documentation-standards/). #### Docblock tags diff --git a/references/documentation-standards.md b/references/documentation-standards.md index 83c6d19d..3ef5d8ab 100644 --- a/references/documentation-standards.md +++ b/references/documentation-standards.md @@ -110,41 +110,6 @@ Success: Switched to 'Twenty Sixteen' theme. * Roles, sidebar ID, post type key, taxonomy key must be wrapped with quotes. * Message in the context of ongoing action could end with `...`. Eg - `Downloading from https://github.com/wp-cli/wp-cli/releases/download/v0.23.1/wp-cli-0.23.1.phar...` -### Exit status annotation - -Commands that return non-default exit codes should document them in an `## EXIT STATUS` section. This makes scripting against your command predictable and allows the documentation to be generated automatically. - -``` -/** - * Checks if a given plugin is installed. - * - * ## OPTIONS - * - * - * : The plugin to check. - * - * ## EXIT STATUS - * - * Returns exit codes for the following conditions: - * - * * 0 - Plugin is installed. - * * 1 - Plugin is not installed. - * - * ## EXAMPLES - * - * # Check whether plugin is installed; exit status 0 if installed, otherwise 1 - * $ wp plugin is-installed hello - * $ echo $? - * 1 - */ -``` - -* The `## EXIT STATUS` section should appear after `## OPTIONS` and before `## EXAMPLES`. -* List each exit code as `* - .` -* Exit codes of `0` (success) and `1` (generic failure from `WP_CLI::error()`) are the default for all commands and do not need to be documented unless you want to make them explicit. - -For a complete reference of how exit codes work and when to use them, see the [exit codes](https://make.wordpress.org/cli/handbook/references/exit-codes/) reference. - ### Command parameter description If there is a set of allowed values for a command parameter, we have set special format (mostly similar to YAML) for default value and available options. diff --git a/references/exit-codes.md b/references/exit-codes.md index 7f7ac9b7..8ac1e9f6 100644 --- a/references/exit-codes.md +++ b/references/exit-codes.md @@ -28,37 +28,6 @@ Use a non-standard exit code when: Do **not** return non-zero exit codes for conditions that are informational rather than erroneous (e.g. a list command that finds no items is still a successful operation). -## Annotating exit codes in PHPDoc - -Commands should document any non-default exit codes they produce using an `## EXIT STATUS` section in the command's longdesc. This allows the documentation to be generated automatically and gives script authors a reliable reference. - -``` -/** - * Checks if a given plugin is installed. - * - * ## OPTIONS - * - * - * : The plugin to check. - * - * ## EXIT STATUS - * - * Returns exit codes for the following conditions: - * - * * 0 - Plugin is installed. - * * 1 - Plugin is not installed. - * - * ## EXAMPLES - * - * # Check whether plugin is installed; exit status 0 if installed, otherwise 1 - * $ wp plugin is-installed hello - * $ echo $? - * 1 - */ -``` - -Exit codes of `0` (success) and `1` (generic failure via `WP_CLI::error()`) are the default for all commands and do not need to be documented in `## EXIT STATUS` unless you want to make them explicit. - ## Using exit codes in scripts Because WP-CLI uses standard exit codes, you can use WP-CLI commands directly in shell conditionals: From 0f874a222f12f1c06070243f82be80acf8a65fb1 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Thu, 19 Mar 2026 23:53:30 +0100 Subject: [PATCH 4/6] Update references/exit-codes.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- references/exit-codes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/references/exit-codes.md b/references/exit-codes.md index 8ac1e9f6..3dc062a1 100644 --- a/references/exit-codes.md +++ b/references/exit-codes.md @@ -9,9 +9,9 @@ WP-CLI follows widely-adopted Unix conventions for exit codes, where `0` signals | `0` | Command completed successfully. The requested operation was performed as expected. | | `1` | Command failed. WP-CLI could not perform the operation as expected (e.g. invalid arguments, WordPress not found, a fatal error was encountered). | -`WP_CLI::error()` ([doc](https://make.wordpress.org/cli/handbook/references/internal-api/wp-cli-error/)) is the conventional way to report a failure and exit with code `1`. +`WP_CLI::error()` ([doc](https://make.wordpress.org/cli/handbook/internal-api/wp-cli-error/)) is the conventional way to report a failure and exit with code `1`. -`WP_CLI::halt()` ([doc](https://make.wordpress.org/cli/handbook/references/internal-api/wp-cli-halt/)) can be used to exit with a specific non-zero code when the command needs to communicate a particular outcome to the calling script. +`WP_CLI::halt()` ([doc](https://make.wordpress.org/cli/handbook/internal-api/wp-cli-halt/)) can be used to exit with a specific non-zero code when the command needs to communicate a particular outcome to the calling script. ## Using non-standard exit codes From 9e46e550e015b184c92aa796255d00bc6bbe32a2 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Thu, 19 Mar 2026 23:53:37 +0100 Subject: [PATCH 5/6] Update references/exit-codes.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- references/exit-codes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/references/exit-codes.md b/references/exit-codes.md index 3dc062a1..f7e0ba53 100644 --- a/references/exit-codes.md +++ b/references/exit-codes.md @@ -1,6 +1,6 @@ # Exit Codes -WP-CLI follows widely-adopted Unix conventions for exit codes, where `0` signals success and any non-zero value signals failure. Scripts that call WP-CLI commands can inspect the exit code to determine whether to continue, retry, or abort. +WP-CLI follows widely-adopted Unix conventions for exit codes: `0` signals success (the command’s primary condition was satisfied), while non-zero values signal that the primary condition was not satisfied. This can represent either an operational error (the command could not perform the requested operation) or an expected negative result that calling scripts are intended to test for (for example, “not installed”). Scripts that call WP-CLI commands can inspect the exit code to determine whether to continue, retry, or abort. ## Standard exit codes From d54e689673927c4bfb9bb69bb7a951f94658d831 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 19 Mar 2026 22:54:49 +0000 Subject: [PATCH 6/6] Rename 'Using non-standard exit codes' section for clarity Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- references/exit-codes.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/references/exit-codes.md b/references/exit-codes.md index f7e0ba53..8ca8e9c3 100644 --- a/references/exit-codes.md +++ b/references/exit-codes.md @@ -13,20 +13,20 @@ WP-CLI follows widely-adopted Unix conventions for exit codes: `0` signals succe `WP_CLI::halt()` ([doc](https://make.wordpress.org/cli/handbook/internal-api/wp-cli-halt/)) can be used to exit with a specific non-zero code when the command needs to communicate a particular outcome to the calling script. -## Using non-standard exit codes +## Exit codes for boolean-result commands -Some commands produce a meaningful binary result and communicate it through the exit code rather than output. For example: +Some commands are designed to communicate a binary result directly through the exit code rather than through output. These commands still use the standard `0`/`1` codes, but `1` means "condition not met" rather than "operational error". For example: * `wp plugin is-installed ` exits with `0` if the plugin is installed, `1` if it is not. * `wp theme is-installed ` follows the same pattern. * `wp core is-installed` exits with `0` when WordPress is installed, `1` when it is not. -Use a non-standard exit code when: +Use exit code `1` to signal "condition not met" (rather than an error) when: 1. The command result is binary (pass/fail, found/not-found) and is intended to be tested directly in a shell conditional. -2. The behavior deviates from the default `0`/`1` convention and the deviation is intentional and documented. +2. The intent is explicitly documented so script authors know the exit code carries a result meaning, not an error meaning. -Do **not** return non-zero exit codes for conditions that are informational rather than erroneous (e.g. a list command that finds no items is still a successful operation). +Do **not** return a non-zero exit code for conditions that are informational rather than a definitive result (e.g. a list command that finds no items is still a successful operation — it returned an empty list). ## Using exit codes in scripts