at master 4.7 kB view raw
1 2from collections import defaultdict 3import copy 4import json 5import os 6from pathlib import Path 7import shutil 8import subprocess 9import sys 10import tempfile 11import toml 12import util 13import yaml 14 15 16registry_path = Path(sys.argv[1]) 17desired_packages_path = Path(sys.argv[2]) 18package_overrides = json.loads(sys.argv[3]) 19dependencies_path = Path(sys.argv[4]) 20out_path = Path(sys.argv[5]) 21 22with open(desired_packages_path, "r") as f: 23 desired_packages = yaml.safe_load(f) or [] 24 25uuid_to_versions = defaultdict(list) 26for pkg in desired_packages: 27 uuid_to_versions[pkg["uuid"]].append(pkg["version"]) 28 29with open(dependencies_path, "r") as f: 30 uuid_to_store_path = yaml.safe_load(f) 31 32os.makedirs(out_path) 33 34full_registry = toml.load(registry_path / "Registry.toml") 35registry = full_registry.copy() 36registry["packages"] = {k: v for k, v in registry["packages"].items() if k in uuid_to_versions} 37 38for (uuid, versions) in uuid_to_versions.items(): 39 if uuid in package_overrides: 40 info = package_overrides[uuid] 41 42 # Make a registry entry based on the info from the package override 43 path = Path(info["name"][0].upper()) / Path(info["name"]) 44 registry["packages"][uuid] = { 45 "name": info["name"], 46 "path": str(path), 47 } 48 49 os.makedirs(out_path / path) 50 51 # Read the Project.yaml from the src 52 project = toml.load(Path(info["src"]) / "Project.toml") 53 54 # Generate all the registry files 55 with open(out_path / path / Path("Compat.toml"), "w") as f: 56 f.write('["%s"]\n' % info["version"]) 57 # Write nothing in Compat.toml, because we've already resolved everything 58 with open(out_path / path / Path("Deps.toml"), "w") as f: 59 f.write('["%s"]\n' % info["version"]) 60 if "deps" in project: 61 toml.dump(project["deps"], f) 62 with open(out_path / path / Path("Versions.toml"), "w") as f: 63 f.write('["%s"]\n' % info["version"]) 64 f.write('git-tree-sha1 = "%s"\n' % info["treehash"]) 65 with open(out_path / path / Path("Package.toml"), "w") as f: 66 toml.dump({ 67 "name": info["name"], 68 "uuid": uuid, 69 "repo": "file://" + info["src"], 70 }, f) 71 72 elif uuid in registry["packages"]: 73 registry_info = registry["packages"][uuid] 74 name = registry_info["name"] 75 path = registry_info["path"] 76 77 os.makedirs(out_path / path) 78 79 # Copy some files to the minimal repo unchanged 80 for f in ["Compat.toml", "Deps.toml", "WeakCompat.toml", "WeakDeps.toml"]: 81 if (registry_path / path / f).exists(): 82 shutil.copy2(registry_path / path / f, out_path / path) 83 84 # Copy the Versions.toml file, trimming down to the versions we care about. 85 # In the case where versions=None, this is a weak dep, and we keep all versions. 86 all_versions = toml.load(registry_path / path / "Versions.toml") 87 versions_to_keep = {k: v for k, v in all_versions.items() if k in versions} if versions != None else all_versions 88 for k, v in versions_to_keep.items(): 89 del v["nix-sha256"] 90 with open(out_path / path / "Versions.toml", "w") as f: 91 toml.dump(versions_to_keep, f) 92 93 if versions is None: 94 # This is a weak dep; just grab the whole Package.toml 95 shutil.copy2(registry_path / path / "Package.toml", out_path / path / "Package.toml") 96 elif uuid in uuid_to_store_path: 97 # Fill in the local store path for the repo 98 package_toml = toml.load(registry_path / path / "Package.toml") 99 package_toml["repo"] = "file://" + uuid_to_store_path[uuid] 100 with open(out_path / path / "Package.toml", "w") as f: 101 toml.dump(package_toml, f) 102 103# Look for missing weak deps and include them. This can happen when our initial 104# resolve step finds dependencies, but we fail to resolve them at the project.py 105# stage. Usually this happens because the package that depends on them does so 106# as a weak dep, but doesn't have a Package.toml in its repo making this clear. 107for pkg in desired_packages: 108 for dep in (pkg.get("deps", []) or []): 109 uuid = dep["uuid"] 110 if not uuid in uuid_to_versions: 111 entry = full_registry["packages"].get(uuid) 112 if not entry: 113 print(f"""WARNING: found missing UUID but couldn't resolve it: {uuid}""") 114 continue 115 116 # Add this entry back to the minimal Registry.toml 117 registry["packages"][uuid] = entry 118 119 # Bring over the Package.toml 120 path = Path(entry["path"]) 121 if (out_path / path / "Package.toml").exists(): 122 continue 123 Path(out_path / path).mkdir(parents=True, exist_ok=True) 124 shutil.copy2(registry_path / path / "Package.toml", out_path / path / "Package.toml") 125 126# Finally, dump the Registry.toml 127with open(out_path / "Registry.toml", "w") as f: 128 toml.dump(registry, f)