Skip to content

tests/test_doctor_legs_members_next.py (#276, PR #354) never runs the PowerShell form of the git line a Windows reader is handed, and its test that the explanation holds "none of ;, ', a backtick or a parenthesis" passes only because pytest's temporary roots need no quoting: under a root with a space the same sentence's keep line is git -C '<root>/spec' branch NAME, as the file's own spelling test expects #415

Closed

Description

@brettheap

Lane: openreposhape-4 (openRepoShape-4)

Found by this lane's adversarial review of #276 (PR #354, head c30bfb2: its N6 and N7). PR #354's body carries both as follow-ups at its head cb2a684. #354 is open, and the test file this is about is new in it. Verified at cb2a684. Local bare remotes, an empty global git config, GIT_ALLOW_PROTOCOL=file, and a gh that exits 97 (only the machine row calls it). Two test gaps; neither is a wrong line printed today.

What is wrong.

  1. N6: the PowerShell line is never run.
    • On a Windows host, submodule_update_next prints the git line in PowerShell's quoting: git -C 'C:\...' submodule update --init --recursive --checkout -- <paths>.
    • tests/test_doctor_legs_members_next.py asserts that text (test_the_line_is_spelled_for_the_readers_shell), and every test that PASTES a line is WINDOWS_SKIP, because it pastes through sh -c.
    • So tests-windows never runs the line a Windows reader is handed. The review held it right by PowerShell's documented parsing (-- is passed through to a native command, and a single-quoted root is one argument), but only by reading.
    • The suite already has the pattern: tests/test_shape_doctor.py::test_a_template_validators_next_runs_when_pasted_into_powershell (skipif(os.name != "nt"), powershell -NoProfile -NonInteractive -Command "<line>; exit $LASTEXITCODE"), "the one test that RUNS it". It covers the template validator's line, not this one.
  2. N7: the "no character a pasted tail would break on" test holds only by accident.
    • Its docstring says "New tail text has none of ;, ', a backtick or a parenthesis", and it checks the sentence over CHECKOUT_SCENARIOS, the detached leg included.
    • The same sentence carries the keep line git -C <mount> branch NAME, with the mount quoted by quote_arg. A root whose path needs quoting puts '…' in it, as the file's own spelling test expects ("git -C '/srv/my atlas/spec' branch NAME" in why).
    • The property holds in CI only because pytest's temporary roots need no quoting:
U=<openRepoShape checkout>   # a clean checkout of PR #354's head cb2a684
# Runs in bash on Linux (GNU coreutils). Nothing leaves the machine: every repository is a local bare one under $R, git
# reads an empty global config, GIT_ALLOW_PROTOCOL=file makes any accidental https/ssh clone fail, and a `gh` that exits
# 97 stands first on PATH.
R=$(mktemp -d); mkdir $R/bin; printf '#!/bin/sh\nexit 97\n' > $R/bin/gh; chmod +x $R/bin/gh; touch $R/gitconfig
export PATH=$R/bin:$PATH GIT_CONFIG_GLOBAL=$R/gitconfig GIT_CONFIG_NOSYSTEM=1 GIT_ALLOW_PROTOCOL=file \
       GIT_AUTHOR_NAME=t GIT_AUTHOR_EMAIL=t@t.invalid GIT_COMMITTER_NAME=t GIT_COMMITTER_EMAIL=t@t.invalid
python3 $U/scaffold-project.py --org testorg --project Atlas --elected-by 'Test Human' --elected-on 2026-10-12 \
    --local-remote-dir $R/remotes --work-dir $R/work >/dev/null
C="$R/my projects/Atlas"; git clone -q --recurse-submodules $R/remotes/Atlas.git "$C"     # a root whose path needs quoting
(cd "$C/spec" && echo x >> README.md && git commit -qam 'past the pin, on a detached HEAD')
python3 $U/shape-doctor.py --root "$C" --json > $R/d.json
python3 - $R/d.json <<'PY'
import json, sys
row = [r for r in json.load(open(sys.argv[1]))["rows"] if r["id"] == "legs"][0]
why = row["next"].partition("   # ")[2]
print("the sentence's keep line:", why[why.index("run first"):why.index(" with a name")])
print("characters the test says it never holds:", [c for c in (";", "'", "`", "(", ")") if c in why])
PY
cd $U && grep -n -A9 '^def test_the_explanation_carries_no_character' tests/test_doctor_legs_members_next.py | grep -E 'def |"""|for character|assert'
grep -n -B1 -A5 '^CHECKOUT_SCENARIOS = {' tests/test_doctor_legs_members_next.py | grep -E 'detached'
echo "tests in the new file that run the PowerShell form of a line: $(grep -c -E '"powershell"|powershell\.exe' tests/test_doctor_legs_members_next.py)"

Output at cb2a684:

the sentence's keep line: run first git -C '$R/my projects/Atlas/spec' branch NAME
characters the test says it never holds: ["'"]
356:def test_the_explanation_carries_no_character_a_pasted_tail_would_break_on(
358-    """New tail text has none of `;`, `'`, a backtick or a parenthesis: a
360-    precedent of #267; #277 moves the text out of the NEXT)."""
363-    for character in (";", "'", "`", "(", ")"):
364-        assert character not in why, (character, why)
171-    "detached-past-the-pin": make_detached_past_the_pin,
tests in the new file that run the PowerShell form of a line: 0

The quote is balanced, so the line still pastes in sh. What is wrong is that the test claims a property that the code does not have and that the test's roots never exercise.

Why. N6: the paste tests were written for sh, and the PowerShell half was left at text level, as the writer's brief chose. N7: the property was written for the fixed words of the sentence, and the path the sentence interpolates was not considered.

What it should do. The decisions are the author's:

  1. N6. A Windows-only test, in the precedent's manner: on a root with an empty mount, paste the git line into powershell -NoProfile -NonInteractive -Command "<line>; exit $LASTEXITCODE" (tail cut off first, as the precedent does), assert exit 0, and assert the legs row is ok afterwards. A second root with a space in its path holds the quoting.
  2. N7. Restate the property for the FIXED words of the sentence (strip the quoted paths first, or build the sentence over a root that needs quoting and assert that shlex.split of it succeeds), or drop the test once shape-doctor.py: fifteen NEXT builders end the command with # <comment>, which a stock interactive zsh (macOS's default shell) does not read as a comment, so pasting the line hands the comment's words to the command as arguments, runs whatever follows a ;, and runs the make bootstrap the legs and members comments put in backticks, then exits 127 #277 moves the sentence into why, where it is never pasted.

How to test. These items ARE tests. For N7, a mutant that puts a ' into the fixed words of the sentence must still fail the restated test.

Verified at PR #354's head cb2a684 (tests/test_doctor_legs_members_next.py sha256 2095ef0a…, shape-doctor.py 82a5ac78…).

Related: #276 / PR #354, #277 (the sentence moves to why; in progress in this lane), #238 (the PowerShell paste test's precedent), #413, #414.

Activity

  1. brettheap commented on Oct 18, 2026

    @brettheap
    ContributorAuthor

    CLAIMED — lane openRepoShape-1, session 300f8f46-004a-4e72-8587-4f192be2e108@Eagle, 2026-10-18T14:13:07Z, for #415

    Logged in lanes/log/openRepoShape-1.md at 06f329239c59081c4cde7569dfd262acfa5ae3e8.

    The three reads (lane-collision-protocol Rule 1):

    1. existing `CLAIMED —` comments on opensoft/openRepoShape#415:
       none
    2. `gh pr list --repo opensoft/openRepoShape --state all --search "#415"`, kept where the row or its body names `#415`:
    554	tests: every test that clones a just-pushed local remote by its plain path now clones it with `clone_just_pushed`, so the macOS `failed to copy file` race of #440 cannot reach it; `load_without_bytecode` keeps the doctor's and the Windows-path tests' loads of the family root's scripts from writing `.pyc` into the templates; the not-a-list doctor cases hold INVALID, exit 1; and `GOOD_KEYS` holds th	l3-544-test-hygiene	MERGED
    3. `git ls-remote --heads git@github.com:opensoft/openRepoShape` branches naming `415` as a whole token:
       none
    
  2. added this to the v1.2.0 milestone on Oct 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions