Skip to content

Add ERB Lint to lint templates (RuboCop only covers .rb)#1988

Open
maebeale wants to merge 9 commits into
mainfrom
maebeale/erb-lint
Open

Add ERB Lint to lint templates (RuboCop only covers .rb)#1988
maebeale wants to merge 9 commits into
mainfrom
maebeale/erb-lint

Conversation

@maebeale

@maebeale maebeale commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator

🤖 suggested review level: 3 Read 📖 lint tooling + a large but mechanical autocorrect sweep — review the config, skim the sweep

Why

RuboCop only parses .rb, so nothing checked the Ruby inside <% %> tags or the ERB/HTML conventions in CLAUDE.md — documented but unenforced. This adds an actual ERB linter.

What

  • erb_lint gem + .erb_lint.yml, following the gem's recommended setup:
    • Default linters stay on (formatting, self-closing tags, tag spacing, parser errors, etc.).
    • The Rubocop linter inherit_from: .rubocop.yml — Ruby inside tags is held to the same omakase style as our .rb files, nothing duplicated. Only the cops that can't work on Ruby extracted from a single tag are disabled (README list + the indentation/alignment family, since a multi-line if/case spans separate tags).
    • Explicit disables: RequireInputAutocomplete (adding autofill tokens to ~64 existing inputs is a per-field UX decision, out of scope) and an allowance for <script type="module"> (legit ESM).
  • Wired into ai/lint (runs with RuboCop; --fix autocorrects both) and CI.
  • Autocorrect sweep across templates — whitespace, quoting, spacing, self-closing/void-element normalization. No behavioral changes.

Notes

  • The AllowedScriptType check caught a real bug: an (unused) webfonts partial whose <script> tag and JS body used curly quotes. Fixed the quotes; flagged as a deletion candidate.
  • erb_lint skips Ruby it can't extract from multi-line/split tags, so a few single-quoted strings there remain.

maebeale and others added 2 commits July 14, 2026 19:10
RuboCop only parses .rb, so nothing checked the Ruby inside <% %> tags or
the ERB/HTML conventions documented in CLAUDE.md. Add erb_lint with a
conservative, fully-autocorrectable ruleset (mechanical HTML/ERB formatting
plus an omakase-matching RuboCop subset), wire it into ai/lint, and run it
in CI alongside RuboCop.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Mechanical only: normalizes whitespace around/inside ERB tags and applies
the omakase Ruby style (double quotes, brace/bracket spacing) to code inside
<%= %> tags. No behavioral changes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 14, 2026 23:11

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

The HTML/ERB conventions are now enforced, not just documented; note that
and update the ai/lint command descriptions to mention ERB Lint.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 14, 2026 23:12

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@maebeale maebeale marked this pull request as ready for review July 14, 2026 23:33
maebeale and others added 2 commits July 14, 2026 19:40
The array/hash/block brace cops default to no_space in bare RuboCop but
omakase wants a space inside them; enabling the cops without pinning
EnforcedStyle silently enforced the opposite, so 772 array-bracket
violations went undetected. Pin the styles to omakase's values and extend
the subset to the other autocorrectable rules documented in CLAUDE.md:
block-brace spacing, no trailing commas, no redundant .to_s coercion, and
no semicolons.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Applies the newly-covered rules — omakase array/block-brace spacing and
trailing-comma removal — across templates. Mechanical only.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 14, 2026 23:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

CI installs gems into vendor/bundle (bundler-cache), so `erb_lint --lint-all`
was linting third-party gem templates and failing on 237 offenses in files we
don't own. RuboCop excludes vendor by default; erb_lint doesn't, so exclude it
(plus node_modules and tmp) explicitly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 15, 2026 00:28

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@maebeale maebeale requested a review from jmilljr24 July 15, 2026 01:24
Comment thread .erb_lint.yml Outdated
# checked the Ruby inside <% %> tags or our ERB/HTML conventions (CLAUDE.md).
# Scoped conservatively: mechanical HTML/ERB formatting linters plus a small,
# fully autocorrectable RuboCop subset mirroring our omakase style rules.
EnableDefaultLinters: false

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use the defaults and be explicit on what we disable? This is set to false and the majority of the default are re-enabled below.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 From Claude: Done — EnableDefaultLinters is back on (all 14 defaults run). Only RequireInputAutocomplete is explicitly disabled (adding autofill tokens to ~64 existing inputs is a per-field UX call, out of scope), and AllowedScriptType is configured to also allow type="module". That last check caught a real bug: a webfonts partial using curly quotes in its <script> tag.

Comment thread .erb_lint.yml
Comment on lines +39 to +40
Rubocop:
enabled: true

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Rubocop:
enabled: true
Rubocop:
enabled: true
rubocop_config:
inherit_from:
- .rubocop.yml

Why duplicate everything in our rubocop.yml ?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 From Claude: Done — the Rubocop linter now inherit_from: .rubocop.yml, so nothing is duplicated. The only cops set here are the ones that can't work on the Ruby extracted from a single tag: the README's recommended list plus the block/indentation-alignment family (a multi-line if/case is split across separate <% %> tags, so RuboCop sees misaligned fragments). Net effect: it also surfaced more real style issues (space after colon/comma) than my earlier hand-picked subset.

@jmilljr24 jmilljr24 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you take a look at the docs for this? erb_lint

maebeale and others added 3 commits July 15, 2026 08:46
Per review: stop disabling the default linters and re-enabling a subset, and
stop duplicating our RuboCop rules. Follow Shopify/erb_lint's recommended
config instead:

- EnableDefaultLinters stays on; the Rubocop linter inherits .rubocop.yml so
  Ruby in tags is held to the exact same omakase style as our .rb files (no
  rules restated here). Disable only the cops that can't work on the Ruby
  extracted from a tag — the README's list plus the block/indentation
  alignment family (a multi-line if/case is split across separate tags).
- Explicitly disable RequireInputAutocomplete (adding autofill tokens to every
  existing input is a per-field UX decision, out of scope) and allow
  <script type="module"> (legit ESM) — the "be explicit about what we disable"
  approach rather than turning the defaults off wholesale.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…tType)

The <script> type attribute (and the JS body) used curly quotes, which are
invalid — the script would raise a syntax error. This partial appears unused;
fixing the quotes rather than deleting it for now.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Mechanical only: the full default linter set now normalizes HTML too
(SelfClosingTag drops the slash on HTML void elements, keeps it on SVG;
SpaceInHtmlTag tidies tag spacing), and the inherited omakase config adds a
few more space cops (after colon/comma) on Ruby in tags.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 15, 2026 12:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants