Skip to content

(CAT-2635) Add rubocop-hash_inspect to PDK rubocop gem group and plugins#646

Merged
gavindidrichsen merged 1 commit into
mainfrom
CAT-2635-rubocop-hash_inspect
Jun 17, 2026
Merged

(CAT-2635) Add rubocop-hash_inspect to PDK rubocop gem group and plugins#646
gavindidrichsen merged 1 commit into
mainfrom
CAT-2635-rubocop-hash_inspect

Conversation

@david22swan

@david22swan david22swan commented Jun 17, 2026

Copy link
Copy Markdown
Member

Summary

Ruby 3.4 (December 2024, Bug #20433) changed the output of Hash#inspect from the legacy rocket syntax to colon syntax:

Ruby version {a: 1, "b" => 2}.inspect output
Ruby <= 3.3 (Puppet 8) {:a=>1, "b"=>2}
Ruby >= 3.4 (Puppet 9 / Ruby 4) {a: 1, "b" => 2}

Test assertions that hardcode the old format — for example eq("{:a=>1}") or match(/\{:name=>"foo"\}/) — silently break on Puppet 9. The rubocop-hash_inspect gem provides a single conservative cop (HashInspect/LegacyHashInspectFormat) that flags those literals statically during pdk validate, so module authors can fix them before upgrading.

This PR adds rubocop-hash_inspect ~> 0.2 to the :development gem group in config_defaults.yml (alongside rubocop-performance and rubocop-rspec) and adds 'rubocop-hash_inspect' to the defaults['plugins'] array in moduleroot/.rubocop.yml.erb, so the cop runs automatically on every pdk validate after a pdk update.

Additional Context

Before (Ruby 3.4 / Puppet 9 breaks silently):

expect(result.inspect).to eq("{:a=>1}")
expect(msg).to match(/\{:name=>"foo"\}/)

After — the cop flags these on pdk validate:

Offense: Legacy `Hash#inspect` format (`{:sym=>...}`). Ruby 3.4+ renders hashes as
`{sym: ...}`, so this hardcoded value breaks on Ruby 3.4 / Puppet 9. Update it to
the new format.

Correct form:

expect(result.inspect).to eq("{a: 1}")
expect(msg).to match(/\{name: "foo"\}/)
# Or better — use a matcher that doesn't depend on inspect output:
expect(result).to eq({ a: 1 })

Version constraint: ~> 0.2 targets the published 0.2.0 release (pessimistic minor lock — compatible with any 0.2.x patch but will not automatically pull in a future 0.3.0/1.0.0 that may change detection semantics).

On by default: The cop ships enabled at convention severity, matching rubocop-performance. It is non-blocking (PDK does not fail validate on convention offenses) and produces no false positives against the puppetlabs-stdlib and puppetlabs-concat baseline corpora.

A note on the ERB template comment: moduleroot/.rubocop.yml.erb carries the comment "note that these hashes need to use rockets, not colons, because rubocop config requires strings as keys". That refers to the ERB hash-key syntax used to render the template (writing 'plugins' => [...] rather than plugins: [...]), and is unrelated to the string values the cop flags. Config files are outside the cop's detection scope — only string and regexp literals in module source code are checked.

Related Issues (if any)

Checklist

  • 🟢 Spec tests.
  • Manually verified.

@david22swan david22swan requested a review from a team as a code owner June 17, 2026 11:02
@gavindidrichsen gavindidrichsen merged commit c391e21 into main Jun 17, 2026
2 checks passed
@gavindidrichsen gavindidrichsen deleted the CAT-2635-rubocop-hash_inspect branch June 17, 2026 13:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants