Skip to content

fix(rubocop): declare the cop options config/default.yml only documented - #9

Merged
mhenrixon merged 1 commit into
mainfrom
issue-7-declare-libraries-cop-option
Jul 25, 2026
Merged

fix(rubocop): declare the cop options config/default.yml only documented#9
mhenrixon merged 1 commit into
mainfrom
issue-7-declare-libraries-cop-option

Conversation

@mhenrixon

Copy link
Copy Markdown
Collaborator

Fixes #7.

The problem

RuboCop derives each cop's supported-parameter list from the keys actually present in the gem's config/default.ymlConfigValidator#each_invalid_parameter does a literal default_config.key?(param). An option that a cop reads but the file only documents in a comment is invisible to that check and gets reported as unsupported on every single run.

Issue #7 reports one instance. Reproducing it against a real rubocop invocation surfaced four:

Cop Option State in config/default.yml
Glyphs/IconResolution Libraries comment only
Glyphs/LegacyIconHelper Mappings comment only
Glyphs/LegacyIconHelper LibraryComponents absent entirely
Glyphs/PreferLibraryComponent LibraryComponents absent entirely

The bottom two are the sharpest case: LegacyIconHelper's own MSG_UNKNOWN offence message tells the user to "add a LibraryComponents mapping for library X" — and following that advice produced a warning telling them the option does not exist.

All four options genuinely work, which is what makes the warning harmful: the natural reaction is to delete working configuration.

The fix

Declare each key with an empty default, keeping the example as a comment above it. The reads are all no-ops against an empty hash:

  • DEFAULT_LIBRARIES.merge({}) and LIBRARY_TO_COMPONENT.merge({}) return the built-in maps unchanged.
  • LegacyIconHelper#mappings already special-cases empty (configured.empty? ? DEFAULT_MAPPINGS : ...), so Mappings: {} keeps the built-in helper map.

Nobody's behaviour changes; RuboCop just stops lying about the option.

Test plan

  • spec/rubocop/plugin_spec.rb gains a drift guard: it scans each registered Glyphs cop — and every RuboCop::Cop::Glyphs::* module the cop includes, which is where LibraryComponents actually lives — for cop_config["Key"], then asserts config/default.yml declares each one. Verified it fails correctly by deleting Libraries: {} and watching it report Glyphs/IconResolution reads undeclared Libraries.
  • Each cop spec gains a case pinning the no-op property of the new empty default, so a future refactor that stops treating {} as "use built-ins" is caught.

End-to-end before/after

Same project config (all four options set), same target file, only config/default.yml differing:

BEFORE: 4 x "Warning: Glyphs/... does not support ... parameter."
        4 offences detected
AFTER:  0 warnings
        4 offences detected — byte-identical

The identical offence list is the important half: it proves the declarations did not quietly change how the options resolve.

Suite

  • bundle exec rubocop lib spec — clean
  • bundle exec rspec — 137 examples, 0 failures

Deviations & judgment calls

  • Scope widened from one warning to four. The issue names only Libraries. The reproduction showed the identical declaration gap on three more options across the other two cops. Fixing only the reported one would have left the exact same bug in place for the next person, so all four are fixed together — one root cause, one commit.

  • The regression guard derives the parameter list from source rather than hardcoding it. A spec listing the expected keys would only restate config/default.yml and would not catch the next option added to a cop without a declaration. Scanning the cop classes plus their RuboCop::Cop::Glyphs::* mixins for cop_config["Key"] mirrors RuboCop's own check and turns this class of bug into a test failure. Cost: the guard is regex-over-source, so a dynamically-built key (cop_config[some_var]) would slip past it — no such call exists today.

  • Out-of-scope discovery, not fixed here: require "glyphs/rubocop" raises NameError. lib/rubocop/cop/glyphs/library_call_helpers.rb:15 references ::Glyphs::IconReference, but lib/glyphs/rubocop.rb never requires glyphs. It works today only because the plugins: path loads the gem first — but README line 192 documents require: [glyphs/rubocop] as a supported alternative, and that path is broken. Different bug, different symptom; it deserves its own issue rather than being smuggled in here.

  • Not touched: Glyphs/IconResolution silently skips validation when the icon directory is missing (fails open) #8 (fail-open on a missing icons directory). Referenced by Glyphs/IconResolution: Libraries is documented in config/default.yml but not declared, so RuboCop warns it is unsupported #7 as a companion, but it is a behaviour change, not a declaration fix.

  • README gained a LibraryComponents example for both cops that read it. It was previously undocumented despite being named in a cop offence message — arguably the reason the declaration was missed in the first place.

## Summary

RuboCop builds each cop's supported-parameter list from the keys actually
present in `config/default.yml` (`ConfigValidator#each_invalid_parameter`
checks `default_config.key?(param)`). Four working options were invisible to
that check, so every run warned they were unsupported:

- `Glyphs/IconResolution` `Libraries` — comment only
- `Glyphs/LegacyIconHelper` `Mappings` — comment only
- `Glyphs/LegacyIconHelper` `LibraryComponents` — absent entirely
- `Glyphs/PreferLibraryComponent` `LibraryComponents` — absent entirely

The last two are the sharpest case: `LegacyIconHelper`'s own `MSG_UNKNOWN`
tells users to "add a `LibraryComponents` mapping", and doing so warned.

Each is now declared with an empty default. `DEFAULT_LIBRARIES.merge({})` and
`LIBRARY_TO_COMPONENT.merge({})` are no-ops, and `LegacyIconHelper#mappings`
already falls back to `DEFAULT_MAPPINGS` when the configured hash is empty, so
behaviour is unchanged for everyone.

## Test Coverage

- plugin_spec: derives every `cop_config["Key"]` read by each registered Glyphs
  cop (and its `RuboCop::Cop::Glyphs::*` mixins) from source and asserts
  `config/default.yml` declares it — a new undeclared option now fails the suite
- icon_resolution_spec: `Libraries: {}` still resolves via the built-in defaults
- legacy_icon_helper_spec: `Mappings: {}` / `LibraryComponents: {}` still apply
  the built-in helper map and library components
- prefer_library_component_spec: `LibraryComponents: {}` still applies defaults

## Verification

- [x] bundle exec rubocop lib spec passes
- [x] bundle exec rspec passes (137 examples)
- [x] Real `rubocop` run against a project config setting all four options:
      4 warnings before, 0 after, byte-identical offences

Refs #7
@mhenrixon mhenrixon self-assigned this Jul 25, 2026
@mhenrixon mhenrixon added the enhancement New feature or request label Jul 25, 2026
@mhenrixon
mhenrixon merged commit e2e46b4 into main Jul 25, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Glyphs/IconResolution: Libraries is documented in config/default.yml but not declared, so RuboCop warns it is unsupported

1 participant