Skip to content

Remove the dead format keyword from Grape::Router::Pattern#2782

Merged
dblock merged 1 commit into
masterfrom
remove_pattern_format
Jul 5, 2026
Merged

Remove the dead format keyword from Grape::Router::Pattern#2782
dblock merged 1 commit into
masterfrom
remove_pattern_format

Conversation

@ericproulx

Copy link
Copy Markdown
Contributor

Grape::Router::Pattern#initialize took a format: keyword and used it in extract_capture to constrain the mustermann :format capture. It was dead:

  • Nothing passed a non-nil value. The endpoint stopped passing format: when the vestigial Grape::Endpoint::Options format member was removed (Promote route metadata to Route keyword arguments #2779), and grape-swagger's test helper passes format: nil. So format.present? was never true and capture[:format] = … never ran.
  • It was redundant. A route's :format capture comes from the path suffix that Grape::Path builds — (.json) for a specific format, (.:format) otherwise — not from the pattern.

This drops the keyword and the dead branch. DEFAULT_CAPTURES still lists format (that path-derived capture) and map_str still serves version, so matching is unchanged — format :json still yields /x(.json), plain /x(.:format).

Upgrading

Grape::Router::Pattern.new(..., format: …) now raises unknown keyword: :format. The UPGRADING note from #2781 (which described format: as an optional keyword on Pattern) is corrected accordingly.

Note: grape-swagger's test helper passes format: nil to Pattern.new and will need a one-line drop — but it already can't run against grape 4.0 HEAD (it calls Route.new without the required forward_match:), so this folds into the 4.0 update it needs regardless.

🤖 Generated with Claude Code

`Pattern#initialize` took a `format:` keyword and, in `extract_capture`,
constrained the mustermann `:format` capture with it. But nothing ever
passed a non-nil value: the endpoint stopped passing `format:` when the
vestigial `Grape::Endpoint::Options` `format` member was removed (#2779),
and grape-swagger's helper passes `format: nil`. It was also redundant —
a route's `:format` capture comes from the path suffix built by
`Grape::Path` (`(.json)` for a specific format, `(.:format)` otherwise),
not from the pattern.

Drop the keyword and the dead capture branch. `DEFAULT_CAPTURES` still
lists `format` (the path-derived capture) and `map_str` still serves
`version`, so matching is unchanged. `Grape::Router::Pattern.new(...,
format: …)` now raises `unknown keyword: :format`; corrected the
UPGRADING note that previously described it as an optional keyword.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ericproulx ericproulx force-pushed the remove_pattern_format branch from 4956ab9 to 5b62850 Compare July 5, 2026 18:46
@github-actions

github-actions Bot commented Jul 5, 2026

Copy link
Copy Markdown

Danger Report

No issues found.

View run

@dblock dblock merged commit 99f42ae into master Jul 5, 2026
69 checks passed
ericproulx added a commit that referenced this pull request Jul 5, 2026
`version`, `anchor` and `requirements` are the attributes that shape the
matcher — they are passed to `Grape::Router::Pattern` to build the
mustermann pattern. They were also passed a second time to
`Grape::Router::Route` and stored as ivars, purely to back the readers.

Expose them on `Pattern` instead (`attr_reader`) and delegate the
`BaseRoute` readers to `@pattern`, alongside the existing `path`/`origin`
delegation. `to_routes` no longer passes them to `Route.new`. Metadata
that does not shape matching — `namespace`, `prefix`, `settings` — stays
as route keyword arguments.

grape-swagger already passes these to `Pattern.new` and none of them to
`Route.new`, so its routes' readers become correct rather than `nil`.

Also collapse `extract_capture` to a guard plus a single merge. With the
`format` keyword gone (#2782) it just adds an optional `version`
constraint to `requirements`, so the intermediate accumulator was noise.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ericproulx added a commit that referenced this pull request Jul 6, 2026
`version`, `anchor` and `requirements` are the attributes that shape the
matcher — they are passed to `Grape::Router::Pattern` to build the
mustermann pattern. They were also passed a second time to
`Grape::Router::Route` and stored as ivars, purely to back the readers.

Expose them on `Pattern` instead (`attr_reader`) and delegate the
`BaseRoute` readers to `@pattern`, alongside the existing `path`/`origin`
delegation. `to_routes` no longer passes them to `Route.new`. Metadata
that does not shape matching — `namespace`, `prefix`, `settings` — stays
as route keyword arguments.

grape-swagger already passes these to `Pattern.new` and none of them to
`Route.new`, so its routes' readers become correct rather than `nil`.

Also collapse `extract_capture` to a guard plus a single merge. With the
`format` keyword gone (#2782) it just adds an optional `version`
constraint to `requirements`, so the intermediate accumulator was noise.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants