Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
a30091f
scaffold-project.py, validate-pins.py, repo_shape.py: two neutral pro…
brettheap Oct 12, 2026
53fb96e
adopt-project.py: `plan --pin` takes `[owner/]product@<40 hex>` as th…
brettheap Oct 12, 2026
38ba912
Merge origin/main (87373a6) into fix/adopt-pin-writes-pin-file
brettheap Oct 12, 2026
a44b8c2
Merge fix/pin-source-env-collisions (a30091f, #275) into fix/adopt-pi…
brettheap Oct 12, 2026
2dc1f57
adopt-project.py: say where the pin findings come from at their call …
brettheap Oct 12, 2026
6a28c2a
Merge origin/main (e43fa95) into fix/adopt-pin-writes-pin-file: #269,…
brettheap Oct 12, 2026
34dbd86
Merge origin/main (ab623dd) into fix/pin-source-env-collisions: valid…
Oct 12, 2026
5690235
Merge fix/pin-source-env-collisions (34dbd86, #275 over origin/main a…
Oct 12, 2026
d806e8f
tests/test_adopt_template_values.py: #270's `pins-surrogate` case exp…
Oct 12, 2026
7a94b6b
shape_materialize.py: `pin_digest_from_source` turns any `OSError` ou…
brettheap Oct 12, 2026
6494714
validate-pins.py, repo_shape.py: `neutral-pin-source-collides` is a n…
brettheap Oct 12, 2026
583f647
Merge fix/pin-source-env-collisions (6494714, #275's fix round) into …
Oct 12, 2026
2bcfa69
Merge origin/main (cd1fc79) into fix/adopt-pin-writes-pin-file: #245,…
Oct 12, 2026
74ce4d9
shape_materialize.py, adopt-project.py: a `--pin-source` that is not …
Oct 12, 2026
4098b61
Merge origin/main (45e01f4) into fix/adopt-pin-writes-pin-file: #396'…
Oct 12, 2026
421e4e5
Merge origin/main (3ef059c, #314) into fix/adopt-pin-writes-pin-file:…
Oct 12, 2026
f63d1ed
tests/test_adopt_pins.py: `plan` with a `--pin-source` and no `--pin`…
Oct 12, 2026
f9ed46f
Merge origin/main (9736424, #409's squash) into fix/adopt-pin-writes-…
Oct 13, 2026
73d65c6
adopt-project.py: `_read_pins` reads `pins:` with `plan.get`, so `_co…
Oct 13, 2026
33bae3f
Merge branch 'main' into fix/adopt-pin-writes-pin-file
brettheap Oct 13, 2026
2170526
Merge branch 'main' into fix/adopt-pin-writes-pin-file
brettheap Oct 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
502 changes: 430 additions & 72 deletions adopt-project.py

Large diffs are not rendered by default.

30 changes: 23 additions & 7 deletions docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,9 @@ usage: adopt-project.py plan [-h] --source SOURCE --project PROJECT
[--elected-on ELECTED_ON] [--reference REFERENCE]
[--tracking-branch TRACKING_BRANCH]
[--spec-path SPEC_PATH] [--code-path CODE_PATH]
[--pin PIN] [--allow-empty-leg {spec,code}]
[--pin openProduct@COMMIT]
[--pin-owner PIN_OWNER] [--pin-source PIN_SOURCE]
[--allow-empty-leg {spec,code}]
[--path-policy PATH_POLICY] [--out OUT]
[--work-dir WORK_DIR]

Expand Down Expand Up @@ -428,12 +430,26 @@ options:
`code` pass. Either refusal writes no plan and
rewrites nothing, and its `Remediation:` line states
the whole rule; you pass the value again.
--pin PIN a neutral product this project declares a pin on — a
NAME only, e.g. --pin openGlass or --pin
opensoft/openGlass to name the owner explicitly.
Adopting a project pins no commit at plan time, so a
trailing @<commit> (scaffold-project.py's syntax) is
refused.
--pin openProduct@COMMIT
declare a neutral-product pin, as scaffold-project.py
--pin does, e.g. --pin openGlass@<40 hex>. `plan`
reads the digest of the product's tree at that commit
(from --pin-source, or `gh api`) and records it in the
plan; `execute` writes
contracts/<openproduct>-pin.yaml from it and lists the
product in the manifest. A name with no @<commit>, a
product named spec, code or shape, and one product
twice are refused. Repeatable.
--pin-owner PIN_OWNER
the organisation an UNQUALIFIED --pin name resolves
under (default: opensoft, where every neutral
open<Product> lives — never the adopted repository's
own --org). Name the owner in --pin itself
(owner/openProduct@<sha>) to override it for one pin.
--pin-source PIN_SOURCE
a local clone to compute --pin digests from, instead
of reading the forge with `gh api` (the TEST path; no
network)
--allow-empty-leg {spec,code}
record in the plan that this leg having NO path is
intended, so it may be SEEDED from the shape's
Expand Down
313 changes: 8 additions & 305 deletions scaffold-project.py

Large diffs are not rendered by default.

462 changes: 460 additions & 2 deletions scripts/shape_materialize.py

Large diffs are not rendered by default.

12 changes: 11 additions & 1 deletion tests/test_adopt_manifest_values.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,12 +242,22 @@ def test_plan_asks_what_check_asks_of_the_same_keys(adopter, tmp_path,
monkeypatch.setattr(adopter, "_flag_plan",
lambda *a: built.append(real(*a)) or built[-1])
source = make_source_repo(tmp_path / "Thing")
# A pin is `<product>@<40 hex>` with its digest read at `plan` (#273):
# a local stand-in for `openGlass` answers it, with no network.
glass = tmp_path / "openGlass"
glass.mkdir()
git("init", "-q", "-b", "main", cwd=glass)
(glass / "README.md").write_bytes(b"# openGlass\n")
git("add", "-A", cwd=glass)
git("commit", "-qm", "seed", cwd=glass)
commit = git("rev-parse", "HEAD", cwd=glass).stdout.strip()
out = tmp_path / "plan.yaml"
code = adopter.main(["plan", "--source", str(source), "--project",
PROJECT, "--org", "testorg", "--elected-by",
"Test Human", "--elected-on", "2026-09-02",
"--visibility", "internal", "--tracking-branch",
"trunk", "--pin", "openGlass", "--out", str(out)])
"trunk", "--pin", f"openGlass@{commit}",
"--pin-source", str(glass), "--out", str(out)])
assert code == 0, capsys.readouterr().err
(flag_plan,) = built
written = adopter.Plan.load(out)
Expand Down
Loading
Loading