+# nix-pin-deps: gc-pin dependencies of a partially-built derivation
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation, version 3.
+
+
from contextlib import contextmanager
import json
import os
class ParseNixStoreQueryGraphML(xml.sax.handler.ContentHandler):
def __init__(self) -> None:
+ super().__init__()
self.roots: Set[str] = set()
self.non_roots: Set[str] = set()
self.deps: Dict[str, List[str]] = {}
def getDeps(drv: str) -> ParseNixStoreQueryGraphML:
with log("Loading dependency tree..."):
- process = subprocess.Popen(
- ["nix-store", "--query", "--graphml", drv], stdout=subprocess.PIPE)
- parser = ParseNixStoreQueryGraphML()
- assert process.stdout
- xml.sax.parse(process.stdout, parser)
- assert process.wait() == 0
+ with subprocess.Popen(
+ ["nix-store", "--query", "--graphml", drv], stdout=subprocess.PIPE) as process:
+ parser = ParseNixStoreQueryGraphML()
+ assert process.stdout
+ xml.sax.parse(process.stdout, parser)
+ assert process.wait() == 0
return parser
def getDrvInfo(drv: str) -> Any:
- with log("Loading %s..." % drv):
- process = subprocess.Popen(["nix",
- "--experimental-features",
- "nix-command",
- "show-derivation",
- "/nix/store/" + drv],
- stdout=subprocess.PIPE)
- assert process.stdout
- info = json.load(process.stdout)
- assert process.wait() == 0
+ with log(f"Loading {drv}..."):
+ with subprocess.Popen(
+ ["nix", "--experimental-features", "nix-command",
+ "derivation", "show", f"/nix/store/{drv}^*"],
+ stdout=subprocess.PIPE) as process:
+ assert process.stdout
+ info = json.load(process.stdout)
+ assert process.wait() == 0
return info
def pin(drv: str) -> None:
outPath = os.path.join(sys.argv[2], removesuffix(drv, ".drv"))
if not os.path.exists(outPath):
- process = subprocess.run(["nix-store",
- "--realise",
- "--add-root",
- outPath,
- "/nix/store/" + drv],
- check=True)
+ subprocess.run(["nix-store", "--realise", "--add-root",
+ outPath, "/nix/store/" + drv], check=True)
def pinBuiltThings(thing: str,
pinBuiltThings(dep, done, deps)
-dep_graph = getDeps(sys.argv[1])
-for root in dep_graph.roots:
- pinBuiltThings(root, set(), dep_graph.deps)
+def main() -> None:
+ dep_graph = getDeps(sys.argv[1])
+ for root in dep_graph.roots:
+ pinBuiltThings(root, set(), dep_graph.deps)
+
+
+if __name__ == '__main__':
+ main()