72 lines
2.9 KiB
Python
72 lines
2.9 KiB
Python
#!/usr/bin/env python3
|
|
|
|
import sys
|
|
import json
|
|
import os
|
|
import subprocess
|
|
import string
|
|
|
|
|
|
def eprint(text: str):
|
|
print(text, file=sys.stderr)
|
|
|
|
|
|
if not os.path.exists("dub.selections.json"):
|
|
eprint("The file `dub.selections.json` does not exist in the current working directory")
|
|
eprint("run `dub upgrade --annotate` to generate it")
|
|
sys.exit(1)
|
|
|
|
with open("dub.selections.json") as f:
|
|
selectionsJson = json.load(f)
|
|
|
|
depsDict: dict = selectionsJson["versions"]
|
|
|
|
# For each dependency expand non-expanded version into a dict with a "version" key
|
|
depsDict = {pname: (versionOrDepDict if isinstance(versionOrDepDict, dict) else {"version": versionOrDepDict}) for (pname, versionOrDepDict) in depsDict.items()}
|
|
|
|
# Don't process path-type selections
|
|
depsDict = {pname: depDict for (pname, depDict) in depsDict.items() if "path" not in depDict}
|
|
|
|
# Pre-validate selections before trying to fetch
|
|
for pname in depsDict:
|
|
depDict = depsDict[pname]
|
|
version = depDict["version"]
|
|
if version.startswith("~"):
|
|
eprint(f'Expected version of "{pname}" to be non-branch type')
|
|
eprint(f'Found: "{version}"')
|
|
eprint("Please specify a non-branch version inside `dub.selections.json`")
|
|
eprint("When packaging, you might also need to patch the version value in the appropriate places (`dub.selections.json`, dub.sdl`, `dub.json`)")
|
|
sys.exit(1)
|
|
if "repository" in depDict:
|
|
repository = depDict["repository"]
|
|
if not repository.startswith("git+"):
|
|
eprint(f'Expected repository field of "{pname}" to begin with "git+"')
|
|
eprint(f'Found: "{repository}"')
|
|
sys.exit(1)
|
|
if (len(version) < 7 or len(version) > 40 or not all(c in string.hexdigits for c in version)):
|
|
eprint(f'Expected version field of "{pname}" to begin be a valid git revision')
|
|
eprint(f'Found: "{version}"')
|
|
sys.exit(1)
|
|
|
|
lockedDepsDict: dict[str, dict[str, str]] = {}
|
|
|
|
for pname in depsDict:
|
|
depDict = depsDict[pname]
|
|
version = depDict["version"]
|
|
if "repository" in depDict:
|
|
repository = depDict["repository"]
|
|
strippedRepo = repository[4:]
|
|
eprint(f"Fetching {pname}@{version} ({strippedRepo})")
|
|
command = ["nix-prefetch-git", strippedRepo, version]
|
|
rawRes = subprocess.run(command, check=True, text=True, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL).stdout
|
|
sha256 = json.loads(rawRes)["sha256"]
|
|
lockedDepsDict[pname] = {"version": version, "repository": repository, "sha256": sha256}
|
|
else:
|
|
eprint(f"Fetching {pname}@{version}")
|
|
url = f"https://code.dlang.org/packages/{pname}/{version}.zip"
|
|
command = ["nix-prefetch-url", "--type", "sha256", url]
|
|
sha256 = subprocess.run(command, check=True, text=True, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL).stdout.rstrip()
|
|
lockedDepsDict[pname] = {"version": version, "sha256": sha256}
|
|
|
|
print(json.dumps({"dependencies": lockedDepsDict}, indent=2))
|