diff --git a/build_mp.py b/build_mp.py index 476529a..4d5b58c 100755 --- a/build_mp.py +++ b/build_mp.py @@ -321,7 +321,9 @@ def sparse(repo, origin, sha, paths): # every other module, anywhere else a clone at the pinned commit. The tree is # assembled into deps/omnipython-lib on every build that needs it; the outside # packages the library pins by tag (pygraphics, audiocomponents' two) are -# cloned once into deps/omnipython-lib-sources. +# cloned once into deps/omnipython-lib-sources. In the workspace those come +# from the sibling checkouts instead, the way every module does, so a +# workspace build freezes the code beside it rather than the pinned tag. LIBRARY = "omnipython-lib" @@ -367,15 +369,35 @@ def build(self): out = DEPS / LIBRARY DEPS.mkdir(exist_ok=True) say(f"assembling the {LIBRARY} tree from {self.source.resolve()}") + sources = [] + for name, sibling in self.sibling_sources(): + say(f" {name} from the sibling checkout {sibling}, not its pinned tag") + sources += ["--source", f"{name}={sibling}"] r = subprocess.run( [sys.executable, str(self.source / "tools" / "libbuild.py"), "build", "--tree-only", "--root", str(self.source), "--out", str(out), "--cache", str(DEPS / f"{LIBRARY}-sources"), - "--library-name", LIBRARY], text=True, capture_output=True) + "--library-name", LIBRARY, *sources], text=True, capture_output=True) if r.returncode != 0: die(f"{self.source / 'tools' / 'libbuild.py'} failed:\n{r.stdout}{r.stderr}") self.tree = out / "library" return self.tree + def sibling_sources(self): + """[(package, checkout)] for each package the library's lib-lock.json pins + from another repository that the workspace has a checkout of.""" + if not self.ws: + return [] + try: + pinned = json.loads((self.source / "lib-lock.json").read_text())["pinned"] + except (OSError, ValueError, KeyError): + return [] + out = [] + for name, row in sorted(pinned.items()): + sibling = self.ws / row["repository"].rsplit("/", 1)[-1] + if (sibling / "lib" / name).is_dir(): + out.append((name, sibling)) + return out + def names(self): """Every package in the tree.""" return {p.name for p in self.build().iterdir() if (p / "manifest.py").is_file()} diff --git a/docs/build-plan.md b/docs/build-plan.md index 7794142..5242da1 100644 --- a/docs/build-plan.md +++ b/docs/build-plan.md @@ -214,8 +214,10 @@ with `add_library("omnipython-lib", ...)`, and a manifest then says checkout is a link to the sibling `pydevices`, which wins over the pin like every other module; anywhere else it is a clone at the pinned commit. The tree goes to `deps/omnipython-lib`, and the outside packages the library builds from -other repositories at a tag (audiocomponents' instruments and effects) are -cloned once into `deps/omnipython-lib-sources`. +other repositories at a tag (audiocomponents' instruments and effects, +pygraphics) are cloned once into `deps/omnipython-lib-sources`. In the +workspace they come from the sibling checkouts instead, as modules do, so a +workspace build freezes the code beside it; the build says which. You still choose per build: name `pydevices`, `palettes`, `pdwidgets` or `audiocomponents` in `--modules` and it's frozen (each is a small manifest in