Skip to content

Internalize all InheritableSetting state behind semantic accessors (integration of #2797–#2808)#2809

Open
ericproulx wants to merge 26 commits into
masterfrom
inheritable-setting-integration
Open

Internalize all InheritableSetting state behind semantic accessors (integration of #2797–#2808)#2809
ericproulx wants to merge 26 commits into
masterfrom
inheritable-setting-integration

Conversation

@ericproulx

@ericproulx ericproulx commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Integration of the full Grape::Util::InheritableSetting encapsulation series. Every semantic key held in the namespace_stackable and namespace_inheritable stores is now written and read through an intention-revealing accessor on InheritableSetting — no caller outside the class indexes into either store per key anymore. Merging this PR closes the twelve standalone PRs it integrates:

Each sub-PR was developed standalone against master with a full green suite; this branch merges them with conflicts resolved (details below). If you prefer to merge the PRs individually, close this one instead — it adds nothing beyond the merge resolutions and one .rubocop.yml bump.

What each piece contributes

PR Concern Accessors Notes
#2797 Params state validations / add_validation, declared_params / add_declared_params, params_documentation / add_params_documentation, named_params / add_named_params, reset_validations!, point_in_time_copy_for_endpoint Also removes the unused api_class / point_in_time_copies readers; renames route_setting(:saved_validations)route_setting(:validations)
#2798 Callbacks callbacks / add_callback Keyed by DSL names (callbacks[:before]); singular→pluralized storage mapping centralized in CALLBACK_STORE_KEYS; Endpoint#compile! reads with fetch so key drift fails at boot
#2799 Rescue configuration rescue_options / add_rescue_options, add_all_rescue_handler, add_grape_exceptions_rescue_handler, add_internal_grape_exceptions_rescue_handler, rescue_all?, rescue_grape_exceptions?, handler readers rescue_options absorbs the nearest-wins .last; rescue_from drops its namespace_inheritable/arg prelude
#2800 Content negotiation content_types, formatters, parsers, error_formatters + add_* Writers absorb the single-entry-Hash shape, readers absorb the deep-merge convention
#2801 Representations representations / add_representation Removes the provably inert `namespace_stackable[:representations]
#2802 Middleware + helpers middleware / add_middleware, helpers / add_helper Removes the dead || [] fallback in the middleware DSL reader (same root cause)
#2803 Namespaces + mount path namespaces / add_namespace, namespace_path, namespace_requirements, mount_path / add_mount_path Derived readers absorb joined_space_path and filter_map(&:requirements); mount_path absorbs the outermost-wins .first; fixes the wrong @param doc on Namespace.joined_space_path
#2804 Contract key maps contract_key_maps / add_contract_key_map Completes the stackable side
#2805 Format & error defaults format, default_format, default_error_formatter, default_error_status (+ = writers) First namespace_inheritable batch; error_middleware_options becomes fully store-free
#2806 Versioning version, version_options, root_prefix, cascade (+ = writers), cascade_defined? cascade is presence-sensitive (explicit nil ≠ never-set); both key?(:cascade) call sites now read through cascade_defined?
#2807 Routing flags do_not_route_head, do_not_route_options, do_not_document, lint (! writers / ? readers) Mirrors the DSL's own bang methods; also removes the vestigial namespace_inheritable.to_hash.except(*ROOT_PREFIX_VERSIONING_KEYS) copy in Instance — its consumer only ever read the two routing flags, so the versioning-key stripping guarded reads that no longer exist
#2808 build_params_with + auth build_params_with / =, auth / = build_params_with's two DSL writers (API-level and params-block build_with) funnel through one accessor

Cross-cutting design

  • Naming taxonomy documents semantics: add_* writers mean stacking registrations (stackable store), plain = writers mean nearest-wins scalar overrides (inheritable store), !/? mean flags. Readers absorb the read conventions previously spelled out at call sites (.last, .first, flatten stays caller-side where it's a caller concern, deep-merge, filter_map); writers absorb the storage shapes (single-entry hashes, pluralized keys).
  • Storage is unchanged throughout: every key still lives under its original name in its original store, so to_hash output, route pattern settings and any external readers (grape-swagger) see identical values. The raw keys are declared internal in UPGRADING; actually narrowing the visibility of namespace_stackable / namespace_stackable_with_hash / namespace_inheritable is a deliberate follow-up, not part of this PR.
  • Dead code fell out of one root factStackableValues#[] never returns nil — discovered while writing the accessors: the representations ||= [] seeding, the middleware || [] fallback, and a now-unnecessary &. before .last were all removed with empirical verification.
  • Documented micro-changes, all UPGRADING'd: the boolean ? readers return false rather than nil when unset (all consumers are boolean-context); the empty middleware read returns the shared frozen array instead of a fresh mutable one.
  • CHANGELOG carries the twelve individual entries and UPGRADING the twelve sections, so history stays attributable per concern.

Integration-only changes (beyond the twelve PRs)

What deliberately remains raw (the follow-up visibility PR)

One bulk to_hash consumer, which needs a dedicated accessor before the store readers can go protected: Endpoint#prepare_default_path_settings (merged stackable+inheritable hash for route pattern settings). The other former bulk consumer — Instance's route-config hash copy — turned out to be vestigial and was removed in #2807.

Verification

Full rubocop (330 files, no offenses) and the full spec suite (2363 examples, 0 failures) pass on this branch, as they did on each of the twelve standalone branches.

🤖 Generated with Claude Code

ericproulx and others added 24 commits July 17, 2026 18:07
…sors

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ccessors

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ng accessors

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…Setting accessors

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…tting accessors

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…nheritableSetting accessors

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…::InheritableSetting accessors

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…accessors

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…-integration

# Conflicts:
#	lib/grape/util/inheritable_setting.rb
…tting-integration

# Conflicts:
#	lib/grape/util/inheritable_setting.rb
…le-setting-integration

# Conflicts:
#	lib/grape/endpoint.rb
#	lib/grape/util/inheritable_setting.rb
…etting-integration

# Conflicts:
#	lib/grape/endpoint.rb
#	lib/grape/util/inheritable_setting.rb
…e-setting-integration

# Conflicts:
#	lib/grape/util/inheritable_setting.rb
…tting-integration

# Conflicts:
#	lib/grape/util/inheritable_setting.rb
…setting-integration

# Conflicts:
#	lib/grape/util/inheritable_setting.rb
#	lib/grape/validations/contract_scope.rb
…heritableSetting accessors

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ccessors

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…g accessors

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…eSetting accessors

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…etting-integration

# Conflicts:
#	lib/grape/endpoint.rb
#	lib/grape/util/inheritable_setting.rb
…g-integration

# Conflicts:
#	lib/grape/endpoint.rb
#	lib/grape/util/inheritable_setting.rb
…ting-integration

# Conflicts:
#	lib/grape/util/inheritable_setting.rb
…le-setting-integration

# Conflicts:
#	lib/grape/endpoint.rb
#	lib/grape/util/inheritable_setting.rb
…r catalog

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 19, 2026

Copy link
Copy Markdown

Danger Report

No issues found.

View run

@ericproulx

Copy link
Copy Markdown
Contributor Author

@dblock this one includes a 2797 to 2808.

ericproulx and others added 2 commits July 18, 2026 21:52
…espace_inheritable hash copy

collect_route_config_per_pattern only ever read do_not_route_head and
do_not_route_options from the hash, so the to_hash copy, the
ROOT_PREFIX_VERSIONING_KEYS stripping and its concurrency comment were
all guarding reads that no longer exist.

Co-Authored-By: Claude Fable 5 <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.

1 participant