lol
1#!/usr/bin/env nix-shell
2#!nix-shell -i python3 -p cargo -p "python3.withPackages (ps: with ps; [ requests ])"
3import json
4import pathlib
5import re
6import tempfile
7import os
8import shutil
9from hashlib import sha1
10from struct import unpack
11from subprocess import run
12import subprocess
13
14from requests import get
15
16# Fetch the latest stable release metadata from GitHub
17releaseMetadata = get("https://api.github.com/repos/facebook/sapling/releases/latest").json()
18latestTag = releaseMetadata["tag_name"]
19latestTarballURL = releaseMetadata["tarball_url"]
20
21[_tarballHash, sourceDirectory] = run(
22 ["nix-prefetch-url", "--print-path", "--unpack", latestTarballURL],
23 check=True,
24 text=True,
25 stdout=subprocess.PIPE,
26).stdout.rstrip().splitlines()
27
28def updateCargoLock():
29 with tempfile.TemporaryDirectory() as tempDir:
30 tempDir = pathlib.Path(tempDir)
31
32 # NOTE(strager): We cannot use shutil.tree because it copies the
33 # read-only permissions.
34 for dirpath, dirnames, filenames in os.walk(sourceDirectory):
35 relativeDirpath = os.path.relpath(dirpath, sourceDirectory)
36 for filename in filenames:
37 shutil.copy(os.path.join(dirpath, filename), tempDir / relativeDirpath / filename)
38 for dirname in dirnames:
39 os.mkdir(tempDir / relativeDirpath / dirname)
40
41 run(["cargo", "fetch"], check=True, cwd=tempDir / "eden" / "scm")
42 shutil.copy(tempDir / "eden" / "scm" / "Cargo.lock", "Cargo.lock")
43
44updateCargoLock()
45
46def nixPrefetchUrl(url):
47 return run(
48 ["nix-prefetch-url", "--type", "sha256", url],
49 check=True,
50 text=True,
51 capture_output=True,
52 ).stdout.rstrip()
53
54
55# Fetch the `setup.py` source and look for instances of assets being downloaded
56# from files.pythonhosted.org.
57setupPy = (pathlib.Path(sourceDirectory) / "eden/scm/setup.py").read_text()
58foundUrls = re.findall(r'(https://files\.pythonhosted\.org/packages/[^\s]+)"', setupPy)
59
60dataDeps = {
61 "links": [{"url": url, "sha256": nixPrefetchUrl(url)} for url in foundUrls],
62 "version": latestTag,
63 # Find latest's git tag which corresponds to the Sapling version. Also
64 # needed is a hash of the version, so calculate that here. Taken from
65 # Sapling source `$root/eden/scm/setup_with_version.py`.
66 "versionHash": str(unpack(">Q", sha1(latestTag.encode("ascii")).digest()[:8])[0]),
67}
68
69open("deps.json", "w").write(json.dumps(dataDeps, indent=2, sort_keys=True) + "\n")