Enable Style/FrozenStringLiteralComment - #40
Merged
Merged
Conversation
Remove the .rubocop.yml entry that disabled the cop, so it runs with its default EnforcedStyle (always). Add "# frozen_string_literal: true" to the 13 files the cop flagged: Gemfile, Rakefile, code_teams.gemspec, lib/code_teams/plugin.rb, lib/code_teams/plugins/identity.rb, and every spec file. Where the pragma sits above a Sorbet "# typed:" sigil it comes first, matching the lib files that already had it. Blank lines after the magic comments satisfy Layout/EmptyLineAfterMagicComment. No mutation fixes were needed. The newly frozen literals are only used as hash keys, gemspec/Gemfile values, and read-only spec inputs. Strings the library hands back to callers (validation errors, missing_key_error_message) are interpolated, so they stay mutable on the supported Rubies (>= 3.3).
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.
Why
With the
# frozen_string_literal: truepragma, Ruby raises aFrozenErrorif code mutates a string literal by accident. The pragma also lets identical literals share one object instead of allocating a new string each time the line runs. Half oflib/already had the pragma (lib/code_teams.rb,testing.rb,testing/rspec_helpers.rb,utils.rb, and thebin/*binstubs), but the cop was turned off with the note "Disabling for now until it's clearer why we want this". This PR turns it back on so every file behaves the same way.Config change
.rubocop.yml: removed theStyle/FrozenStringLiteralComment: Enabled: falseblock and its comment. The cop now runs with its defaultEnforcedStyle: always. The repo has no.rubocop_todo.yml, and the existingAllCops: Excludelist (vendor/bundle/**,bin/**) is unchanged.Files that got the pragma (13)
Gemfile,Rakefile,code_teams.gemspeclib/code_teams/plugin.rb,lib/code_teams/plugins/identity.rbspec/spec_helper.rb,spec/support/io_helpers.rb, and the 6 spec files underspec/rubocop -A --only Style/FrozenStringLiteralCommentadded the pragmas, andrubocop -a --only Layout/EmptyLineAfterMagicCommentfixed the blank lines after them. Where a file has a Sorbet sigil, the pragma goes directly above# typed:, matching the files that already had it.srb tc --print=file-table-jsonconfirms Sorbet still reads each file's strictness level (plugin.rbstrict,identity.rbtrue,Rakefileignore).No new exclusions:
bin/*binstubs are generated by Bundler, already carry the pragma, and were already excluded.sorbet/rbi/todo.rbiis generated, and rubocop's defaultIncludedoesn't cover.rbifiles, so I left it alone.Runtime fixes
None were needed. No spec failed, and the static and dynamic checks below found no string literal that gets mutated. In the two
lib/files that just got the pragma, the only frozen literals are'name':lib/code_teams/plugin.rb:69andlib/code_teams/plugins/identity.rb:15use it only as a hash key.lib/code_teams/plugins/identity.rb:31passes it tomissing_key_error_message, which only interpolates it.The strings these files return to callers (
plugin.rb:56,identity.rb:28) are interpolated. Those are not frozen on Ruby >= 3.0, and the gem requires>= 3.3, so callers can still append to validation error messages.Verification
main) and after, on Ruby 4.0.5. The branch also passes on Ruby 3.3.11 and 3.4.11 (the full CI matrix). All runs usedRUBYOPT=-W:deprecated, with noFrozenErrorand no chilled-string warnings. The suite also passes withRUBYOPT=--enable-frozen-string-literalon all three Rubies.srb tc: no errors.Stringmethod,[]=,StringIO, IO buffer arguments andString.new. Every<</[]=/prependhit is on an Array, Hash or Module, never a String.Plugin.missing_key_error_message, the nil-name branch ofIdentity.validation_errors,tag_value_for/to_tag,Team.from_hash, and the defaultdata_accessor_name. A differential probe ran these against bothmainand this branch on all three Rubies (including with Sorbet runtime checks off, so the nil-name branch really runs). Results matched, and every returned string could still be appended to.rake -T,rake build,gem build,Gem::Specification.load(...).validate, and a simulatedrake releaseagainst a local bare remote all worked with the pragma in theGemfile,Rakefileand gemspec.No version bump.