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: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "grove"
version = "0.5.1"
version = "0.5.3"
description = "Git Worktree Workspace Orchestrator"
readme = "README.md"
authors = [
Expand Down
8 changes: 1 addition & 7 deletions shell/grove.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,7 @@ gw() {
return $rc
fi

# For create --go, use a temp file so stdout stays connected to the tty
local has_go=false
for arg in "$@"; do
[ "$arg" = "--go" ] && has_go=true
done

if [ "$has_go" = true ]; then
if [ "$1" = "create" ]; then
local tmpfile
tmpfile="$(mktemp)"
command gw "$@" | tee "$tmpfile"
Expand Down
13 changes: 3 additions & 10 deletions src/grove/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,6 @@ def create(
autocompletion=complete_preset_name,
),
all_repos: bool = typer.Option(False, "--all", help="Use all discovered repos"),
go: bool = typer.Option(False, "--go", help="Print cd sentinel after creation"),
) -> None:
"""Create a new workspace with worktrees from selected repos."""
cfg = config.require_config()
Expand Down Expand Up @@ -288,9 +287,8 @@ def create(
console.print()
success(f"Workspace [bold]{name}[/] created at {ws.path}")

if go:
# Sentinel for shell function to intercept and cd
print(f"__grove_cd:{ws.path}")
# Sentinel for shell function to intercept and cd
print(f"__grove_cd:{ws.path}")


@app.command("list")
Expand Down Expand Up @@ -578,12 +576,7 @@ def shell_init() -> None:
return $rc
fi

local has_go=false
for arg in "$@"; do
[ "$arg" = "--go" ] && has_go=true
done

if [ "$has_go" = true ]; then
if [ "$1" = "create" ]; then
local tmpfile
tmpfile="$(mktemp)"
command gw "$@" | tee "$tmpfile"
Expand Down
2 changes: 1 addition & 1 deletion src/grove/console.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def success(msg: str) -> None:


def info(msg: str) -> None:
_err_console.print(f"[dim]{msg}[/]")
_err_console.print(msg, style="dim")


def warning(msg: str) -> None:
Expand Down
8 changes: 4 additions & 4 deletions src/grove/workspace.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ def create_workspace(

# --- Run per-repo setup hooks ---
for repo_wt in created:
_run_setup(repo_wt.repo_name, repo_wt.worktree_path)
_run_setup(repo_wt.repo_name, repo_wt.source_repo, repo_wt.worktree_path)

workspace = Workspace(
name=name,
Expand All @@ -106,9 +106,9 @@ def create_workspace(
return workspace


def _run_setup(repo_name: str, worktree_path: Path) -> None:
"""Run setup commands from ``.grove.toml`` in the worktree."""
cfg = git.read_grove_config(worktree_path)
def _run_setup(repo_name: str, source_repo: Path, worktree_path: Path) -> None:
"""Run setup commands from ``.grove.toml`` (read from source repo, run in worktree)."""
cfg = git.read_grove_config(source_repo)
setup = cfg.get("setup")
if not setup:
return
Expand Down
4 changes: 2 additions & 2 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ def test_invalid_preset(self, tmp_grove, fake_repos):
assert result.exit_code == 1
assert "not found" in result.output

def test_go_flag_prints_sentinel(self, tmp_grove, fake_repos):
def test_create_prints_cd_sentinel(self, tmp_grove, fake_repos):
ws_path = tmp_grove["workspace_dir"] / "feat-go"
mock_ws = Workspace(name="feat-go", path=ws_path, branch="feat/go", repos=[])

Expand All @@ -144,7 +144,7 @@ def test_go_flag_prints_sentinel(self, tmp_grove, fake_repos):
):
mock_cfg.return_value = self._make_config(tmp_grove)
mock_find.return_value = fake_repos
result = runner.invoke(app, ["create", "-r", "svc-auth", "-b", "feat/go", "--go"])
result = runner.invoke(app, ["create", "-r", "svc-auth", "-b", "feat/go"])
assert result.exit_code == 0
assert f"__grove_cd:{ws_path}" in result.output

Expand Down
4 changes: 3 additions & 1 deletion tests/test_workspace.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,12 @@ def test_runs_setup_command(self, tmp_grove):
patch(
"grove.workspace.git.read_grove_config",
return_value={"setup": "pnpm install"},
),
) as mock_cfg,
):
ws = workspace.create_workspace("test", {"svc-api": repo_path}, "feat/x", cfg)
assert ws is not None
# Config should be read from the source repo, not the worktree
mock_cfg.assert_called_once_with(repo_path)
mock_sub.assert_called_once_with(
"pnpm install",
cwd=ws.path / "svc-api",
Expand Down
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.