Skip to content

Commit 7367910

Browse files
committed
bughunt maven probe: global repo discovery
1 parent 2463257 commit 7367910

1 file changed

Lines changed: 93 additions & 0 deletions

File tree

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
name: bughunt-maven probe
2+
on:
3+
push:
4+
branches: ['bughunt/maven/**']
5+
permissions:
6+
contents: read
7+
jobs:
8+
probe:
9+
strategy:
10+
fail-fast: false
11+
matrix:
12+
os: [ubuntu-latest, macos-latest, windows-latest]
13+
runs-on: ${{ matrix.os }}
14+
timeout-minutes: 45
15+
steps:
16+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
17+
- name: Build
18+
shell: bash
19+
run: cargo build --release -p socket-patch-cli
20+
- name: Probe Maven global discovery
21+
shell: bash
22+
run: |
23+
cat > "$RUNNER_TEMP/probe.py" <<'PY'
24+
import http.server, json, os, subprocess, sys, tarfile, threading, urllib.request, shutil, tempfile, re
25+
WIN = os.name == "nt"
26+
SP = os.path.abspath("target/release/socket-patch" + (".exe" if WIN else ""))
27+
T = os.environ["RUNNER_TEMP"]
28+
LOG = []
29+
class H(http.server.BaseHTTPRequestHandler):
30+
def _r(self):
31+
n = int(self.headers.get("Content-Length") or 0)
32+
LOG.append(self.rfile.read(n).decode() if n else self.path)
33+
out = json.dumps({"packages": [], "canAccessPaidPatches": False}).encode()
34+
self.send_response(200); self.send_header("Content-Type", "application/json")
35+
self.send_header("Content-Length", str(len(out))); self.end_headers(); self.wfile.write(out)
36+
do_GET = _r; do_POST = _r
37+
def log_message(self, *a): pass
38+
srv = http.server.ThreadingHTTPServer(("127.0.0.1", 0), H)
39+
threading.Thread(target=srv.serve_forever, daemon=True).start()
40+
PROXY = f"http://127.0.0.1:{srv.server_address[1]}"
41+
home = os.path.expanduser("~")
42+
m2 = os.path.join(home, ".m2")
43+
proj = os.path.join(T, "proj"); os.makedirs(proj, exist_ok=True)
44+
open(os.path.join(proj, "pom.xml"), "w").write('<project xmlns="http://maven.apache.org/POM/4.0.0"><modelVersion>4.0.0</modelVersion><groupId>t</groupId><artifactId>p</artifactId><version>1</version></project>')
45+
def mvn_bin(v):
46+
d = os.path.join(T, f"apache-maven-{v}")
47+
if not os.path.isdir(d):
48+
major = v.split(".")[0]
49+
url = f"https://archive.apache.org/dist/maven/maven-{major}/{v}/binaries/apache-maven-{v}-bin.tar.gz"
50+
p = os.path.join(T, f"m{v}.tgz"); urllib.request.urlretrieve(url, p)
51+
tarfile.open(p).extractall(T)
52+
return d, os.path.join(d, "bin", "mvn.cmd" if WIN else "mvn")
53+
def mvn(m, args, env=None):
54+
cmd = f'"{m}" -B ' + " ".join(args)
55+
r = subprocess.run(cmd, shell=True, cwd=proj, env=env or os.environ.copy(), capture_output=True, text=True)
56+
return r.returncode, r.stdout + r.stderr
57+
def maven_repo(m, env=None):
58+
rc, out = mvn(m, ["-X", "-o", "validate"], env)
59+
g = re.search(r"Using local repository at (\S+)", out)
60+
return g.group(1) if g else f"?(rc={rc})"
61+
def scan(env):
62+
LOG.clear()
63+
r = subprocess.run([SP, "scan", "-g", "--json", "--proxy-url", PROXY, "--ecosystems", "maven"], cwd=proj, env=env, capture_output=True, text=True)
64+
try: n = json.loads(r.stdout).get("scannedPackages")
65+
except Exception: n = f"nojson rc={r.returncode} {r.stderr[:200]}"
66+
return n, any("commons-text@1.10.0" in l for l in LOG)
67+
rows = []
68+
for v in ["3.6.3", "3.9.11", "4.0.0-rc-7"]:
69+
d, m = mvn_bin(v)
70+
shutil.rmtree(m2, ignore_errors=True)
71+
rc, out = mvn(m, ["org.apache.maven.plugins:maven-dependency-plugin:3.1.2:get", "-Dartifact=org.apache.commons:commons-text:1.10.0"])
72+
if rc != 0: rows.append((v, "seed", f"seed failed rc={rc}", out[-400:])); continue
73+
base = {k: val for k, val in os.environ.items() if k not in ("M2_HOME", "MAVEN_REPO_LOCAL")}
74+
rows.append((v, "default", maven_repo(m, base), scan(base)))
75+
e = dict(base, M2_HOME=d)
76+
rows.append((v, "M2_HOME=<maven install>", maven_repo(m, e), scan(e)))
77+
if WIN:
78+
other = os.path.join(T, "githome"); os.makedirs(other, exist_ok=True)
79+
e = dict(base, HOME=other)
80+
rows.append((v, "HOME!=USERPROFILE", maven_repo(m, e), scan(e)))
81+
e = {k: val for k, val in base.items() if k != "HOME"}
82+
rows.append((v, "HOME unset", maven_repo(m, e), scan(e)))
83+
custom = os.path.join(T, f"custom repo {v}")
84+
shutil.rmtree(m2, ignore_errors=True); os.makedirs(m2)
85+
open(os.path.join(m2, "settings.xml"), "w").write(f"<settings><localRepository>{custom}</localRepository></settings>")
86+
rc, out = mvn(m, ["org.apache.maven.plugins:maven-dependency-plugin:3.1.2:get", "-Dartifact=org.apache.commons:commons-text:1.10.0"], base)
87+
rows.append((v, "settings.xml <localRepository>", maven_repo(m, base), scan(base) if rc == 0 else f"seed rc={rc}"))
88+
os.remove(os.path.join(m2, "settings.xml"))
89+
print(f"OS={sys.platform} HOME={os.environ.get('HOME')} USERPROFILE={os.environ.get('USERPROFILE')} expanduser={home}")
90+
for r in rows: print("ROW", " | ".join(str(x) for x in r))
91+
PY
92+
PYBIN=python3; if [ "$RUNNER_OS" = Windows ]; then PYBIN=python; fi
93+
"$PYBIN" "$RUNNER_TEMP/probe.py"

0 commit comments

Comments
 (0)