Skip to content
Open
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
7 changes: 4 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: '1.23'
go-version-file: go.mod

- name: Download dependencies
run: go mod download
Expand All @@ -44,9 +44,10 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: '1.23'
go-version-file: go.mod

- name: Run golangci-lint
uses: golangci/golangci-lint-action@v6
with:
version: latest
version: v1.64.8
args: --config .golangci.yml ./...
14 changes: 14 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
run:
timeout: 5m
go: "1.24"
modules-download-mode: readonly

linters:
disable-all: true
enable:
- errcheck
- gosimple
- govet
- ineffassign
- staticcheck
- unused
81 changes: 62 additions & 19 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,50 +1,90 @@
.PHONY: build test test-verbose test-race coverage coverage-html lint clean deps check install calibrate-providers install-hooks help
.PHONY: build fmt vet test test-verbose test-race coverage coverage-html lint lint-install clean deps check install calibrate-providers install-hooks help

# Binary name
BINARY=nightshift
PKG=./cmd/nightshift
GO=go
GOLANGCI_LINT=golangci-lint
GOLANGCI_LINT_CONFIG=.golangci.yml
GOLANGCI_LINT_VERSION=v1.64.8
GO_ROOT_BIN=$(shell $(GO) env GOROOT)/bin
GOFMT=$(GO_ROOT_BIN)/gofmt
GO_BIN_OVERRIDE=$(shell $(GO) env GOBIN)
GO_BIN_DIR=$(if $(GO_BIN_OVERRIDE),$(GO_BIN_OVERRIDE),$(shell $(GO) env GOPATH)/bin)
GOLANGCI_LINT_BIN=$(GO_BIN_DIR)/$(GOLANGCI_LINT)

# Build the binary
build:
go build -o $(BINARY) $(PKG)
$(GO) build -o $(BINARY) $(PKG)

# Install the binary to your Go bin directory
install:
go install $(PKG)
@echo "Installed $(BINARY) to $$(if [ -n "$$(go env GOBIN)" ]; then go env GOBIN; else echo "$$(go env GOPATH)/bin"; fi)"
$(GO) install $(PKG)
@echo "Installed $(BINARY) to $$(if [ -n "$$($(GO) env GOBIN)" ]; then $(GO) env GOBIN; else echo "$$($(GO) env GOPATH)/bin"; fi)"

# Run provider calibration comparison tool
calibrate-providers:
go run ./cmd/provider-calibration --repo "$$(pwd)" --codex-originator codex_cli_rs --min-user-turns 2
$(GO) run ./cmd/provider-calibration --repo "$$(pwd)" --codex-originator codex_cli_rs --min-user-turns 2

# Check formatting without rewriting files
fmt:
@GO_FILES="$$(git ls-files -- '*.go')"; \
if [ -z "$$GO_FILES" ]; then \
echo "gofmt: no Go files"; \
else \
UNFORMATTED="$$( $(GOFMT) -l $$GO_FILES )" || exit 1; \
if [ -z "$$UNFORMATTED" ]; then \
echo "gofmt: ok"; \
else \
echo "gofmt: run 'gofmt -w' on:"; \
echo "$$UNFORMATTED"; \
exit 1; \
fi; \
fi

# Run go vet across the module
vet:
$(GO) vet ./...

# Run all tests
test:
go test ./...
$(GO) test ./...

# Run tests with verbose output
test-verbose:
go test -v ./...
$(GO) test -v ./...

# Run tests with race detection
test-race:
go test -race ./...
$(GO) test -race ./...

# Run tests with coverage report
coverage:
go test -coverprofile=coverage.out ./...
go tool cover -func=coverage.out
$(GO) test -coverprofile=coverage.out ./...
$(GO) tool cover -func=coverage.out
@echo ""
@echo "To view HTML coverage report, run: go tool cover -html=coverage.out"

# Generate HTML coverage report
coverage-html: coverage
go tool cover -html=coverage.out -o coverage.html
$(GO) tool cover -html=coverage.out -o coverage.html
@echo "Coverage report generated: coverage.html"

# Run golangci-lint (if installed)
# Run golangci-lint with the checked-in config
lint:
@which golangci-lint > /dev/null || (echo "golangci-lint not installed. Run: go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest" && exit 1)
golangci-lint run
@if command -v $(GOLANGCI_LINT) > /dev/null; then \
LINT_BIN="$$(command -v $(GOLANGCI_LINT))"; \
elif [ -x "$(GOLANGCI_LINT_BIN)" ]; then \
LINT_BIN="$(GOLANGCI_LINT_BIN)"; \
else \
echo "golangci-lint not installed. Run: make lint-install"; \
exit 1; \
fi; \
PATH="$(GO_ROOT_BIN):$$PATH" "$$LINT_BIN" run --config $(GOLANGCI_LINT_CONFIG) ./...

# Install the repo's pinned golangci-lint version
lint-install:
$(GO) install github.com/golangci/golangci-lint/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION)

# Clean build artifacts
clean:
Expand All @@ -54,25 +94,28 @@ clean:

# Install development dependencies
deps:
go mod download
go mod tidy
$(GO) mod download
$(GO) mod tidy

# Run all checks (test + lint)
check: test lint
# Run the full local verification suite
check: fmt vet test lint

# Show help
help:
@echo "Available targets:"
@echo " build - Build the binary"
@echo " fmt - Check gofmt output"
@echo " vet - Run go vet"
@echo " test - Run all tests"
@echo " test-verbose - Run tests with verbose output"
@echo " test-race - Run tests with race detection"
@echo " coverage - Run tests with coverage report"
@echo " coverage-html - Generate HTML coverage report"
@echo " lint - Run golangci-lint"
@echo " lint-install - Install pinned golangci-lint ($(GOLANGCI_LINT_VERSION))"
@echo " clean - Clean build artifacts"
@echo " deps - Download and tidy dependencies"
@echo " check - Run tests and lint"
@echo " check - Run fmt, vet, tests, and lint"
@echo " install - Build and install to Go bin directory"
@echo " calibrate-providers - Compare local Claude/Codex session usage for calibration"
@echo " install-hooks - Install git pre-commit hook"
Expand Down
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ Each task has a default cooldown interval to prevent the same task from running

### Pre-commit hooks

Install the git pre-commit hook to catch formatting and vet issues before pushing:
Install the git pre-commit hook to catch the fast local checks before pushing:

```bash
make install-hooks
Expand All @@ -271,6 +271,15 @@ This symlinks `scripts/pre-commit.sh` into `.git/hooks/pre-commit`. The hook run
- **go vet** — catches common correctness issues
- **go build** — ensures the project compiles

Full linting is intentionally separate so the hook stays quick:

```bash
make lint-install
make check
```

`make lint-install` installs the repo's pinned `golangci-lint` into your Go bin directory, and `make lint`/`make check` will use that copy even if the directory is not on your `PATH`.

To bypass in a pinch: `git commit --no-verify`

## Uninstalling
Expand Down
7 changes: 3 additions & 4 deletions scripts/pre-commit.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ else
fi

# --- go vet ---
# Keep the hook fast: full golangci-lint still runs via `make lint` and CI.
printf " %-20s" "go vet"
VET_OUT=$(go vet ./... 2>&1)
if [[ $? -eq 0 ]]; then
if VET_OUT=$(go vet ./... 2>&1); then
echo "✓"
PASS=$((PASS+1))
else
Expand All @@ -41,8 +41,7 @@ fi

# --- go build ---
printf " %-20s" "go build"
BUILD_OUT=$(go build ./... 2>&1)
if [[ $? -eq 0 ]]; then
if BUILD_OUT=$(go build ./... 2>&1); then
echo "✓"
PASS=$((PASS+1))
else
Expand Down
Loading