Skip to content

Warn about files that don't parse, read <%== in ERB, and release 0.7.0 - #72

Merged
dduugg merged 8 commits into
mainfrom
list-references-follow-ups
Oct 12, 2026
Merged

dduugg merged 8 commits into
mainfrom
list-references-follow-ups

Conversation

@dduugg

@dduugg dduugg commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

Summary

Follow-ups from the review of #71, plus a Dependabot config and the 0.7.0 bump. Each commit stands alone and has its own explanation.

  • Syntax errors warn. When pks can't parse one of the app's files, it now says so on stderr, with the file, the first error and, in Ruby, the line. Until now it silently used whatever partial tree the parser recovered, so check could pass while missing the file's references.
  • <%== is read as Ruby. The ERB-to-Ruby regex took one =, so Rails' unescaped-output tag became = foo(Bar), which doesn't parse. The tag's references and every reference after it in the file were missed.
  • -p no longer breaks JSON. --print-files progress lines go to stderr, so check -o json -p and list-references -p produce valid JSON.
  • list-references --referencing-pack reads only those packs' files, rather than parsing everything and filtering afterwards.
  • rm shares list-references' reference selection (filter, sort, merge of copies), now in reference_extractor.
  • Tests: pks() and the schema validator move to tests/common, and tests that expect an empty stderr remove RUST_LOG, so they pass with RUST_LOG=debug set.
  • Dependabot updates Cargo dependencies and GitHub Actions monthly, in one group each with a 7-day cooldown, as in rubyatscale/packs-specification.
  • Version 0.7.0. list-references is a new command. Merging this releases v0.7.0 through auto-release.yml.

Design notes

  • Which files warn. Only the app's included files warn. expose-monkey-patches also parses Ruby's and the gems' sources, which can use syntax pks can't parse and aren't the app's to fix, so they stay quiet and cached.
  • Warnings and the cache. A file pks warns about isn't cached, so the warning comes back every run until the file is fixed. syntax_error isn't serialized, so the cache format pks shares with packwerk doesn't change.
  • Noise. On three large Rails apps, the <%== files were the only ones that failed to parse. With that fixed, neither parser gives any warnings there.
  • Newer Ruby syntax. lib-ruby-parser can't read some newer syntax, such as Ruby 3.2's anonymous argument forwarding (def foo(*) = bar(*)), so files using it now warn instead of silently losing references. lib-ruby-parser's repository is archived, and its last release is from April 2024. Moving to ruby-prism, the official bindings to the parser Ruby itself uses, would fix this, and belongs in its own PR.
  • versioning-strategy: increase. Cargo.lock isn't tracked. Dependabot's default strategy leaves a requirement alone when it already allows the new release, as rayon = "1.7.0" allows 1.12. increase raises the floor in Cargo.toml instead, which is what Add pks list-references to list the references between packs #71 had to do by hand for par_chunk_by.
  • release.yml is left out of the Actions updates. dist generates it and pins its actions in dist-workspace.toml. exclude-paths is documented per update block, but I couldn't confirm that the github-actions ecosystem honors it. If it doesn't, Dependabot may propose edits to release.yml that should be closed.

Who this affects

  • Apps with Ruby files that don't parse, or ERB with <%==. check can now report violations it missed before, and those files print a warning.
  • Anyone running -p with JSON output, or list-references --referencing-pack on a large app.

Test plan

  • New tests: syntax-error warnings for Ruby and ERB under both parsers, repeated on a warm cache; no warnings for Ruby or gem sources in expose-monkey-patches; <%==; -p with JSON output; --referencing-pack not reading other packs' files; rm listing a reference once when several files define its constant. Each fails when the behavior it covers is removed.
  • For two packs in each of two large Rails apps, --referencing-pack output matches the full list limited to those packs, under both parsers. With the default parser, the larger app took 2.6 s instead of 8.0 s.
  • Every commit passes cargo fmt --check and cargo clippy --all-targets --all-features with -Dwarnings. The suite passes with and without RUST_LOG=debug. zizmor finds nothing in the new dependabot.yml.

`-p` printed "Started processing" and "Finished processing" lines to
stdout, so the JSON from `check -o json` and `list-references` came
after them and didn't parse. They are progress, not output, so they now
go to stderr, where pks's warnings already go.
Rails' `<%== %>` outputs without escaping, but the regex that pulls Ruby
out of ERB took only one `=` after `<%`, so `<%== foo(Bar) %>` became
`= foo(Bar)`. That doesn't parse. lib-ruby-parser recovers only part of
the file, and the tag's references and every reference after it were
missed: with `<%= SomeConcern %>`, `<%== Bar.bar %>` and `<%= Baz %>`,
pks found only `::SomeConcern`.

In three large Rails apps, these were the only files that failed to
parse. Packwerk reads ERB with a real parser and handles the tag.
@dduugg
dduugg marked this pull request as ready for review October 12, 2026 20:22
@dduugg
dduugg requested a review from a team as a code owner October 12, 2026 20:22
When lib-ruby-parser couldn't parse a file, pks used whatever partial
tree it recovered, or none, and said nothing, so `check` could pass
while missing the file's references. Packwerk reports a syntax error as
an offense. pks now prints a warning to stderr with the file and the
first error, and its line in Ruby. ERB gets no line, since its lines are
those of the Ruby pks makes from it.

The error rides on `ProcessedFile` as `syntax_error`, which isn't
serialized, so the cache format that pks shares with packwerk doesn't
change. A file pks warns about isn't written to the cache, so the
warning comes back on every run until the file is fixed, instead of
only when the file is first parsed.

Only the app's own files, its included files, warn.
`expose-monkey-patches` also parses Ruby's and the gems' sources, which
can use syntax pks can't parse and aren't the app's to fix; they stay
quiet and cached.

An empty file has no AST but no error either, so it doesn't warn. Three
large Rails apps give no warnings under either parser, now that `<%==`
is read correctly. The parser can't read some newer syntax, such as
Ruby 3.2's anonymous argument forwarding, and those files warn too.
`--referencing-pack` filtered references after pks had parsed every
included file, so asking about one pack cost as much as asking about
all of them. Only a pack's own files can make references from it, so
pks now passes just those to `get_all_references`, as `check <paths>`
passes its paths. The experimental parser still reads every file for
definitions inside `get_all_references`, so it gains less.

For two packs of a large Rails app, the output is the same as the full
list limited to those packs, under both parsers, and the run took 2.6 s
instead of 8.0 s with the default parser. A test checks that a file in
another pack isn't read: one that doesn't parse would make pks warn.
pks's logger reads `RUST_LOG` even without `--debug`, so a developer
with `RUST_LOG=debug` set saw every test that expects an empty stderr
fail: 7 in `rm_test.rs`, all of `list_references_test.rs` and 5 in
`check_test.rs`. CI doesn't set it, so only local runs were affected.

`rm_test.rs` and `list_references_test.rs` each had the same `pks()`
helper, and `list_references_test.rs` and `check_test.rs` each had a
schema validator. Both move to `tests/common`, where `pks()` removes
`RUST_LOG`; the new syntax error tests use it too. The `check_test.rs`
tests run against the fixtures in place rather than through `Fixture`,
so those five remove it themselves. With `RUST_LOG=debug`, the suite
now fails only on `test_gitignore_negation_patterns`, which depends on
the global gitignore rather than on logging.
`rm`'s search for references into the pack it removes filtered, sorted
and deduplicated the references the way `list-references` does, with
its own copy of each step. `between_packs` now holds the filter and the
sort, and `rm` asks it for the references to one pack from the others,
then keeps one copy of each, as `list-references` merges them. It and
`identity` move to `reference_extractor`, which both commands already
use, rather than one command reaching into the other's module. The
order `rm` prints references in is unchanged, since `identity` only
adds the defining pack, which is the same for all of them.

Nothing tested that `rm` lists a reference once when several of the
pack's files define its constant, so a new test does, under the
experimental parser. It passes before and after this change and fails
without the deduplication.
#71 needed `rayon`'s requirement raised from 1.7.0 to 1.10.0 by hand,
for `par_chunk_by`. Nothing else raises a requirement, so a new API is
found missing only when the build breaks. This takes the bundler and
github-actions setup from rubyatscale/packs-specification: monthly, all
updates in one group per ecosystem, with a 7-day cooldown.

Cargo.lock isn't tracked, and Dependabot's default strategy leaves a
requirement alone when it already allows the new release, as `1.7.0`
allows 1.12. `versioning-strategy: increase` raises the requirement to
the newest release instead, so Cargo.toml keeps up with what CI builds.

dist generates release.yml and pins its actions in dist-workspace.toml,
so the actions update leaves that file out.
`pks list-references` is a new command, and pre-1.0 a new feature wants
a minor bump. Once this merges, auto-release.yml tags and releases
v0.7.0, since Cargo.toml's version has no tag yet.

Retitle `## Unreleased` to `## 0.7.0`, the heading dist takes the
release notes from.
@dduugg
dduugg force-pushed the list-references-follow-ups branch from 07336b2 to 8637fbd Compare October 12, 2026 20:24
@dduugg
dduugg merged commit 6adcd73 into main Oct 12, 2026
16 checks passed
@dduugg
dduugg deleted the list-references-follow-ups branch October 12, 2026 20:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant