Repository navigation
Description
[agent] Filed by the scheduled architecture audit (audit-core). Register: #1830 register.
Kind: bug. Register ID: A72.
Problem
gradle/wrapper/gradle-wrapper.properties is read by three different readers, and they disagree on which Gradle version a build pins:
crawlers::gradle_cache::parse_properties+WrapperProps::of:``` a realjava.util.Propertiesreader (`=`/`:`/whitespace separators, escapes, continuation lines, a later key wins). Used only for init-script discovery.gradle::graph::wrapper_version: takes the first line that starts withdistributionUrl(sodistributionUrlBackup=…matches too) and joins no continuation lines. It drives the hosted "Gradle 6.8 or newer" refusal (redirect/gradle.rs L697-L705).````vendor::jvm::wrapper_version: needs the exact prefixdistributionUrl=(no spaces around=, no:, no BOM). It drives the vendored "Gradle 6.8 or newer" refusal (vendor/jvm/gradle.rs L261-L266) and the Maven-wrapper warnings (maven_reactor.rs L154-L160).`````
A fourth spot derives the distribution name from the URL again: GradleHome::wrapper_init_dirs beside WrapperProps::name.``````
Executed (the three functions copied verbatim from main @ cbbbdb9 into a scratch crate):
gradle-wrapper.properties |
graph (hosted gate) |
vendor::jvm (vendored gate) |
parse_properties (what Gradle reads) |
|---|---|---|---|
distributionUrl = https\\://…/gradle-6.7-bin.zip |
(6, 7, 0): refused | None: not refused | gradle-6.7 |
BOM + distributionUrl=…/gradle-6.7-bin.zip |
(6, 7, 0): refused | None: not refused | gradle-6.7 |
distributionUrlBackup=…/gradle-6.9.4… then distributionUrl=…/gradle-8.14.3… |
(6, 9, 4) | (8, 14, 3) | gradle-8.14.3 |
two distributionUrl lines, 6.9.4 then 8.14.3 |
(6, 9, 4) | (6, 9, 4) | gradle-8.14.3 (last wins) |
distributionUrl=…/distributions/\\ + continuation gradle-8.14.3-bin.zip |
None | None | gradle-8.14.3 |
So a Gradle 6.7 build written with distributionUrl = … (or saved with a BOM) is refused in hosted mode and vendored anyway. The two hosted/vendored gates also feed the major that selects Gradle 6 vs 7+ range semantics.
Proposed change
- Move
parse_propertiesandWrapperPropsout ofcrawlers::gradle_cacheinto a puregradle::wrappermodule overTextReadFn(thegradlemodule already forbidsstd::fs;WrapperProps::ofkeeps a thin disk adapter in the crawler). - Add
WrapperProps::version() -> Option<(u32, u32, u32)>and deletegraph::wrapper_version. - Make
vendor::jvm::wrapper_versionread through the same properties parser for both tools (.mvn/wrapper/maven-wrapper.propertiesis a.propertiesfile too), or delete it in favour of the shared one. home::wrapper_init_dirstakes the distribution name fromWrapperProps::nameinstead of re-deriving it.
Size
4–5 files (gradle/{mod,graph,home}.rs, new gradle/wrapper.rs, crawlers/gradle_cache.rs, vendor/jvm/mod.rs); about −60/+40 lines.
Acceptance criteria
- One properties reader for wrapper files;
grep -rn 'strip_prefix("distributionUrl' cratesfinds nothing. - New unit cases for the five rows above, asserting the same version from the hosted and the vendored gate.
graph::tests::android_kmp_and_wrapper_versionandgradle_cache'sparse_properties_*tests keep passing (moved with the code).
Generated by Claude Code
Activity
audit-core: golden, gradle/*, hash/*, engine.rs to L960 (A72 #1963, A73)
mikolalysenko commentedon Nov 2, 2026
[agent] Triage:
priority:p3(Gradle/Maven wrapper parsing, cross-cutting refactor). No duplicate or open PR found.Generated by Claude Code