diff --git a/spec/audit.py b/spec/audit.py index d6fbe33f..934500cd 100755 --- a/spec/audit.py +++ b/spec/audit.py @@ -4737,6 +4737,13 @@ def _selftest_cases(): ["git", "config", "user.name", "test"], ): subprocess.run(cmd, cwd=tmp_root_path, check=True, capture_output=True) + (tmp_root_path / "control.txt").write_text("x") + subprocess.run( + ["git", "add", "--", "control.txt"], + cwd=tmp_root_path, + check=True, + capture_output=True, + ) added = False try: (tmp_root_path / bad_name).write_text("x") @@ -4746,7 +4753,10 @@ def _selftest_cases(): else: try: subprocess.run( - ["git", "add", "-A"], cwd=tmp_root_path, check=True, capture_output=True + ["git", "add", "--", bad_name], + cwd=tmp_root_path, + check=True, + capture_output=True, ) except subprocess.CalledProcessError: if not _IS_WINDOWS: diff --git a/tests/test_audit.py b/tests/test_audit.py index 7b20be88..2dc95757 100755 --- a/tests/test_audit.py +++ b/tests/test_audit.py @@ -196,17 +196,15 @@ def test_a_failed_shebang_read_raises_rather_than_reading_as_undecided(self) -> run_audit(tree, {"bin/Run_Backup": "100755"}, frozenset({"bin/Run_Backup"})) -def _probe_run(add: Any, commit: Any = None) -> Any: - """A subprocess.run stand-in whose answer to the invalid-byte probe's own git add is `add`.""" +def _probe_run(add: Any, commit: Any = None, control: Any = None) -> Any: + """A subprocess.run stand-in answering the invalid-byte probe's own git add of the bad name with `add`.""" real_run = subprocess.run def run(cmd: list[str], *args: Any, **kwargs: Any) -> Any: cwd = kwargs.get("cwd") - if ( - cmd == ["git", "add", "-A"] - and cwd - and any(p.name.startswith("bad-") for p in pathlib.Path(cwd).iterdir()) - ): + if control is not None and cmd == ["git", "add", "--", "control.txt"]: + return control(cmd) + if cmd[:3] == ["git", "add", "--"] and cwd and cmd[3].startswith("bad-"): return add(cmd) if commit is not None and cmd[:2] == ["git", "commit"] and "add invalid-utf8 name" in cmd: return commit(cmd) @@ -254,9 +252,16 @@ def _error_of(self, run: Any, windows: bool) -> subprocess.CalledProcessError: self._require_probe_file(out.getvalue()) self.fail("the git failure did not propagate") + def test_a_failing_control_add_fails_loudly_on_windows(self) -> None: + error = self._error_of( + _probe_run(lambda cmd: subprocess.CompletedProcess(cmd, 0), control=_fail), + windows=True, + ) + self.assertEqual(error.cmd, ["git", "add", "--", "control.txt"]) + def test_a_failing_add_of_the_probe_file_fails_loudly_elsewhere(self) -> None: error = self._error_of(_probe_run(_fail), windows=False) - self.assertEqual(error.cmd, ["git", "add", "-A"]) + self.assertEqual(error.cmd[:3], ["git", "add", "--"]) def test_another_git_failure_still_fails_loudly(self) -> None: run = _probe_run(