Complete action runtime rewrite
This commit is contained in:
@@ -2,14 +2,18 @@
|
||||
|
||||
import subprocess
|
||||
|
||||
import pytest
|
||||
|
||||
from flow.core.config import AppConfig, FlowContext
|
||||
from flow.core.console import Console
|
||||
from flow.core.errors import FlowError
|
||||
from flow.core.platform import PlatformInfo
|
||||
from flow.core.runtime import SystemRuntime
|
||||
from flow.services.projects import ProjectService
|
||||
from flow.app.projects import ProjectService
|
||||
|
||||
|
||||
def _make_ctx(projects_dir):
|
||||
def _make_ctx(projects_dir, monkeypatch):
|
||||
monkeypatch.setattr("flow.actions.executor.paths.STATE_DIR", projects_dir / ".state")
|
||||
return FlowContext(
|
||||
config=AppConfig(projects_dir=str(projects_dir)),
|
||||
manifest={},
|
||||
@@ -19,25 +23,44 @@ def _make_ctx(projects_dir):
|
||||
)
|
||||
|
||||
|
||||
def _git(*args):
|
||||
return subprocess.run(
|
||||
["git", *[str(arg) for arg in args]],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True,
|
||||
)
|
||||
|
||||
|
||||
def _init_repo(path, commit=True):
|
||||
"""Create a git repo with an initial commit."""
|
||||
path.mkdir(parents=True, exist_ok=True)
|
||||
subprocess.run(["git", "init", str(path)], capture_output=True, check=True)
|
||||
subprocess.run(["git", "-C", str(path), "config", "user.email", "test@test.com"], capture_output=True, check=True)
|
||||
subprocess.run(["git", "-C", str(path), "config", "user.name", "Test"], capture_output=True, check=True)
|
||||
_git("init", path)
|
||||
_git("-C", path, "config", "user.email", "test@test.com")
|
||||
_git("-C", path, "config", "user.name", "Test")
|
||||
if commit:
|
||||
(path / "README.md").write_text("# test")
|
||||
subprocess.run(["git", "-C", str(path), "add", "."], capture_output=True, check=True)
|
||||
subprocess.run(["git", "-C", str(path), "commit", "-m", "init"], capture_output=True, check=True)
|
||||
_git("-C", path, "add", ".")
|
||||
_git("-C", path, "commit", "-m", "init")
|
||||
|
||||
|
||||
def _add_upstream(repo):
|
||||
remote = repo.parent / f"{repo.name}.git"
|
||||
_git("init", "--bare", remote)
|
||||
_git("-C", repo, "remote", "add", "origin", remote)
|
||||
branch = _git("-C", repo, "branch", "--show-current").stdout.strip()
|
||||
_git("-C", repo, "push", "-u", "origin", branch)
|
||||
|
||||
|
||||
class TestProjectService:
|
||||
def test_check_clean_repo(self, tmp_path, capsys):
|
||||
def test_check_clean_repo(self, tmp_path, monkeypatch, capsys):
|
||||
projects = tmp_path / "projects"
|
||||
projects.mkdir()
|
||||
_init_repo(projects / "myrepo")
|
||||
repo = projects / "myrepo"
|
||||
_init_repo(repo)
|
||||
_add_upstream(repo)
|
||||
|
||||
ctx = _make_ctx(projects)
|
||||
ctx = _make_ctx(projects, monkeypatch)
|
||||
svc = ProjectService(ctx)
|
||||
svc.check(fetch=False)
|
||||
|
||||
@@ -45,33 +68,74 @@ class TestProjectService:
|
||||
assert "myrepo" in output
|
||||
assert "clean" in output
|
||||
|
||||
def test_check_uncommitted_changes(self, tmp_path, capsys):
|
||||
def test_check_uncommitted_changes(self, tmp_path, monkeypatch, capsys):
|
||||
projects = tmp_path / "projects"
|
||||
projects.mkdir()
|
||||
_init_repo(projects / "myrepo")
|
||||
(projects / "myrepo" / "new_file.txt").write_text("changes")
|
||||
repo = projects / "myrepo"
|
||||
_init_repo(repo)
|
||||
_add_upstream(repo)
|
||||
(repo / "new_file.txt").write_text("changes")
|
||||
|
||||
ctx = _make_ctx(projects)
|
||||
ctx = _make_ctx(projects, monkeypatch)
|
||||
svc = ProjectService(ctx)
|
||||
svc.check(fetch=False)
|
||||
|
||||
output = capsys.readouterr().out
|
||||
assert "uncommitted" in output
|
||||
|
||||
def test_check_no_git_repos(self, tmp_path, capsys):
|
||||
def test_check_no_git_repos(self, tmp_path, monkeypatch, capsys):
|
||||
projects = tmp_path / "projects"
|
||||
projects.mkdir()
|
||||
(projects / "not-a-repo").mkdir()
|
||||
|
||||
ctx = _make_ctx(projects)
|
||||
ctx = _make_ctx(projects, monkeypatch)
|
||||
svc = ProjectService(ctx)
|
||||
svc.check(fetch=False)
|
||||
|
||||
output = capsys.readouterr().out
|
||||
assert "No git" in output
|
||||
|
||||
def test_missing_projects_dir(self, tmp_path, capsys):
|
||||
ctx = _make_ctx(tmp_path / "nonexistent")
|
||||
def test_missing_projects_dir(self, tmp_path, monkeypatch, capsys):
|
||||
ctx = _make_ctx(tmp_path / "nonexistent", monkeypatch)
|
||||
svc = ProjectService(ctx)
|
||||
svc.check(fetch=False)
|
||||
assert "not found" in capsys.readouterr().out
|
||||
|
||||
def test_fetch_failure_raises(self, tmp_path, monkeypatch):
|
||||
projects = tmp_path / "projects"
|
||||
projects.mkdir()
|
||||
repo = projects / "myrepo"
|
||||
_init_repo(repo)
|
||||
_git("-C", repo, "remote", "add", "origin", tmp_path / "missing-origin")
|
||||
|
||||
ctx = _make_ctx(projects, monkeypatch)
|
||||
svc = ProjectService(ctx)
|
||||
|
||||
with pytest.raises(FlowError, match="Fetch remotes for myrepo"):
|
||||
svc.check(fetch=True)
|
||||
|
||||
def test_status_failure_raises(self, tmp_path, monkeypatch):
|
||||
projects = tmp_path / "projects"
|
||||
projects.mkdir()
|
||||
repo = projects / "myrepo"
|
||||
_init_repo(repo)
|
||||
(repo / ".git" / "HEAD").unlink()
|
||||
|
||||
ctx = _make_ctx(projects, monkeypatch)
|
||||
svc = ProjectService(ctx)
|
||||
|
||||
with pytest.raises(FlowError, match="Check working tree for myrepo"):
|
||||
svc.check(fetch=False)
|
||||
|
||||
def test_missing_upstream_raises_instead_of_clean(self, tmp_path, monkeypatch, capsys):
|
||||
projects = tmp_path / "projects"
|
||||
projects.mkdir()
|
||||
_init_repo(projects / "myrepo")
|
||||
|
||||
ctx = _make_ctx(projects, monkeypatch)
|
||||
svc = ProjectService(ctx)
|
||||
|
||||
with pytest.raises(FlowError, match="rev-list"):
|
||||
svc.check(fetch=False)
|
||||
|
||||
assert "clean" not in capsys.readouterr().out
|
||||
|
||||
Reference in New Issue
Block a user