Make the PHP built-in web server step work without server-command - #363
Conversation
`start_php_server()` always passed `{RUN_DIR}/vendor/wp-cli/server-command/router.php`
as the router script, but no built-in step puts wp-cli/server-command into
the run directory (`Given a WP installation with Composer` only requires
WordPress core). PHP then fails every request with a fatal error while
trying to open the router, and with `display_errors=On` that error page is
even served with a 200 status, so a scenario serving static files gets an
error page instead of its fixture and a missing file never yields a 404.
Only pass the router when it actually exists, looking in the run directory
first and then in the vendor directory of the project under test. Without a
router, PHP's built-in web server serves the directory as-is, which is what
a plain directory of files needs.
The `Then the HTTP status code should be` step relied on the Requests v1
class, which WP-CLI no longer autoloads, so it failed with a fatal error
before the request was made. Use whichever Requests version WP-CLI ships.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019g8sd6U4w59qiQW7LTt1jG
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (3)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthroughThe PHP built-in server step now supports plain directories without a router package. Router discovery is conditional. HTTP status checks load the bundled Requests library dynamically. A Behat scenario verifies a plain directory returns status 200. ChangesPHP server support
Priority: ⬇️ Low Estimated code review effort: 2 (Simple) | ~10 minutes Change: Bug fix Suggested reviewers: Merge Risk: ⚪ Minimal · up to The PHP server steps retain router-backed behavior while supporting static directories without the optional router package. No actionable merge-blocking risk remains. 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
|
On the red Generated by Claude Code |
There was a problem hiding this comment.
🟡 Changes recommended
Two moderate issues remain regarding custom vendor directories and insufficient server-response coverage.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
This PR fixes PHP built-in server routing and HTTP status checks for WP-CLI 3 compatibility.
Changes:
- Conditionally discovers available router scripts.
- Uses
RequestsLibraryfor HTTP requests. - Adds plain-directory server coverage.
File summaries
| File | Summary | Final review note |
|---|---|---|
src/Context/ThenStepDefinitions.php |
Uses the supported Requests abstraction. | No unresolved finding. |
src/Context/FeatureContext.php |
Resolves optional PHP server routers. | Moderate: Hard-coded /vendor misses custom Composer vendor directories (2 votes). |
features/behat-steps.feature |
Adds plain-directory server coverage. | Moderate: The assertion can pass on PHP’s fatal-error page; verify the response body or a 404 (3 votes). |
Review details
- Files reviewed: 3/3 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Look up the server-command router in the vendor directory configured in the run directory's composer.json, so that a WP installation with a custom vendor directory is covered as well. Extend the scenarios to check the response body and a real 404, so that they fail against the old behavior of serving PHP's fatal-error page with a 200 status. PHP's built-in web server falls back to index.html for unknown paths when it exists, so the 404 case lives in its own scenario without an index file. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019g8sd6U4w59qiQW7LTt1jG
PHPStan flags `$argv` as possibly undefined in the PHP blocks of feature files, so read the argument from `$_SERVER['argv']` instead. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019g8sd6U4w59qiQW7LTt1jG
PHP 8.5 deprecates the `$http_response_header` variable, and the deprecation notice on STDERR fails the `I run` step. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019g8sd6U4w59qiQW7LTt1jG
wp-cli/wp-cli-tests v5.3.2 makes `a PHP built-in web server` work in a plain directory (wp-cli/wp-cli-tests#363), so the manual `php -S` launch is no longer needed. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019g8sd6U4w59qiQW7LTt1jG
Problem
Given a PHP built-in web server(and theto serve :subdirvariant) always passes{RUN_DIR}/vendor/wp-cli/server-command/router.phpas the router script tophp -S. No built-in step ever puts wp-cli/server-command into the run directory:Given a WP installation with Composeronly requires WordPress core. PHP therefore fails every request with a fatal error while trying to open the router, and because CI runs withdisplay_errors=On, that error page is served with a 200 status.This surfaced in wp-cli/package-command#250: scenarios that serve a ZIP fixture from an empty directory received the PHP error page instead of the file ("Not a zip archive"), and a request for a missing file never produced a 404. The only in-tree consumer of the step, in wp-cli/wp-cli's
bootstrap.feature, is tagged@broken, likely for the same reason.Separately,
Then the HTTP status code should be :codestill called the Requests v1Requestsclass, which WP-CLI 3 no longer autoloads, so the step died withClass "Requests" not foundbefore making the request.Changes
start_php_server()only passes a router when one exists. It checks the run directory's Composer vendor directory first (honoring a customvendor-dirin its composer.json), then the vendor directory of the project under test. Without a router, PHP's built-in web server serves the directory as-is, which is what a plain directory of static files needs.then_the_http_status_code_should_be()usesRequestsLibraryso it works with whichever Requests version WP-CLI ships.behat-steps.feature: one serves a plain directory and asserts the status and the served body, the other asserts a real 404 for a missing file. Both fail against the old behavior of serving PHP's fatal-error page with a 200.Testing
composer phpstan(including the PHP blocks in feature files),composer phpcsand gherkin-lint pass.Utils\make_temp_file()/Utils\make_temp_dir()for package ZIP install temp paths package-command#250 pass using the originalAnd a PHP built-in web serverstep, including the 404 case.🤖 Generated with Claude Code
https://claude.ai/code/session_019g8sd6U4w59qiQW7LTt1jG