Skip to content

ast-grep matching-semantics differential: verify rules match the same nodes across an upgrade #184

Description

@thecodedrift

What this is

#182 upgrades the vendored ast-grep from 0.41.0 to 0.45.2 and verifies that the binary's interface did not move: JSON stream shape, exit codes, severity vocabulary, sg test output, $$$ arity, language: handling, .tests/ invisibility. It also verifies that no rule shipped in this repo uses the one breaking schema construct (a rewriter without fix).

It does not verify that a valid rule still matches the same nodes. That is a different question, and nothing local answers it today. A rule can keep parsing, keep exiting 0, and quietly match a different set of nodes than it did at 0.41.0. Four upstream changes can do exactly that, with no error at any point:

Change Effect
#2677 metavariable bindings no longer leak across nthChild siblings
#2676 nor out of a negated not
#2868 root metavariables now match comments
#2803 ignore files are no longer read outside rule_dirs

The first three are the silent-wrong-answer class. The fourth changes which files are scanned rather than which nodes match, and it intersects the --no-ignore hidden and --globs work from #153.

Why this is not a vendor-contract test

The existing suite pins the interface by asking the binary a question and comparing the answer to a constant. A differential cannot work that way: the expected value is the other binary's output, so both 0.41.0 and 0.45.2 have to be resolvable in the same run. That is the piece of infrastructure this needs and the vendor-contract suite does not have.

It is also explicitly not a Vale-shaped corpus problem. ast-grep publishes a schema, so validity is already covered. The open question here is regression, not vocabulary.

Shape

  • Both binaries resolvable at once. The one hard prerequisite.
  • Compare findings as sets of (file, range, ruleId), never as counts. A count is equal in the case that matters least and hides a swap where one match appears as another disappears.
  • A corpus exercising the changed constructs: nthChild with sibling metavariables, metavariables bound inside a negated not, root metavariables adjacent to comments.
  • A fixture tree with hidden directories and nested ignore files, arranged so #2803 is isolated from fix(cli): let ast-grep rules see inside hidden directories #153's --no-ignore hidden / --globs behavior. Without that isolation a difference cannot be attributed to either change.
  • Four to eight cases is the target. This is a regression probe, not a corpus sweep.

Also unverified

Whether #2803 altered the --no-ignore hidden behavior from #153. #182 did not exercise it, and that is precisely what this harness is for.

Note on scope

This is deliberately out of scope for #182 and is not a blocker for it. #182's own body records the same reasoning, so this issue is the tracking counterpart to that note.

Refs #162
Refs #153

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions