Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
481 changes: 436 additions & 45 deletions scripts/family.py

Large diffs are not rendered by default.

35 changes: 25 additions & 10 deletions tests/test_family.py
Original file line number Diff line number Diff line change
Expand Up @@ -1046,10 +1046,11 @@ def test_bump_to_the_commit_already_pinned_ignores_what_the_member_holds(

def test_bump_to_the_commit_already_pinned_leaves_an_uncommitted_edit_alone(
holder):
"""The rewrite equals `HEAD`, so there is nothing to record, and what the
working copy held before is put back: an uncommitted edit to the `members:`
block is not this run's to discard, however wrong it is. `git status` says
the same before and after."""
"""An uncommitted edit to the `members:` block is not this run's to
discard, however wrong it is. The rewrite equals `HEAD`, so there would be
nothing to record; since #684 `bump` refuses the edit before that, as a
`family.yaml` holding a change HEAD does not, and leaves it where it is.
`git status` says the same before and after."""
pinned = git("rev-parse", "HEAD:members/IRRS", cwd=holder).stdout.strip()
manifest_path = holder / "family.yaml"
manifest_path.write_text(manifest_path.read_text().replace(
Expand All @@ -1061,8 +1062,9 @@ def test_bump_to_the_commit_already_pinned_leaves_an_uncommitted_edit_alone(
result = run_script(FAMILY, "bump", "--family-root", str(holder),
"--member", "IRRS", "--to", pinned)

assert result.returncode == 1, result.stderr + result.stdout
assert nothing_to_do_line("IRRS", pinned) in result.stdout
assert result.returncode == 2, result.stderr + result.stdout
assert result.stdout == ""
assert result.stderr.startswith("REFUSED family-manifest-uncommitted: ")
assert manifest_path.read_bytes() == edited
assert git("status", "--porcelain", cwd=holder).stdout == status

Expand Down Expand Up @@ -1110,7 +1112,13 @@ def test_bump_finishes_a_bump_an_earlier_run_staged_and_did_not_commit(holder):
commit: a run that wrote the row and staged both paths and then died
before `git commit` — a hook that refused, a lock — leaves exactly this.
Reading `was == --to` as "nothing to do" would call the half-finished bump
done and leave the commit for somebody to make by hand (#210)."""
done and leave the commit for somebody to make by hand (#210). Since #684
the staged `family.yaml` is refused first, as a change HEAD does not hold,
and with the gitlink staged beside it the refusal names one way out
alone: `git checkout HEAD -- family.yaml`, which leaves the gitlink
staged, and the same bump then finishes in ONE commit of both paths.
(`git commit -- family.yaml` would commit the row without its
gitlink.)"""
member = holder / "members" / "IRRS"
before = git("rev-parse", "HEAD:members/IRRS", cwd=holder).stdout.strip()
after = commit_in_member(member)
Expand All @@ -1120,9 +1128,16 @@ def test_bump_finishes_a_bump_an_earlier_run_staged_and_did_not_commit(holder):
manifest_path.write_text(text.replace(before, after, 1))
git("add", "--", "members/IRRS", "family.yaml", cwd=holder)
head = git("rev-parse", "HEAD", cwd=holder).stdout.strip()

result = run_script(FAMILY, "bump", "--family-root", str(holder),
"--member", "IRRS", "--to", after)
args = ["bump", "--family-root", str(holder), "--member", "IRRS", "--to",
after]

refused = run_script(FAMILY, *args)
assert refused.returncode == 2, refused.stderr + refused.stdout
assert refused.stderr.startswith("REFUSED family-manifest-uncommitted: ")
assert ("Remediation: the index also stages a gitlink under members/ "
in refused.stderr), refused.stderr
git("checkout", "HEAD", "--", "family.yaml", cwd=holder)
result = run_script(FAMILY, *args)

assert result.returncode == 0, result.stderr + result.stdout
assert "nothing to do" not in result.stdout
Expand Down
4 changes: 3 additions & 1 deletion tests/test_family_add_refusals.py
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,9 @@ def test_a_manifest_this_tool_will_not_rewrite_is_refused_before_the_mount(
"exactly one was expected, so this tool will not rewrite it",
"Remediation: the manifest was hand-edited into a shape this tool "
"does not recognise. `members:` is the LAST block in the file and "
"everything below it belongs to this tool; fix it by hand this once.")
"everything below it belongs to this tool; fix it by hand this once "
"and commit that (`git commit -- family.yaml`), then run the same "
"command again.")
assert_unchanged(holder, before, SPARE)
offline.assert_left_nothing()

Expand Down
7 changes: 5 additions & 2 deletions tests/test_family_bump_remove_rollback.py
Original file line number Diff line number Diff line change
Expand Up @@ -429,13 +429,16 @@ def test_a_remove_dry_run_under_a_held_index_lock_is_unchanged(
# --- refusals a dry run asks first are asked first (#365) -----------------

def comment_on_members(root: Path, env: dict) -> None:
"""A comment on the `members:` line, uncommitted: YAML reads past it and
the line rewrite does not (`family-members-unrecognised`)."""
"""A comment on the `members:` line, committed: YAML reads past it and
the line rewrite does not (`family-members-unrecognised`). Committed,
since the verbs refuse a `family.yaml` holding a change HEAD does not
first (#684)."""
manifest_path = root / "family.yaml"
text = manifest_path.read_bytes()
assert text.count(b"\nmembers:\n") == 1, "fixture drift"
manifest_path.write_bytes(text.replace(
b"\nmembers:\n", b"\nmembers: # edited by hand\n"))
raw(root, env, "commit", "-q", "-m", "A hand edit", "--", "family.yaml")


@pytest.mark.parametrize("verb", ["remove", "bump"])
Expand Down
16 changes: 8 additions & 8 deletions tests/test_family_dry_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -777,15 +777,12 @@ def test_a_dry_run_asks_the_manifest_refusal_the_real_run_asks_first_too(
ask it after, with the holder changed). The dry run asks it too, exit 2,
before anything is written. The hand edit is the one
`test_family_add_refusals.py` makes: a comment on the `members:` line,
which YAML reads past and the line rewrite does not, left uncommitted.
The real runs are held to the same holder in
which YAML reads past and the line rewrite does not, committed, since
the verbs refuse a `family.yaml` holding a change HEAD does not first
(#684). The real runs are held to the same holder in
`test_family_bump_remove_rollback.py`."""
env = isolated(offline, tmp_path)
manifest_path = holder / "family.yaml"
text = manifest_path.read_bytes().decode("utf-8")
assert text.count("\nmembers:\n") == 1, "fixture drift"
manifest_path.write_bytes(text.replace(
"\nmembers:\n", "\nmembers: # edited by hand\n").encode("utf-8"))
a_members_line_edited_by_hand(holder)
before = state(holder, env)
extra = ["--to", older(family)] if verb == "bump" else []

Expand Down Expand Up @@ -1042,12 +1039,15 @@ def a_cached_store(root: Path) -> None:

def a_members_line_edited_by_hand(root: Path) -> None:
"""A comment on the `members:` line, which YAML reads past and the line
rewrite does not, left uncommitted."""
rewrite does not, committed: the verbs refuse a `family.yaml` holding a
change HEAD does not before this (#684)."""
manifest_path = root / "family.yaml"
text = manifest_path.read_bytes().decode("utf-8")
assert text.count("\nmembers:\n") == 1, "fixture drift"
manifest_path.write_bytes(text.replace(
"\nmembers:\n", "\nmembers: # edited by hand\n").encode("utf-8"))
git("-c", "user.name=t", "-c", "user.email=t@t", "commit", "-qm",
"A hand edit", "--", "family.yaml", cwd=root)


def a_renamed_copy_of_a_member(root: Path) -> Path:
Expand Down
Loading
Loading