fix(cli): implement routes --filter and --format - #3613
Merged
Merged
Conversation
Both flags were advertised in the wrapper's help text for as long as the command has existed: Usage: wheels routes [--filter=<pattern>] [--format=<text|json>] and neither was ever read. routes() took no arguments at all — it fetched every route and printed the table unconditionally. Found rehearsing `wheels routes --filter=posts` as a before/after for the scaffold beat: it returned all 57 routes, which on stage reads as a bug. routes() now parses an ArgSpec (the same builder registered in mcpToolSpecs, so the CLI surface and the MCP advertisement cannot drift — this is the migration the mcpToolSpecs comment listed routes as still needing). --filter: case-insensitive substring over name, pattern and controller#action — the three fields the help names. Substring, not regex: `[key]` in a pattern must match literally, and a presenter should not have to think about escaping. A no-match prints "No routes match '<text>'." instead of the misleading "No routes configured." --format=json: emits the filtered array and nothing else on stdout, with lower-case quoted keys. A CFML struct serializes its keys UPPER-CASE, so `jq .pattern` on the raw shape silently yields null. On a fresh app scaffolded with Post: 41 routes before, 57 after, `--filter=posts` shows exactly the 16 that changed. CLI suite: 1377 pass, 0 fail, 0 error. The four DbCommandSpec failures carried as "pre-existing" all day were an artefact of a server always occupying 8080 during my runs — they expect Wheels.ServerNotRunning. On a clean port they pass. Signed-off-by: Peter Amiri <peter@alurium.com>
The presenter added a routes call before the Post scaffold to show the
delta. The card now frames both ends: 41 framework routes before (name
them, or the audience reads noise), and --filter=posts after so exactly
the 16 new routes are on the projector rather than 57 lines to hunt
through. Points at the one .resources("posts") line that produced them.
Signed-off-by: Peter Amiri <peter@alurium.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Both flags were advertised in the command's help for as long as it has existed:
and neither was ever read.
routes()took no arguments — it fetched every route and printed the table unconditionally. Found rehearsingwheels routes --filter=postsas a before/after for the scaffold beat: it returned all 57 routes, which on stage reads as a bug in front of the audience.What works now
routes()parses an ArgSpec — the same builder now registered inmcpToolSpecs(), so the CLI surface and the MCP advertisement can't drift. This is the migration themcpToolSpecscomment listedroutesas still needing; an assistant can now callroutes(filter="posts").--filter— case-insensitive substring over name, pattern andcontroller#action(the three fields the help names). Substring, not regex:[key]in a pattern must match literally, and a presenter shouldn't have to think about escaping. No match printsNo routes match 'x'.rather than the misleadingNo routes configured.--format=json— the filtered array and nothing else on stdout, with lower-case quoted keys. A CFML struct serializes keys UPPER-CASE, sojq .patternon the raw shape silently yieldsnull.The demo moment it enables
/wheels/…tooling, plus/up, wildcards,/scaffold Post--filter=postsSixteen routes from one
.resources("posts")line. The runbook card now frames both ends.Tests
7 specs on the pure
$filterRoutes()(case, name/pattern/controller matching, literal brackets, empty, no mutation), 2 on the ArgSpec defaults, 1 asserting the MCP schema advertises both params.CLI suite: 1377 pass, 0 fail, 0 error.
Worth noting: the four
DbCommandSpecfailures carried as "pre-existing baseline" all day were an artefact of a server always occupying 8080 during my runs — they expectWheels.ServerNotRunning. Run on a clean port, they pass. The baseline was never actually red.