Repository navigation
Vendored Gradle: on a Windows (core.autocrlf=true) checkout, vendor --check fails and vendor --revert / remove / rollback leave the settings script behind, because the index and script aren't covered by the -text .gitattributes #429
Description
[agent] Found by the scheduled Gradle bug-hunt routine (ledger #319).
Summary
Gradle vendoring commits two text files that later commands compare byte for byte: .socket/gradle/socket-patch.settings.gradle and .socket/vendor/gradle-index.tsv. The * -text .gitattributes it writes covers only .socket/vendor/gradle/ (GITATTRIBUTES_REL), so neither file is protected. Git for Windows ships core.autocrlf=true in its system gitconfig, as GitHub's windows-latest runners do (file:C:/Program Files/Git/etc/gitconfig true). On such a checkout both files come out CRLF, and:
vendor --checkfails on a pristine checkout: exit 1,partialFailure,vendor_check_failed: "vendored wiring or metadata drifted: .socket/gradle/socket-patch.settings.gradle". After fixing that file, it reports…: .socket/vendor/gradle-index.tsv. Any Windows CI that gates onvendor --check(the documented offline integrity audit) is permanently red.vendor --revert,remove <purl>androllbackexit 0 but leave.socket/gradle/socket-patch.settings.gradlebehind, withvendor_lock_entry_drifted(".socket/gradle/socket-patch.settings.gradle was modified; left alone"), so the revert isn't clean. In the buildSrc scenario,buildSrc/settings.gradle(created by vendor) is also left behind asMinstead of being removed.
The Gradle build itself is fine: the script is CRLF-tolerant and the jar/pom are protected by -text, so :printCp resolves the patched vendored jar. Only socket-patch's own audit and revert are wrong.
Repro (Linux, simulating the Windows default)
I used the e2e_vendor_jvm_build patch-service fixture and a staged manifest + blob for pkg:maven/org.apache.commons/commons-text@1.10.0, as in gradle_multi_project_vendor_locked_offline_tamper_and_byte_exact_revert. The Gradle-only project is settings.gradle + a Groovy build.gradle with repositories { mavenCentral() } and implementation 'org.apache.commons:commons-text:1.10.0'.
socket-patch vendor --json --offline # exit 0, applied 1
git init -q && git add -A && git commit -qm vendored
git -c core.autocrlf=true clone -q . ../win && cd ../win
file .socket/vendor/gradle-index.tsv .socket/gradle/socket-patch.settings.gradle # both "with CRLF line terminators"
socket-patch vendor --check --json # exit 1: vendor_check_failed "...drifted: .socket/gradle/socket-patch.settings.gradle"
sed -i 's/\r$//' .socket/gradle/socket-patch.settings.gradle
socket-patch vendor --check --json # exit 1: "...drifted: .socket/vendor/gradle-index.tsv"
sed -i 's/\r$//' .socket/vendor/gradle-index.tsv
socket-patch vendor --check --json # exit 0: vendor_check_ok
# fresh CRLF clone again:
socket-patch vendor --revert --json --offline # exit 0, skipped vendor_lock_entry_drifted; the script file remainsControls: a core.autocrlf=input clone, or an LF clone, gives vendor_check_ok, and revert removes everything. A CRLF settings.gradle on its own is handled correctly (the apply-line fragment matches across endings).
Expected vs actual
- Expected:
docs/design/maven-vendoring.mdsays vendoring commits "a local repository so another checkout can build without socket-patch", and thatvendor --check"checks artifact hashes, recorded tree files, wiring, Gradle's index and script".docs/ecosystems.mdsets the precedent: vlt's vendored tree carries "a.gitattributesthat turns EOL conversion off so anautocrlfcheckout stays byte-exact". A normal Windows checkout of a committed vendored project should passvendor --checkand revert cleanly. - Actual:
vendor --checkexits 1 on a pristine Windows checkout. Revert, remove and rollback exit 0 but leave socket-owned files behind.
OS × Gradle
Probe run (real windows-latest, default Git for Windows config, real Gradle builds): https://github.com/SocketDev/socket-patch/actions/runs/36821988108
| OS | Gradle | vendor --check on fresh clone |
revert on fresh clone | Gradle build |
|---|---|---|---|---|
| Windows (autocrlf=true default) | 6.9.4 (JDK 11) | exit 1 | script left behind | patched ✓ |
| Windows | 7.6.6 (JDK 17) | exit 1 | script left behind | patched ✓ |
| Windows | 9.8.0 (JDK 21) | exit 1 | script left behind | patched ✓ |
Linux, git -c core.autocrlf=true clone |
8.14.3 | exit 1 (2/2) | script left behind | patched ✓ |
| Linux / macOS, default git | 6.9.4 / 7.6.6 / 9.8.0 | ok | clean | patched ✓ (run https://github.com/SocketDev/socket-patch/actions/runs/36821273765) |
First bad version: main 2463257 (#277), which introduced Gradle vendoring.
Suspect code
crates/socket-patch-core/src/vendor/jvm/gradle.rs:32:GITATTRIBUTES_REL = ".socket/vendor/gradle/.gitattributes"only covers the artifact tree, notINDEX_REL(.socket/vendor/gradle-index.tsv) orSCRIPT_REL(.socket/gradle/socket-patch.settings.gradle).crates/socket-patch-core/src/vendor/jvm/apply.rs:767:vendor --checkre-plans and treats any byte difference in a planned write as drift. The revert's owned-file comparison behaves the same way (vendor_lock_entry_drifted,apply.rs:449/:529).
I haven't checked whether the Maven reactor backend's LF files (.mvn/maven.config) have the same exposure. That belongs to the maven routine.
Activity
mikolalysenko commentedon Oct 1, 2026
[agent] Triaged:
priority:p3(Gradle). Not a duplicate. This is the Gradle side of the-textcoverage gap: the vendored.gitattributescovers only the jar/pom tree, while the index and the settings script are compared byte for byte. It is related to the CRLF reports for Maven pom edits (#273), but the code path is different. No open PR covers it.Generated by Claude Code
mikolalysenko commentedon Oct 2, 2026
[agent] Claiming this issue as part of the full Gradle support campaign (agent / hosted / vendored modes, tested on Gradle 6.9/7.6/8.x/9.x on Linux, macOS and Windows). Branch: feat/gradle-support. Claim-ID: 2026-10-02T13:56:32Z-gradle21
Generated by Claude Code
Full Gradle support in agent, hosted and vendored modes (#646)
Compare sbt and scala-cli owned files line-ending-blind
sbt, Mill and scala-cli support in agent, hosted and vendored modes (#…