Skip to content

Commit 435ee07

Browse files
authored
Merge pull request #14 from satococoa/codex/fix-test-execution
Fix test execution and lint tooling
2 parents 537cb24 + 5ecf6ba commit 435ee07

File tree

11 files changed

+81
-331
lines changed

11 files changed

+81
-331
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.cache/

Makefile

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
SHELL := /bin/sh
22

3-
GOFILES := $(shell git ls-files '*.go')
3+
GOFILES := $(shell git ls-files -- '*.go' | while IFS= read -r f; do [ -f "$$f" ] && printf '%s\n' "$$f"; done)
4+
GO_TEST_CACHE_DIR := $(CURDIR)/.cache/go-build
5+
GO_TEST_TMP_DIR := $(CURDIR)/.cache/go-tmp
6+
GO_BIN_DIR := $(CURDIR)/.cache/bin
7+
GOLANGCI_LINT_CACHE_DIR := $(CURDIR)/.cache/golangci-lint
8+
GO_RUN_ENV = GOCACHE="$(GO_TEST_CACHE_DIR)" GOTMPDIR="$(GO_TEST_TMP_DIR)"
9+
LINT_RUN_ENV = $(GO_RUN_ENV) GOLANGCI_LINT_CACHE="$(GOLANGCI_LINT_CACHE_DIR)"
10+
GOLANGCI_LINT_VERSION := v2.10.1
11+
GOLANGCI_LINT := $(GO_BIN_DIR)/golangci-lint-$(GOLANGCI_LINT_VERSION)
412

513
.PHONY: fmt check-fmt vet lint test test-race ci
614

@@ -20,21 +28,28 @@ check-fmt:
2028
fi
2129

2230
vet:
23-
go vet ./...
24-
25-
lint:
26-
@if ! command -v golangci-lint >/dev/null 2>&1; then \
27-
echo "golangci-lint is not installed."; \
28-
echo "Install with:"; \
29-
echo " go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.10.1"; \
30-
exit 1; \
31+
@mkdir -p "$(GO_TEST_CACHE_DIR)" "$(GO_TEST_TMP_DIR)"
32+
$(GO_RUN_ENV) go vet ./...
33+
34+
$(GOLANGCI_LINT):
35+
@mkdir -p "$(GO_TEST_CACHE_DIR)" "$(GO_TEST_TMP_DIR)" "$(GO_BIN_DIR)" "$(GOLANGCI_LINT_CACHE_DIR)"
36+
@if [ -x "$(GO_BIN_DIR)/golangci-lint" ]; then \
37+
cp "$(GO_BIN_DIR)/golangci-lint" "$(GOLANGCI_LINT)"; \
38+
else \
39+
GOBIN="$(GO_BIN_DIR)" $(GO_RUN_ENV) go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION); \
40+
cp "$(GO_BIN_DIR)/golangci-lint" "$(GOLANGCI_LINT)"; \
3141
fi
32-
golangci-lint run ./...
42+
43+
lint: $(GOLANGCI_LINT)
44+
@mkdir -p "$(GOLANGCI_LINT_CACHE_DIR)"
45+
$(LINT_RUN_ENV) $(GOLANGCI_LINT) run
3346

3447
test:
35-
go test ./...
48+
@mkdir -p "$(GO_TEST_CACHE_DIR)" "$(GO_TEST_TMP_DIR)"
49+
$(GO_RUN_ENV) go test ./...
3650

3751
test-race:
38-
go test -race ./...
52+
@mkdir -p "$(GO_TEST_CACHE_DIR)" "$(GO_TEST_TMP_DIR)"
53+
$(GO_RUN_ENV) go test -race ./...
3954

4055
ci: check-fmt vet lint test test-race

README.md

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -109,22 +109,6 @@ Shows:
109109
- no-op reason when include file is missing in source
110110
- matched / copy planned / conflicts / missing source / skipped same / errors
111111

112-
### `git-worktreeinclude hook path`
113-
114-
Prints the hooks directory path while respecting `core.hooksPath`.
115-
116-
```sh
117-
git-worktreeinclude hook path [--absolute]
118-
```
119-
120-
### `git-worktreeinclude hook print post-checkout`
121-
122-
Prints the recommended `post-checkout` hook snippet.
123-
124-
```sh
125-
git-worktreeinclude hook print post-checkout
126-
```
127-
128112
## JSON output
129113

130114
`apply --json` emits a single JSON object to stdout.
@@ -173,7 +157,15 @@ This project does not auto-install hooks. Use manual setup.
173157

174158
```sh
175159
mkdir -p .githooks
176-
git-worktreeinclude hook print post-checkout > .githooks/post-checkout
160+
cat > .githooks/post-checkout <<'EOF'
161+
#!/bin/sh
162+
set -eu
163+
164+
old="$1"
165+
if [ "$old" = "0000000000000000000000000000000000000000" ]; then
166+
git worktreeinclude apply --quiet || true
167+
fi
168+
EOF
177169
chmod +x .githooks/post-checkout
178170
git config core.hooksPath .githooks
179171
```
@@ -233,6 +225,7 @@ make ci
233225

234226
CI runs on pull requests and pushes to `main` via GitHub Actions.
235227
`golangci-lint` is used with its default configuration (no `.golangci.yml`).
228+
`make lint` installs a pinned `golangci-lint` binary into `.cache/bin` on first run, so the first run needs network access to fetch the tool.
236229

237230
## License
238231

internal/cli/cli.go

Lines changed: 0 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,12 @@ import (
77
"fmt"
88
"io"
99
"os"
10-
"path/filepath"
1110
"strings"
1211

1312
ucli "github.com/urfave/cli/v3"
1413

1514
"github.com/satococoa/git-worktreeinclude/internal/engine"
1615
"github.com/satococoa/git-worktreeinclude/internal/exitcode"
17-
"github.com/satococoa/git-worktreeinclude/internal/hooks"
1816
)
1917

2018
type App struct {
@@ -62,7 +60,6 @@ func (a *App) newRootCommand() *ucli.Command {
6260
Commands: []*ucli.Command{
6361
a.newApplyCommand(),
6462
a.newDoctorCommand(),
65-
a.newHookCommand(),
6663
},
6764
}
6865
}
@@ -260,75 +257,6 @@ func (a *App) runDoctor(ctx context.Context, cmd *ucli.Command) error {
260257
return nil
261258
}
262259

263-
func (a *App) newHookCommand() *ucli.Command {
264-
return &ucli.Command{
265-
Name: "hook",
266-
Usage: "hook helpers",
267-
OnUsageError: a.onUsageError,
268-
Action: func(ctx context.Context, cmd *ucli.Command) error {
269-
if cmd.Args().Len() == 0 {
270-
return a.onUsageError(ctx, cmd, errors.New("hook subcommand is required"), true)
271-
}
272-
name := cmd.Args().First()
273-
if cmd.Command(name) == nil {
274-
return a.onUsageError(ctx, cmd, fmt.Errorf("unknown hook subcommand: %s", name), true)
275-
}
276-
return nil
277-
},
278-
Commands: []*ucli.Command{
279-
{
280-
Name: "path",
281-
Usage: "print hooks path",
282-
OnUsageError: a.onUsageError,
283-
Flags: []ucli.Flag{
284-
&ucli.BoolFlag{Name: "absolute", Usage: "print absolute hooks path"},
285-
},
286-
Action: a.runHookPath,
287-
},
288-
{
289-
Name: "print",
290-
Usage: "print hook snippet",
291-
ArgsUsage: "post-checkout",
292-
OnUsageError: a.onUsageError,
293-
Action: a.runHookPrint,
294-
},
295-
},
296-
}
297-
}
298-
299-
func (a *App) runHookPath(ctx context.Context, cmd *ucli.Command) error {
300-
if cmd.Args().Len() != 0 {
301-
return a.onUsageError(ctx, cmd, errors.New("hook path does not accept positional arguments"), true)
302-
}
303-
304-
wd, err := currentWorkdir()
305-
if err != nil {
306-
return ucli.Exit(err.Error(), exitcode.Env)
307-
}
308-
309-
p, err := a.engine.HookPath(ctx, wd, cmd.Bool("absolute"))
310-
if err != nil {
311-
return ucli.Exit(err, codedOrDefault(err, exitcode.Internal))
312-
}
313-
314-
writeln(a.stdout, filepath.ToSlash(p))
315-
return nil
316-
}
317-
318-
func (a *App) runHookPrint(ctx context.Context, cmd *ucli.Command) error {
319-
if cmd.Args().Len() != 1 {
320-
return a.onUsageError(ctx, cmd, errors.New("hook print requires exactly one argument: post-checkout"), true)
321-
}
322-
323-
snippet, err := hooks.PrintSnippet(cmd.Args().First())
324-
if err != nil {
325-
return ucli.Exit(err.Error(), exitcode.Args)
326-
}
327-
328-
write(a.stdout, snippet)
329-
return nil
330-
}
331-
332260
func (a *App) handleExitError(_ context.Context, _ *ucli.Command, err error) {
333261
var exitErr ucli.ExitCoder
334262
if !errors.As(err, &exitErr) {
@@ -438,10 +366,6 @@ func currentWorkdir() (string, error) {
438366
return wd, nil
439367
}
440368

441-
func write(w io.Writer, s string) {
442-
_, _ = fmt.Fprint(w, s)
443-
}
444-
445369
func writeln(w io.Writer, a ...any) {
446370
_, _ = fmt.Fprintln(w, a...)
447371
}

0 commit comments

Comments
 (0)