Skip the JsonPathMatcher walk for non-matching keys in setup-java/setup-node recipes - #220
Merged
Conversation
`JsonPathMatcher.matches` walks the whole document: for a `..`-prefixed
path `find0` starts at `cursorPath.get(0)`, so calling it from
`visitMappingEntry` re-visits the enclosing document once per mapping
entry. Testing the key name first skips that walk for every entry that
cannot match. Visit time on a synthetic workflow, parse excluded, mean
of 10 warmed runs:
lines=74 0.40 ms -> 0.04 ms
lines=284 2.80 ms -> 0.24 ms
lines=1124 32.25 ms -> 2.49 ms
The unchecked `(Yaml.Scalar) entry.getValue()` is a crash rather than a
cost. The path matches the entry regardless of what its value holds, so
a sequence value throws `ClassCastException`:
java-version:
- 11
- 17
Adding `instanceof Yaml.Scalar` leaves those unchanged, matching how the
recipes already skip values they cannot interpret.
`SetupJavaDistributionReplacerVisitor` carries the same two problems, so
it gets the same guards, with the existing `originalDistributions`
membership test moved ahead of the matcher for the same reason.
`.editorconfig` sets `ij_continuation_indent_size = 2` for `src/test/java`, and every other test file in the repository follows it. This one used 8-space continuation steps, making it the sole outlier. Whitespace only; the text block contents are unchanged once the incidental indentation is stripped, which the tests confirm.
A sequence under `with` is not valid GitHub Actions input, so it is not worth covering. Drop those tests. `strategy.matrix.<name>` is valid and common, though, and it is the case the new key comparison actually puts at risk: the key name alone no longer distinguishes a matrix declaration from a step input, so these tests pin down that only the latter is rewritten. That also removes the reason for the `instanceof Yaml.Scalar` guards, which only ever caught the invalid spelling. The one place they were load-bearing was `SetupJavaDistributionReplacerVisitor`, where hoisting the `originalDistributions` test above the matcher let a matrix sequence reach the cast; putting the matcher back in front fixes that without the extra guard, and the matcher was always the expensive half anyway.
setup-java/setup-node version matchers on key and scalarJsonPathMatcher walk for non-matching keys in setup-java/setup-node recipes
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.
What's changed?
Carries the
JsonPathMatcheroptimization from #219 back to the recipes that PR was modelled on.JsonPathMatcher.matches, inSetupJavaUpgradeJavaVersion,SetupNodeUpgradeNodeVersionandSetupJavaDistributionReplacerVisitor.strategy.matrixtest per recipe.SetupNodeUpgradeNodeVersionTestto the continuation indent.editorconfigasks for (separate whitespace-only commit).What's your motivation?
JsonPathMatcher.matcheswalks the whole document: for a..-prefixed pathfind0starts atcursorPath.get(0), so calling it fromvisitMappingEntryre-visits the enclosing document once per mapping entry. Testing the key name first skips that walk for every entry that cannot match. Visit time on a synthetic workflow, parse excluded, mean of 10 warmed runs:Anything in particular you'd like reviewers to focus on?
The key comparison is the one thing here that could change behaviour, because the key name alone no longer distinguishes a matrix declaration from a step input:
None of the three recipes had any matrix coverage, so the new tests pin down that only the step input is considered. In
SetupJavaDistributionReplacerVisitorthis is load-bearing rather than theoretical: I first hoisted theoriginalDistributionsmembership test above the matcher, which let the matrix sequence reach(Yaml.Scalar) entry.getValue()and throwClassCastException. The matcher is back in front of it, anddoNotChangeMatrixDistributionfails if it moves again.Have you considered any alternatives or workarounds?
The other changes in #219 do not carry over:
-\n 18\nand a literal as\n 18\n, and the version pattern is anchored at a digit, so both already fall through.Semverrewrite has nothing to replace. These recipes parse a leading major with one regex and compare ints; they never attempt range arithmetic. Making the Node recipe understand ranges like^18or18.xwould be a behaviour change, so I left it out.I also had
instanceof Yaml.Scalarguards here for a sequence written directly underwith, but that is not valid GitHub Actions input, so covering it is not worth the code.Checklist
./gradlew build.