forked from bats-core/bats-core
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathjustfile
More file actions
296 lines (261 loc) · 11.2 KB
/
Copy pathjustfile
File metadata and controls
296 lines (261 loc) · 11.2 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
296
# bats / batman — see eng-design_patterns-justfile(7) for conventions.
cmd_nix_dev := "nix develop --command"
default: validate lint build test-batman
# --- pre-build ---
[group("pre-build")]
validate: validate-flake
# run nix flake check (check-bats-libs-path, batman-self-proof, formatting)
[group("pre-build")]
validate-flake:
nix flake check --keep-going
[group("pre-build")]
lint: lint-fmt lint-shell
# run shellcheck on lib/bats-core/*.bash and libexec/bats-core/*
[group("pre-build")]
lint-shell:
nix develop --command shellcheck lib/bats-core/*.bash libexec/bats-core/*
# Read-only formatting gate: builds the `checks.formatting` derivation,
# which runs conformist against a /nix/store snapshot of the source tree
# and fails if anything would change. Does NOT modify files in the
# worktree — the modifying counterpart is codemod-fmt. Also runs as
# part of validate-flake.
#
# check the tree's formatting without modifying files
[group("pre-build")]
lint-fmt:
nix build --no-link --print-build-logs .#checks.{{ arch() }}-linux.formatting
# --- build ---
[group("build")]
build: build-batman build-bats-libs build-devshell
# realize the default batman bundle into the nix store and print the path
[group("build")]
build-batman:
@nix build --no-link --print-out-paths .#default
# realize just the bats-libs bundle and print the path
[group("build")]
build-bats-libs:
@nix build --no-link --print-out-paths .#bats-libs
# Verify the devShell evaluates and builds without errors. Catches
# vendor-env / overlay breakage that the prod-binary build can mask.
#
# verify the devShell evaluates and builds without errors
[group("build")]
build-devshell:
nix build --no-link .#devShells.{{ arch() }}-linux.default
# --- post-build ---
[group("post-build")]
test-batman: test-batman-fence test-batman-fence-wrapper test-batman-self-proof
# Run batman.bats under PLAIN nixpkgs bats. Filters any $HOME-rooted
# entries out of PATH so a user-profile-installed wrapped `bats` does
# not shadow the devshell's nixpkgs bats. The filter pattern covers
# both linux (/home/...) and darwin (/Users/...) user dirs by anchoring
# on $HOME rather than hard-coding "/home/".
#
# `mkdir -p /tmp/fence` is required because fence sets TMPDIR=/tmp/fence
# for its sandboxed child; bats picks that up as BATS_TMPDIR and refuses
# to start if the directory is missing. fence's own integration tests do
# the same dance.
#
# run batman.bats under plain nixpkgs bats
[group("post-build")]
test-batman-fence:
@mkdir -p /tmp/fence; \
batman=$(nix build --no-link --print-out-paths .#default); \
BATMAN_BIN=$batman/bin/batman \
BATS_LIB_PATH=$batman/share/bats \
{{cmd_nix_dev}} bash -c 'PATH=$(echo "$PATH" | tr ":" "\n" | grep -Fv -- "$HOME/" | tr "\n" ":"); exec bats --tap --jobs $(nproc) packages/batman/zz-tests_bats/batman.bats'
# Run bats_wrapper_fence.bats host-side. These tests exercise the
# fence-wrapped bats path via `$BATS_WRAPPER`; on darwin, Determinate
# Nix's nix-daemon attaches Seatbelt to every build child and macOS
# refuses nested `sandbox_apply`, so they cannot run inside `nix build`
# (see the batman-self-proof comment in flake.nix). Running here at
# user-shell level means no enclosing Seatbelt, and fence's own
# sandbox-exec invocation succeeds. See test-batman-fence for the
# /tmp/fence mkdir rationale and the $HOME-rooted PATH filter.
#
# `--no-sandbox` is required because the user's PATH typically resolves
# `bats` to the batman wrapper itself (the $HOME filter strips
# user-installed binaries but the devshell PATH may still surface the
# wrapper). If the OUTER bats fence-wraps, every inner
# `$BATS_WRAPPER` invocation inside the .bats file would be a nested
# fence call, which fails. `--no-sandbox` at the outer level keeps the
# inner-wrapper-asserting tests as the only fence path under test.
#
# run bats_wrapper_fence.bats host-side against the fence-wrapped bats
[group("post-build")]
test-batman-fence-wrapper:
@mkdir -p /tmp/fence; \
batman=$(nix build --no-link --print-out-paths .#default); \
BATMAN_BIN=$batman/bin/batman \
BATS_WRAPPER=$batman/bin/bats \
BATS_LIB_PATH=$batman/share/bats \
{{cmd_nix_dev}} bash -c 'PATH=$(echo "$PATH" | tr ":" "\n" | grep -Fv -- "$HOME/" | tr "\n" ":"); exec bats --no-sandbox --tap packages/batman/zz-tests_bats/bats_wrapper_fence.bats'
# Run the batsLane self-proof: batman's own bats suite executed via the
# batsLane builder this repo exports, inside the nix sandbox. Picks up
# all three zz-tests_bats/*.bats files with BATMAN_BIN and BATS_WRAPPER
# pointed at the built batman bundle. Also runs as part of validate-flake.
#
# run batman's own bats suite via the batsLane builder in the nix sandbox
[group("post-build")]
test-batman-self-proof:
nix build --no-link --print-out-paths ".#checks.$(nix eval --raw --impure --expr builtins.currentSystem).batman-self-proof"
[group("post-build")]
test-extras: test-batman-container-self-proof test-bats-core
# Run batman's tests inside a podman container built from a nix OCI
# image (the container lane). Sibling to test-batman-self-proof and
# test-batman-fence, not part of the test-batman aggregate. Requires
# podman on the host (on Darwin, also `podman machine`).
# See FDR-0002 (packages/batman/docs/features/0002-podman-container-lane.md).
#
# run batman's tests inside a podman container (the container lane)
[group("post-build")]
test-batman-container-self-proof:
nix run .#batman-container-self-proof
# Opt-in manual; not part of default.
#
# run the upstream bats-core tests (test/ tree)
[group("post-build")]
test-bats-core *ARGS:
nix develop --command bats test/ {{ARGS}}
# --- operational ---
# Useful for smoke-testing.
#
# invoke the built batman binary with arbitrary args
[group("operational")]
run-batman *args:
@batman=$(nix build --no-link --print-out-paths .#default); $batman/bin/batman {{args}}
# Generic ad-hoc invocation of the container lane against an arbitrary
# bats source tree. Usage: `just run-bats-container ./path/to/zz-tests_bats`.
#
# run the container lane against an arbitrary bats source tree
[group("operational")]
run-bats-container *args:
nix run .#bats-lane-container -- {{args}}
# Create a signed annotated tag, push it to origin, and verify the
# signature. The "v" prefix is added for you, so pass the semver
# without it. Usage: just deploy-tag 0.1.0 "feat: initial fork release"
#
# create a signed annotated tag, push it to origin, and verify the signature
[group("operational")]
deploy-tag version message:
#!/usr/bin/env bash
set -euo pipefail
tag="v{{version}}"
prev=$(git tag --sort=-v:refname -l "v*" | head -1)
if [[ -n "$prev" ]]; then
gum log --level info "Previous: $prev"
git log --oneline "$prev"..HEAD
fi
git tag -s -m "{{message}}" "$tag"
gum log --level info "Created tag: $tag"
git push origin "$tag"
gum log --level info "Pushed $tag"
git tag -v "$tag"
# Cut a release: must be run on master. Bumps BATMAN_VERSION in
# version.env, commits the bump with a changelog-style message built
# from commits since the last v* tag, pushes master, then signs and
# pushes the v{{version}} tag. The "v" prefix is added for you, so
# pass the semver without it. Usage: just deploy-release 0.1.1
#
# The deploy-tag recipe stays standalone for callers that want to control
# the commit message themselves without bumping. deploy-release inlines
# the tag-step here because passing a multi-line message across `just`
# recipe boundaries was unreliable — the inner recipe saw a malformed
# argument and `git tag -s` would fail in a way that didn't surface
# until much later (see madder release-v0.3.0 incident).
#
# cut a release from master: bump version.env, then sign and push the tag
[group("operational")]
deploy-release version:
#!/usr/bin/env bash
set -euo pipefail
current_branch=$(git rev-parse --abbrev-ref HEAD)
if [[ "$current_branch" != "master" ]]; then
gum log --level error "just deploy-release must be run on master (currently on $current_branch)"
exit 1
fi
prev=$(git tag --sort=-v:refname -l "v*" | head -1)
header="release v{{version}}"
if [[ -n "$prev" ]]; then
summary=$(git log --format='- %s' "$prev"..HEAD)
if [[ -n "$summary" ]]; then
msg="$header"$'\n\n'"$summary"
else
msg="$header"
fi
else
msg="$header"
fi
just bump-version "{{version}}"
if ! git diff --quiet version.env; then
git add version.env
git commit -m "chore: release v{{version}}"
git push origin master
gum log --level info "pushed version.env bump to master"
fi
tag="v{{version}}"
if [[ -n "$prev" ]]; then
gum log --level info "Previous: $prev"
git log --oneline "$prev"..HEAD || true
fi
git tag -s -m "$msg" "$tag"
gum log --level info "Created tag: $tag"
git push origin "$tag"
gum log --level info "Pushed $tag"
# --- codemod ---
[group("codemod")]
codemod-fmt: codemod-fmt-tree
# Format the tree in place (repair mode) via `nix fmt`.
# nixfmt + shfmt driven by conformist; config in ./conformist.nix.
#
# format the tree in place via nix fmt
[group("codemod")]
codemod-fmt-tree:
nix fmt
# --- maintenance ---
# Sed-rewrite BATMAN_VERSION in version.env to the given semver.
# version.env is the single source of truth for the release version;
# flake.nix reads it via builtins.readFile, and the nix build threads
# it through batman.nix's `batmanVersion` arg into every owned
# derivation + the `batman version` runtimeEnv. No-op if already at
# the target. Usage: just bump-version 0.1.1
#
# rewrite BATMAN_VERSION in version.env to the given semver
[group("maintenance")]
bump-version new_version:
#!/usr/bin/env bash
set -euo pipefail
current=$(grep '^export BATMAN_VERSION=' version.env | cut -d= -f2)
if [[ "$current" == "{{new_version}}" ]]; then
gum log --level info "already at {{new_version}}"
exit 0
fi
sed -i.bak 's/^export BATMAN_VERSION=.*/export BATMAN_VERSION={{new_version}}/' version.env && rm version.env.bak
gum log --level info "bumped BATMAN_VERSION: $current → {{new_version}}"
[group("maintenance")]
clean: clean-result-symlinks
# clean stray result symlinks (if any leaked from past `nix build -o ...` runs)
[group("maintenance")]
clean-result-symlinks:
rm -f result result-*
# --- debug ---
# Build the artificial-failure NDJSON demo and print only the NDJSON
# block from the build log. The build deliberately fails (one of the
# demo's bats cases is `false`); the batsLane `emitNdjson` script
# echoes the captured records to stderr between sentinel markers, so
# `sed` between them is all we need. See bats-lane(7) "NDJSON OUTPUT".
#
# print the NDJSON block from the artificial-failure demo build log
[group("debug")]
debug-batman-ndjson:
-nix build .#batman-ndjson-demo 2>&1 \
| sed -n '/BATSLANE NDJSON BEGIN/,/BATSLANE NDJSON END/p' \
| sed '1d;$d'
# Print the full nix build log for a given .drv path. Wrapper around
# `nix log` so the recipe is allowlisted and runs without permission
# prompts when an agent is investigating a failed build.
#
# print the full nix build log for a given .drv path
[group("debug")]
debug-nix-log drv:
nix log {{drv}}