[bot] Fix Layout/ClosingHeredocIndentation#853
Merged
Conversation
9c844d8 to
d90dd3a
Compare
Contributor
|
✅ Cop-check results (8 shards)
All shards passed — ready to merge. |
6
approved these changes
Mar 30, 2026
Owner
6
left a comment
There was a problem hiding this comment.
Reviewed: correctly clears argument_indent context for AssocNode values, preventing heredoc indentation exceptions from leaking into hash pair values. Resolves 27 FNs.
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.
Automated fix fix for
Layout/ClosingHeredocIndentationcorpus conformance.Details
Layout/ClosingHeredocIndentationResult
Changes
Agent conversation excerpt
I’m reading the CI guidance first, then I’ll inspect the current cop, its fixtures, and RuboCop’s reference implementation to pin down the false-negative pattern before editing anything.
I’m reading the CI guidance first, then I’ll inspect the current cop, its fixtures, and RuboCop’s reference implementation to pin down the false-negative pattern before editing anything.
I’ve got the current implementation and reference behavior. The fixture already has some bare closing-token lines appended at the bottom, so I’m checking the worktree before I touch anything and then I’ll reproduce the failing behavior with the focused cop test.
I’ve got the current implementation and reference behavior. The fixture already has some bare closing-token lines appended at the bottom, so I’m checking the worktree before I touch anything and then I’ll reproduce the failing behavior with the focused cop test.
The worktree shows only the target fixture file as modified. I’m treating that as in-scope and checking whether the currently appended bare markers are enough to fail the focused test or if I need to replace them with parseable snippets.
The worktree shows only the target fixture file as modified. I’m treating that as in-scope and checking whether the currently appended bare markers are enough to fail the focused test or if I need to replace them with parseable snippets.
The current fixture is syntactically incomplete at the bottom, which is likely why it was left in this state. I’m letting the focused cop test finish so I can confirm the exact failure mode before I replace those placeholders with real parseable Ruby cases.
The current fixture is syntactically incomplete at the bottom, which is likely why it was left in this state. I’m letting the focused cop test finish so I can confirm the exact failure mode before I replace those placeholders with real parseable Ruby cases.
I’ve confirmed the corpus FN cluster is all the same shape: heredocs used as hash values or keyword arguments inside call arguments. The current visitor only establishes “argument context” for
CallNodearguments, so I’m now drilling into Prism’s node shape around hash pairs to see where that context gets dropped.I’ve confirmed the corpus FN cluster is all the same shape: heredocs used as hash values or keyword arguments inside call arguments. The current visitor only establishes “argument context” for
CallNodearguments, so I’m now drilling into Prism’s node shape around hash pairs to see where that context gets dropped.The quick Prism probe was malformed because of shell quoting, so I’m rerunning it with a real temp file. I also still have the focused test running in the background; once it returns I’ll replace the broken fixture tail with concrete reproductions and confirm the test fails for the right reason.
The quick Prism probe was malformed because of shell quoting, so I’m rerunning it with a real temp file. I also still have the focused test running in the background; once it returns I’ll replace the broken fixture tail with concrete reproductions and confirm the test fails for the right reason.
Recent Updates
TEMPLATE ) RUBY ruby -e 'req`The FN mechanism is clear now: the visitor is treating every heredoc anywhere inside a call’s argument list as eligible for “align to method definition,” but RuboCop only grants that exception to direct arguments or chained heredoc calls. Hash-pair values like
cooked: <<~COOKED,should stay strict against their own opening line.The FN mechanism is clear now: the visitor is treating every heredoc anywhere inside a call’s argument list as eligible for “align to method definition,” but RuboCop only grants that exception to direct arguments or chained heredoc calls. Hash-pair values like
cooked: <<~COOKED,should stay strict against their own opening line.I have the fix shape. Next I’m editing the fixture first: removing the non-parseable placeholder lines and replacing them with minimal, real Ruby reproductions for hash-pair heredocs so the failing test is meaningful.
I have the fix shape. Next I’m editing the fixture first: removing the non-parseable placeholder lines and replacing them with minimal, real Ruby reproductions for hash-pair heredocs so the failing test is meaningful.
Recent Updates
TEMPLATE ) RUBY rubocop --only Layout/ClosingHeredoc`The fixture now contains real Ruby repros for the hash-pair cases. I’m rerunning the focused cop test to confirm those new cases fail against the current implementation before I change the Rust logic.
The fixture now contains real Ruby repros for the hash-pair cases. I’m rerunning the focused cop test to confirm those new cases fail against the current implementation before I change the Rust logic.
I’ve reproduced the meaningful failure. I’m patching the visitor now so
argument_indentis cleared when traversing anAssocNodevalue, which keeps the “align to method definition” exception limited to direct heredoc arguments and chained heredoc calls, matching RuboCop.I’ve reproduced the meaningful failure. I’m patching the visitor now so
argument_indentis cleared when traversing anAssocNodevalue, which keeps the “align to method definition” exception limited to direct heredoc arguments and chained heredoc calls, matching RuboCop.Task prompt (6989 tokens)
Fix Layout/ClosingHeredocIndentation — 0 FP, 30 FN
Instructions
You are fixing ONE cop in nitrocop, a Rust Ruby linter that uses Prism for parsing.
Current state: 5,970 matches, 0 false positives, 30 false negatives.
Focus on: FN (RuboCop flags code nitrocop misses).
⚠ 5,970 existing matches must not regress. Validate with
check_cop.pybefore committing.Workflow
behavior on BOTH the specific FP case AND the general pattern:
tests/fixtures/cops/layout/closing_heredoc_indentation/offense.rbwith^annotationtests/fixtures/cops/layout/closing_heredoc_indentation/no_offense.rbcargo test --lib -- cop::layout::closing_heredoc_indentationsrc/cop/layout/closing_heredoc_indentation.rscargo test --lib -- cop::layout::closing_heredoc_indentation///doc comment on the cop struct documenting what you found and fixedFixture Format
Mark offenses with
^markers on the line AFTER the offending source line.The
^characters must align with the offending columns. The message format isLayout/ClosingHeredocIndentation: <message text>.See the Current Fixture sections below for real examples from this cop.
If your test passes immediately
If you add a test case and it passes without code changes, the corpus mismatch is
caused by config/context differences, not a detection bug.
Do NOT loop trying to make the test fail. Instead:
src/config/or the cop's config handling, not detection logica
///comment on the cop struct and commitCRITICAL: Avoid regressions in the opposite direction
When fixing FPs, your change MUST NOT suppress legitimate detections. When fixing FNs,
your change MUST NOT flag code that RuboCop accepts. A fix that eliminates a few issues
in one direction but introduces hundreds in the other is a catastrophic regression.
Before exempting a category of patterns, verify with RuboCop that the general case
is still an offense:
If RuboCop flags the general pattern but not your specific case, the difference is in
a narrow context (e.g., enclosing structure, receiver type, argument count) — your fix
must target that specific context, not the broad category.
Rule of thumb: if your fix adds an early
returnorcontinuethat skips a wholenode type, operator class, or naming pattern, it's probably too broad. Prefer adding a
condition that matches the SPECIFIC differentiating context.
Rules
src/cop/layout/closing_heredoc_indentation.rsandtests/fixtures/cops/layout/closing_heredoc_indentation/cargo test --lib -- cop::layout::closing_heredoc_indentationto verify your fix (do NOT run the full test suite)python3 scripts/check_cop.py Layout/ClosingHeredocIndentation --rerun --clone --sample 15before committing to catch regressionsgit stashCurrent Fixture: offense.rb
tests/fixtures/cops/layout/closing_heredoc_indentation/offense.rbCurrent Fixture: no_offense.rb
tests/fixtures/cops/layout/closing_heredoc_indentation/no_offense.rbKey Source Files
src/cop/layout/closing_heredoc_indentation.rsvendor/rubocop/lib/rubocop/cop/layout/closing_heredoc_indentation.rbvendor/rubocop/spec/rubocop/cop/layout/closing_heredoc_indentation_spec.rbRead these files before making changes.
Start Here
Use the existing corpus data to focus on the most concentrated regressions first.
Helpful local commands:
python3 scripts/investigate_cop.py Layout/ClosingHeredocIndentation --repos-onlypython3 scripts/investigate_cop.py Layout/ClosingHeredocIndentation --contextpython3 scripts/verify_cop_locations.py Layout/ClosingHeredocIndentationTop FN repos:
browsermedia__browsercms__0a7fb92(5 FN) — examplelib/generators/browser_cms/demo_site/templates/demo.seeds.rb:95discourse__discourse__9c8f125(4 FN) — exampleplugins/chat/spec/models/chat/message_spec.rb:503github__octocatalog-diff__59d46a6(3 FN) — examplespec/octocatalog-diff/fixtures/repos/default/modules/stdlib/lib/puppet/parser/functions/defined_with_params.rb:19Representative FN examples:
browsermedia__browsercms__0a7fb92: lib/generators/browser_cms/demo_site/templates/demo.seeds.rb:95—TEMPLATEis not aligned with:template => <<-TEMPLATE.browsermedia__browsercms__0a7fb92: lib/generators/browser_cms/demo_site/templates/demo.seeds.rb:157—HTMLis not aligned with:body => <<-HTML.browsermedia__browsercms__0a7fb92: lib/generators/browser_cms/demo_site/templates/demo.seeds.rb:200—HTMLis not aligned with:body => <<-HTML.Pre-diagnostic Results
Diagnosis Summary
Each example was tested by running nitrocop on the extracted source in isolation
with
--force-default-configto determine if the issue is a code bug or config issue.Note: source context is truncated and may not parse perfectly. If a diagnosis
seems wrong (e.g., your test passes immediately for a 'CODE BUG'), treat it as
a config/context issue instead.
FN #1:
browsermedia__browsercms__0a7fb92: lib/generators/browser_cms/demo_site/templates/demo.seeds.rb:95NOT DETECTED — CODE BUG
The cop fails to detect this pattern. Fix the detection logic.
Message: ``TEMPLATE
is not aligned with:template => <<-TEMPLATE`.`Ready-made test snippet (add to offense.rb, adjust
^count):Full file context (30 lines before offense):
FN #2:
browsermedia__browsercms__0a7fb92: lib/generators/browser_cms/demo_site/templates/demo.seeds.rb:157NOT DETECTED — CODE BUG
The cop fails to detect this pattern. Fix the detection logic.
Message: ``HTML
is not aligned with:body => <<-HTML`.`Ready-made test snippet (add to offense.rb, adjust
^count):Full file context (30 lines before offense):
FN #3:
browsermedia__browsercms__0a7fb92: lib/generators/browser_cms/demo_site/templates/demo.seeds.rb:200NOT DETECTED — CODE BUG
The cop fails to detect this pattern. Fix the detection logic.
Message: ``HTML
is not aligned with:body => <<-HTML`.`Ready-made test snippet (add to offense.rb, adjust
^count):Full file context (30 lines before offense):
FN #4:
browsermedia__browsercms__0a7fb92: lib/generators/browser_cms/demo_site/templates/demo.seeds.rb:215NOT DETECTED — CODE BUG
The cop fails to detect this pattern. Fix the detection logic.
Message: ``HTML
is not aligned with:body => <<-HTML`.`Ready-made test snippet (add to offense.rb, adjust
^count):Full file context (30 lines before offense):
FN #5:
browsermedia__browsercms__0a7fb92: lib/generators/browser_cms/demo_site/templates/demo.seeds.rb:246NOT DETECTED — CODE BUG
The cop fails to detect this pattern. Fix the detection logic.
Message: ``HTML
is not aligned with:body => <<-HTML`.`Ready-made test snippet (add to offense.rb, adjust
^count):Full file context (30 lines before offense):
FN #6:
discourse__discourse__9c8f125: plugins/chat/spec/models/chat/message_spec.rb:503NOT DETECTED — CODE BUG
The cop fails to detect this pattern. Fix the detection logic.
Full-file enclosing chain: enclosing line 497:
message => block (do..end) (line 488:it "includes links in pretty text excerpt if the raw message is a single link and the PrettyText excerpt is blank" do) > block (do..end) (line 170:describe ".cook" do) > block (do..end) (line 3:describe Chat::Message do)Message: ``COOKED
is not aligned withcooked: <<~COOKED,`.`Ready-made test snippet (add to offense.rb, adjust
^count):Full file context (30 lines before offense):
FN #7:
discourse__discourse__9c8f125: spec/integration/activerecord_preventing_writes_spec.rb:15NOT DETECTED — CODE BUG
The cop fails to detect this pattern. Fix the detection logic.
Full-file enclosing chain: enclosing line 5:
theme_field => block (do..end) (line 4:it "should not result in an error response when there is a theme field that needs to be baked" do) > block (do..end) (line 3:RSpec.describe "When ActiveRecord is preventing writes" do)Message: ``HTML
is not aligned withvalue: <<~HTML,`.`Ready-made test snippet (add to offense.rb, adjust
^count):Full file context (30 lines before offense):
FN #8:
discourse__discourse__9c8f125: spec/models/theme_spec.rb:1362NOT DETECTED — CODE BUG
The cop fails to detect this pattern. Fix the detection logic.
Full-file enclosing chain: enclosing line 1352:
second_migration_field => block (do..end) (line 1351:it "does not raise an out of sequence error and does not createThemeSettingsMigrationrecord for out of sequence migration whenallow_out_of_sequence_migrationkwarg is set to true" do) > block (do..end) (line 1091:describe "#migrate_settings" do) > enclosing line 249:HTMLMessage: ``JS
is not aligned withvalue: <<~JS,`.`Ready-made test snippet (add to offense.rb, adjust
^count):Full file context (30 lines before offense):
Omitted 7 additional diagnosed FN example(s) for brevity.