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
2 changes: 0 additions & 2 deletions frontend/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -544,8 +544,6 @@ async def clone_and_build(request: Request) -> dict:
workdir = _repository_workdir(name, explicit_workdir)

try:
from server import _ensure_git_installed
_ensure_git_installed()
Path(workdir).parent.mkdir(parents=True, exist_ok=True)
if (Path(workdir) / ".git").exists():
subprocess.run(["git", "-C", workdir, "pull", "--ff-only"], check=True)
Expand Down
28 changes: 0 additions & 28 deletions server.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,33 +310,6 @@ def repository_workdir(provider_name: str, spec: dict[str, Any]) -> str | None:
return str(REPOS_DIR / safe)


def _ensure_git_installed() -> None:
"""Verify ``git`` is on PATH; attempt apt-get install if missing.

Repository providers need ``git``. The Dockerfile installs it during the
image build, but older images (or non-Docker environments) may not have
it — try a best-effort apt-get install before bailing out. Runs at most
once per process.
"""
import shutil
if shutil.which("git"):
return
print("git not found on PATH — attempting apt-get install...")
try:
subprocess.run(["apt-get", "update"], check=True)
subprocess.run(
["apt-get", "install", "-y", "--no-install-recommends", "git"],
check=True,
)
except Exception as exc:
raise RuntimeError(
"git is required for repository providers but is not installed, "
f"and automatic apt-get install failed: {exc}"
) from exc
if not shutil.which("git"):
raise RuntimeError("apt-get install succeeded but git is still not on PATH")


def materialize_repository(spec: dict[str, Any]) -> None:
"""Clone the repo (if absent) and run build_commands. Idempotent.

Expand All @@ -359,7 +332,6 @@ def materialize_repository(spec: dict[str, Any]) -> None:
build_commands = list(repo.get("build_commands") or [])

try:
_ensure_git_installed()
wd_path = Path(workdir)
wd_path.parent.mkdir(parents=True, exist_ok=True)

Expand Down
29 changes: 0 additions & 29 deletions tests/test_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -770,35 +770,6 @@ def test_default_workdir_uses_provider_name(self):
assert wd.endswith("linkedin")


class TestEnsureGitInstalled:
def test_noop_when_git_present(self):
from server import _ensure_git_installed
with patch("shutil.which", return_value="/usr/bin/git"), \
patch("server.subprocess.run") as mock_run:
_ensure_git_installed()
mock_run.assert_not_called()

def test_runs_apt_get_when_missing(self):
from server import _ensure_git_installed
# First which() returns None, second (after install) returns the path
which_calls = iter([None, "/usr/bin/git"])
with patch("shutil.which", side_effect=lambda _: next(which_calls)), \
patch("server.subprocess.run") as mock_run:
_ensure_git_installed()
cmds = [c[0][0] for c in mock_run.call_args_list]
assert cmds[0] == ["apt-get", "update"]
assert cmds[1][:3] == ["apt-get", "install", "-y"]
assert "git" in cmds[1]

def test_raises_when_install_fails(self):
from server import _ensure_git_installed
import subprocess as sp
with patch("shutil.which", return_value=None), \
patch("server.subprocess.run", side_effect=sp.CalledProcessError(1, "apt-get")):
with pytest.raises(RuntimeError, match="git is required"):
_ensure_git_installed()


class TestMaterializeRepository:
def _spec(self, tmp_path: Path, **overrides):
repo = {
Expand Down
Loading