scripts/bootstrap_git.py (2556B)
1 #!/usr/bin/env python3
2 """Build a pinned, patched Git locally without modifying the system installation."""
3
4 import hashlib
5 import os
6 from pathlib import Path
7 import subprocess
8 import tarfile
9 from urllib.request import urlopen
10
11 ROOT = Path(__file__).resolve().parents[1]
12 VERSION = "2.56.1"
13 SHA256 = "f0b0bf89264b9bd2e1c640363e7529643989da76281600473c50745cd34a607f"
14
15
16 def main():
17 if os.name == "nt":
18 raise SystemExit("Run this script inside WSL Ubuntu")
19 cache = ROOT / ".cache/secure-git"
20 cache.mkdir(parents=True, exist_ok=True)
21 archive = cache / f"git-{VERSION}.tar.xz"
22 if not archive.exists():
23 with urlopen(f"https://www.kernel.org/pub/software/scm/git/{archive.name}", timeout=90) as response:
24 data = response.read(32 * 1024 * 1024 + 1)
25 if len(data) > 32 * 1024 * 1024:
26 raise RuntimeError("Git source archive exceeds the download limit")
27 archive.write_bytes(data)
28 if hashlib.sha256(archive.read_bytes()).hexdigest() != SHA256:
29 raise RuntimeError("Git source checksum does not match the pinned upstream release")
30 source = cache / f"git-{VERSION}"
31 if not source.exists():
32 with tarfile.open(archive) as bundle:
33 bundle.extractall(cache, filter="data")
34 prefix = cache / "installed"
35 options = [f"prefix={prefix}", "NO_GETTEXT=YesPlease", "NO_TCLTK=YesPlease",
36 "NO_PERL=YesPlease", "NO_PYTHON=YesPlease", "NO_EXPAT=YesPlease"]
37 if not Path("/usr/include/x86_64-linux-gnu/curl/curl.h").exists():
38 # Obtain Ubuntu's authenticated development package without root access.
39 packages = cache / "curl-dev"
40 packages.mkdir(exist_ok=True)
41 subprocess.run(["apt-get", "download", "libcurl4-openssl-dev"], cwd=packages, check=True, timeout=120)
42 candidates = list(packages.glob("libcurl4-openssl-dev_*.deb"))
43 if len(candidates) != 1:
44 raise RuntimeError("Expected exactly one curl development package")
45 subprocess.run(["dpkg-deb", "-x", candidates[0], packages], check=True, timeout=60)
46 options.extend([f"CURL_CFLAGS=-I{packages}/usr/include/x86_64-linux-gnu",
47 "CURL_LIBCURL=/usr/lib/x86_64-linux-gnu/libcurl.so.4"])
48 subprocess.run(["make", "-j", str(min(os.cpu_count() or 2, 8)), *options, "all"], cwd=source, check=True, timeout=900)
49 subprocess.run(["make", *options, "install"], cwd=source, check=True, timeout=120)
50 subprocess.run([prefix / "bin/git", "--version"], check=True)
51
52
53 if __name__ == "__main__":
54 main()