You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit ae775fb
Browse filesBrowse the repository at this point in the historyBrowse files
feat(v5): implement vendored Maven reactors and Gradle builds (#287)
* Add the vendored Maven and Gradle design
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
* Drop unused rollback fixture hash fields
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
* Prototype vendored Maven reactors and Gradle
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
* Keep rollback fixture hashes for the macOS test
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
* Check out the Gradle settings script byte for byte
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
* feat: complete v5 Maven reactor and Gradle vendoring
* test: close v5 validation gaps and require JVM toolchains
* test: align v5 help and canonical restore goldens
* test: make JVM build capstones portable on Windows
* ci: extract Maven without interpreting Windows drives as hosts
* ci: use native-path Maven extraction and parallelize build checks
* test: normalize paths in Gradle integrity diagnostics
---------
Co-authored-by: Claude <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: crates/socket-patch-cli/CLI_CONTRACT.md
+25-1Lines changed: 25 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -42,7 +42,7 @@ Rows are in `--help` order (v5.0): the hosted/vendored workflow (`scan` → `vex
42
42
43
43
## Global arguments
44
44
45
-
Every subcommand accepts the same set of "global" flags via a single shared `GlobalArgs` struct that's `#[command(flatten)]`-ed into each per-command struct (`crates/socket-patch-cli/src/args.rs`). Subcommands that don't actually consume a given flag accept it silently — e.g. `list --global` parses fine and is a no-op. Every flag also has an environment-variable binding; precedence is **CLI arg > env var > default** — and for exactly three keys (`--api-token`, `--org`, `--api-url`) the JS socket-cli's persisted login sits between env var and default: **CLI arg > env var (canonical, then `SOCKET_CLI_*` alias) > socket-cli `config.json` > default**. See "Persisted configuration" under Environment variables.
45
+
Every subcommand accepts the same set of "global" flags via a single shared `GlobalArgs` struct that's `#[command(flatten)]`-ed into each per-command struct (`crates/socket-patch-cli/src/args.rs`). Subcommands that don't actually consume a given flag accept it silently — e.g. `list --global` parses fine and is a no-op. For flags with an environment-variable binding, precedence is **CLI arg > env var > default** — and for exactly three keys (`--api-token`, `--org`, `--api-url`) the JS socket-cli's persisted login sits between env var and default: **CLI arg > env var (canonical, then `SOCKET_CLI_*` alias) > socket-cli `config.json` > default**. See "Persisted configuration" under Environment variables.
46
46
47
47
| Long | Short | Env var | Default | Type | Semantic |
48
48
|---|---|---|---|---|---|
@@ -55,6 +55,7 @@ Every subcommand accepts the same set of "global" flags via a single shared `Glo
55
55
|`--ecosystems`|`-e`|`SOCKET_ECOSYSTEMS`| (all) | CSV → `Vec<String>`| Restrict to these ecosystems |
56
56
|`--download-mode`| — |`SOCKET_DOWNLOAD_MODE`|**`diff`**| enum: `diff`\|`file` (`package` was removed and is rejected) | Patch artifact format |
57
57
|`--vendor-source`| — |`SOCKET_VENDOR_SOURCE`|**`auto`**| enum: `auto`\|`service`\|`build`| How `vendor` acquires the installable artifact (see "Prebuilt vendor artifacts") |
58
+
|`--maven-config`| — | — | (recorded choice, else `auto`) | enum: `auto`\|`none`| Maven reactor vendoring: write the repository tail (`auto`) or use only the fallback file repository (`none`). The choice persists in the vendor ledger. |
58
59
|`--vendor-url`| — |`SOCKET_VENDOR_URL`| (active API/proxy base) | string | Base host for the vendoring-service package-reference request |
59
60
|`--patch-server-url`| — |`SOCKET_PATCH_SERVER_URL`| (server-returned) | string | Override the host of the prebuilt-archive download URL (local-dev / testing) |
60
61
|`--offline`| — |`SOCKET_OFFLINE`|`false`| bool |**Strict airgap on every command** — never contact the network |
@@ -87,6 +88,8 @@ Beyond the globals above, each subcommand defines a small set of local arguments
87
88
|`apply`|`--check`| — | Read-only audit that the committed **Go**`replace`-redirects match the manifest (CI / GitHub-App auditing) — Go ONLY (cargo patches in place, so there is no redirect to audit). Lock-free, crawl-free, offline-safe; exits 0 in sync, 1 on drift. Vendored modules are excluded from the audit |
88
89
|`vendor`|`--force` / `-f`|`SOCKET_FORCE`| Tolerate missing patch-target files in the stage + bypass the variant probe. A beforeHash mismatch no longer needs it: vendor staging auto-overwrites with the verified patched content (`vendor_content_mismatch_overwritten` warning) |
89
90
|`vendor`|`--revert`|`SOCKET_VENDOR_REVERT`| Undo vendoring: restore recorded original lockfile fragments + remove `.socket/vendor/` artifacts. Works without a manifest. A package vendored over a hosted pin returns to its upstream registry entry, never to hosted (see "Takeover reconciliation") |
91
+
|`vendor`|`--check`| — | Offline, read-only artifact and wiring audit; exits 1 on drift. Conflicts with `--revert`. |
92
+
|`vendor`|`--local-repo <path>`| — | With `--check`, also inspect suffixed Maven jar/POM copies in this cache for conflicts. |
90
93
|`apply`, `scan`, `vendor`|`--vex`|`SOCKET_VEX`| Generate an OpenVEX 0.2.0 document at this path on a successful run; see "embedded VEX" below |
91
94
|`apply`, `scan`, `vendor`|`--vex-product`, `--vex-no-verify`, `--vex-doc-id`, `--vex-compact`|`SOCKET_VEX_PRODUCT`, `SOCKET_VEX_NO_VERIFY`, `SOCKET_VEX_DOC_ID`, `SOCKET_VEX_COMPACT`| Passthrough to the embedded VEX builder; mirror the standalone `vex` knobs. Inert unless `--vex` is set |
92
95
|`scan`| positional `[PATHS]...`| — | (v5.0) Meaning depends on the mode. **Hosted / vendored** (bare `scan` included): each PATH, or directory glob (`apps/*`), is a project directory scanned on its own as if it were `--cwd`. **Agent** (and a mode-less `--prune`/`--global` report): path globs scoping DISCOVERY to packages installed under matching paths (`packages/foo`, `apps/**`). See "Path-scoped scans" below |
@@ -1722,3 +1725,24 @@ Every item in this document is locked in by at least one of:
1722
1725
-**Async `run()` integration tests** in `tests/cli_parse_list.rs`, `tests/cli_parse_remove.rs` — exercise the no-network error paths and assert JSON shape via `serde_json::from_str::<Value>` + per-key assertions.
1723
1726
1724
1727
If you add a new flag/subcommand/JSON key, add a test here that locks the new surface in the same PR.
1728
+
1729
+
1730
+
### Vendored JVM support (v5)
1731
+
1732
+
Maven reactors and Gradle 6.8+ route to the JVM backend automatically. Ledger
1733
+
entries use ecosystem `jvm` with Maven PURLs. Revert, remove, rollback and repair
1734
+
share the v5 vendored backend; existing prototype wiring remains readable.
1735
+
See [the JVM design](../../docs/design/maven-vendoring.md) for supported shapes.
1736
+
1737
+
`vendor --check` is an offline, read-only audit. Healthy entries emit `verified`
1738
+
with `vendor_check_ok`; drift emits `failed` with `vendor_check_failed`, a
1739
+
`partialFailure` envelope and exit 1. Missing ledger entries fail with
1740
+
`vendor_ledger_missing`. Offline upstream metadata is reported as the run warning
1741
+
`vendor_jvm_upstream_unverified`. The check never starts an API client or writes
1742
+
lock/recovery files. `--check` conflicts with `--revert`.
0 commit comments