diff --git a/pre_build.sh b/pre_build.sh index f74f476..c06b9e9 100644 --- a/pre_build.sh +++ b/pre_build.sh @@ -167,9 +167,10 @@ run_workspace() { # Format only the dirs this script stages — black'ing "." reformatted files # no staging rule covered (13 files across HowTo*/assistant), leaving them # perpetually dirty-local on every release (#156). - for d in scripts slam_pipeline; do - if [ -d "$d" ]; then black "$d/"; fi - done + if [ -d "scripts" ]; then black "scripts/"; fi + # slam_pipeline/ is staged only for slam=true repos, so black only there — + # black'ing it elsewhere re-dirtied autolens_workspace_developer every release. + if [ "$slam" = "true" ] && [ -d "slam_pipeline" ]; then black "slam_pipeline/"; fi if [ "$generate" = "true" ]; then echo " Running generate.py ($project)..." diff --git a/tests/test_pre_build_skill.py b/tests/test_pre_build_skill.py index b96464a..3c65bae 100644 --- a/tests/test_pre_build_skill.py +++ b/tests/test_pre_build_skill.py @@ -60,6 +60,6 @@ def test_pre_build_wip_preflight_precedes_every_mutation(): preflight = script.index("=== Checking workspaces for uncommitted work ===") assert preflight < script.index("run_workspace() {") # The invocations themselves, not the words — both appear in prose above. - assert preflight < script.index('black "$d/"') + assert preflight < script.index('black "scripts/"') assert preflight < script.index("git add -u --") assert "ABORT: uncommitted work" in script diff --git a/tests/test_pre_build_staging.py b/tests/test_pre_build_staging.py index f0821fc..910ef0b 100644 --- a/tests/test_pre_build_staging.py +++ b/tests/test_pre_build_staging.py @@ -231,3 +231,32 @@ def test_tracked_deletions_are_staged(base, stub_bin): assert "notebooks/committed.ipynb" not in _git(work, "ls-files", "notebooks") assert "pre build" in _git(work, "log", "--oneline") + + +def test_black_touches_only_what_is_staged(base, stub_bin): + """No workspace is left dirty: black runs on exactly the dirs that are staged. + + pre_build black'd `slam_pipeline/` everywhere but staged it only for + slam=true repos, so slam=false workspaces were re-dirtied by every + release (2026.10.16.2) and Heart reported it as worktree drift. + """ + # A black that really reformats: append a line to every .py it is given. + (stub_bin / "black").write_text( + "#!/bin/bash\n" + 'for d in "$@"; do find "$d" -name "*.py" -exec sh -c ' + "'echo \"# black\" >> \"$1\"' _ {} \\; ; done\n" + "exit 0\n" + ) + for repo, _p, _g, _s in SPECS: + work = base / repo + (work / "slam_pipeline").mkdir() + (work / "slam_pipeline" / "pipe.py").write_text("y = 2\n") + _commit_all(work, "fixture slam_pipeline") + _git(work, "push", "-q", "origin", "main") + + result = _run(base, stub_bin) + assert result.returncode == 0, result.stderr + for repo, _p, _g, slam in SPECS: + assert _git(base / repo, "status", "--porcelain") == "", repo + reformatted = "# black" in (base / repo / "slam_pipeline" / "pipe.py").read_text() + assert reformatted == (slam == "true"), repo