1# https://taskfile.dev
2
3version: "3"
4
5vars:
6 VERSION:
7 sh: git describe --long 2>/dev/null || echo ""
8 RACE:
9 sh: test -f race.log && echo "1" || echo ""
10
11env:
12 CGO_ENABLED: 0
13 GOEXPERIMENT: greenteagc
14
15tasks:
16 lint:install:
17 desc: Install golangci-lint
18 cmds:
19 - go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest
20 env:
21 GOTOOLCHAIN: go1.25.0
22
23 lint:
24 desc: Run base linters
25 cmds:
26 - golangci-lint run --path-mode=abs --config=".golangci.yml" --timeout=5m
27 env:
28 GOEXPERIMENT: null
29
30 lint:fix:
31 desc: Run base linters and fix issues
32 cmds:
33 - golangci-lint run --path-mode=abs --config=".golangci.yml" --timeout=5m --fix
34 env:
35 GOEXPERIMENT: null
36
37 build:
38 desc: Run build
39 vars:
40 LDFLAGS: '{{if .VERSION}}-ldflags="-X github.com/charmbracelet/crush/internal/version.Version={{.VERSION}}"{{end}}'
41 cmds:
42 - "go build {{if .RACE}}-race{{end}} {{.LDFLAGS}} ."
43 generates:
44 - crush
45
46 run:
47 desc: Run build
48 cmds:
49 - task: build
50 - "./crush {{.CLI_ARGS}} {{if .RACE}}2>race.log{{end}}"
51
52 test:
53 desc: Run tests
54 cmds:
55 - go test -race -failfast ./... {{.CLI_ARGS}}
56
57 test:record:
58 desc: Run tests and record all VCR cassettes again
59 aliases: [record]
60 cmds:
61 - rm -r internal/agent/testdata
62 - go test -v -count=1 -timeout=1h ./internal/agent
63
64 fmt:
65 desc: Run gofumpt
66 cmds:
67 - gofumpt -w .
68
69 fmt:html:
70 desc: Run prettier on HTML/CSS/JS files
71 cmds:
72 - prettier --write internal/cmd/stats/index.html internal/cmd/stats/index.css internal/cmd/stats/index.js
73
74 dev:
75 desc: Run with profiling enabled
76 env:
77 CRUSH_PROFILE: true
78 cmds:
79 - go run .
80
81 install:
82 desc: Install the application
83 vars:
84 LDFLAGS: '{{if .VERSION}}-ldflags="-X github.com/charmbracelet/crush/internal/version.Version={{.VERSION}}"{{end}}'
85 cmds:
86 - task: fetch-tags
87 - go install {{.LDFLAGS}} -v .
88
89 profile:cpu:
90 desc: 10s CPU profile
91 cmds:
92 - go tool pprof -http :6061 'http://localhost:6060/debug/pprof/profile?seconds=10'
93
94 profile:heap:
95 desc: Heap profile
96 cmds:
97 - go tool pprof -http :6061 'http://localhost:6060/debug/pprof/heap'
98
99 profile:allocs:
100 desc: Allocations profile
101 cmds:
102 - go tool pprof -http :6061 'http://localhost:6060/debug/pprof/allocs'
103
104 schema:
105 desc: Generate JSON schema for configuration
106 cmds:
107 - go run main.go schema > schema.json
108 - echo "Generated schema.json"
109 generates:
110 - schema.json
111
112 hyper:
113 desc: Update Hyper embedded provider.json
114 cmds:
115 - go generate ./internal/agent/hyper/...
116 generates:
117 - ./internal/agent/hyper/provider.json
118
119 release:
120 desc: Create and push a new tag following semver
121 vars:
122 NEXT:
123 sh: svu next --always || go run github.com/caarlos0/svu/v3@latest next --always
124 prompt: "This will release {{.NEXT}}. Continue?"
125 preconditions:
126 - sh: '[ $(git symbolic-ref --short HEAD) = "main" ]'
127 msg: Not on main branch
128 - sh: "[ $(git status --porcelain=2 | wc -l) = 0 ]"
129 msg: "Git is dirty"
130 - sh: 'gh run list --workflow build.yml --commit $(git rev-parse HEAD) --status success --json conclusion -q ".[0].conclusion" | grep -q success'
131 msg: "Test build for this commit failed or not present"
132 - sh: 'gh run list --workflow snapshot.yml --commit $(git rev-parse HEAD) --status success --json conclusion -q ".[0].conclusion" | grep -q success'
133 msg: "Snapshot build for this commit failed or not present"
134 cmds:
135 - task: fetch-tags
136 - git commit --allow-empty -m "{{.NEXT}}"
137 - git tag --annotate --sign -m "{{.NEXT}}" {{.NEXT}} {{.CLI_ARGS}}
138 - echo "Pushing {{.NEXT}}..."
139 - git push origin main --follow-tags
140
141 fetch-tags:
142 cmds:
143 - git tag -d nightly || true
144 - git fetch --tags
145
146 deps:
147 desc: Update Fantasy and Catwalk
148 cmds:
149 - go get charm.land/fantasy
150 - go get github.com/charmbracelet/catwalk
151 - go mod tidy