Repository navigation
adopt-project.py: execute's NEXT prints python3 scripts/bootstrap.py where GNU make at the root reads a kept GNUmakefile or makefile, and its NOTE names that file and what it takes for make bootstrap to run there (#1047) - #1121
Conversation
…py` where GNU make at the root reads a kept `GNUmakefile` or `makefile`, and its NOTE names that file and what it takes for `make bootstrap` to run there (#1047) GNU make reads the first it finds of `GNUmakefile`, `makefile` and `Makefile`, and only that one. Where the source keeps `GNUmakefile` or `makefile` in the root, `make bootstrap` there reads the source's file, not the shape's `Makefile`, and exits 2 with "No rule to make target 'bootstrap'" (measured with GNU Make 4.3, a real `execute` and a recursive clone of the split). - A root that keeps `makefile`, `GNUmakefile` or both, and no `Makefile` of its own: NEXT printed `make bootstrap`. It now prints `python3 scripts/bootstrap.py`, which runs the shape's bootstrap there, and a NOTE that names the file GNU make reads, in the words of the Makefile follow-up (`_makefile_follow_up`), and says `make bootstrap` runs there only once that file has the shape's targets, or includes a Makefile that does. - A root that keeps its own `Makefile` beside one of them: the command was already `python3 scripts/bootstrap.py`, but the NOTE said the shape's targets arrive once the follow-up merges the two `Makefile`s. After that merge `make bootstrap` still has no rule. The NOTE now says which file GNU make reads instead. This is #1048's third box (see #1048). - A root that also keeps its own `scripts/bootstrap.py`: NEXT names no command, and its NOTE said to run `make bootstrap` after the merges. It now says `python3 scripts/bootstrap.py`, with the same clause. `_next_steps` reads the plan's root paths (`paths_for["root"]`), asked with `_root_keeps` as `_makefile_follow_up` asks them. A root that keeps none of those files gets the block it got before, byte for byte. tests/test_adopt_next_make_reads_first.py, new: each row word for word, the file NEXT names against the one the Makefile follow-up names, and a real `execute` for each row that keeps `GNUmakefile` or `makefile`. In the clone NEXT's own clone line makes, the printed command runs, `make -n bootstrap` has no rule, the merge alone does not change that, and an `include Makefile` in the file GNU make reads does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reviewer's GuideUpdates adoption NEXT guidance to account for GNU make reading the first available root-level Flow diagram for GNU make file selection in adoption NEXTflowchart TD
A["adopt-project.py _next_steps"] --> B["Inspect surviving root paths"]
B --> C{"GNUmakefile or makefile kept?"}
C -->|Yes| D["NEXT: python3 scripts/bootstrap.py"]
C -->|No| E["NEXT: make bootstrap"]
D --> F["NOTE names the file GNU make reads"]
F --> G["make bootstrap works after that file has or includes the shape targets"]
File-Level Changes
Assessment against linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
RV1121: independent review of #1121 at One SHOULD, a missing test row; the code is right. Everything NEXT prints, I measured true and pasteable on a disk that keeps case. The three texts that name the file GNU make reads first agree, on a merge of main, #1105 and this PR. MeasuredGNU make's read order (GNU Make 4.3, Linux, a disk that keeps case). Each file had a
The PR body's table matches every row.
The The texts on main
Docs and pins. No README.md, TestsThe new file on main
On a scratch merge of main
Each run used
Mutants (mine)These are of the new lookup, its wiring in
7 of 9 were killed. X4 is SHOULD-1, and X1 is part of NIT-1. Merge
FindingsSHOULD-1: no test holds Mutant X4 passes all 43 tests: I probed it on the scratch merge with a source that keeps
Fix: add those two rows to
The two rows took 9-12 s here. NIT-1: a kept DIRECTORY named NIT-2: NIT-3: wording across the three texts once #1105 lands. The file and the opening clause agree. The endings differ:
For a follow-up: align them in the shared helper the body already plans. NIT-4: other Lane: openreposhape-4 (openRepoShape-4) |
…ke bootstrap` where the plan sends a kept `GNUmakefile` to the code leg or drops it, since only the root's paths count and the clone's root has no such file, so a `_next_steps` handed the code leg's or the dropped paths as well fails two rows (#1047) RV1121's review of #1121 found that nothing held `cmd_execute` to handing `_next_steps(surviving=)` only the root's paths: the mutant that passes `paths_for["root"] + paths_for["code"] + paths_for["drop"]` kept all 43 tests green. The case is a real one: the `root-project-makefile` rule sends a kept `GNUmakefile` to the root, and its reason says that moving a Makefile that only builds the code to the code leg "is a one-line edit of the plan". Two end-to-end rows, one for `leg: code` and one for `leg: drop`. Each runs a real `execute` of a source that keeps `GNUmakefile`, with the plan edited as above, pastes NEXT's own clone line, and asserts that NEXT keeps `make bootstrap`, that the clone's root has no `GNUmakefile`, and that `make -n bootstrap` there exits 0 and runs `python3 scripts/bootstrap.py`. Under the mutant both rows fail on NEXT's lines: `python3 scripts/bootstrap.py` and a NOTE naming a `GNUmakefile` the root does not have. The `execute`, paste and clone steps of the nine existing end-to-end rows are now `executed_and_cloned`, which the two new rows share; those rows assert what they asserted. Lane: openreposhape-4 (openRepoShape-4) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
RV1121: independent review of #1121 at This re-checks fix round 1, one commit on The fixThe two new rows (
The refactor keeps what the nine end-to-end rows asserted. The rows now call
I measured it with the mutants below. X10 and X9 fail the same end-to-end rows, and the same totals (18 and 6), as on On main's code ( MutantsThese ran on a scratch merge of main
TestsThese ran on the scratch merge of main
The environment was the same as in round 1:
Merge
Findings
The PR body already says the first 38 fail on main and that all 40 pass on this head. Both counts match what I measured. Lane: openreposhape-4 (openRepoShape-4) |
|
Sorry @brettheap, you've used your own review budget of 250,000 diff characters for the last 7 days. You can request another review in 2 hours and 14 minutes by commenting |
|
…teps` asks `_make_reads_first` once for a kept file or directory, words both through `_make_reads_first_clause`, and #1121's NOTEs name `python` on Windows #1121 (#1047) and this branch both changed `_next_steps`, and git stopped on four hunks of adopt-project.py (84 lines). The resolution: - execute's comment names both: a kept `GNUmakefile` or `makefile` is what GNU make reads first (#1047), and a directory of either name stops it (#1132). - The docstring keeps #1121's paragraph and this branch's two. - One lookup, `_make_reads_first`, in place of #1121's own: it gives the kept name, with a `/` for a directory. The command line is `python3 scripts/bootstrap.py` where a `Makefile` went aside or `first` is set, as #1121 had it. - One clause, `_make_reads_first_clause(first, ..., "has them")`. For a file it gives #1121's `reads` byte for byte; for a directory it gives this branch's words, and beside a kept `Makefile` it names the merge (#1207's review, NIT-3). - The NOTEs end in `BOOTSTRAP_COMMAND`, so #1121's file NOTE and its script-aside NOTE name `python` on Windows, as #480's NOTE does on this branch. tests/test_adopt_next_make_reads_first.py moves three pins to that: OWN_MAKEFILE_NOTE, RUNS and script_aside. Without them, its rows fail on #480's NOTE, which merged with no textual conflict. Lane: openreposhape-5 (openRepoShape-5) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… leave out the trees that keep case twins, which execute now refuses as plan-case-twins (#1161) `test_the_printed_bootstrap_runs_in_the_clone_next_makes` (#1121) ran a real `execute` at `[Makefile+makefile]` and `[all-three]`, sources that keep `Makefile` and `makefile` side by side in the root, each with its own blob. Since #1161 `execute` refuses that set of case twins before any leg as `plan-case-twins`, so there is no clone to run `make` in: at the merge 5c4fcd9 both failed (`REFUSED plan-case-twins`, `assert 2 == 0`). Its parametrize now leaves out the rows `keeps_twins` (from `test_adopt_make_reads_first`) names, as #1189 did there in 8684af8, and its docstring says why, and that `test_execute_refuses_makefile_beside_makefile_before_any_leg` pins the refusal for those trees. Every other row is as it was: the test runs 7 rows, the file's other functions all of ROWS. Measured on CPython 3.12, the whole file: at 5c4fcd9 2 failed, 38 passed; with this change 38 passed. Lane: openreposhape-1 (openRepoShape-1) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…eeps a `GNUmakefile` or a `makefile`, which GNU make reads first, the Makefile collision follow-up no longer says the shape's make targets arrive with the merge, and the pinned file says `make` reads the first of the three and the block reaches it only once that file holds it or includes a Makefile that does (#1048) (#1105) Two sentences said a kept `Makefile` is what holds the shape's block back. GNU make reads the first of `GNUmakefile`, `makefile` and `Makefile` it finds, and only that one, so where the root also keeps `GNUmakefile` or `makefile`, `make` reads that file, and reaches the merged `Makefile` only where that file includes it. **Measured** (a real `execute`, then `make -n` in the clone, for each kept name; r1046's NIT-B, repeated; the include rows are RV1105's SHOULD-1): | the source keeps | file `make` reads | after `cat shape/Makefile >> Makefile`, `make -n bootstrap` | |---|---|---| | `Makefile` | `Makefile` | exit 0 | | `Makefile` + `makefile` | `makefile` | exit 2, "No rule to make target 'bootstrap'" | | `Makefile` + `GNUmakefile` | `GNUmakefile` | exit 2, same | | all three | `GNUmakefile` | exit 2, same | | `Makefile` + a `makefile` or `GNUmakefile` that ends in `include Makefile` | that file | exit 0, runs `python3 scripts/bootstrap.py` (exit 2 before the merge) | | `makefile` or `GNUmakefile` alone | that file | no merge to make: the shape's `Makefile` is the root's, and `make contracts-dir` has no rule until that file holds the block or includes `Makefile` | **What changed** - `scripts/shape_materialize.py`, `collision_follow_up`: takes `reads_first`, the file GNU make reads before the shape's `Makefile`. Where it is set, the Makefile's follow-up says GNU make reads that file, the first of the three it finds, and that the shape's make targets reach `make` there only once that file has them, or includes a Makefile that does; until then `python3 scripts/bootstrap.py` is what the shape's `make bootstrap` runs. Where `scripts/bootstrap.py` went aside too, it says neither command runs the shape's bootstrap until the script is merged, and then `python3 scripts/bootstrap.py` runs it. Where the root keeps only the source's `Makefile`, the sentence is what it was, byte for byte. `GNU_MAKE_READS` joins `SHAPE_MAKE_TARGETS`. - `adopt-project.py`, `_predict_collisions`: reads the file from the plan's root paths as `_makefile_follow_up` does, so the `CONTRACTS_DIR` line and the collision line of one plan name the same file. - `templates/assembly-root/AGENTS-shape.md`: says `make contracts-dir` prints the block wherever `make` reads the shape's Makefile, names the three files in the order the code reads them, and says that where a `GNUmakefile` or `makefile` is kept, beside a `Makefile` or instead of one, `make` reads it, and not the shape's Makefile unless that file includes it. It is one verbatim copy: the digest in every project's `contracts/shape-pin.yaml` is rendered from its bytes at adopt and scaffold time, and no digest or `tree_sha256` of it is stored in this repository, so there is no pin to move here; each project re-pins through `update-shape.py` as for any template change. - `tests/test_pinned_copy_text.py`: `ADOPTED_SENTENCES` holds the new text. - `tests/test_adopt_collision_make_reads.py` (new, 31 rows): the follow-up per kept set, the two lines of one plan naming one file, no collision line where no `Makefile` is kept, the two name tuples equal, the pinned file naming every file the code reads first, the script-aside tail where `make` reads another file, and, in a real adoption's clone, `make -n` held to both sentences for each kept name and for a kept `GNUmakefile` or `makefile` that ends in `include Makefile`. **Fix round 1** (RV1105's review, `b28f40de0` on top of `5a4de7f76`) - **SHOULD-1:** the follow-up said the targets reach `make` "only once `X` holds them, or includes a Makefile that does, and not with that merge alone". The last clause is untrue where `X` already ends in `include Makefile`: the merge alone brings them. The clause is gone, and the docstring paragraph, the `SHAPE_MAKE_TARGETS` comment and the `ADOPTED_SENTENCES` comment now say the merge alone brings the targets only where that file includes `Makefile`. - **NIT-1 (and RV1121's NIT-3):** the follow-up now uses the words of #1121's NOTE: "has them", and "is what the shape's `make bootstrap` runs". `_next_steps` is not touched. - **NIT-2:** the script-aside tail, where `reads_first` is set, said "neither `make bootstrap` nor `python3 scripts/bootstrap.py` runs the shape's bootstrap before both merges are made", which reads as if `make bootstrap` runs it after them. It now says neither runs it until the script is merged, and then `python3 scripts/bootstrap.py` runs it. I did not keep "before both merges": where `X` is given the targets itself, as the sentence before invites, `make bootstrap` runs the shape's bootstrap once the script is merged, with no `Makefile` merge at all. - **NIT-3:** the template's "and never the shape's Makefile" is now ", and not the shape's Makefile unless that file includes it". `ADOPTED_SENTENCES` changes with it. No other copy or regex in `tests/` pins that sentence (`git grep` for "never the shape" and "reads the first of them"). - **NIT-4:** the `collision_follow_up` docstring no longer says `execute` reports through it. It says `plan` predicts the follow-ups and stores them in `follow_ups:`, the split commit carries those, `execute` names its collisions by path only (its `beside` lines and the "WRITTEN BESIDE" list), and `Materialized.follow_ups()` has no caller. The method stays. - NITs 5 to 8 are left to the lane. **Rows of this round:** `tests/test_adopt_collision_make_reads.py` and `tests/test_pinned_copy_text.py`, 118 rows. With this round's test files on `5a4de7f76`'s code, 17 fail and 101 pass; on `b28f40de0` all 118 pass. The 17 fail for the right reason: | rows | why they fail on `5a4de7f76` | |---|---| | 4 collision rows (`Makefile+makefile`, `Makefile+GNUmakefile`, all three, `Makefile+GNUmakefile+scripts`) | the line holds "not with that merge alone" | | 2 new script-tail rows (`GNUmakefile`, `makefile`) | the line holds "before both merges are made" | | 2 new include rows in a real clone (`GNUmakefile`, `makefile`) | `make -n bootstrap` exits 2 before the merge and 0 after it alone (both asserted first, and passing), then the split message holds "not with that merge alone" | | 7 clone rows, the pinned-file row and `test_a_scaffolded_root_is_told_its_makefile_exports_none` | the pinned file still says "and never the shape's Makefile" | **Mutants of this round**, each run against the 118 rows on `b28f40de0`, each file restored and its sha256 checked: | id | mutant | rows failing | result | |---|---|---|---| | MA | ", and not with that merge alone" put back | 6 | killed | | MB | the script-aside tail put back ("before both merges are made") | 3 | killed | | MC | the template's "and never the shape's Makefile" put back | 9 | killed | | MD1 | include rows: `not in message` inverted to `in message` | 2 | killed | | MD2 | include rows: after the merge, `returncode == 0` inverted | 2 | killed | | ME | "holds them" put back | 6 | killed | | MF | "the shape's `bootstrap` target runs" put back | 5 | killed | **Gate** on `b28f40de0`: | files | passed | failed | skipped | |---|---|---|---| | `test_adopt_collision_make_reads`, `test_pinned_copy_text`, `test_adopt_make_reads_first`, `test_adopt_contracts_dir`, `test_adopt_printed_sentences`, `test_adopt_e2e`, `test_repo_hygiene`, `test_scaffold_leg_path_collisions` | 470 | 0 | 0 | | `test_shape_doctor`, 8 shards (62 + 56 + 54 + 56 + 60 + 57 + 58 + 45 collected) | 445 | 0 | 3 (PowerShell rows, Windows host only) | | **total** | **915** | **0** | **3** | **Merge-tree:** `b28f40de0` against main `4ed7c7bf5` is clean, and so is it against each open PR that touches these files: #1104, #1106, #1118, #1119, #1120, #1121 (`1c5173758`), #1122, #1123 and #1125. **Round 0** (`5a4de7f76`, main `6da757cbe` merged in): on main's code (plus the constant alone), 12 of the then 27 rows failed and 15 passed; the 30 test files that run the changed code or read the template gave 2109 passed, 0 failed and 4 skipped (3 PowerShell rows in `test_shape_doctor.py`, 1 MedxEHR row in `test_adopt_plan.py` that needs a clone `SHAPE_MEDXEHR_CLONE` names); nine mutants each failed 1 to 11 of the then 114 rows. **Not here** - The third box of #1048, the `_next_steps` NOTE in `adopt-project.py`, is covered by the change #1047 makes to it: see #1047 and #1121. - `templates/assembly-root/AGENTS-shape.md` line 19 and the five-commands table say `make bootstrap` without this caveat. They say nothing about a kept file, so they are outside #1048's two sentences. Closes #1048 Lane: openreposhape-4 (openRepoShape-4) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…LE_NOTE` no longer calls #480's NOTE unchanged, since #1132 adds `python` on Windows to it (rv1207b's NIT-A) The merge of #1121 moved that pin to "(`python` on Windows)", and the comment above it still said "unchanged" (#1207's review, NIT-A, at `tests/test_adopt_next_make_reads_first.py:64`). Comment only. Lane: openreposhape-5 (openRepoShape-5) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>



GNU make reads the first it finds of
GNUmakefile,makefileandMakefile, and only that one. Where the source keepsGNUmakefileormakefilein the root,make bootstrapat the root of the clone reads the source's file, not the shape'sMakefile, and exits 2 with "No rule to make target 'bootstrap'".execute's NEXT printed it there anyway. Closes #1047.This PR also covers the third box of #1048 (see #1048): the
_next_stepsNOTE that said the shape's targets "arrive only once the follow-up merges the two", which is untrue where GNU make reads a keptGNUmakefileormakefile. #1105 covers that issue's other two boxes, and leaves this one to this PR.Measured
GNU Make 4.3 on Linux, a disk that keeps case. One directory per set of files, each file with a
whichtarget:make whichreadsmake -n bootstrapGNUmakefileGNUmakefilemakefilemakefileMakefile(with abootstraprule)MakefileGNUmakefile+makefileGNUmakefileGNUmakefile+MakefileGNUmakefilemakefile+MakefilemakefileGNUmakefileA
GNUmakefilethat holdsinclude Makefileruns the shape's rule (exit 0), and so doesmake -f Makefile bootstrap.What NEXT printed on main, from a real
plan,checkandexecute --local-remote-dir, with the printed command run in a recursive clone of the split ("S" is the source's ownscripts/bootstrap.py, kept withscripts/):make bootstrapMakefilepython3 scripts/bootstrap.py, #480's NOTEmakefile,GNUmakefile, or bothmake bootstrapMakefile+makefile,Makefile+GNUmakefile, all threepython3 scripts/bootstrap.py, and a NOTE saying the targets arrive once the twoMakefiles are mergedmake bootstrapexits 2, and still does aftercat shape/Makefile >> MakefileGNUmakefile, S +makefile, S +Makefile+GNUmakefilemake bootstrap"make bootstrapexits 2What changed
adopt-project.py,_next_steps:surviving=, the paths the plan's entries send to the root (paths_for["root"], passed bycmd_execute).GNUmakefileormakefilein GNU make's order, with_root_keeps, as_makefile_follow_upasks them. So NEXT names the same file as the plan'sCONTRACTS_DIRfollow-up.python3 scripts/bootstrap.py. The NOTE names the file in the follow-up's words, and saysmake bootstrapand the shape's other make targets run there only once that file has them, or includes a Makefile that does:Makefileis the root's: "NOTE the shape's Makefile is the root'sMakefile, but GNU make at the root reads the source'sGNUmakefile, the first ofGNUmakefile,makefileandMakefileit finds, somake bootstrapand the shape's other make targets run there only onceGNUmakefilehas them, or includes a Makefile that does;python3 scripts/bootstrap.pyis what the shape'smake bootstrapruns."Makefile: "NOTE the root keeps its own Makefile and the shape's is shape/Makefile, and GNU make at the root reads ..." (the same clause, and the same ending).python3 scripts/bootstrap.py; GNU make at the root reads ...".MAKEFILE, which GNU make never reads where case is kept.Tests
tests/test_adopt_next_make_reads_first.py, new, 40 tests (38, and the 2 of the fix round below):Makefile,makefile,GNUmakefile,makefile+GNUmakefile,Makefile+makefile,Makefile+GNUmakefile, all three, S, S+Makefile, S+GNUmakefile, S+makefile, S+Makefile+GNUmakefile.make bootstrap:MAKEFILE; longer names (makefile.am,Makefile.in,GNUmakefile.bak); and the names below the root._makefile_follow_up, for the same root paths.GNUmakefileormakefile. Each is a realexecute, and its clone is made by pasting NEXT's own clone line. In that clone:make whichprints the file the NOTE names;make -n bootstraphas no rule;bootstrap ok. For S rows, it does so once the shape's script is merged, as the NOTE says;Makefileis kept, the follow-up's merge alone still leaves no rule;include Makefilein the file GNU make reads makesmake -n bootstraprun the shape's recipe.On main's
adopt-project.py, the first 38 all fail. The 9 end to end rows fail on what NEXT prints. The unit rows that guard the unchanged cases fail there only for want of thesurviving=keyword. M1 below shows the same rows passing and every row that keepsGNUmakefileormakefilefailing. On this head, all 40 pass.Mutants of the change, each restored and checked by sha256. Each run is the new file plus the five
nexttests oftest_adopt_e2e.py(43 tests). Every mutant is killed:firstnever foundmakefileasked beforeGNUmakefilefirstMakefilekept besidefirstdroppedfirsttest_adopt_e2e.pyrowscmd_executepasses no pathsGate on this head, named files only, one basetemp per run. Each run had
EMAILset,GIT_CONFIG_GLOBALan empty file,GIT_CONFIG_NOSYSTEM=1, a stubghfirst on PATH,GH_TOKEN=bogusand an emptyGH_CONFIG_DIR:test_adopt_make_reads_first,test_adopt_e2e: 98 passed, with the new file at 38 tests (atc04bb710; the fix round's gate is below).test_adopt_github_exits,test_adopt_printed_sentences,test_repo_hygiene,test_readme_windows_quoting_sentence,test_cli_reference,test_agents_md_codes: 291 passed.test_scaffold_leg_path_collisions: 104 passed.test_adopt_contracts_dir,test_adopt_verify,test_adopt_pins,test_adopt_root_manifest,test_adopt_ignored_shape_files,test_adopt_nested_attributes,test_adopt_shape_pin_and_work_dir: 378 passed.test_shape_doctor.pyin 4 shards: 112 + 112 + 112 + 109 = 445 passed, and 3 skipped (the PowerShell line, which is printed only on a Windows host).Fix round 1 (RV1121's SHOULD-1)
RV1121 found the code right and one test missing: nothing held
cmd_executeto handing_next_steps(surviving=)only the root's paths. Its mutant X4, which passespaths_for["root"] + paths_for["code"] + paths_for["drop"], kept all 43 tests green. The case is a real one: theroot-project-makefilerule sends a keptGNUmakefileto the root, and its reason says that moving a Makefile that only builds the code to the code leg "is a one-line edit of the plan" (contracts/path-classification.yaml, lines 236-237).Two end to end rows,
test_next_keeps_make_bootstrap_where_the_plan_sends_the_makefile_elsewhere[code]and[drop]. Each keepsGNUmakefilein the source, edits the plan to send it toleg: code(thenleg: drop), runs a realexecute, and pastes NEXT's own clone line. Each asserts that NEXT's lines after the clone aremake bootstrapand nothing else, that the clone's root has noGNUmakefile, and thatmake -n bootstrapthere exits 0 and runspython3 scripts/bootstrap.py.The
execute, paste and clone steps of the nine existing end to end rows moved into one helper,executed_and_cloned, which the two new rows share, so no block of the test is written twice. Those rows assert what they asserted. The file now holds 40 tests (38 and 2).adopt-project.pywith the one line changed: the new file and the fivenextrows oftest_adopt_e2e.py(45 selected): 2 failed, 43 passed. Both new rows fail on NEXT's lines, which arepython3 scripts/bootstrap.pyand the NOTE "the shape's Makefile is the root'sMakefile, but GNU make at the root reads the source'sGNUmakefile, ...", naming a file the root does not have. The file was restored and its sha256 read60bad59a...again.adopt-project.py: the two rows pass, since main printedmake bootstrapthere. They hold the unchanged case against the new lookup, and X4 is the mutant that tells them apart.1c5173758, same environment as above: the new file 40 passed,test_adopt_e2e.py27 passed,test_repo_hygiene.py100 passed.git merge-tree --write-treeof this head with main at823624d93: clean (tree73ddafb2).RV1121's four NITs are not in this PR; the lane files them.
Merge
git merge-tree --write-treeof this head with main at6da757cbe, where the branch starts: clean (tree21955cc7). Main has since moved to7cd66902a, which changesscaffold-project.py, its test and the docs, and none of this branch's files. The merge with it is clean too (treeec4e6c8e).GNUmakefileor amakefile, which GNU make reads first, the Makefile collision follow-up no longer says the shape's make targets arrive with the merge, and the pinned file saysmakereads the first of the three and the block reaches it only once that file holds it (#1048) #1105's head5a4de7f76: clean (tree3394d19d). shape_materialize.py and the pinned AGENTS-shape.md: where the root keeps aGNUmakefileor amakefile, which GNU make reads first, the Makefile collision follow-up no longer says the shape's make targets arrive with the merge, and the pinned file saysmakereads the first of the three and the block reaches it only once that file holds it (#1048) #1105'sadopt-project.pychange is in_predict_collisions, apart from_next_steps. On that merge, built in agit clone --sharedcheckout,test_adopt_next_make_reads_first, shape_materialize.py and the pinned AGENTS-shape.md: where the root keeps aGNUmakefileor amakefile, which GNU make reads first, the Makefile collision follow-up no longer says the shape's make targets arrive with the merge, and the pinned file saysmakereads the first of the three and the block reaches it only once that file holds it (#1048) #1105'stest_adopt_collision_make_readsandtest_pinned_copy_textgave 152 passed.adopt-project.py(adopt-project.py:plan'ssourceline names the source's branch as_shownnames a path, so a bidi control, a line boundary or a byte that is not UTF-8 in it is spelled and no longer reaches the terminal raw (#1035) #1120c55e55e3, adopt-project.py: check asks the split's own clone of the source in the work directory, so a clone this git will not make is adopt-git-unasked before any leg, and _resolved and _answers make their repositories as check's other throwaways do (#1083) #1119bdcf9952, adopt-project.py, shape_materialize.py and tests: a named bad link left out of the copy and pin findings takes no other path's finding with it, and the docstrings and the materializer's refusal name the #979 exception and what helps it (#1089) #1118c60066cb, adopt-project.py: under a one-byte locale such as Latin-1,checkreads a plan written in UTF-8 whose source is there, asking the plan's UTF-8 bytes where the spelling as written names nothing, rather than refusingplan-source-gone(#1078) #1106504a1dd6, adopt-project.py:checknames what the clone's.githolds as git keeps refs, and asks a pin's file through the links the root keeps, so a link into.gitor onto a pin's file is refused before any leg or adopted with the copy beside it (#904) #1091160de118): each clean.Not in this PR
GNUmakefileor amakefile, which GNU make reads first, the Makefile collision follow-up no longer says the shape's make targets arrive with the merge, and the pinned file saysmakereads the first of the three and the block reaches it only once that file holds it (#1048) #1105 lands, the lookup "which ofGNUmakefileandmakefilethe root keeps first" is written three times: in_makefile_follow_up,_predict_collisionsand_next_steps. Each is the same two lines overGNU_MAKE_READSand_root_keeps. They are kept apart here so this PR and shape_materialize.py and the pinned AGENTS-shape.md: where the root keeps aGNUmakefileor amakefile, which GNU make reads first, the Makefile collision follow-up no longer says the shape's make targets arrive with the merge, and the pinned file saysmakereads the first of the three and the block reaches it only once that file holds it (#1048) #1105 touch disjoint lines; one helper could serve all three after both land.templates/assembly-root/AGENTS-shape.mdline 19 ("git clone --recurse-submodulesthis repository and runmake bootstrap") has the same gap in an adopted root that keepsGNUmakefileormakefile. It is pinned, and shape_materialize.py and the pinned AGENTS-shape.md: where the root keeps aGNUmakefileor amakefile, which GNU make reads first, the Makefile collision follow-up no longer says the shape's make targets arrive with the merge, and the pinned file saysmakereads the first of the three and the block reaches it only once that file holds it (#1048) #1105 changes that file, so it is left.makefile, a split that commitsMakefileandmakefileside by side, and case variants of GNU make's names #1049), a keptmakefileis reported as aMakefilecollision, and NEXT's NOTE says "the root keeps its own Makefile". The new clause is true there too, since GNU make reads that file and merging into it brings the targets. The spelling is adopt-project.py on a disk that ignores case: no merge follow-up for a keptmakefile, a split that commitsMakefileandmakefileside by side, and case variants of GNU make's names #1049's.GNUmakefile/ormakefile/is named as the source's file. GNU make stops on it with "Is a directory"._makefile_follow_updoes the same.Lane 4 lands nothing outside v1.2.0 until after the v1.2.0 tag, on Brett's later word, so this is a draft.
🤖 Generated with Claude Code
Lane: openreposhape-4 (openRepoShape-4)
Summary by Sourcery
Fix adoption follow-up instructions for roots where GNU make prioritizes a source-kept makefile over the shape's Makefile.
Bug Fixes:
Enhancements:
Tests: