@@ -15,20 +15,21 @@ Guidance for AI coding agents working in this repository. Document only reflects
- Module path: `git.secluded.site/np`
- Binary name: `np`
-## Development Commands (justfile)
-
-- Format: `just fmt` (installs and runs gofumpt)
-- Lint: `just lint` (golangci-lint)
-- Static analysis: `just staticcheck`
-- Tests: `just test` (go test -v ./...)
-- Vulnerabilities: `just vuln` (govulncheck)
-- License compliance: `just reuse` (REUSE)
-- Build: `just build` (produces `./np`, injects version via ldflags)
-- Run: `just run -- <flags>` (runs with ldflags)
-- Docs: `just docs` (generates CLI docs via internal/tools/docgen)
-- Pack: `just pack` (UPX compresses `np`)
-- Clean: `just clean` / `just clean-all`
-- Full check: `just` (default target runs fmt, lint, staticcheck, test, vuln, reuse)
+## Development Commands (Taskfile)
+
+- Format: `task fmt` (installs and runs gofumpt)
+- Lint: `task lint` (golangci-lint)
+- Static analysis: `task staticcheck`
+- Tests: `task test` (go test -v ./...)
+- Vulnerabilities: `task vuln` (govulncheck)
+- License compliance: `task reuse` (REUSE)
+- Build: `task build` (produces `./np`, injects version via ldflags)
+- Run: `task run -- <flags>` (runs with ldflags)
+- Docs: `task docs` (generates CLI docs via internal/tools/docgen)
+- Pack: `task pack` (UPX compresses `np`)
+- Clean: `task clean` / `task clean-all`
+- Release: `task release` (interactive semver release with gum/svu)
+- Full check: `task` (default runs fmt, lint, staticcheck, test, vuln, reuse)
Single test:
@@ -123,14 +124,14 @@ All stores accept an optional `timeutil.Clock`; default is a UTC system clock. `
- Tests live under `internal/*_test.go` (goal, task, event)
- Helpers: `testutil.OpenDB(t)` opens a temp Badger DB with cleanup; `testutil.SequenceClock` yields deterministic times
-- Run: `just test` or `go test -v ./...`
+- Run: `task test` or `go test -v ./...`
- Example single test pattern: `go test -v -run TestName ./internal/task`
## Doc Generation
- Tool: `internal/tools/docgen` (cobra/doc based)
-- `just docs` runs two invocations: one tree under `docs/cli/`, and a single-file reference `docs/llm-reference.md`
-- Note: the justfile passes `-exclude m` but `docgen` has no `-exclude` flag; adjust the recipe if this causes failures
+- `task docs` runs two invocations: one tree under `docs/cli/`, and a single-file reference `docs/llm-reference.md`
+- Note: the Taskfile passes `-exclude m` but `docgen` has no `-exclude` flag; adjust if this causes failures
## Output Format for LLMs
@@ -145,7 +146,7 @@ All stores accept an optional `timeutil.Clock`; default is a UTC system clock. `
## Gotchas
-- `just docs` may fail due to `-exclude` flag unsupported by docgen
+- `task docs` may fail due to `-exclude` flag unsupported by docgen
- `db.Options` sets `SyncWrites=true` by default when not read-only (durability over throughput)
- Event sequence counter is raw 8-byte big-endian; do not store decimal strings
- Windows: directory canonicalization lowercases paths; hashes derive from canonicalized form
@@ -0,0 +1,180 @@
+# SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
+#
+# SPDX-License-Identifier: CC0-1.0
+
+version: "3"
+
+vars:
+ VERSION:
+ sh: git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0"
+ GOOS:
+ sh: go env GOOS
+ GOARCH:
+ sh: go env GOARCH
+
+env:
+ CGO_ENABLED: 0
+
+tasks:
+ default:
+ desc: Run all checks
+ cmds:
+ - task: fmt
+ - task: lint
+ - task: staticcheck
+ - task: test
+ - task: vuln
+ - task: reuse
+
+ fmt:
+ desc: Format all Go source code
+ cmds:
+ - go install mvdan.cc/gofumpt@latest
+ - gofumpt -l -w .
+
+ lint:
+ desc: Lint Go source code
+ cmds:
+ - golangci-lint run
+
+ staticcheck:
+ desc: Perform static analysis
+ cmds:
+ - go install honnef.co/go/tools/cmd/staticcheck@latest
+ - staticcheck ./...
+
+ test:
+ desc: Run tests
+ cmds:
+ - go test -v ./...
+
+ vuln:
+ desc: Check for vulnerabilities
+ cmds:
+ - go install golang.org/x/vuln/cmd/govulncheck@latest
+ - govulncheck ./...
+
+ reuse:
+ desc: Lint licenses and copyright headers
+ cmds:
+ - reuse lint
+
+ docs:
+ desc: Generate CLI documentation
+ cmds:
+ - go run ./internal/tools/docgen -out ./docs/cli -format markdown
+ - go run ./internal/tools/docgen -out ./docs -format markdown -single llm-reference.md -exclude m
+ generates:
+ - docs/cli/**/*
+ - docs/llm-reference.md
+
+ build:
+ desc: Build nasin-pali
+ cmds:
+ - go build -o np -ldflags "-s -w -X main.version={{.VERSION}}"
+ generates:
+ - np
+
+ install:
+ desc: Install nasin-pali
+ cmds:
+ - go install -ldflags "-s -w -X main.version={{.VERSION}}"
+
+ run:
+ desc: Run np
+ cmds:
+ - go run -ldflags "-s -w -X main.version={{.VERSION}}" . {{.CLI_ARGS}}
+
+ pack:
+ desc: Pack np with UPX
+ cmds:
+ - upx --best -qo np.min np
+ - mv np.min np
+ sources:
+ - np
+
+ clean:
+ desc: Remove build artifacts
+ cmds:
+ - rm -rf np
+
+ clean-all:
+ desc: Remove build artifacts and config.toml
+ cmds:
+ - rm -rf np config.toml
+
+ release:
+ desc: Interactive release workflow
+ vars:
+ BUMP:
+ sh: gum choose "major" "minor" "patch" "prerelease"
+ CURRENT_VERSION:
+ sh: git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0"
+ IS_CURRENT_PRERELEASE:
+ sh: |
+ current="{{.CURRENT_VERSION}}"
+ if echo "$current" | grep -qE '\-[a-zA-Z]+\.[0-9]+$'; then
+ echo "yes"
+ else
+ echo "no"
+ fi
+ IS_PRERELEASE:
+ sh: |
+ if [ "{{.BUMP}}" = "prerelease" ]; then
+ echo "yes"
+ else
+ gum confirm "Create pre-release?" && echo "yes" || echo "no"
+ fi
+ PRERELEASE_SUFFIX:
+ sh: |
+ if [ "{{.BUMP}}" = "prerelease" ] && [ "{{.IS_CURRENT_PRERELEASE}}" = "yes" ]; then
+ # Extract suffix from current version (e.g., v1.2.3-beta.0 -> beta)
+ echo "{{.CURRENT_VERSION}}" | sed -E 's/.*-([a-zA-Z]+)\.[0-9]+$/\1/'
+ elif [ "{{.IS_PRERELEASE}}" = "yes" ]; then
+ gum input --placeholder "Enter pre-release suffix (e.g., beta, rc)"
+ fi
+ BASE_NEXT:
+ sh: |
+ if [ "{{.BUMP}}" = "prerelease" ] && [ "{{.IS_CURRENT_PRERELEASE}}" = "yes" ]; then
+ # Extract base version from current prerelease (e.g., v1.2.3-beta.0 -> v1.2.3)
+ echo "{{.CURRENT_VERSION}}" | sed -E 's/-[a-zA-Z]+\.[0-9]+$//'
+ else
+ svu {{.BUMP}}
+ fi
+ SUFFIX_VERSION:
+ sh: |
+ if [ "{{.IS_PRERELEASE}}" = "yes" ] && [ -n "{{.PRERELEASE_SUFFIX}}" ]; then
+ if [ "{{.BUMP}}" = "prerelease" ] && [ "{{.IS_CURRENT_PRERELEASE}}" = "yes" ]; then
+ # Increment the current prerelease number
+ current_num=$(echo "{{.CURRENT_VERSION}}" | sed -E 's/.*-[a-zA-Z]+\.([0-9]+)$/\1/')
+ echo $((current_num + 1))
+ else
+ # Find existing tags with this suffix and get the highest version number
+ highest=$(git tag -l "{{.BASE_NEXT}}-{{.PRERELEASE_SUFFIX}}.*" | \
+ sed 's/.*-{{.PRERELEASE_SUFFIX}}\.//' | \
+ sort -n | tail -1)
+ if [ -n "$highest" ]; then
+ echo $((highest + 1))
+ else
+ echo 0
+ fi
+ fi
+ fi
+ NEXT:
+ sh: |
+ if [ "{{.IS_PRERELEASE}}" = "yes" ] && [ -n "{{.PRERELEASE_SUFFIX}}" ]; then
+ echo "{{.BASE_NEXT}}-{{.PRERELEASE_SUFFIX}}.{{.SUFFIX_VERSION}}"
+ else
+ echo "{{.BASE_NEXT}}"
+ fi
+ prompt: "Release {{.NEXT}}?"
+ preconditions:
+ - sh: '[ $(git symbolic-ref --short HEAD) = "main" ] || [ $(git symbolic-ref --short HEAD) = "dev" ]'
+ msg: Not on main or dev branch
+ - sh: "[ $(git status --porcelain=2 | wc -l) = 0 ]"
+ msg: "Git is dirty"
+ cmds:
+ - llm-tag {{.NEXT}}
+ - git push soft {{.NEXT}}
+ - go list -m git.secluded.site/np@{{.NEXT}} > /dev/null
+ - echo "Released {{.NEXT}} and notified module proxy"
@@ -1,66 +0,0 @@
-# SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
-#
-# SPDX-License-Identifier: CC0-1.0
-
-GOOS := env("GOOS", `go env GOOS`)
-GOARCH := env("GOARCH", `go env GOARCH`)
-VERSION := `git describe --long 2>/dev/null | sed 's/\([^-]*-g\)/r\1/;s/-/./g'`
-
-default: fmt lint staticcheck test vuln reuse
-
-fmt:
- # Formatting all Go source code
- go install mvdan.cc/gofumpt@latest
- gofumpt -l -w .
-
-lint:
- # Linting Go source code
- golangci-lint run
-
-staticcheck:
- # Performing static analysis
- go install honnef.co/go/tools/cmd/staticcheck@latest
- staticcheck ./...
-
-test:
- # Running tests
- go test -v ./...
-
-vuln:
- # Checking for vulnerabilities
- go install golang.org/x/vuln/cmd/govulncheck@latest
- govulncheck ./...
-
-reuse:
- # Linting licenses and copyright headers
- reuse lint
-
-docs:
- # Generating CLI documentation (per-command and LLM reference)
- go run ./internal/tools/docgen -out ./docs/cli -format markdown
- go run ./internal/tools/docgen -out ./docs -format markdown -single llm-reference.md -exclude m
-
-build:
- # Building nasin-pali
- CGO_ENABLED=0 GOOS={{GOOS}} GOARCH={{GOARCH}} go build -o np -ldflags "-s -w -X main.version={{VERSION}}"
-
-install:
- # Installing nasin-pali
- CGO_ENABLED=0 GOOS={{GOOS}} GOARCH={{GOARCH}} go install -ldflags "-s -w -X main.version={{VERSION}}"
-
-run *FLAGS:
- # Running np
- CGO_ENABLED=0 GOOS={{GOOS}} GOARCH={{GOARCH}} go run -ldflags "-s -w -X main.version={{VERSION}}" . {{FLAGS}}
-
-pack:
- # Packing np
- upx --best -qo np.min np
- mv np.min np
-
-clean:
- # Removing build artifacts
- rm -rf np
-
-clean-all:
- # Removing build artifacts and config.toml
- rm -rf np config.toml