fix(6245): bind_repo(moved_from=…) moves the snippet locations recorded in the old repo
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 16s
CI & Build / TypeScript typecheck (push) Successful in 58s
CI & Build / integration (push) Failing after 1m16s
CI & Build / Python tests (push) Successful in 2m33s
CI & Build / Build & push image (push) Skipped
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 16s
CI & Build / TypeScript typecheck (push) Successful in 58s
CI & Build / integration (push) Failing after 1m16s
CI & Build / Python tests (push) Successful in 2m33s
CI & Build / Build & push image (push) Skipped
A repo renamed on its forge kept every snippet location naming the old repo: the binding and the shape ledger moved, the snippets did not. - snippets.move_location_repo rewrites, on every live snippet of the project, each location whose repo is the old remote in any form (URL, normalized key, "owner/Repo", bare "Repo", compared without case) to the new normalized key. A snippet the caller can only read is listed in read_only and left alone. - Its loop is shared with move_locations through _rewrite_locations, which saves each changed snippet through update_snippet. - bind_repo calls it after the binding moves and reports snippets_moved and snippets_read_only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -100,3 +100,35 @@ async def test_the_same_repo_under_both_names_is_refused(bound):
|
||||
await svc.move_binding(
|
||||
bound["owner"], OLD, "git@git.example.com:alice/oldname", bound["pid"],
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.integration
|
||||
async def test_the_snippets_recorded_in_the_old_repo_move_with_it(bound):
|
||||
from grimoire.services import snippets as snippets_svc
|
||||
|
||||
owner, pid = bound["owner"], bound["pid"]
|
||||
|
||||
async def snippet(name, *repos):
|
||||
note = await snippets_svc.create_snippet(
|
||||
owner, name=name, code=f"def {name}():\n pass\n", language="python",
|
||||
project_id=pid,
|
||||
locations=[{"repo": r, "path": "src/app.py", "symbol": name} for r in repos],
|
||||
)
|
||||
return int(note.id)
|
||||
|
||||
moved_one = await snippet("moved_one", "OldName", "alice/oldname", OLD)
|
||||
mixed = await snippet("mixed", "git.example.com/alice/oldname", "elsewhere/gadget")
|
||||
untouched = await snippet("untouched", "Gadget", "git.example.com/alice/oldnamesake")
|
||||
|
||||
result = await snippets_svc.move_location_repo(owner, pid, OLD, NEW)
|
||||
|
||||
assert sorted(result["moved"]) == sorted([moved_one, mixed])
|
||||
assert result["read_only"] == []
|
||||
|
||||
async def repos(snippet_id):
|
||||
note = await snippets_svc.get_snippet(owner, snippet_id)
|
||||
return [loc["repo"] for loc in snippets_svc.snippet_fields(note)["locations"]]
|
||||
|
||||
assert await repos(moved_one) == [NEW_KEY, NEW_KEY, NEW_KEY]
|
||||
assert await repos(mixed) == [NEW_KEY, "elsewhere/gadget"]
|
||||
assert await repos(untouched) == ["Gadget", "git.example.com/alice/oldnamesake"]
|
||||
|
||||
Reference in New Issue
Block a user