feat(shared-skills): batch 85 (10 files)
This commit is contained in:
@@ -0,0 +1,13 @@
|
|||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
indent_style = tab
|
||||||
|
indent_size = 4
|
||||||
|
end_of_line = lf
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
|
[*.{yml,yaml,json,md}]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
version: "2"
|
||||||
|
|
||||||
|
run:
|
||||||
|
timeout: 5m
|
||||||
|
tests: true
|
||||||
|
modules-download-mode: readonly
|
||||||
|
|
||||||
|
linters:
|
||||||
|
default: none
|
||||||
|
enable:
|
||||||
|
- govet
|
||||||
|
- staticcheck
|
||||||
|
- errcheck
|
||||||
|
- errorlint
|
||||||
|
- nilerr
|
||||||
|
- nilnil
|
||||||
|
- bodyclose
|
||||||
|
- rowserrcheck
|
||||||
|
- sqlclosecheck
|
||||||
|
- contextcheck
|
||||||
|
- fatcontext
|
||||||
|
- copyloopvar
|
||||||
|
- intrange
|
||||||
|
- usetesting
|
||||||
|
- testifylint
|
||||||
|
- gofumpt
|
||||||
|
- goimports
|
||||||
|
- whitespace
|
||||||
|
- misspell
|
||||||
|
- unconvert
|
||||||
|
- unparam
|
||||||
|
- ineffassign
|
||||||
|
- dupword
|
||||||
|
- gocognit
|
||||||
|
- gocyclo
|
||||||
|
- funlen
|
||||||
|
- lll
|
||||||
|
- nestif
|
||||||
|
- dupl
|
||||||
|
- revive
|
||||||
|
- unused
|
||||||
|
- exhaustive
|
||||||
|
- gosec
|
||||||
|
- sloglint
|
||||||
|
- perfsprint
|
||||||
|
- prealloc
|
||||||
|
- makezero
|
||||||
|
|
||||||
|
linters-settings:
|
||||||
|
errcheck:
|
||||||
|
check-type-assertions: true
|
||||||
|
check-blank: true
|
||||||
|
errorlint:
|
||||||
|
errorf: true
|
||||||
|
asserts: true
|
||||||
|
comparison: true
|
||||||
|
gocognit:
|
||||||
|
min-complexity: 25
|
||||||
|
gocyclo:
|
||||||
|
min-complexity: 15
|
||||||
|
funlen:
|
||||||
|
lines: 90
|
||||||
|
statements: 60
|
||||||
|
lll:
|
||||||
|
line-length: 120
|
||||||
|
tab-width: 4
|
||||||
|
nestif:
|
||||||
|
min-complexity: 4
|
||||||
|
exhaustive:
|
||||||
|
default-signifies-exhaustive: false
|
||||||
|
check: [switch, map]
|
||||||
|
sloglint:
|
||||||
|
no-mixed-args: true
|
||||||
|
attr-only: true
|
||||||
|
no-global: all
|
||||||
|
context: scope
|
||||||
|
static-msg: true
|
||||||
|
no-raw-keys: true
|
||||||
|
key-naming-case: snake
|
||||||
|
|
||||||
|
formatters:
|
||||||
|
enable:
|
||||||
|
- gofumpt
|
||||||
|
- goimports
|
||||||
|
|
||||||
|
issues:
|
||||||
|
max-issues-per-linter: 0
|
||||||
|
max-same-issues: 0
|
||||||
|
exclude-rules:
|
||||||
|
- path: _test\\.go
|
||||||
|
linters: [funlen, lll, dupl, gosec]
|
||||||
|
- path: \\.pb\\.go$
|
||||||
|
linters: [all]
|
||||||
|
- path: \\.connect\\.go$
|
||||||
|
linters: [all]
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# AGENTS.md
|
||||||
|
|
||||||
|
Go 1.23+ $short_purpose service.
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
- `task` — fmt + lint + test
|
||||||
|
- `task build` — produce ./bin/server
|
||||||
|
- `task ci` — full CI pipeline locally
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
- `cmd/server/main.go` — entrypoint, ≤50 LOC
|
||||||
|
- `internal/cmd/` — root command, signal wiring
|
||||||
|
- `internal/api/` — HTTP handlers + middleware (gin)
|
||||||
|
- `internal/domain/` — smart-constructor types, no I/O
|
||||||
|
- `internal/store/` — DB layer (sqlc-generated, never hand-edited)
|
||||||
|
- `internal/config/` — env-driven Config
|
||||||
|
- `internal/obs/` — slog setup, observability
|
||||||
|
|
||||||
|
## Conventions
|
||||||
|
- `slog` for all logs; never `log.*`, never `fmt.Println` in libs
|
||||||
|
- `context.Context` first arg for every public function with I/O
|
||||||
|
- Errors wrapped with `%w`; check with `errors.Is/As`
|
||||||
|
- 250 pure LOC ceiling per file
|
||||||
|
- Tests follow Given/When/Then; less mock the better
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
# $name
|
||||||
|
|
||||||
|
Bootstrapped with the `programming` skill's Go scaffold.
|
||||||
|
|
||||||
|
## Run
|
||||||
|
|
||||||
|
```bash
|
||||||
|
task # fmt + lint + test
|
||||||
|
task run # build + run server
|
||||||
|
```
|
||||||
|
|
||||||
|
See `AGENTS.md` for architecture conventions.
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
version: '3'
|
||||||
|
|
||||||
|
vars:
|
||||||
|
BINARY: server
|
||||||
|
PKG: ./cmd/server
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
default:
|
||||||
|
deps: [fmt, lint, test]
|
||||||
|
|
||||||
|
fmt:
|
||||||
|
cmds:
|
||||||
|
- gofumpt -w .
|
||||||
|
- goimports -w -local "$(go list -m)" .
|
||||||
|
|
||||||
|
lint:
|
||||||
|
cmds:
|
||||||
|
- golangci-lint run --timeout 5m ./...
|
||||||
|
- nilaway ./... || true
|
||||||
|
|
||||||
|
test:
|
||||||
|
cmds:
|
||||||
|
- go test -race -shuffle=on -count=1 ./...
|
||||||
|
|
||||||
|
test-cover:
|
||||||
|
cmds:
|
||||||
|
- go test -race -shuffle=on -count=1 -coverprofile=coverage.out ./...
|
||||||
|
- go tool cover -html=coverage.out -o coverage.html
|
||||||
|
|
||||||
|
build:
|
||||||
|
cmds:
|
||||||
|
- go build -trimpath -ldflags="-s -w" -o bin/{{.BINARY}} {{.PKG}}
|
||||||
|
|
||||||
|
run:
|
||||||
|
deps: [build]
|
||||||
|
cmds:
|
||||||
|
- ./bin/{{.BINARY}}
|
||||||
|
|
||||||
|
ci:
|
||||||
|
deps: [fmt, lint, test, build]
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
name: ci
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
ci:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: '1.23'
|
||||||
|
cache: true
|
||||||
|
|
||||||
|
- name: Install tools
|
||||||
|
run: |
|
||||||
|
go install mvdan.cc/gofumpt@latest
|
||||||
|
go install github.com/golangci/golangci-lint/cmd/golangci-lint@v2.0.0
|
||||||
|
go install go.uber.org/nilaway/cmd/nilaway@latest
|
||||||
|
go install github.com/go-task/task/v3/cmd/task@latest
|
||||||
|
|
||||||
|
- name: Format check
|
||||||
|
run: gofumpt -l . | (! grep .)
|
||||||
|
|
||||||
|
- name: Lint
|
||||||
|
run: golangci-lint run --timeout 5m ./...
|
||||||
|
|
||||||
|
- name: Nilaway
|
||||||
|
run: nilaway ./... || true
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
run: go test -race -shuffle=on -count=1 ./...
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: go build -trimpath ./...
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
// Package config loads typed config from env.
|
||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/caarlos0/env/v11"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
Host string `env:"HOST" envDefault:"0.0.0.0"`
|
||||||
|
Port int `env:"PORT" envDefault:"8080"`
|
||||||
|
ShutdownTimeout time.Duration `env:"SHUTDOWN_TIMEOUT" envDefault:"20s"`
|
||||||
|
LogLevel string `env:"LOG_LEVEL" envDefault:"info"`
|
||||||
|
LogFormat string `env:"LOG_FORMAT" envDefault:"json"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func Load() (Config, error) {
|
||||||
|
var cfg Config
|
||||||
|
if err := env.Parse(&cfg); err != nil {
|
||||||
|
return Config{}, err
|
||||||
|
}
|
||||||
|
return cfg, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
bin/
|
||||||
|
coverage.out
|
||||||
|
coverage.html
|
||||||
|
*.test
|
||||||
|
*.prof
|
||||||
|
|
||||||
|
.idea/
|
||||||
|
.vscode/
|
||||||
|
*.swp
|
||||||
|
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
|
||||||
|
*.pem
|
||||||
|
*.key
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"log/slog"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"$module/internal/cmd"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
ctx, stop := signal.NotifyContext(context.Background(),
|
||||||
|
syscall.SIGINT, syscall.SIGTERM)
|
||||||
|
defer stop()
|
||||||
|
|
||||||
|
if err := cmd.Execute(ctx); err != nil {
|
||||||
|
slog.Error("fatal", slog.Any("err", err))
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// Package cmd wires the root command and subcommands.
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"log/slog"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Execute runs the root command. Wire cobra/subcommands here.
|
||||||
|
func Execute(ctx context.Context) error {
|
||||||
|
slog.New(slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelInfo}))
|
||||||
|
slog.InfoContext(ctx, "starting")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user