[
https://issues.apache.org/jira/browse/GROOVY-12005?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18079994#comment-18079994
]
Paul King commented on GROOVY-12005:
------------------------------------
Here are the major commits with GitHub URLs, grouped by what they delivered:
## Diagnostic & CI cache (first wave)
- [`dea71cc8df`](https://github.com/apache/groovy/commit/dea71cc8df) — github
actions for grape caching (adds `actions/cache` for `~/.groovy/grapes` + the
`groovy-purge-grape-cache.yml` scrub workflow)
- [`f597292f28`](https://github.com/apache/groovy/commit/f597292f28) — improved
error message for some cases when `.groovy/grapes` cache is corrupt (PR1
diagnostic hint)
## StrictLocalM2Resolver (PR2)
- [`1559a9d12a`](https://github.com/apache/groovy/commit/1559a9d12a) — *titled*
"turn on ivy debugging temporarily" *but actually carries*
`StrictLocalM2Resolver` + its test + the `defaultGrapeConfig.xml`
`<strict-localm2>` wiring
- [`2e3257a562`](https://github.com/apache/groovy/commit/2e3257a562) —
`StrictLocalM2Resolver`: flip default to on (opt-out via
`-Dgroovy.grape.strict-localm2=false`)
## Cloudflare / User-Agent workaround
- [`07e99d65ba`](https://github.com/apache/groovy/commit/07e99d65ba) — user
agent workaround (initial: GrapeIvy static init + test plugin JVM arg)
- [`799693c5df`](https://github.com/apache/groovy/commit/799693c5df) — switch
to Maven-shaped UA `Apache-Maven/x.y.z (Java X; OS X)`; use `systemProperty` so
spaces in the value reach the test JVM intact
## Test infra: bridge, pre-warm, forwarder
- [`c18dd839c7`](https://github.com/apache/groovy/commit/c18dd839c7) — bridge
`~/.groovy/grapes` + `~/.m2/repository` into per-task test temp; add Maven
`dependency:get` pre-warm step to workflows; extend `actions/cache` to cover m2
- [`06645cd674`](https://github.com/apache/groovy/commit/06645cd674) —
`ForkedJvmExtension`: always inherit `http.agent` into child JVMs
- [`f68a20639e`](https://github.com/apache/groovy/commit/f68a20639e) — generic
`groovy.grape.*` property forwarder in test plugin (replaces per-flag wiring)
## StrictCachedGrapesResolver (this session, final)
- [`df8fc81071`](https://github.com/apache/groovy/commit/df8fc81071) —
`StrictCachedGrapesResolver` + test + `defaultGrapeConfig.xml` wiring. Refuses
stub synthesis from artifact-only state; rejects existing cached descriptors
lacking the companion `.original` POM (self-heals corrupted caches by forcing
fall-through to ibiblio).
## Related (already on master before this saga)
- [`b6169df6e2`](https://github.com/apache/groovy/commit/b6169df6e2) —
GROOVY-12004: grape command line tool should accept maven/ivy shorthands.
Separate UX work (Maven/Ivy shorthand parsing in `grape install` and
`Grape.grab(String)`), not part of the robustness story but landed in the same
window.
If you want a single bisect range covering just the robustness work:
`dea71cc8df..df8fc81071` (with `b6169df6e2` excluded if you prefer to keep the
shorthand-parsing as a separate ticket).
> Harden Grape against cache corruption and CDN throttling
> --------------------------------------------------------
>
> Key: GROOVY-12005
> URL: https://issues.apache.org/jira/browse/GROOVY-12005
> Project: Groovy
> Issue Type: Improvement
> Components: Grape
> Reporter: Paul King
> Assignee: Paul King
> Priority: Major
>
> h2. Grape robustness measures
> Two complementary cache-validation guards plus a CDN compatibility fix,
> addressing
> hard-to-diagnose @Grab failures caused by half-populated caches and
> Cloudflare's
> recent filtering of the JDK URLConnection default User-Agent.
> h3. Cache resilience
> * New {{StrictLocalM2Resolver}} (extends {{IBiblioResolver}}) — rejects a
> {{localm2}} entry when its POM has no JAR alongside (typical
> {{staged-releases}} lineage). Resolution falls through to {{ibiblio}}
> instead of failing with "download failed". Default-on; opt-out
> {{-Dgroovy.grape.strict-localm2=false}}.
> * New {{StrictCachedGrapesResolver}} (extends {{FileSystemResolver}},
> {{descriptor="required"}}) — refuses to synthesise stub descriptors from
> artifact-only state, and refuses cached ivy descriptors lacking the
> companion {{.original}} POM (which signals a previously-synthesised stub).
> Self-heals existing corruption by forcing fall-through. Default-on; opt-out
> {{-Dgroovy.grape.strict-cached-grapes=false}}.
> h3. CDN compatibility
> * {{GrapeIvy}} static initializer sets {{http.agent}} to a Maven-shaped
> User-Agent {{Apache-Maven/x.y.z (Java X; OS X)}}, since Maven Central
> (Fastly) returns HTTP 404 to the JDK default {{Java/<version>}}.
> Covers CLI and standalone script use.
> * Build plugin {{org.apache.groovy-tested}} sets the same value as a JVM
> arg for test JVMs (static init runs too late for already-warm test JVMs).
> * {{ForkedJvmExtension}} always inherits {{http.agent}} into child JVMs.
> h3. Diagnostics & generality
> * {{GrapeIvy.getDependencies}} now appends an actionable hint when a failure
> matches the half-populated {{localm2}} pattern, naming the artifact, the
> cache paths to clean, and the {{mvn dependency:get}} command.
> * Test plugin generically forwards any {{groovy.grape.*}} system or project
> property to test JVMs (covers strict-localm2, strict-cached-grapes, plus
> any future flag).
> h3. Test infrastructure
> * CI workflow pre-warms {{~/.m2/repository}} via {{mvn dependency:get}}
> for every {{@Grab}} coord discovered in test sources (Maven uses
> Apache HttpClient and isn't filtered by Cloudflare). Bridge copies
> the warm cache into each test task's isolated temp at task start.
> * {{actions/cache}} extended to persist {{~/.m2/repository}} alongside
> {{~/.groovy/grapes}} between runs.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)