diff options
Diffstat (limited to 'link/pi-models.py')
| -rw-r--r-- | link/pi-models.py | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/link/pi-models.py b/link/pi-models.py new file mode 100644 index 0000000..6188c94 --- /dev/null +++ b/link/pi-models.py @@ -0,0 +1,66 @@ +"""Generate ~/.pi/agent/models.json from the repo and its fragments. + +Run by link/pi.sh. It lives in a file rather than a heredoc inside $( ): +macOS ships bash 3.2, which does not skip heredoc content when it scans +for the end of a command substitution, so an odd number of apostrophes in +here would stop the whole script parsing -- which it did, on 2026-09-25. +""" + +import glob, json, os, sys + +base_path, frag_dir, target = sys.argv[1:4] + + +def load(path): + with open(path) as f: + return json.load(f) + + +# The repo's providers, then each fragment's. A fragment may add a provider or +# replace one of the same name; any other top-level key takes the last file's +# value. Which provider came from where is reported: a fragment quietly +# shadowing a provider the repo ships would otherwise be invisible. +desired = {} +notes = [] +for path in [base_path] + sorted(glob.glob(os.path.join(frag_dir, "*.json"))): + try: + layer = load(path) + except (OSError, ValueError) as e: + print("error:cannot read %s: %s" % (path, e)) + sys.exit(0) + for key, value in layer.items(): + if key == "providers": + providers = desired.setdefault("providers", {}) + if path != base_path: + for name in value: + notes.append("%s %s by %s" % ( + name, + "replaced" if name in providers else "added", + os.path.basename(path), + )) + providers.update(value) + else: + desired[key] = value + +# A symlink is the pre-generation state: replace it, even with no fragments, so +# the live file is never the tracked one. +was_link = os.path.islink(target) +try: + current = None if was_link else load(target) +except (OSError, ValueError): + current = None + +for note in notes: + print("note:" + note) + +if current == desired: + print("unchanged:") +elif os.environ.get("DRY_RUN"): + print("would-write:" + ("replacing the link" if was_link else "merged changes")) +else: + tmp = target + ".dotfiles-tmp" + with open(tmp, "w") as f: + json.dump(desired, f, indent=2) + f.write("\n") + os.replace(tmp, target) + print("wrote:" + ("replaced the link" if was_link else "merged changes")) |
