test: suppress git noise and add quiet test target

Amolith created

- Add spec/test_helper.lua with git() function that configures
init.defaultBranch, user.email, user.name, and advice.detachedHead to
suppress hints and warnings while preserving real errors
- Update spec files to use the helper
- Add make test-quiet target that shows full output only on failure

Assisted-by: Claude Opus 4.5 via Amp

Change summary

AGENTS.md                  |  3 +
Makefile                   | 12 +++++++
spec/cmd_init_spec.lua     | 61 +++++++++++++++++++++------------------
spec/cmd_remove_spec.lua   | 34 +++++++++------------
spec/project_root_spec.lua | 12 ++++---
spec/test_helper.lua       | 16 ++++++++++
6 files changed, 84 insertions(+), 54 deletions(-)

Detailed changes

AGENTS.md 🔗

@@ -11,7 +11,8 @@ SPDX-License-Identifier: CC0-1.0
 - `make fmt` — format code with stylua
 - `make lint` — lint with luacheck
 - `make check` — type-check with emmylua
-- `make test` — run all tests with busted
+- `make test` — run all tests with busted (verbose)
+- `make test-quiet` — run tests, show full output only on failure (use this!)
 - `lx test spec/foo_spec.lua` — run a single test file
 - `lx run` — run the application (src/main.lua)
 - `make ci` — CI mode (format check + lint + check + test)

Makefile 🔗

@@ -2,7 +2,7 @@
 #
 # SPDX-License-Identifier: CC0-1.0
 
-.PHONY: all fmt fmt-check lint check test ci dist clean
+.PHONY: all fmt fmt-check lint check test test-quiet ci dist clean
 
 all: fmt lint check test
 
@@ -32,4 +32,14 @@ check:
 test:
 	lx test
 
+# For agents: show full output only on failure, otherwise just summary
+test-quiet:
+	@output=$$(lx test 2>&1); rc=$$?; \
+	if [ $$rc -eq 0 ]; then \
+		echo "$$output" | tail -1; \
+	else \
+		echo "$$output"; \
+	fi; \
+	exit $$rc
+
 ci: fmt-check lint check test

spec/cmd_init_spec.lua 🔗

@@ -4,6 +4,8 @@
 
 package.path = package.path .. ";./?.lua"
 local wt = dofile("src/main.lua")
+local helper = require("spec.test_helper")
+local git = helper.git
 
 describe("cmd_init", function()
 	local temp_dir
@@ -39,7 +41,7 @@ describe("cmd_init", function()
 			end
 			local project = temp_dir .. "/already-wt"
 			os.execute("mkdir -p " .. project .. "/.bare")
-			os.execute("git init --bare " .. project .. "/.bare")
+			git("init --bare " .. project .. "/.bare")
 			local f = io.open(project .. "/.git", "w")
 			if f then
 				f:write("gitdir: ./.bare\n")
@@ -61,7 +63,7 @@ describe("cmd_init", function()
 			local project = temp_dir .. "/wt-project"
 			local worktree = project .. "/main"
 			os.execute("mkdir -p " .. project .. "/.bare")
-			os.execute("git init --bare " .. project .. "/.bare")
+			git("init --bare " .. project .. "/.bare")
 			os.execute("mkdir -p " .. worktree)
 			local f = io.open(worktree .. "/.git", "w")
 			if f then
@@ -98,7 +100,7 @@ describe("cmd_init", function()
 			end
 			local project = temp_dir .. "/bare-only"
 			os.execute("mkdir -p " .. project .. "/.bare")
-			os.execute("git init --bare " .. project .. "/.bare")
+			git("init --bare " .. project .. "/.bare")
 
 			local output, code = wt.run_cmd("cd " .. project .. " && lua " .. original_cwd .. "/src/main.lua init 2>&1")
 			assert.are_not.equal(0, code)
@@ -114,8 +116,8 @@ describe("cmd_init", function()
 			end
 			local project = temp_dir .. "/has-worktrees"
 			os.execute("mkdir -p " .. project)
-			os.execute("git init " .. project)
-			os.execute("cd " .. project .. " && git commit --allow-empty -m 'initial'")
+			git("init " .. project)
+			git("-C " .. project .. " commit --allow-empty -m 'initial'")
 			os.execute("mkdir -p " .. project .. "/.git/worktrees/feature-branch")
 
 			local output, code = wt.run_cmd("cd " .. project .. " && lua " .. original_cwd .. "/src/main.lua init 2>&1")
@@ -132,14 +134,14 @@ describe("cmd_init", function()
 			end
 			local project = temp_dir .. "/dirty-repo"
 			os.execute("mkdir -p " .. project)
-			os.execute("git init " .. project)
-			os.execute("cd " .. project .. " && git commit --allow-empty -m 'initial'")
+			git("init " .. project)
+			git("-C " .. project .. " commit --allow-empty -m 'initial'")
 			local f = io.open(project .. "/dirty.txt", "w")
 			if f then
 				f:write("uncommitted\n")
 				f:close()
 			end
-			os.execute("cd " .. project .. " && git add dirty.txt")
+			git("-C " .. project .. " add dirty.txt")
 
 			local output, code = wt.run_cmd("cd " .. project .. " && lua " .. original_cwd .. "/src/main.lua init 2>&1")
 			assert.are_not.equal(0, code)
@@ -155,8 +157,8 @@ describe("cmd_init", function()
 			end
 			local project = temp_dir .. "/dry-run-test"
 			os.execute("mkdir -p " .. project)
-			os.execute("git init " .. project)
-			os.execute("cd " .. project .. " && git commit --allow-empty -m 'initial'")
+			git("init " .. project)
+			git("-C " .. project .. " commit --allow-empty -m 'initial'")
 
 			local cmd = "cd " .. project .. " && lua " .. original_cwd .. "/src/main.lua init --dry-run 2>&1"
 			local output, code = wt.run_cmd(cmd)
@@ -180,15 +182,16 @@ describe("cmd_init", function()
 			end
 			local project = temp_dir .. "/dry-orphans"
 			os.execute("mkdir -p " .. project)
-			os.execute("git init " .. project)
-			os.execute("cd " .. project .. " && git commit --allow-empty -m 'initial'")
+			git("init " .. project)
+			git("-C " .. project .. " commit --allow-empty -m 'initial'")
 
 			local f = io.open(project .. "/README.md", "w")
 			if f then
 				f:write("# Test\n")
 				f:close()
 			end
-			os.execute("cd " .. project .. " && git add README.md && git commit -m 'add readme'")
+			git("-C " .. project .. " add README.md")
+			git("-C " .. project .. " commit -m 'add readme'")
 
 			local cmd = "cd " .. project .. " && lua " .. original_cwd .. "/src/main.lua init --dry-run 2>&1"
 			local output, code = wt.run_cmd(cmd)
@@ -203,8 +206,8 @@ describe("cmd_init", function()
 			end
 			local project = temp_dir .. "/dry-worktree"
 			os.execute("mkdir -p " .. project)
-			os.execute("git init " .. project)
-			os.execute("cd " .. project .. " && git commit --allow-empty -m 'initial'")
+			git("init " .. project)
+			git("-C " .. project .. " commit --allow-empty -m 'initial'")
 
 			local cmd = "cd " .. project .. " && lua " .. original_cwd .. "/src/main.lua init --dry-run 2>&1"
 			local output, code = wt.run_cmd(cmd)
@@ -221,8 +224,8 @@ describe("cmd_init", function()
 			end
 			local project = temp_dir .. "/yes-test"
 			os.execute("mkdir -p " .. project)
-			os.execute("git init " .. project)
-			os.execute("cd " .. project .. " && git commit --allow-empty -m 'initial'")
+			git("init " .. project)
+			git("-C " .. project .. " commit --allow-empty -m 'initial'")
 
 			local output, code = wt.run_cmd("cd " .. project .. " && lua " .. original_cwd .. "/src/main.lua init -y 2>&1")
 			assert.are.equal(0, code)
@@ -251,8 +254,8 @@ describe("cmd_init", function()
 			end
 			local project = temp_dir .. "/convert-test"
 			os.execute("mkdir -p " .. project)
-			os.execute("git init " .. project)
-			os.execute("cd " .. project .. " && git commit --allow-empty -m 'initial'")
+			git("init " .. project)
+			git("-C " .. project .. " commit --allow-empty -m 'initial'")
 
 			local _, code = wt.run_cmd("cd " .. project .. " && lua " .. original_cwd .. "/src/main.lua init -y 2>&1")
 			assert.are.equal(0, code)
@@ -271,8 +274,8 @@ describe("cmd_init", function()
 			end
 			local project = temp_dir .. "/git-file-test"
 			os.execute("mkdir -p " .. project)
-			os.execute("git init " .. project)
-			os.execute("cd " .. project .. " && git commit --allow-empty -m 'initial'")
+			git("init " .. project)
+			git("-C " .. project .. " commit --allow-empty -m 'initial'")
 
 			local _, code = wt.run_cmd("cd " .. project .. " && lua " .. original_cwd .. "/src/main.lua init -y 2>&1")
 			assert.are.equal(0, code)
@@ -293,8 +296,8 @@ describe("cmd_init", function()
 			end
 			local project = temp_dir .. "/worktree-created"
 			os.execute("mkdir -p " .. project)
-			os.execute("git init " .. project)
-			os.execute("cd " .. project .. " && git commit --allow-empty -m 'initial'")
+			git("init " .. project)
+			git("-C " .. project .. " commit --allow-empty -m 'initial'")
 
 			local cmd = "cd " .. project .. " && lua " .. original_cwd .. "/src/main.lua init -y 2>&1"
 			local _, code = wt.run_cmd(cmd)
@@ -311,13 +314,14 @@ describe("cmd_init", function()
 			end
 			local project = temp_dir .. "/orphan-cleanup"
 			os.execute("mkdir -p " .. project)
-			os.execute("git init " .. project)
+			git("init " .. project)
 			local f = io.open(project .. "/tracked.txt", "w")
 			if f then
 				f:write("tracked\n")
 				f:close()
 			end
-			os.execute("cd " .. project .. " && git add tracked.txt && git commit -m 'add file'")
+			git("-C " .. project .. " add tracked.txt")
+			git("-C " .. project .. " commit -m 'add file'")
 
 			local _, code = wt.run_cmd("cd " .. project .. " && lua " .. original_cwd .. "/src/main.lua init -y 2>&1")
 			assert.are.equal(0, code)
@@ -335,14 +339,15 @@ describe("cmd_init", function()
 			end
 			local project = temp_dir .. "/submodule-warn"
 			os.execute("mkdir -p " .. project)
-			os.execute("git init " .. project)
-			os.execute("cd " .. project .. " && git commit --allow-empty -m 'initial'")
+			git("init " .. project)
+			git("-C " .. project .. " commit --allow-empty -m 'initial'")
 			local f = io.open(project .. "/.gitmodules", "w")
 			if f then
 				f:write("[submodule \"lib\"]\n\tpath = lib\n\turl = https://example.com/lib.git\n")
 				f:close()
 			end
-			os.execute("cd " .. project .. " && git add .gitmodules && git commit -m 'add submodules'")
+			git("-C " .. project .. " add .gitmodules")
+			git("-C " .. project .. " commit -m 'add submodules'")
 
 			local output, _ = wt.run_cmd("cd " .. project .. " && lua " .. original_cwd .. "/src/main.lua init --dry-run 2>&1")
 			assert.is_truthy(output:match("submodule") or output:match("[Ww]arning"))

spec/cmd_remove_spec.lua 🔗

@@ -4,6 +4,8 @@
 
 package.path = package.path .. ";./?.lua"
 local wt = dofile("src/main.lua")
+local helper = require("spec.test_helper")
+local git = helper.git
 
 describe("cmd_remove", function()
 	local temp_dir
@@ -38,7 +40,7 @@ describe("cmd_remove", function()
 	local function create_wt_project(name, branches)
 		local project = temp_dir .. "/" .. name
 		os.execute("mkdir -p " .. project .. "/.bare")
-		os.execute("git init --bare " .. project .. "/.bare")
+		git("init --bare " .. project .. "/.bare")
 		local f = io.open(project .. "/.git", "w")
 		if f then
 			f:write("gitdir: ./.bare\n")
@@ -46,17 +48,15 @@ describe("cmd_remove", function()
 		end
 
 		local first_branch = branches[1] or "main"
-		os.execute("GIT_DIR=" .. project .. "/.bare git symbolic-ref HEAD refs/heads/" .. first_branch)
+		git("--git-dir=" .. project .. "/.bare symbolic-ref HEAD refs/heads/" .. first_branch)
 		local first_wt = project .. "/" .. first_branch
-		os.execute("GIT_DIR=" .. project .. "/.bare git worktree add --orphan -b " .. first_branch .. " -- " .. first_wt)
-		os.execute("cd " .. first_wt .. " && git commit --allow-empty -m 'initial'")
+		git("--git-dir=" .. project .. "/.bare worktree add --orphan -b " .. first_branch .. " -- " .. first_wt)
+		git("-C " .. first_wt .. " commit --allow-empty -m 'initial'")
 
 		for i = 2, #branches do
 			local branch = branches[i]
 			local wt_path = project .. "/" .. branch:gsub("/", "_")
-			local cmd = "GIT_DIR=" .. project .. "/.bare git worktree add -b "
-				.. branch .. " -- " .. wt_path .. " " .. first_branch
-			os.execute(cmd)
+			git("--git-dir=" .. project .. "/.bare worktree add -b " .. branch .. " -- " .. wt_path .. " " .. first_branch)
 		end
 
 		return project
@@ -105,7 +105,7 @@ describe("cmd_remove", function()
 				f:write("dirty file\n")
 				f:close()
 			end
-			os.execute("cd " .. dirty_wt .. " && git add uncommitted.txt")
+			git("-C " .. dirty_wt .. " add uncommitted.txt")
 
 			local output, code = wt.run_cmd("cd " .. project .. "/main && lua " .. original_cwd .. "/src/main.lua r dirty 2>&1")
 			assert.are_not.equal(0, code)
@@ -125,7 +125,7 @@ describe("cmd_remove", function()
 				f:write("dirty file\n")
 				f:close()
 			end
-			os.execute("cd " .. target_wt .. " && git add uncommitted.txt")
+			git("-C " .. target_wt .. " add uncommitted.txt")
 
 			local cmd = "cd " .. project .. "/main && lua " .. original_cwd .. "/src/main.lua r force-test -f 2>&1"
 			local output, code = wt.run_cmd(cmd)
@@ -145,10 +145,10 @@ describe("cmd_remove", function()
 			end
 			local project = create_wt_project("bare-head", { "main", "other" })
 
-			os.execute("GIT_DIR=" .. project .. "/.bare git worktree remove -- " .. project .. "/main")
+			git("--git-dir=" .. project .. "/.bare worktree remove -- " .. project .. "/main")
 
-			os.execute("GIT_DIR=" .. project .. "/.bare git symbolic-ref HEAD refs/heads/main")
-			os.execute("GIT_DIR=" .. project .. "/.bare git worktree add -- " .. project .. "/main main")
+			git("--git-dir=" .. project .. "/.bare symbolic-ref HEAD refs/heads/main")
+			git("--git-dir=" .. project .. "/.bare worktree add -- " .. project .. "/main main")
 
 			local cmd = "cd " .. project .. "/other && lua " .. original_cwd .. "/src/main.lua r main -b 2>&1"
 			local output, _ = wt.run_cmd(cmd)
@@ -178,7 +178,7 @@ describe("cmd_remove", function()
 			end
 			local project = create_wt_project("clean-delete", { "main", "deleteme" })
 
-			os.execute("GIT_DIR=" .. project .. "/.bare git symbolic-ref HEAD refs/heads/main")
+			git("--git-dir=" .. project .. "/.bare symbolic-ref HEAD refs/heads/main")
 
 			local cmd = "cd " .. project .. "/main && lua " .. original_cwd .. "/src/main.lua r deleteme -b 2>&1"
 			local output, code = wt.run_cmd(cmd)
@@ -222,9 +222,7 @@ describe("cmd_remove", function()
 			-- Create worktree at flat-style path even though default config is nested
 			local branch = "feature/auth"
 			local flat_path = project .. "/feature_auth"
-			local wt_cmd = "GIT_DIR=" .. project .. "/.bare git worktree add -b "
-				.. branch .. " -- " .. flat_path .. " main 2>&1"
-			os.execute(wt_cmd)
+			git("--git-dir=" .. project .. "/.bare worktree add -b " .. branch .. " -- " .. flat_path .. " main")
 
 			-- wt r should find it by branch, not by computed path
 			local cmd = "cd " .. project .. "/main && lua " .. original_cwd .. "/src/main.lua r feature/auth 2>&1"
@@ -248,9 +246,7 @@ describe("cmd_remove", function()
 			local branch = "my-feature"
 			local arbitrary_path = project .. "/some/weird/location"
 			os.execute("mkdir -p " .. project .. "/some/weird")
-			local wt_cmd = "GIT_DIR=" .. project .. "/.bare git worktree add -b "
-				.. branch .. " -- " .. arbitrary_path .. " main 2>&1"
-			os.execute(wt_cmd)
+			git("--git-dir=" .. project .. "/.bare worktree add -b " .. branch .. " -- " .. arbitrary_path .. " main")
 
 			local cmd = "cd " .. project .. "/main && lua " .. original_cwd .. "/src/main.lua r my-feature 2>&1"
 			local output, code = wt.run_cmd(cmd)

spec/project_root_spec.lua 🔗

@@ -4,6 +4,8 @@
 
 package.path = package.path .. ";./?.lua"
 local wt = dofile("src/main.lua")
+local helper = require("spec.test_helper")
+local git = helper.git
 
 describe("find_project_root", function()
 	local temp_dir
@@ -30,7 +32,7 @@ describe("find_project_root", function()
 			end
 			local project = temp_dir .. "/project"
 			os.execute("mkdir -p " .. project .. "/.bare")
-			os.execute("git init --bare " .. project .. "/.bare")
+			git("init --bare " .. project .. "/.bare")
 			local f = io.open(project .. "/.git", "w")
 			if f then
 				f:write("gitdir: ./.bare\n")
@@ -49,7 +51,7 @@ describe("find_project_root", function()
 			end
 			local project = temp_dir .. "/project2"
 			os.execute("mkdir -p " .. project .. "/.bare")
-			os.execute("git init --bare " .. project .. "/.bare")
+			git("init --bare " .. project .. "/.bare")
 			local f = io.open(project .. "/.git", "w")
 			if f then
 				f:write("gitdir: ./.bare\n")
@@ -75,7 +77,7 @@ describe("find_project_root", function()
 			end
 			local project = temp_dir .. "/nested-wt"
 			os.execute("mkdir -p " .. project .. "/.bare")
-			os.execute("git init --bare " .. project .. "/.bare")
+			git("init --bare " .. project .. "/.bare")
 			local f = io.open(project .. "/.git", "w")
 			if f then
 				f:write("gitdir: ./.bare\n")
@@ -103,7 +105,7 @@ describe("find_project_root", function()
 			end
 			local project = temp_dir .. "/normal-git"
 			os.execute("mkdir -p " .. project)
-			os.execute("git init " .. project)
+			git("init " .. project)
 
 			local root, err = wt.find_project_root(project)
 			assert.is_nil(root)
@@ -133,7 +135,7 @@ describe("find_project_root", function()
 			end
 			local project = temp_dir .. "/rel-git"
 			os.execute("mkdir -p " .. project .. "/.bare")
-			os.execute("git init --bare " .. project .. "/.bare")
+			git("init --bare " .. project .. "/.bare")
 
 			local f = io.open(project .. "/.git", "w")
 			if f then

spec/test_helper.lua 🔗

@@ -0,0 +1,16 @@
+-- SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
+--
+-- SPDX-License-Identifier: GPL-3.0-or-later
+
+local M = {}
+
+--- Execute a git command with config to suppress noise while preserving errors
+---@param cmd string git subcommand and arguments (without "git" prefix)
+---@return boolean success
+function M.git(cmd)
+	local prefix = "git -c init.defaultBranch=main -c user.email=test@test.com "
+		.. "-c user.name=Test -c advice.detachedHead=false "
+	return os.execute(prefix .. cmd)
+end
+
+return M