Repository navigation
Enable Style/FrozenStringLiteralComment - #86
Merged
Merged
Conversation
Remove the `Style/FrozenStringLiteralComment: Enabled: false` entry from .rubocop.yml so the cop runs with its default EnforcedStyle (always). .rubocop_todo.yml has no entry for this cop. Add `# frozen_string_literal: true` to the 17 files the cop flagged: Rakefile, sorbet/tapioca/require.rb, 11 files under lib/, and 4 spec files. In the `# typed:` files the pragma goes on the line after the sigil, which is how the files that already had it are laid out. The files without a sigil also get a blank line after the pragma (Layout/EmptyLineAfterMagicComment). No mutation fixes were needed. Every mutating call in lib/, spec/, bin/, the gemspec, the Gemfile and the Rakefile acts on an Array, a Hash, a Tempfile, or a string that isn't a literal. The frozen literals in the newly covered files are only compared, interpolated, used as ENV values or hash keys, or passed to non-mutating methods (delete_prefix, delete, gsub, fetch). OffensesAggregatorFormatter returns a frozen '' to Packwerk, which only calls present?/join on it. The generated RBIs under sorbet/rbi/ are not inspected by rubocop, so they are unchanged.
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
# frozen_string_literal: truemakes plain string literals immutable. Code that accidentally mutates a shared literal then raisesFrozenErrorright away instead of silently corrupting the value. It also lets Ruby reuse one object per literal instead of allocating a new String each time the line runs. Ruby 3.4+ already warns about chilled-literal mutation, and a future Ruby will make frozen literals the default, so turning this on now keeps the gem ahead of that change.Config change
.rubocop.yml: removed theStyle/FrozenStringLiteralComment: Enabled: falseblock. The cop now runs with its defaultEnforcedStyle: always..rubocop_todo.ymlhas no entry for this cop and is unchanged. No newExcludewas needed.Files that got the pragma
The pragma was added to 17 files. These are every file the cop flagged.
lib/:basic_reference_offense.rbcheck/default_formatter.rbcheck/offenses_formatter.rbpackwerk_wrapper.rbprivate.rbprivate/git.rbprivate/ownership_information.rbprivate/todo_yml_changes.rbupdate/default_formatter.rbupdate/offenses_formatter.rbviolation_diff.rbRakefileandsorbet/tapioca/require.rb(hand-maintained, not generated)spec/support/danger_plugin.rbIn the
lib/files the pragma goes on the line after# typed: strict. That matches the 5 lib files that already had it, and both positions are valid magic-comment locations. Files with no sigil get a blank line after the pragma (Layout/EmptyLineAfterMagicComment).Nothing was excluded. A few files were left alone:
bin/*binstubs: already excluded byAllCops: Exclude, and they already have the pragma.Gemfileand the gemspec: already had the pragma.sorbet/rbi/**: rubocop never inspects them, becauseAllCops: Includehas no*.rbipattern.Runtime fixes
None were needed. Every string literal in the newly pragma'd files was traced to its uses, including into packwerk, danger, constant_resolver and code_ownership. None of them is mutated.
Every mutating call in
lib/has a non-String receiver:Array#<<:basic_reference_offense.rb:66andtodo_yml_changes.rb:74Hash#[]=:todo_yml_changes.rb:97ENV#[]=:packwerk_wrapper.rb:29Tempfile#<<:todo_yml_changes.rb:162, with an interpolated argumentThe gem requires Ruby >= 3.3, and CI runs 3.3, 3.4 and 4.0. On those versions interpolated strings and interpolated heredocs stay unfrozen, so every formatter message handed to Danger is unfrozen, same as before.
A few methods now return frozen literals:
OffensesAggregatorFormatter#show_offenses,#show_stale_violationsand#show_strict_mode_violationsreturn''. Packwerk only uses these inselect(&:present?).join("\n") + "\n".#identifieris only used as a hash key.Private::OwnershipInformation#ownership_copyreturns'- This pack is unowned.'. It is private API, and its callers only interpolate the value.Uncovered code paths. Specs don't reach
packwerk_wrapper.rb:54-70orcheck/default_formatter.rb:54. They also stubPackwerk::Cli#execute_command,RailsLoadPaths.for,Open3.capture3andgit.diff. The dynamic checks below exercised those paths for real.Verification
Specs: 67 examples, 0 failures on
origin/mainbefore the change. After it: 67 examples, 0 failures on Ruby 4.0.7 and 3.3.11. The runs usedRUBYOPT=-W:deprecatedandRUBYOPT=--enable-frozen-string-literal, with 0FrozenErrors and 0 "literal string will be frozen" warnings.Rubocop: 26 files inspected, no offenses.
srb tc: no errors.Static sweep: read every non-RBI Ruby file line by line, and cross-checked with a Prism scan of every non-interpolated literal and every mutating call. Library code that receives our literals was read as well:
cli,check_command,update_todo_command,offenses_formatter,rails_load_pathsMarkdown,ViolationPragma in effect: compiled every file with
RubyVM::InstructionSequenceon 4.0.7 and 3.3.11. There were noputstringorputchilledstringinstructions, so the pragma is active in every file, including where it sits after the Sorbet sigil.Dynamic checks: end-to-end runs against real Rails/packwerk/code_ownership git fixtures, on 4.0.7 and 3.3.11. They used:
Danger::DangerfileGitRepodiffpackwerk checkthroughOffensesAggregatorFormatterPrivate.constant_resolvergit apply --reversethrough theTempfilewriteDynamic coverage: the runs covered:
package_todo.ymlfiles, plus renamesroot_pathbothniland a subdirectoryfail_buildandon_failurerepo_url_builderand a custom help messageNo
FrozenError, and everypackage_todo.ymlwas restored afterwards.Fresh Eyes: a local pre-push review (
fresh-eyes local --base origin/main) was run on this exact diff (commit 802b439, 18 files). It found 0 blockers, 0 major, 0 minor and 0 info findings.