from __future__ import annotations
import os
import shutil
import stat
import subprocess
from pathlib import Path
import pytest
HARNESS_ROOT = Path(__file__).resolve().parents[1]
REPO_ROOT = HARNESS_ROOT.parents[1]
DEV_INIT = HARNESS_ROOT / "dev-init.sh"
RESOLVER = HARNESS_ROOT / "_resolve_python.sh"
INSTALL_HOOKS = REPO_ROOT / "scripts/install-git-hooks.sh"
HOOK_SOURCES = ("changed-files", "pre-commit", "pre-push", "pre-push-singleflight", "pr-preflight")
def _clean_env() -> dict[str, str]:
"""Environment with Git's repository-local variables stripped.
Git exports GIT_DIR and friends to hooks, so this module runs under them
whenever the pre-push gate invokes it. Left in place, `git init <fixture>`
re-opens the *caller's* repository instead of creating the fixture.
"""
env = os.environ.copy()
local_vars = subprocess.run(
["git", "rev-parse", "--local-env-vars"], text=True, stdout=subprocess.PIPE, check=True
).stdout.split()
for var in local_vars:
env.pop(var, None)
env.pop("PYTHON", None)
return env
def _git(*args: str) -> None:
subprocess.run(["git", *args], env=_clean_env(), check=True, stdout=subprocess.DEVNULL)
def _bash() -> str:
bash = shutil.which("bash")
if not bash:
pytest.skip("Bash is required for dev-init tests")
return bash
def _write_executable(path: Path, body: str) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(body, encoding="utf-8")
path.chmod(path.stat().st_mode | stat.S_IXUSR)
def _fixture_repo(root: Path) -> Path:
"""A checkout carrying just enough of the repo for dev-init.sh to run."""
repo = root / "repo"
repo.mkdir()
_git("init", "-q", "--initial-branch=main", str(repo))
(repo / "scripts/dev-harness").mkdir(parents=True)
shutil.copy2(DEV_INIT, repo / "scripts/dev-harness/dev-init.sh")
shutil.copy2(RESOLVER, repo / "scripts/dev-harness/_resolve_python.sh")
shutil.copy2(INSTALL_HOOKS, repo / "scripts/install-git-hooks.sh")
for name in HOOK_SOURCES:
_write_executable(repo / "scripts" / name, "#!/usr/bin/env bash\nexit 0\n")
(repo / "backend").mkdir()
(repo / "backend/.env.local-dev.template").write_text("OMI_FIXTURE=1\n", encoding="utf-8")
(repo / "backend/requirements.txt").write_text("", encoding="utf-8")
_write_executable(
repo / "backend/.venv/bin/python",
"#!/usr/bin/env bash\n"
'if [ "${1:-}" = "-c" ] && [ "${2:-}" = "import sys; print(sys.prefix)" ]; then\n'
' d="$(cd "$(dirname "$0")/.." && pwd -P)"\n'
' printf \'%s\\n\' "$d"\n'
' exit 0\n'
"fi\n"
"exit 0\n",
)
_git("-C", str(repo), "add", "-A")
_git(
"-C",
str(repo),
"-c",
"user.name=omi",
"-c",
"user.email=omi@example.invalid",
"commit",
"-qm",
"init",
)
return repo
def _run_dev_init(cwd: Path) -> subprocess.CompletedProcess[str]:
return subprocess.run(
[_bash(), "scripts/dev-harness/dev-init.sh"],
cwd=cwd,
env=_clean_env(),
text=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
timeout=120,
check=False,
)
def _hooks_dir(cwd: Path) -> Path:
result = subprocess.run(
["git", "-C", str(cwd), "rev-parse", "--git-path", "hooks"],
env=_clean_env(),
text=True,
stdout=subprocess.PIPE,
check=True,
)
return (cwd / result.stdout.strip()).resolve()
def _linked_worktree_dest(tmp_path: Path) -> Path:
"""Place the linked worktree where the host Git wrapper allows it.
The managed git wrapper refuses destinations under /tmp and ~/workspace so
disposable trees land on scratch. Pytest's tmp_path is typically
/private/tmp, which that guard correctly denies. Task worktrees belong
under $OMI_WORKTREES (normally /Volumes/scratch/worktrees/omi). Do not
bypass the guard or skip this test when that root exists.
"""
candidates: list[Path] = []
env_root = os.environ.get("OMI_WORKTREES", "").strip()
if env_root:
candidates.append(Path(env_root))
default_root = Path("/Volumes/scratch/worktrees/omi")
if default_root not in candidates:
candidates.append(default_root)
for root in candidates:
if root.is_dir():
return root / f".pytest-dev-init-linked-{os.getpid()}-{tmp_path.name}"
return tmp_path / "linked"
def test_dev_init_installs_hooks_from_a_linked_worktree(tmp_path: Path) -> None:
"""A linked worktree's `.git` is a file, so `.git/hooks/pre-commit` does not exist.
dev-init.sh used to symlink that literal path and died with
`ln: .git/hooks/pre-commit: Not a directory` — after `pip install`, so the
failure cost a full dependency install first.
"""
repo = _fixture_repo(tmp_path)
worktree = _linked_worktree_dest(tmp_path)
try:
_git("-C", str(repo), "worktree", "add", "-q", "-b", "work", str(worktree))
assert (worktree / ".git").is_file()
result = _run_dev_init(worktree)
assert result.returncode == 0, result.stdout
hook = _hooks_dir(worktree) / "pre-commit"
assert hook.is_file() and os.access(hook, os.X_OK), result.stdout
finally:
subprocess.run(
["git", "-C", str(repo), "worktree", "remove", "--force", str(worktree)],
env=_clean_env(),
check=False,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
shutil.rmtree(worktree, ignore_errors=True)
def test_dev_init_installs_hooks_in_a_main_checkout(tmp_path: Path) -> None:
repo = _fixture_repo(tmp_path)
result = _run_dev_init(repo)
assert result.returncode == 0, result.stdout
hook = _hooks_dir(repo) / "pre-commit"
assert hook.is_file() and os.access(hook, os.X_OK), result.stdout
assert (repo / "backend/.env.local-dev").is_file(), result.stdout
def test_dev_init_next_steps_cover_mobile_and_desktop(tmp_path: Path) -> None:
"""The closing hint used to name only `make dev-desktop`, so anyone setting
up the harness for mobile/iOS testing against it (which needs `make
dev-up`, not the desktop app) was pointed at the wrong command.
"""
repo = _fixture_repo(tmp_path)
result = _run_dev_init(repo)
assert result.returncode == 0, result.stdout
assert "make dev-up" in result.stdout, result.stdout
assert "make dev-desktop" in result.stdout, result.stdout
def _write_logging_bootstrap_stub(directory: Path, name: str, log: Path, *, pinned_ok: bool) -> None:
"""A fake interpreter whose probes are scripted and whose `venv` subcommand
materializes a stub venv whose python logs its invocations and reports the
venv as its sys.prefix (the membership contract dev-init checks).
`pinned_ok` scripts the version predicate: dev-init's bootstrap probe is
the strict >=3.11,<3.12 pin, so a stub that fails it (a real 3.12 or 3.9)
must not be selected as the pinned backend runtime.
"""
stub = directory / name
stub.write_text(
"#!/usr/bin/env bash\n"
f'LOG="{log}"\n'
f'PINNED_OK="{1 if pinned_ok else 0}"\n'
'if [ "${1:-}" = "-m" ] && [ "${2:-}" = "venv" ]; then\n'
' target="$3"\n'
' mkdir -p "$target/bin"\n'
" cat > \"$target/bin/python\" <<'INNER'\n"
"#!/usr/bin/env bash\n"
f'LOG="{log}"\n'
'if [ "${1:-}" = "-c" ] && [ "${2:-}" = "import sys; print(sys.prefix)" ]; then\n'
' d="$(cd "$(dirname "$0")/.." && pwd -P)"\n'
" printf '%s\\n' \"$d\"\n"
" exit 0\n"
"fi\n"
f'printf \'VENV %s\\n\' "$*" >> "{log}"\n'
"exit 0\n"
"INNER\n"
' chmod +x "$target/bin/python"\n'
f'printf \'%s %s\\n\' "{name}" "$*" >> "{log}"\n'
" exit 0\n"
"fi\n"
'case "$2" in\n'
" *version_info*) exit $((1 - PINNED_OK)) ;;\n"
" *) exit 0 ;;\n"
"esac\n"
f'printf \'%s %s\\n\' "{name}" "$*" >> "{log}"\n'
"exit 0\n",
encoding="utf-8",
)
stub.chmod(stub.stat().st_mode | stat.S_IXUSR)
def _isolate_host_prefixes(repo: Path) -> None:
"""Neutralize the host's real Homebrew 3.11 prefixes in a fixture repo.
`dev_harness_backend_pinned_python` probes absolute Homebrew prefixes, so on
a macOS host with a keg-only 3.11 the fallback/absence fixtures would be
silently rescued (Codex P2). The fixture's resolver copy gets an empty
prefix list; only PATH/uv/PYTHON discovery remains host-dependent, and
those tests already stub them.
"""
resolver = repo / "scripts/dev-harness/_resolve_python.sh"
with resolver.open("a", encoding="utf-8") as handle:
handle.write("\ndev_harness_backend_pinned_prefixes() { :; }\n")
def test_dev_init_refuses_to_bootstrap_without_a_pinned_311(tmp_path: Path) -> None:
"""No discoverable or provisionable 3.11 means refusal — not a fallback.
dev-init provisions the backend requirements install, and the backend
pylock is `>=3.11,<3.12` (mobile_doctor rejects any other version), so a
3.12/3.14 floor pick must not silently create a backend-incompatible venv
(Codex P1 + Oracle review). With only a floor-qualified python3.12 and a
3.9 python3 on PATH and no uv, dev-init must exit 1 with install guidance.
"""
repo = _fixture_repo(tmp_path)
_isolate_host_prefixes(repo)
(repo / "backend/.venv/bin/python").unlink()
log = tmp_path / "bootstrap-calls.log"
stub_bin = tmp_path / "bootstrap-stub-bin"
stub_bin.mkdir()
_write_logging_bootstrap_stub(stub_bin, "python3.12", log, pinned_ok=False)
_write_logging_bootstrap_stub(stub_bin, "python3", log, pinned_ok=False)
env = _clean_env()
env["PATH"] = os.pathsep.join((str(stub_bin), "/usr/bin", "/bin"))
result = subprocess.run(
[_bash(), "scripts/dev-harness/dev-init.sh"],
cwd=repo,
env=env,
text=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
timeout=120,
check=False,
)
assert result.returncode == 1, result.stdout
assert "no Python 3.11 could be provisioned" in result.stdout, result.stdout
assert "uv python install 3.11" in result.stdout, result.stdout
calls = log.read_text(encoding="utf-8").splitlines() if log.exists() else []
assert not any(line.startswith("python3.12 -m venv") for line in calls), calls
assert not any(line.startswith("python3 -m venv") for line in calls), calls
assert not (repo / "backend/.venv/bin/python").exists(), result.stdout
def test_dev_installs_311_via_uv_when_not_on_path(tmp_path: Path) -> None:
"""Without a PATH python3.11, dev-init provisions it through uv.
`uv python install 3.11` is exactly what `make lane-backend` does, so a
uv-present host without a discoverable 3.11 must end up with the pinned
runtime rather than a refusal (Codex P1 + Oracle review).
"""
repo = _fixture_repo(tmp_path)
_isolate_host_prefixes(repo)
(repo / "backend/.venv/bin/python").unlink()
log = tmp_path / "uv-calls.log"
stub_bin = tmp_path / "uv-stub-bin"
stub_bin.mkdir()
_write_logging_bootstrap_stub(stub_bin, "python3.12", log, pinned_ok=False)
template = tmp_path / "pinned-template"
_write_logging_bootstrap_stub(tmp_path, "pinned-template", log, pinned_ok=True)
uv = stub_bin / "uv"
uv.write_text(
"#!/usr/bin/env bash\n"
f'LOG="{log}"\n'
'if [ "${1:-}" = "python" ] && [ "${2:-}" = "install" ] && [ "${3:-}" = "3.11" ]; then\n'
f' printf \'%s %s\\n\' "uv" "$*" >> "{log}"\n'
f' cp "{template}" "$(dirname "$0")/python3.11"\n'
' chmod +x "$(dirname "$0")/python3.11"\n'
" exit 0\n"
"fi\n"
"exit 1\n",
encoding="utf-8",
)
uv.chmod(uv.stat().st_mode | stat.S_IXUSR)
env = _clean_env()
env["PATH"] = os.pathsep.join((str(stub_bin), "/usr/bin", "/bin"))
result = subprocess.run(
[_bash(), "scripts/dev-harness/dev-init.sh"],
cwd=repo,
env=env,
text=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
timeout=120,
check=False,
)
assert result.returncode == 0, result.stdout
assert "uv-provisioned repo-pinned backend runtime" in result.stdout, result.stdout
assert "Created backend/.venv (with python3.11)" in result.stdout, result.stdout
calls = log.read_text(encoding="utf-8").splitlines()
assert any(line.startswith("uv python install 3.11") for line in calls), calls
def test_dev_init_refuses_to_install_outside_the_venv(tmp_path: Path) -> None:
"""The requirements install must never run outside backend/.venv.
dev-init binds the install to this repo's venv python; if that interpreter
has been replaced by (or symlinked to) a foreign one, the sys.prefix
membership check must refuse with lane-bootstrap guidance instead of
pip-installing elsewhere (Oracle follow-up on the Codex P1).
"""
repo = _fixture_repo(tmp_path)
log = tmp_path / "refusal-calls.log"
stub_bin = tmp_path / "refusal-stub-bin"
stub_bin.mkdir()
foreign = stub_bin / "foreign-python"
foreign.write_text(
"#!/usr/bin/env bash\n"
f'printf \'FOREIGN %s\\n\' "$*" >> "{log}"\n'
"exit 0\n",
encoding="utf-8",
)
foreign.chmod(foreign.stat().st_mode | stat.S_IXUSR)
(repo / "backend/.venv/bin/python").unlink()
(repo / "backend/.venv/bin/python").symlink_to(foreign)
env = _clean_env()
result = subprocess.run(
[_bash(), "scripts/dev-harness/dev-init.sh"],
cwd=repo,
env=env,
text=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
timeout=120,
check=False,
)
assert result.returncode == 1, result.stdout
assert "does not belong to this repo's backend/.venv" in result.stdout, result.stdout
assert "make lane-bootstrap" in result.stdout, result.stdout
calls = log.read_text(encoding="utf-8").splitlines() if log.exists() else []
assert not any(line.startswith("FOREIGN -m pip") for line in calls), calls
def test_dev_init_refuses_a_foreign_checkout_venv_override(tmp_path: Path) -> None:
"""A symlinked repo venv python pointing at another checkout must fail.
The membership check compares sys.prefix against THIS repo's venv realpath,
so a backend/.venv/bin/python that resolves into a foreign checkout's venv
(different prefix) cannot pip-install this repo's requirements there.
"""
repo = _fixture_repo(tmp_path)
log = tmp_path / "foreign-venv-calls.log"
other = tmp_path / "other-checkout"
(other / "backend/.venv/bin").mkdir(parents=True)
foreign = other / "backend/.venv/bin/python"
foreign.write_text(
"#!/usr/bin/env bash\n"
f'LOG="{log}"\n'
'if [ "${1:-}" = "-c" ] && [ "${2:-}" = "import sys; print(sys.prefix)" ]; then\n'
' d="$(cd "$(dirname "$0")/../.." && pwd -P)"\n'
' printf \'%s\\n\' "$d"\n'
' exit 0\n'
"fi\n"
f'printf \'FOREIGNVENV %s\\n\' "$*" >> "{log}"\n'
"exit 0\n",
encoding="utf-8",
)
foreign.chmod(foreign.stat().st_mode | stat.S_IXUSR)
(repo / "backend/.venv/bin/python").unlink()
(repo / "backend/.venv/bin/python").symlink_to(foreign)
env = _clean_env()
result = subprocess.run(
[_bash(), "scripts/dev-harness/dev-init.sh"],
cwd=repo,
env=env,
text=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
timeout=120,
check=False,
)
assert result.returncode == 1, result.stdout
assert "does not belong to this repo's backend/.venv" in result.stdout, result.stdout
calls = log.read_text(encoding="utf-8").splitlines() if log.exists() else []
assert not any(line.startswith("FOREIGNVENV -m pip") for line in calls), calls
def test_dev_init_bootstraps_the_pinned_311_when_discoverable(tmp_path: Path) -> None:
"""Bootstrap must prefer the repo-pinned 3.11 over the floor pick.
The backend pylock is `>=3.11,<3.12` and mobile_doctor rejects a non-3.11
backend venv, so dev-init provisioning a 3.12/3.14 venv would create an
environment the documented mobile flow immediately blocks (Codex P1).
Discovery comes from the resolver's pinned-backend helper; this test pins
the dev-init preference contract, not the helper's internals.
"""
repo = _fixture_repo(tmp_path)
(repo / "backend/.venv/bin/python").unlink()
log = tmp_path / "pinned-calls.log"
stub_bin = tmp_path / "pinned-stub-bin"
stub_bin.mkdir()
_write_logging_bootstrap_stub(stub_bin, "python3.11", log, pinned_ok=True)
_write_logging_bootstrap_stub(stub_bin, "python3.12", log, pinned_ok=False)
env = _clean_env()
env["PATH"] = os.pathsep.join((str(stub_bin), "/usr/bin", "/bin"))
result = subprocess.run(
[_bash(), "scripts/dev-harness/dev-init.sh"],
cwd=repo,
env=env,
text=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
timeout=120,
check=False,
)
assert result.returncode == 0, result.stdout
assert "Created backend/.venv (with python3.11)" in result.stdout, result.stdout
calls = log.read_text(encoding="utf-8").splitlines()
assert any(line.startswith("python3.11 -m venv backend/.venv") for line in calls), calls
assert not any(line.startswith("python3.12 -m venv") for line in calls), calls
assert any(line.startswith("VENV -m pip install") for line in calls), calls
def test_dev_init_refuses_an_existing_below_floor_venv(tmp_path: Path) -> None:
"""A pre-existing below-floor venv must not receive the requirements install.
The executable-only bootstrap condition used to skip every check on a
checkout that already had backend/.venv, so dev-init ran the full install
under 3.9 and reported success while the resolver (and the pre-push gate)
ignores that same venv (Codex P1). dev-init must refuse with
lane-bootstrap guidance instead.
"""
repo = _fixture_repo(tmp_path)
venv_python = repo / "backend/.venv/bin/python"
venv_python.write_text(
"#!/usr/bin/env bash\n"
'if [ "${1:-}" = "-c" ]; then\n'
" exit 1\n"
"fi\n"
"exit 0\n",
encoding="utf-8",
)
venv_python.chmod(venv_python.stat().st_mode | 0o755)
env = _clean_env()
env["PATH"] = os.pathsep.join(("/usr/bin", "/bin"))
result = subprocess.run(
[_bash(), "scripts/dev-harness/dev-init.sh"],
cwd=repo,
env=env,
text=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
timeout=120,
check=False,
)
assert result.returncode == 1, result.stdout
assert "not the pinned Python 3.11 runtime" in result.stdout, result.stdout
assert "make lane-bootstrap" in result.stdout, result.stdout
assert "refusing to install requirements into it" in result.stdout, result.stdout
def test_dev_init_completes_an_interrupted_install_in_an_existing_venv(
tmp_path: Path,
) -> None:
"""A floor-OK venv missing cheap-gate packages is completable, not refused.
An interrupted first run leaves backend/.venv at exactly this shape (the
venv was created, the requirements install did not finish). Refusing it
would deadlock: the only tool allowed to finish the install is the one
that refuses. dev-init must complete the install instead (Oracle review
follow-up on the Codex P1).
"""
repo = _fixture_repo(tmp_path)
log = tmp_path / "resume-calls.log"
venv_python = repo / "backend/.venv/bin/python"
venv_python.write_text(
"#!/usr/bin/env bash\n"
f'LOG="{log}"\n'
'if [ "${1:-}" = "-c" ] && [ "${2:-}" = "import sys; print(sys.prefix)" ]; then\n'
' d="$(cd "$(dirname "$0")/.." && pwd -P)"\n'
" printf '%s\\n' \"$d\"\n"
" exit 0\n"
"fi\n"
"printf 'VENV %s\\n' \"$*\" >> \"$LOG\"\n"
"exit 0\n",
encoding="utf-8",
)
venv_python.chmod(venv_python.stat().st_mode | 0o755)
env = _clean_env()
result = subprocess.run(
[_bash(), "scripts/dev-harness/dev-init.sh"],
cwd=repo,
env=env,
text=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
timeout=120,
check=False,
)
assert result.returncode == 0, result.stdout
assert "below the 3.10 floor" not in result.stdout, result.stdout
calls = log.read_text(encoding="utf-8").splitlines()
assert any(line.startswith("VENV -m pip install") for line in calls), calls