Vendored Maven and Gradle: design and prototype - #287
Mikola Lysenko (mikolalysenko) wants to merge 5 commits into
Conversation
Vendored Maven today works for a single pom.xml only. It refuses multi-module reactors and Gradle builds, which covers most enterprise Java. This design says how vendored mode should handle both without dropping any Maven or Gradle version that works today. - Maven uses the server's suffixed version (<v>-socket.<hex8>), found through a committed maven2 tree. Maven 3.9.2+ reads it through maven.repo.local.tail; every version also gets a file:// fallback repository and dependencyManagement pins in each local root pom. - Gradle keeps the same coordinates. One owned settings script, applied by one line, adds an exclusiveContent file repository and checks the vendored files' sha256 on every configuration. Lockfiles, catalogs and build.gradle files are never edited. - Build-time Maven pins (trusted checksums, deny lines) are opt-in for later. The adversarial review found crashes and silent no-ops in them on common Maven versions. The doc includes the supported-shapes matrix, the failure modes, the refusal-code mapping, the migration plan, the server/CLI split, the test plan, the panel scores and the adversarial review findings. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019ZLLAZfofQZ2ywkgrHkdEZ
|
CI note: This isn't caused by this PR. The head commit only adds Generated by Claude Code |
Workspace clippy with -D warnings failed on two fields of the covgap_commands_rollback fixture that nothing reads. The hashes are still computed and used to stage the manifest and blobs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019ZLLAZfofQZ2ywkgrHkdEZ
Vendored Maven refuses multi-module reactors and Gradle builds today. With SOCKET_PATCH_EXPERIMENTAL_JVM_VENDOR=1 set, those two shapes now go to a new backend (vendor/jvm) that implements the v5.0 cut of docs/design/maven-vendoring.md. With the variable unset, nothing that vendors today behaves differently. - Maven reactor: pins the server's suffixed version in every local root pom and rewrites literal and property declarations (including in profiles and middle parents). Adds one shared file:// fallback repository, two .mvn/maven.config lines (offline file protocol and maven.repo.local.tail) and a committed maven2 tree. - Gradle: keeps the same coordinates. One apply line per settings file (root, buildSrc, literal includeBuild) loads an owned script. It adds an exclusiveContent file repository and fails configuration if a vendored file's sha256 no longer matches the index. Lockfiles, catalogs and build scripts are never edited; an existing verification-metadata.xml gets the patched hash. - Revert is per fragment and byte-exact in any order. Shared pieces stay until no other patch uses them. Re-runs, patch updates, --preserve-state, the cold-cache fast path, VEX liveness and repair all handle the new trees. The real-tool capstones (e2e_vendor_jvm_build, ignored by default) build a reactor and a locked Kotlin DSL Gradle build offline from a fresh checkout. They pass on Maven 3.8.8 to 4.0.0-rc-7 and Gradle 6.9.4 to 9.8.0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019ZLLAZfofQZ2ywkgrHkdEZ
|
CI note for head 251b7a3: the Generated by Claude Code |
The previous commit dropped two fixture fields to quiet clippy on Linux. A macOS-only test reads them, so the macOS test build broke. Restore the fields and allow dead code on other platforms instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019ZLLAZfofQZ2ywkgrHkdEZ
The owned Gradle script is embedded with include_str! and written into user repos as is. A Windows checkout with autocrlf turned it into CRLF, so Windows builds would write different script bytes (and the script sanity test failed there). Mark it -text like the other byte-exact files. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019ZLLAZfofQZ2ywkgrHkdEZ
|
#283 landed on release/v5-prerelease as 06437d2; please merge origin/release/v5-prerelease again, resolve conflicts, get green, and keep it ready. Generated by Claude Code |
|
[agent] Not ready yet. The agent session's permission check is blocking the steps needed to land this.
Needed from a human or another session with push rights:
The only CI failures still expected are the base-branch ones already noted above. Generated by Claude Code |
|
#281 landed on release/v5-prerelease as 73c0c4f; please merge origin/release/v5-prerelease again, resolve conflicts, get green, and keep it ready. Generated by Claude Code |
|
#279 landed on release/v5-prerelease as f6bdad5; please merge origin/release/v5-prerelease again, resolve conflicts, get green, and keep it ready. Generated by Claude Code |
|
#282 landed on release/v5-prerelease as 14a9cb0; please merge origin/release/v5-prerelease again, resolve conflicts, get green, and keep it ready. Generated by Claude Code |
|
Coordinator: #287 is next in the landing order but is blocked: it is still a draft, has no Generated by Claude Code |
|
[agent] Replying to the coordinator: the blocker from my earlier comment (5870683708) still applies.
Until that happens, please skip #287 in the landing order. Generated by Claude Code |
|
#294 landed on release/v5-prerelease as 180f10f; please merge origin/release/v5-prerelease again, resolve conflicts, get green, and keep it ready. Generated by Claude Code |
Vendored Maven works today only for a single
pom.xml. It refuses multi-module reactors and Gradle builds, which covers most enterprise Java. This PR adds a design for vendoring both, plus a prototype behind a flag.Design:
docs/design/maven-vendoring.md<v>-socket.<hex8>) from a committed.socket/vendor/maven2tree.maven.repo.local.tailin.mvn/maven.config. It copies nothing into~/.m2, andmirrorOf *does not affect it.file://${maven.multiModuleProjectDirectory}fallback repository.dependencyManagementpins go into each local root pom, and literal and property declarations are rewritten, including in profiles and middle parents.exclusiveContentfile repository and fails configuration if a vendored file's sha256 no longer matches the committed index.verification-metadata.xmlgets the patched hash.system-scope dependencies, and enforce nothing on Maven 3.9.2–3.9.3.mvn -f <root>/pom.xmlrun from outside the project root fails whenmaven.configuses${session.rootDirectory}. The design warns about it and offers--maven-config=none.Prototype:
crates/socket-patch-core/src/vendor/jvm/SOCKET_PATCH_EXPERIMENTAL_JVM_VENDOR=1, and only for shapes that are refused today. Nothing that vendors today behaves differently.--preserve-state, a cold local cache, VEX liveness and repair.Tests
e2e_vendor_jvm_build,#[ignore]): a reactor, and a Kotlin DSL Gradle build with FAIL_ON_PROJECT_REPOS and STRICT dependency locking. Both build offline from a fresh checkout; Gradle lockfiles stay byte-unchanged, and a tampered vendored jar fails the build. They pass on Maven 3.8.8, 3.9.2, 3.9.11 and 4.0.0-rc-7, and on Gradle 6.9.4, 7.6.4, 8.14.3 and 9.8.0.vendor::jvmand 6 subprocess tests invendor_jvm_cli. The existingin_process_vendor, repair, rollback, VEX and ledger-schema suites, and the legacy vendored-Maven capstone, still pass.cargo clippy --workspace --all-targets --all-features -- -D warningsis clean. That needed a separate commit dropping two unused fields incovgap_commands_rollback.rs, which already failed clippy on the base branch.e2e_redirect_cargo_buildfails the same way on the base branch head 8ae7dc3 (commented below).🤖 Generated with Claude Code
https://claude.ai/code/session_019ZLLAZfofQZ2ywkgrHkdEZ