Skip to content

Commit 38d4d8e

Browse files
brabojclaude
andauthored
feat(tests): fork sync migrates the fork's paths across an upstream rename (#1965)
* feat(tests): fork sync migrates the fork's paths across an upstream rename Part of #1944: moving quality-gates.md into core broke the simulated fork's DEPENDS ON path, which a fork fixes mechanically on merge. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(tests): wrap the fork-sync spec step to the line width Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 4073968 commit 38d4d8e

2 files changed

Lines changed: 45 additions & 3 deletions

File tree

‎tests/run_fork_sync.py‎

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,42 @@ def merge(repo, fork, upstream):
187187
return out(repo, "rev-parse", "HEAD"), owned, unexpected
188188

189189

190+
def follow_renames(repo, base, upstream, fork, merged):
191+
"""Point the fork's own files at the paths upstream renamed.
192+
193+
A rename is the one breaking change a fork migrates mechanically, so the
194+
simulation does what the fork would and reports it. Anything a rename
195+
does not explain, a deleted file or a removed ID, still reaches smoke.
196+
"""
197+
status = out(repo, "diff", "-M", "--name-status", "--diff-filter=R",
198+
base, upstream).splitlines()
199+
renames = [tuple(line.split("\t")[1:3]) for line in status]
200+
own = out(repo, "diff", "--name-only", "--diff-filter=A", base,
201+
fork).splitlines()
202+
203+
git(repo, "checkout", "-q", "--detach", merged)
204+
touched = []
205+
for rel in own:
206+
text = read(repo, rel)
207+
moved = text
208+
for old, new in renames:
209+
moved = moved.replace(old, new)
210+
if moved != text:
211+
touched.append(rel)
212+
if not touched:
213+
return merged, renames
214+
215+
def edit(target):
216+
for rel in touched:
217+
text = read(target, rel)
218+
for old, new in renames:
219+
text = text.replace(old, new)
220+
write(target, rel, text)
221+
return touched
222+
223+
return commit(repo, merged, "fork: follow upstream renames", edit), renames
224+
225+
190226
def nested_smoke(repo, upstream):
191227
"""Run the merged tree's own smoke suite, with SYS-20 against upstream."""
192228
env = dict(os.environ, SAIT_UPSTREAM_REF=upstream)
@@ -240,6 +276,10 @@ def real(repo, base, head, fork):
240276
return {"id": "FS-03", "title": title, "notes": notes, "failures": [
241277
f" conflicts outside the fork's own documents: {unexpected}"]}
242278

279+
merged, renames = follow_renames(repo, base, upstream, fork, merged)
280+
notes.append(f" upstream renames, applied to the fork's own files: "
281+
f"{renames or 'none'}")
282+
243283
if not os.path.exists(os.path.join(repo, FORK_STACK)):
244284
return {"id": "FS-03", "title": title, "notes": notes, "failures": [
245285
f" the merged tree lost the fork's stack, {FORK_STACK}"]}

‎tests/specs/SAIT-INT-MNF-06-001A.md‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,9 @@ tags: [manifest, fork, composition, merge]
6262
title
6363
3. FS-03: merge HEAD, or a planted `base:` description edit when HEAD
6464
changes nothing against the base; keep the fork's side of any conflict
65-
in a fork-owned document, then run the merged tree's `run_smoke.py` with
66-
`SAIT_UPSTREAM_REF` at the upstream side
65+
in a fork-owned document, point the fork's own files at each path
66+
upstream renamed, as a fork migrating would, then run the merged
67+
tree's `run_smoke.py` with `SAIT_UPSTREAM_REF` at the upstream side
6768

6869
### Assertions
6970

@@ -72,7 +73,8 @@ tags: [manifest, fork, composition, merge]
7273
2. Assert FS-01 conflicts in `templates/manifest.yaml` only, and is caught
7374
3. Assert FS-02 conflicts in `README.md` only, and completes as the fork's
7475
4. Assert FS-03 conflicts in no file outside the fork-owned documents,
75-
keeps the fork's stack, and its smoke run passes
76+
keeps the fork's stack, and its smoke run passes. A rename is migrated
77+
and reported; a deleted file or a removed ID is not, and fails smoke
7678
5. Assert all three scenarios ran
7779

7880
### Negative controls

0 commit comments

Comments
 (0)