From 6470794a66ec5c7e483a16d36fbbb6de3ac8c89e Mon Sep 17 00:00:00 2001 From: Alain Schlesser Date: Fri, 30 Oct 2026 21:14:12 +0100 Subject: [PATCH] Declare and check the commands that scenarios need Scenarios can declare commands they run that are not always installed with @require-bin- tags. Where a command is not available, its scenarios are left out and reported like other unmet requirements, instead of failing halfway through. The existing @require-composer, @require-download and @require-opcache-save-comments tags never filtered anything and are checked now. Unknown requirement tags are reported, as they would not filter anything either. When a command fails because a command it runs does not exist, the failure names the tag to add, and the Gherkin linting lists scenarios that run commands which are not always installed without declaring them. Co-Authored-By: Claude Opus 5.5 --- .readme-partials/USING.md | 12 +++ bin/run-gherkin-lint-tests | 25 +++-- phpcs.xml.dist | 2 + src/Context/Support.php | 25 +++++ src/Context/ThenStepDefinitions.php | 2 +- src/Context/WhenStepDefinitions.php | 2 + tests/tests/TestBehatTags.php | 25 +++++ tests/tests/TestMissingCommandHint.php | 56 +++++++++++ utils/behat-tags.php | 99 ++++++++++++++++++ utils/check-required-tools.php | 133 +++++++++++++++++++++++++ 10 files changed, 370 insertions(+), 11 deletions(-) create mode 100644 tests/tests/TestMissingCommandHint.php create mode 100644 utils/check-required-tools.php diff --git a/.readme-partials/USING.md b/.readme-partials/USING.md index e67173e91..8822f875e 100644 --- a/.readme-partials/USING.md +++ b/.readme-partials/USING.md @@ -350,6 +350,18 @@ they test. skipped when there is none, which is the case when the database server runs in a container and is only reachable over TCP. Set `WP_CLI_TEST_DBSOCKET` to point at the socket if it lives somewhere unusual. +* `@require-bin-` — the scenario runs a command that is not always installed, such as + `@require-bin-svn` or `@require-bin-ex` for one using `ex` as its editor. It is skipped + where the command is not available. `@require-composer` does the same for Composer. +* `@require-extension-` — the scenario needs a PHP extension, such as + `@require-extension-imagick`. It is skipped where the extension is not loaded. +* `@require-download` — the scenario downloads files from WordPress.org. It is skipped where + WordPress.org cannot be reached. + +Requirement tags the test framework does not know are reported with a warning, as they would +not filter anything. When a command fails because a command it runs does not exist, the +failure names the tag to add, and `composer lint-gherkin` lists the scenarios that run +commands which are not always installed without declaring them. Before the scenarios run, the scenarios that are left out are listed together with the reason, separating the ones the environment cannot run, such as those needing a PHP extension that is diff --git a/bin/run-gherkin-lint-tests b/bin/run-gherkin-lint-tests index aa8339695..3a648e0ca 100755 --- a/bin/run-gherkin-lint-tests +++ b/bin/run-gherkin-lint-tests @@ -6,16 +6,6 @@ then exit 0; fi -# The linter is a Node package, which a PHP project cannot assume is present. -# Skip rather than fail, the same way the Behat runner skips a package without a -# behat.yml. The check still runs in CI, where Node is always available. -if ! command -v npx > /dev/null 2>&1 -then - echo 'Did not detect the "npx" command, skipping the Gherkin linting.' - echo "It is part of Node.js 20 or later, see https://nodejs.org/ for installation instructions." - exit 0; -fi - # To retrieve the WP-CLI tests package root folder, we start with this scripts # location. SOURCE="$0" @@ -61,6 +51,21 @@ then set -- features fi +# Flag scenarios that run tools which are not always installed without declaring them. +# This only reports, so that existing feature files can be tagged over time. +php "${WP_CLI_TESTS_ROOT}/utils/check-required-tools.php" "$@" + +# The linter is a Node package, which a PHP project cannot assume is present. +# Skip rather than fail, the same way the Behat runner skips a package without a +# behat.yml. The check still runs in CI, where Node is always available. +if ! command -v npx > /dev/null 2>&1 +then + echo 'Did not detect the "npx" command, skipping the Gherkin linting.' + echo "It is part of Node.js 20 or later, see https://nodejs.org/ for installation instructions." + exit 0; +fi + + run_linter() { npx --yes "gherkin-lint-plus@${GHERKIN_LINT_VERSION}" --config "${CONFIG_FILE}" "$@" } diff --git a/phpcs.xml.dist b/phpcs.xml.dist index cad054193..74b4ade1e 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -79,9 +79,11 @@ so this file does not have to comply with WP naming conventions. --> */utils/behat-tags\.php$ + */utils/check-required-tools\.php$ */utils/behat-tags\.php$ + */utils/check-required-tools\.php$