-
-
Notifications
You must be signed in to change notification settings - Fork 56
Expand file tree
/
Copy pathmise.toml
More file actions
295 lines (263 loc) · 11.1 KB
/
Copy pathmise.toml
File metadata and controls
295 lines (263 loc) · 11.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
min_version = "2026.8.16"
[env]
CARGO_TERM_COLOR = 'always'
_.path = ["./target/debug"]
[tools]
mr-boxington = "1.8.3"
# Pinned rather than "latest" because tak is the measuring instrument: an
# upgrade that changes how it samples would land in the series as a step change
# in usage's numbers, indistinguishable from a real regression. Bump deliberately.
"github:jdx/tak" = "v0.0.9"
actionlint = "latest"
aube = "latest"
communique = "latest"
cargo-binstall = "1.22.0"
gh = "latest"
"cargo:cargo-edit" = "latest"
"aqua:mitsuhiko/insta" = "latest"
"github:crate-ci/cargo-release" = "latest"
"github:obi1kenobi/cargo-semver-checks" = "latest"
"aqua:orhun/git-cliff" = "latest"
"npm:prettier" = "latest"
shellcheck = "latest"
go = "1.27.0"
node = "24"
python = "latest"
"npm:tsc" = "latest"
[wrappers.cargo]
command = "mbx"
env = { MBX_CARGO_SHIM_MODE = "1" }
[tasks.autofix]
depends = ["render", "lint-fix", "snapshots"]
[tasks.build]
sources = ['{cli/,}src/**/*.rs', '{cli/,}Cargo.toml']
outputs = ['target/debug/rtx']
run = 'cargo build --all'
[tasks.cli]
alias = ['x']
depends = ['build']
run = 'usage'
raw = true
[tasks.complete-word]
alias = ['cw']
depends = ['build']
run = 'usage cw'
raw = true
[tasks.run-example]
depends = ['build']
run = './examples/example.sh'
raw = true
[tasks.complete_fish]
depends = ['build']
run = 'usage g completion fish -f examples/example.sh > ~/.config/fish/completions/ex.fish'
raw = true
[tasks."docs:dev"]
alias = "docs"
dir = 'docs'
run = 'aube install && aube run docs:dev'
[tasks.test]
alias = 't'
run = 'cargo test --all --all-features'
# The Go parser answers the same corpus the Rust one does, so its suite needs the
# `usage` CLI: a vector's spec is KDL, and lowering it is the CLI's job rather than
# something the Go module carries a parser for. `build` puts one on PATH.
[tasks."test:go"]
dir = '{{config_root}}'
depends = ['build']
# The shadows are the last line, and skipped when the frameworks cannot be fetched: they
# are a benchmark fixture, and a machine without a proxy should still get the suite that
# matters. Asked as its own question rather than with `|| true`, so a generator change that
# broke a shadow is a failure rather than a skip.
run = [
'cd go && go test ./...',
'cd integrations/cobra && go test ./...',
'cd benches/go && if go mod download >/dev/null 2>&1; then go test ./...; else echo "skipped: the benchmark frameworks could not be fetched"; fi',
]
[tasks.lint]
depends = ['lint:*']
[tasks."lint:actionlint"]
run = 'actionlint'
[tasks."lint:prettier"]
run = "prettier -c ."
[tasks."lint:clippy"]
run = 'cargo clippy --all --all-features --all-targets -- -D warnings'
[tasks."lint:fmt"]
run = 'cargo fmt --all -- --check'
[tasks."lint:semver"]
run = "cargo semver-checks check-release -p usage-lib"
[tasks."lint:rust-docs-version"]
run = '''
major=$(sed -n 's/^version = "\([0-9]*\)\..*/\1/p' lib/Cargo.toml | head -1)
python3 - "$major" <<'PY'
import re
import sys
from pathlib import Path
want = sys.argv[1]
paths = [
*Path("docs/rust").glob("*.md"),
Path("usage-rs/src/lib.rs"),
Path("test/src/lib.rs"),
]
dependency = re.compile(
r'^(?:\s*//!\s*)?usage(?:-[a-z]+)?\s*=\s*\{[^\n]*?\bversion\s*=\s*"([^"]+)"',
re.MULTILINE,
)
found = 0
wrong = []
for path in paths:
for match in dependency.finditer(path.read_text()):
found += 1
if match.group(1) != want:
wrong.append(f"{path}: expected major {want}, found {match.group(1)}")
if not found:
wrong.append("no Rust dependency examples found")
if wrong:
raise SystemExit("\n".join(wrong))
print(f"{found} Rust dependency examples use major {want}")
PY
'''
[tasks."lint:go"]
dir = "{{config_root}}"
# `gofmt -l` prints what it would change and exits 0 either way, so the output is
# the failure condition.
#
# Both modules. Everything under `benches/go` is generated, and a generated file that gofmt
# would reformat is one the generator is not finished with — `gen-shadow` runs gofmt for
# exactly that reason.
#
# The benches module is skipped only when its dependencies cannot be *fetched* — asked as its
# own question, because `go vet ./... || true` would swallow a generator regression as well: a
# shadow that no longer compiles would pass the lint and then report itself unmeasured.
run = [
# The status as well as the output: a file gofmt cannot *parse* is reported on stderr with
# nothing on stdout, so `test -z "$(gofmt -l …)"` called that a pass — the one case where
# the answer matters most.
'list=$(gofmt -l go benches/go) || { echo "gofmt could not parse a file; see above"; exit 1; }; test -z "$list" || { echo "$list"; echo "gofmt would change these; run mise run lint-fix"; exit 1; }',
'cd go && go vet ./...',
'cd benches/go && if go mod download >/dev/null 2>&1; then go vet ./...; else echo "skipped: the benchmark frameworks could not be fetched"; fi',
]
[tasks.lint-fix]
run = [
'cargo clippy --all --all-features --fix --allow-dirty --allow-staged -- -D warnings',
'cargo fmt --all',
'gofmt -w go benches/go',
'prettier -w .',
]
[tasks.ci]
depends = ['test', 'test:go', 'lint']
[tasks.pre-commit]
depends = ['render', 'snapshots']
[tasks.render]
depends = ['render:*']
[tasks."render:usage-cli-completions"]
depends = ['build']
run = [
'usage --usage-spec > cli/usage.usage.kdl',
'rm -rf docs/cli/reference && mkdir -p docs/cli/reference',
'usage g json -f cli/usage.usage.kdl > docs/cli/reference/commands.json',
'usage g md -mf cli/usage.usage.kdl --out-dir docs/cli/reference --url-prefix /cli/reference --indented-blocks-to-code-fences',
'usage g manpage -f cli/usage.usage.kdl -o cli/assets/usage.1',
'usage --completions bash > cli/assets/completions/usage.bash',
'usage --completions fish > cli/assets/completions/usage.fish',
'usage --completions zsh > cli/assets/completions/_usage',
'usage --completions powershell > cli/assets/completions/usage.ps1',
'mise run lint-fix',
]
[tasks."render:example-md"]
depends = ['build']
run = [
"usage g md -f benches/mise.usage.kdl --out-file examples/docs/MISE_INLINE.md --indented-blocks-to-code-fences",
"usage g md -f benches/mise.usage.kdl --out-file examples/docs/MISE_MULTI.md --indented-blocks-to-code-fences",
]
[tasks."render:fig"]
depends = ['build']
wait_for = 'render:usage-cli-completions'
run = [
'usage generate fig -f cli/usage.usage.kdl --out-file cli/assets/fig.ts',
'prettier -w cli/assets/fig.ts',
]
[tasks.release]
run = "cargo release --workspace"
[tasks.snapshots]
run = "cargo insta test --accept"
[task_config]
includes = ['tasks']
[tasks.install-dev]
run = "cargo install --path cli --debug"
# Regenerate the shadow CLIs the gate measures. Checked in rather than built by a
# `build.rs`, so that the compile-time comparison has a fixed input and a reviewer can
# read the diff when the derive's vocabulary changes.
[tasks."gen-shadow"]
dir = "{{config_root}}"
run = [
"cargo run -q -p xtask -- gen-shadow benches/mise.usage.kdl benches/shadows/mise usage",
"cargo run -q -p xtask -- gen-shadow benches/mise.usage.kdl benches/shadows/mise-clap clap",
"cargo run -q -p xtask -- gen-shadow benches/mise.usage.kdl benches/shadows/mise-bpaf bpaf",
# Go, in a module of its own: these three are what usage-go is compared against, so they
# must not be dependencies of the module being measured.
"cargo run -q -p xtask -- gen-shadow benches/mise.usage.kdl benches/go/mise-cobra cobra",
"cargo run -q -p xtask -- gen-shadow benches/mise.usage.kdl benches/go/mise-urfave urfave",
"cargo run -q -p xtask -- gen-shadow benches/mise.usage.kdl benches/go/mise-kong kong",
"cargo run -q -p xtask -- gen-shadow benches/fleet/hk.usage.kdl benches/shadows/hk usage",
"cargo run -q -p xtask -- gen-shadow benches/fleet/fnox.usage.kdl benches/shadows/fnox usage",
"cargo run -q -p xtask -- gen-shadow benches/fleet/pitchfork.usage.kdl benches/shadows/pitchfork usage",
"cargo run -q -p xtask -- gen-shadow benches/fleet/aube.usage.kdl benches/shadows/aube usage",
"cargo run -q -p xtask -- gen-shadow benches/fleet/tak.usage.kdl benches/shadows/tak usage",
"cargo run -q -p xtask -- gen-shadow benches/fleet/communique.usage.kdl benches/shadows/communique usage",
"cargo run -q -p xtask -- gen-shadow benches/external/fd.usage.kdl benches/shadows/external-fd usage",
"cargo run -q -p xtask -- gen-shadow benches/external/tokei.usage.kdl benches/shadows/external-tokei usage",
"cargo run -q -p xtask -- gen-shadow benches/external/starship.usage.kdl benches/shadows/external-starship usage",
# The Go emitters write valid Go and leave the columns to gofmt, which is the tool that
# decides where they go. Emitting pre-aligned struct fields would mean reimplementing
# tabwriter's heuristics to guess what it would have done, and being wrong about it
# every time `lint:go` ran.
"gofmt -w benches/go",
]
# The Go tables the shadow test parses against, from the same spec and for the same
# reasons: checked in so a reviewer sees the diff when the emitter's vocabulary
# changes, and so CI can assert that regenerating produces none.
#
# No formatter afterwards, unlike `render:fig`. `usage generate go` emits
# gofmt-clean output, which `lint:go` then checks — a generated file an adopter has
# to reformat before committing is one the generator is not finished with.
#
# Twice, into two modules, on purpose. `go/internal/shadow/mise` is the Go module's own
# fixture: its tests measure allocations at mise's scale and must keep running on a machine
# with no network, so the module they live in has no dependencies to fetch.
# `benches/go/mise` is the same tables in the module that has cobra, urfave and kong, which
# is where the four are timed in one process — and Go's `internal` rule means that module
# cannot import the first copy however the two are laid out.
[tasks."gen-go"]
dir = "{{config_root}}"
depends = ['build']
run = [
"usage generate go -f benches/mise.usage.kdl --package mise -o go/internal/shadow/mise/tables.go",
"usage generate go -f benches/mise.usage.kdl --package mise -o benches/go/mise/tables.go",
]
# The shadow comparison: usage against clap, at mise's scale. Reported, never gated — see
# the note in tak.toml. Takes an optional path to write the markdown to.
[tasks."perf:shadow"]
dir = "{{config_root}}"
run = ["mbx build --release", "./tasks/perf-shadow.sh"]
# What binding a mise-sized command line costs a Go CLI. Reported, never gated — see the
# note at the top of the script, and `perf:shadow` for the Rust side's version of the same
# comparison.
[tasks."perf:go"]
dir = "{{config_root}}"
run = './tasks/perf-go.sh'
# Instruction-counted benchmarks (see tak.toml). Needs valgrind for the counts;
# without it tak reports wall clock only and says so, so this still works on
# macOS where there is no usable cachegrind.
[tasks."perf:build"]
run = "mbx build --release"
[tasks.perf]
dir = "{{config_root}}"
depends = ["perf:build"]
run = "tak run"
# Same measurement, appended to refs/notes/tak for this commit. Run by the
# `perf` workflow on every push to main; the notes are the history. Safe to run
# locally — nothing leaves the machine until `tak push`.
[tasks."perf:record"]
dir = "{{config_root}}"
depends = ["perf:build"]
run = "tak run --record"