forgedock 1.28.0 → 1.29.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/engine/outcome-codes.mjs +29 -0
- package/bin/engine-cli.mjs +77 -16
- package/bin/lean/batch.test.mjs +2 -2
- package/bin/lean/conformance.mjs +47 -2
- package/bin/lean/conformance.test.mjs +53 -1
- package/bin/lean/context.mjs +356 -0
- package/bin/lean/context.test.mjs +307 -0
- package/bin/lean/effects.mjs +19 -1
- package/bin/lean/lean.mjs +178 -37
- package/bin/lean/lean.test.mjs +441 -7
- package/bin/lean/orchestrate.mjs +112 -5
- package/bin/lean/prefilter.mjs +81 -16
- package/bin/lean/prefilter.test.mjs +91 -2
- package/bin/lean/prompts.mjs +22 -7
- package/bin/lean/recovery.test.mjs +419 -0
- package/bin/lean/render.mjs +38 -5
- package/bin/lean/testmap.mjs +101 -0
- package/bin/lean/testmap.test.mjs +73 -0
- package/bin/lean/verify.mjs +48 -3
- package/bin/lean/verify.test.mjs +81 -3
- package/bin/stats/index.mjs +12 -2
- package/bin/stats/local-source.mjs +13 -0
- package/bin/stats/query.mjs +27 -0
- package/bin/stats/stats.test.mjs +41 -2
- package/commands/deploy-pr.md +5 -4
- package/commands/orchestrate.md +54 -7
- package/commands/review-pr-staging.md +6 -1
- package/docs/CONFIG.md +15 -0
- package/docs/OUTCOME-CODES.md +14 -0
- package/docs/RELEASE-NOTES.md +9 -0
- package/package.json +1 -1
- package/scripts/check-spec-markers.sh +1 -0
- package/scripts/code-index.sh +33 -33
- package/scripts/code-index.test.sh +21 -2
- package/scripts/fixtures/test-map/go/.github/workflows/ci.yml +25 -0
- package/scripts/fixtures/test-map/go/Makefile +5 -0
- package/scripts/fixtures/test-map/go/README.md +1 -0
- package/scripts/fixtures/test-map/go/go.mod +3 -0
- package/scripts/fixtures/test-map/go/internal/util/util.go +3 -0
- package/scripts/fixtures/test-map/go/main.go +3 -0
- package/scripts/fixtures/test-map/node/package.json +10 -0
- package/scripts/fixtures/test-map/node/packages/ui/package.json +4 -0
- package/scripts/fixtures/test-map/node/packages/ui/src/button.tsx +1 -0
- package/scripts/fixtures/test-map/node/pnpm-lock.yaml +1 -0
- package/scripts/fixtures/test-map/node/src/a.ts +1 -0
- package/scripts/fixtures/test-map/node/vitest.config.ts +1 -0
- package/scripts/fixtures/test-map/python/pkg/__init__.py +0 -0
- package/scripts/fixtures/test-map/python/pkg/mod.py +2 -0
- package/scripts/fixtures/test-map/python/pyproject.toml +9 -0
- package/scripts/fixtures/test-map/python/tests/test_mod.py +5 -0
- package/scripts/fixtures/test-map/python/uv.lock +1 -0
- package/scripts/repo-facts.sh +146 -0
- package/scripts/repo-facts.test.sh +106 -0
- package/scripts/review-prepare.sh +28 -6
- package/scripts/review-prepare.test.sh +22 -2
- package/scripts/test-map.sh +317 -0
- package/scripts/test-map.test.sh +353 -0
- package/scripts/verify-phase-trail.test.sh +44 -44
- package/scripts/wait-ci-green.sh +10 -4
- package/scripts/wait-ci-green.test.sh +13 -0
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# test-map.test.sh — cases for scripts/test-map.sh over the node, python and go fixtures (forge#4272).
|
|
3
|
+
# SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios
|
|
4
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
5
|
+
set -uo pipefail
|
|
6
|
+
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
7
|
+
S="$HERE/test-map.sh"
|
|
8
|
+
SEL="$HERE/../bin/lean/testmap.mjs"
|
|
9
|
+
FIX="$HERE/fixtures/test-map"
|
|
10
|
+
PASS=0; FAILN=0
|
|
11
|
+
TMP="$(mktemp -d "${TMPDIR:-/tmp}/test-map-test.XXXXXX")"; trap 'rm -rf "$TMP"' EXIT
|
|
12
|
+
ok() { PASS=$((PASS+1)); }
|
|
13
|
+
bad() { FAILN=$((FAILN+1)); echo "FAIL: $1"; }
|
|
14
|
+
eq() { if [ "$2" = "$3" ]; then ok; else bad "$1 (got: $2 want: $3)"; fi }
|
|
15
|
+
|
|
16
|
+
# copy a fixture into a fresh git repo and build its map
|
|
17
|
+
setup() {
|
|
18
|
+
rm -rf "${TMP:?}/$1"; cp -R "$FIX/$1" "$TMP/$1"; cd "$TMP/$1" || exit 1
|
|
19
|
+
git init -q -b main; git config user.email t@example.com; git config user.name t; git config commit.gpgsign false
|
|
20
|
+
git add -A; git commit -qm init
|
|
21
|
+
OUTP="$(bash "$S")"; RC=$?
|
|
22
|
+
}
|
|
23
|
+
# forge#4300: workflow-derived entries of the map JSON in $2 carry no bare `**` glob
|
|
24
|
+
nostar() { eq "$1 no bare ** on workflow entries" "$(printf '%s' "$2" | jq '[.entries[] | select(.source | startswith(".github/workflows/")) | .globs[] | select(. == "**")] | length')" 0; }
|
|
25
|
+
# selected commands for changed files, sorted, joined by |
|
|
26
|
+
sel() { node "$SEL" --map .forge/test-map.json --select "$@" | LC_ALL=C sort | paste -sd'|' -; }
|
|
27
|
+
|
|
28
|
+
# ---- 1. node: root scripts for root files, workspace scripts for package files ----
|
|
29
|
+
setup node
|
|
30
|
+
eq "node rc" "$RC" 0
|
|
31
|
+
eq "node output path" "$OUTP" ".forge/test-map.json"
|
|
32
|
+
eq "schema" "$(jq -c '[.version, (.entries | length > 0), (.entries | all(has("globs") and has("command") and has("cwd") and has("source")))]' .forge/test-map.json)" '[1,true,true]'
|
|
33
|
+
eq "non-check script ignored" "$(jq '[.entries[] | select(.command | test("build"))] | length' .forge/test-map.json)" 0
|
|
34
|
+
eq "root file" "$(sel src/a.ts)" "pnpm run lint|pnpm run test"
|
|
35
|
+
eq "package file" "$(sel packages/ui/src/button.tsx)" "cd packages/ui && pnpm run test|cd packages/ui && pnpm run typecheck|pnpm run lint|pnpm run test"
|
|
36
|
+
eq "vitest config noted" "$(jq -r '.entries[] | select(.cwd == "." and .command == "pnpm run test") | .source' .forge/test-map.json)" "package.json#scripts.test (vitest/jest config)"
|
|
37
|
+
eq "unrelated file" "$(sel README.md)" ""
|
|
38
|
+
|
|
39
|
+
# ---- 2. python: pytest + ruff through uv ----
|
|
40
|
+
setup python
|
|
41
|
+
eq "python rc" "$RC" 0
|
|
42
|
+
eq "python file" "$(sel pkg/mod.py)" "uv run pytest|uv run ruff check ."
|
|
43
|
+
eq "python test file" "$(sel tests/test_mod.py)" "uv run pytest|uv run ruff check ."
|
|
44
|
+
eq "python non-py" "$(sel uv.lock)" ""
|
|
45
|
+
|
|
46
|
+
# ---- 3. go: go.mod, Makefile and CI workflow steps; CI-only lint step; install lines skipped ----
|
|
47
|
+
setup go
|
|
48
|
+
eq "go rc" "$RC" 0
|
|
49
|
+
eq "go file" "$(sel main.go)" "go test ./...|go vet ./...|golangci-lint run ./...|make test|make vet"
|
|
50
|
+
eq "nested go file" "$(sel internal/util/util.go)" "go test ./...|go vet ./...|golangci-lint run ./...|make test|make vet"
|
|
51
|
+
eq "unrecognised ci script dropped" "$(jq '[.entries[] | select(.command | test("check-docs"))] | length' .forge/test-map.json)" 0
|
|
52
|
+
eq "ci-only lint source" "$(jq -r '.entries[] | select(.command == "golangci-lint run ./...") | .source' .forge/test-map.json)" ".github/workflows/ci.yml#jobs.lint"
|
|
53
|
+
eq "install line skipped" "$(jq '[.entries[] | select(.command | test("mod download"))] | length' .forge/test-map.json)" 0
|
|
54
|
+
eq "paths filter fallback" "$(jq -c '.entries[] | select(.command == "make vet") | .globs' .forge/test-map.json)" '["**.go","go.mod"]'
|
|
55
|
+
eq "docs file" "$(sel README.md)" "make test"
|
|
56
|
+
eq "go.sum" "$(sel go.sum)" "go test ./...|go vet ./...|make test"
|
|
57
|
+
nostar go "$(cat .forge/test-map.json)"
|
|
58
|
+
|
|
59
|
+
# ---- 4. regenerable: a rerun is byte-identical; --stdout writes nothing; --output ----
|
|
60
|
+
cp .forge/test-map.json "$TMP/first.json"
|
|
61
|
+
bash "$S" >/dev/null
|
|
62
|
+
if cmp -s .forge/test-map.json "$TMP/first.json"; then ok; else bad "rerun not byte-identical"; fi
|
|
63
|
+
rm -rf .forge; OUTS="$(bash "$S" --stdout)"
|
|
64
|
+
eq "stdout same map" "$OUTS" "$(cat "$TMP/first.json")"
|
|
65
|
+
eq "stdout writes nothing" "$([ -e .forge ] && echo yes || echo no)" no
|
|
66
|
+
bash "$S" --repo-path "$TMP/go" --output "$TMP/out/map.json" >/dev/null
|
|
67
|
+
if cmp -s "$TMP/out/map.json" "$TMP/first.json"; then ok; else bad "--output differs"; fi
|
|
68
|
+
|
|
69
|
+
# ---- 5. block runs, continuation lines, setup lines, workflow without paths ----
|
|
70
|
+
mkdir -p "$TMP/wf/.github/workflows"; cd "$TMP/wf" || exit 1
|
|
71
|
+
git init -q -b main
|
|
72
|
+
cat > .github/workflows/lint.yaml <<'EOF'
|
|
73
|
+
on: push
|
|
74
|
+
jobs:
|
|
75
|
+
checks:
|
|
76
|
+
runs-on: ubuntu-latest
|
|
77
|
+
steps:
|
|
78
|
+
- run: npm ci
|
|
79
|
+
- run: "shellcheck scripts/*.sh"
|
|
80
|
+
- run: >-
|
|
81
|
+
ruff check
|
|
82
|
+
--fix
|
|
83
|
+
- run: |
|
|
84
|
+
echo hi
|
|
85
|
+
bash scripts/verify.sh \
|
|
86
|
+
--strict
|
|
87
|
+
./custom-check
|
|
88
|
+
EOF
|
|
89
|
+
git add -A
|
|
90
|
+
OUTS="$(bash "$S" --stdout)"
|
|
91
|
+
# forge#4300: ./custom-check and `bash scripts/verify.sh` are not allowlisted checks, so they are dropped
|
|
92
|
+
# forge#4316: `ruff check --fix` rewrites the tree, so it is dropped too
|
|
93
|
+
eq "wf commands" "$(printf '%s' "$OUTS" | jq -r '[.entries[].command] | sort | join("|")')" "shellcheck scripts/*.sh"
|
|
94
|
+
eq "wf globs" "$(printf '%s' "$OUTS" | jq -c '[.entries[] | {(.command): .globs}] | add')" '{"shellcheck scripts/*.sh":["**/*.sh"]}'
|
|
95
|
+
nostar wf "$OUTS"
|
|
96
|
+
|
|
97
|
+
# ---- 5b. forge#4297: `- run: |` then env:/shell: ends the block; deploy/publish/release/push/secret steps dropped ----
|
|
98
|
+
mkdir -p "$TMP/wf2/.github/workflows"; cd "$TMP/wf2" || exit 1
|
|
99
|
+
git init -q -b main
|
|
100
|
+
cat > .github/workflows/ci.yml <<'EOF'
|
|
101
|
+
on:
|
|
102
|
+
push:
|
|
103
|
+
branches: [main]
|
|
104
|
+
jobs:
|
|
105
|
+
test:
|
|
106
|
+
runs-on: ubuntu-latest
|
|
107
|
+
steps:
|
|
108
|
+
- run: |
|
|
109
|
+
npm test
|
|
110
|
+
env:
|
|
111
|
+
CI: true
|
|
112
|
+
shell: bash
|
|
113
|
+
- name: Lint
|
|
114
|
+
run: |
|
|
115
|
+
npm run lint
|
|
116
|
+
working-directory: .
|
|
117
|
+
- name: Publish to npm
|
|
118
|
+
run: npm run ship
|
|
119
|
+
- run: ./scripts/release.sh
|
|
120
|
+
- run: git push origin HEAD
|
|
121
|
+
- run: curl -H "token ${{ secrets.TOKEN }}" https://x
|
|
122
|
+
- run: >-
|
|
123
|
+
tsc
|
|
124
|
+
--noEmit
|
|
125
|
+
shell: bash
|
|
126
|
+
deploy:
|
|
127
|
+
name: Ship it
|
|
128
|
+
runs-on: ubuntu-latest
|
|
129
|
+
steps:
|
|
130
|
+
- run: ./ship.sh
|
|
131
|
+
site:
|
|
132
|
+
name: Deploy site
|
|
133
|
+
runs-on: ubuntu-latest
|
|
134
|
+
steps:
|
|
135
|
+
- run: ./build-site.sh
|
|
136
|
+
EOF
|
|
137
|
+
git add -A
|
|
138
|
+
OUTS="$(bash "$S" --stdout)"
|
|
139
|
+
eq "wf2 commands" "$(printf '%s' "$OUTS" | jq -r '[.entries[].command] | sort | join("|")')" "npm run lint|npm test|tsc --noEmit"
|
|
140
|
+
nostar wf2 "$OUTS"
|
|
141
|
+
|
|
142
|
+
# ---- 5d. forge#4300: allowlist, not a name/substring denylist; names never decide; cd/pushd prefix becomes the cwd ----
|
|
143
|
+
mkdir -p "$TMP/wf3/.github/workflows"; cd "$TMP/wf3" || exit 1
|
|
144
|
+
git init -q -b main
|
|
145
|
+
cat > .github/workflows/ci.yml <<'EOF'
|
|
146
|
+
on: pull_request
|
|
147
|
+
jobs:
|
|
148
|
+
release-tests:
|
|
149
|
+
runs-on: ubuntu-latest
|
|
150
|
+
steps:
|
|
151
|
+
- run: npm test
|
|
152
|
+
- run: pytest tests/test_release.py
|
|
153
|
+
- run: pushd sub && make test
|
|
154
|
+
- run: npm run lint
|
|
155
|
+
name: Deploy
|
|
156
|
+
- name: Run tests
|
|
157
|
+
uses: some/action@v1
|
|
158
|
+
with:
|
|
159
|
+
name: release
|
|
160
|
+
- name: Typecheck
|
|
161
|
+
with:
|
|
162
|
+
name: release
|
|
163
|
+
run: npm run typecheck
|
|
164
|
+
ship:
|
|
165
|
+
runs-on: ubuntu-latest
|
|
166
|
+
steps:
|
|
167
|
+
- run: twine upload dist/*
|
|
168
|
+
- run: terraform apply -auto-approve
|
|
169
|
+
- run: kubectl apply -f k8s/
|
|
170
|
+
- run: ./deploy.sh
|
|
171
|
+
name: test
|
|
172
|
+
- name: Tests
|
|
173
|
+
with:
|
|
174
|
+
name: test
|
|
175
|
+
run: ./publish.sh
|
|
176
|
+
- run: pytest && twine upload dist/*
|
|
177
|
+
- run: cd ../other && make test
|
|
178
|
+
- run: npm run build
|
|
179
|
+
- run: npm test -- --token=${{ secrets.NPM_TOKEN }}
|
|
180
|
+
EOF
|
|
181
|
+
git add -A
|
|
182
|
+
OUTS="$(bash "$S" --stdout)"
|
|
183
|
+
eq "wf3 commands" "$(printf '%s' "$OUTS" | jq -r '[.entries[].command] | sort | join("|")')" "make test|npm run lint|npm run typecheck|npm test|pytest tests/test_release.py"
|
|
184
|
+
eq "wf3 release-tests job kept" "$(printf '%s' "$OUTS" | jq -r '[.entries[].source] | unique | join("|")')" ".github/workflows/ci.yml#jobs.release-tests"
|
|
185
|
+
eq "wf3 pushd cwd + globs" "$(printf '%s' "$OUTS" | jq -c '[.entries[] | select(.command == "make test") | {cwd, globs}]')" '[{"cwd":"sub","globs":["sub/**"]}]'
|
|
186
|
+
eq "wf3 no mutating command" "$(printf '%s' "$OUTS" | jq '[.entries[] | select(.command | test("twine|terraform|kubectl|deploy|publish|build|secrets"))] | length')" 0
|
|
187
|
+
nostar wf3 "$OUTS"
|
|
188
|
+
printf '%s' "$OUTS" > "$TMP/wf3-map.json"
|
|
189
|
+
eq "wf3 pushd entry runs in its dir" "$(node "$SEL" --map "$TMP/wf3-map.json" --select sub/Makefile)" "cd sub && make test"
|
|
190
|
+
|
|
191
|
+
# ---- 5c. forge#4298: a package dir with a space and a non-ASCII name keeps whole globs; workflow paths with spaces ----
|
|
192
|
+
mkdir -p "$TMP/sp/web app" "$TMP/sp/pkg/ü/src" "$TMP/sp/.github/workflows"; cd "$TMP/sp" || exit 1
|
|
193
|
+
git init -q -b main
|
|
194
|
+
echo '{"name":"root","private":true}' > package.json
|
|
195
|
+
echo '{"name":"web","scripts":{"test":"vitest run"}}' > "web app/package.json"
|
|
196
|
+
echo '{"name":"u","scripts":{"lint":"eslint ."}}' > "pkg/ü/package.json"
|
|
197
|
+
echo 'x' > "pkg/ü/src/a.ts"
|
|
198
|
+
cat > .github/workflows/ci.yml <<'EOF'
|
|
199
|
+
on:
|
|
200
|
+
push:
|
|
201
|
+
paths:
|
|
202
|
+
- "docs site/**"
|
|
203
|
+
jobs:
|
|
204
|
+
docs:
|
|
205
|
+
runs-on: ubuntu-latest
|
|
206
|
+
steps:
|
|
207
|
+
- run: ./build-docs.sh
|
|
208
|
+
- run: make check
|
|
209
|
+
EOF
|
|
210
|
+
git add -A
|
|
211
|
+
OUTS="$(bash "$S" --stdout)"
|
|
212
|
+
eq "spaced package globs" "$(printf '%s' "$OUTS" | jq -c '[.entries[] | select(.cwd == "web app") | .globs[]] | map(select(endswith("package.json") or endswith(".js")))')" '["web app/**/*.js","web app/package.json"]'
|
|
213
|
+
eq "non-ASCII package dir" "$(printf '%s' "$OUTS" | jq -r '[.entries[] | select(.command == "npm run lint") | .cwd] | join("|")')" "pkg/ü"
|
|
214
|
+
eq "spaced workflow path filter" "$(printf '%s' "$OUTS" | jq -c '[.entries[] | select(.command == "make check") | .globs]')" '[["docs site/**"]]'
|
|
215
|
+
nostar sp "$OUTS"
|
|
216
|
+
eq "unrecognised docs script dropped" "$(printf '%s' "$OUTS" | jq '[.entries[] | select(.command == "./build-docs.sh")] | length')" 0
|
|
217
|
+
printf '%s' "$OUTS" > "$TMP/sp-map.json"
|
|
218
|
+
eq "spaced changed file selects its package test" "$(node "$SEL" --map "$TMP/sp-map.json" --select "web app/src/x.js")" "cd 'web app' && npm run test"
|
|
219
|
+
|
|
220
|
+
# ---- 5e. forge#4315: real runners per ecosystem are mapped with their globs; mutating siblings stay dropped ----
|
|
221
|
+
# wf_case NAME: the step commands on stdin become .github/workflows/ci.yml of a fresh repo; OUTS = its map
|
|
222
|
+
wf_case() {
|
|
223
|
+
mkdir -p "$TMP/$1/.github/workflows"; cd "$TMP/$1" || exit 1
|
|
224
|
+
git init -q -b main
|
|
225
|
+
{ printf 'on: pull_request\njobs:\n ci:\n runs-on: ubuntu-latest\n steps:\n'; sed 's/^/ - run: /'; } > .github/workflows/ci.yml
|
|
226
|
+
git add -A
|
|
227
|
+
OUTS="$(bash "$S" --stdout)"
|
|
228
|
+
nostar "$1" "$OUTS"
|
|
229
|
+
}
|
|
230
|
+
cmds() { printf '%s' "$OUTS" | jq -r '[.entries[].command] | sort | join("|")'; }
|
|
231
|
+
globs_of() { printf '%s' "$OUTS" | jq -r --arg c "$1" '[.entries[] | select(.command == $c) | .globs[]] | join(",")'; }
|
|
232
|
+
|
|
233
|
+
wf_case rust <<'WF'
|
|
234
|
+
cargo test --workspace
|
|
235
|
+
cargo clippy -- -D warnings
|
|
236
|
+
cargo publish
|
|
237
|
+
cargo build --release
|
|
238
|
+
WF
|
|
239
|
+
eq "rust commands" "$(cmds)" "cargo clippy -- -D warnings|cargo test --workspace"
|
|
240
|
+
eq "rust globs" "$(globs_of "cargo test --workspace")" "**/*.rs,**/Cargo.toml,Cargo.lock"
|
|
241
|
+
|
|
242
|
+
wf_case jvm <<'WF'
|
|
243
|
+
./gradlew test
|
|
244
|
+
./gradlew :app:check --no-daemon
|
|
245
|
+
mvn -B test
|
|
246
|
+
./gradlew publish
|
|
247
|
+
./gradlew test publish
|
|
248
|
+
mvn deploy
|
|
249
|
+
mvn install
|
|
250
|
+
WF
|
|
251
|
+
eq "jvm commands" "$(cmds)" "./gradlew :app:check --no-daemon|./gradlew test|mvn -B test"
|
|
252
|
+
eq "jvm globs" "$(globs_of "mvn -B test")" "**/*.java,**/*.kt,**/*.kts,**/*.gradle,**/*.groovy,**/*.scala,**/pom.xml"
|
|
253
|
+
|
|
254
|
+
wf_case ruby <<'WF'
|
|
255
|
+
bundle exec rspec
|
|
256
|
+
rspec spec/models
|
|
257
|
+
bundle exec rake release
|
|
258
|
+
WF
|
|
259
|
+
eq "ruby commands" "$(cmds)" "bundle exec rspec|rspec spec/models"
|
|
260
|
+
eq "ruby globs" "$(globs_of "bundle exec rspec")" "**/*.rb"
|
|
261
|
+
|
|
262
|
+
wf_case pyrun <<'WF'
|
|
263
|
+
python manage.py test
|
|
264
|
+
python -m unittest discover
|
|
265
|
+
tox
|
|
266
|
+
nox -s lint
|
|
267
|
+
tox -e publish
|
|
268
|
+
nox -s release
|
|
269
|
+
python manage.py migrate
|
|
270
|
+
WF
|
|
271
|
+
eq "python runner commands" "$(cmds)" "nox -s lint|python -m unittest discover|python manage.py test|tox"
|
|
272
|
+
eq "python runner globs" "$(globs_of "tox")" "**/*.py"
|
|
273
|
+
|
|
274
|
+
wf_case js <<'WF'
|
|
275
|
+
deno test
|
|
276
|
+
bun test
|
|
277
|
+
pnpm -r test
|
|
278
|
+
npm --prefix web test
|
|
279
|
+
npm run test:unit
|
|
280
|
+
deno deploy
|
|
281
|
+
npm run deploy:prod
|
|
282
|
+
npm --prefix ../x test
|
|
283
|
+
WF
|
|
284
|
+
eq "js runner commands" "$(cmds)" "bun test|deno test|npm --prefix web test|npm run test:unit|pnpm -r test"
|
|
285
|
+
eq "bun globs" "$(globs_of "bun test")" "**/*.js,**/*.jsx,**/*.ts,**/*.tsx,**/*.mjs,**/*.cjs"
|
|
286
|
+
eq "npm --prefix globs" "$(globs_of "npm --prefix web test")" "web/**/*.js,web/**/*.jsx,web/**/*.ts,web/**/*.tsx,web/**/*.mjs,web/**/*.cjs"
|
|
287
|
+
|
|
288
|
+
# ---- 5f. forge#4314: package.json script suffix allowlist (fixers/watchers/e2e/deploy never run pre-PR) ----
|
|
289
|
+
mkdir -p "$TMP/sfx"; cd "$TMP/sfx" || exit 1
|
|
290
|
+
git init -q -b main
|
|
291
|
+
cat > package.json <<'JSON'
|
|
292
|
+
{"name":"s","scripts":{"test":"x","test:unit":"x","test:ci":"x","test:node":"x","test:types":"x","lint:ts":"x","lint:js":"x","check:static":"x","check:types":"x","tsc":"tsc --noEmit","typecheck":"tsc","lint:check":"x","test:unit:ci":"x","lint:format":"prettier --check .","check:format":"prettier --write .",
|
|
293
|
+
"lint:fix":"eslint --fix .","check:fix":"x","test:watch":"x","test:e2e":"x","test:integration":"x","test:deploy":"x","test:update":"x","test:snapshot":"x","lint:css":"x","test:unit:watch":"x","test:-u":"x","lint:write":"x","test:dev":"x","check:release":"x"}}
|
|
294
|
+
JSON
|
|
295
|
+
git add -A
|
|
296
|
+
SFX="$(bash "$S" --stdout | jq -r '[.entries[].source | sub("^package.json#scripts\\.";"")] | sort | join("|")')"
|
|
297
|
+
eq "script suffix allowlist" "$SFX" "check:static|check:types|lint:check|lint:format|lint:js|lint:ts|test|test:ci|test:node|test:types|test:unit|test:unit:ci|tsc|typecheck"
|
|
298
|
+
|
|
299
|
+
wf_case sfxwf <<'WF'
|
|
300
|
+
npm run lint:fix
|
|
301
|
+
npm run check:fix
|
|
302
|
+
pnpm test:watch
|
|
303
|
+
yarn test:e2e
|
|
304
|
+
bun run test:integration
|
|
305
|
+
npm run test:deploy
|
|
306
|
+
pnpm run lint:fix
|
|
307
|
+
npm run test:unit
|
|
308
|
+
pnpm lint:ts
|
|
309
|
+
yarn check:types
|
|
310
|
+
bun run test:ci
|
|
311
|
+
WF
|
|
312
|
+
eq "workflow suffix commands" "$(cmds)" "bun run test:ci|npm run test:unit|pnpm lint:ts|yarn check:types"
|
|
313
|
+
|
|
314
|
+
wf_case shell <<'WF'
|
|
315
|
+
bash scripts/a.test.sh
|
|
316
|
+
sh tests/b.test.sh
|
|
317
|
+
bash scripts/deploy.sh
|
|
318
|
+
bash scripts/verify.sh
|
|
319
|
+
WF
|
|
320
|
+
eq "shell commands" "$(cmds)" "bash scripts/a.test.sh|sh tests/b.test.sh"
|
|
321
|
+
eq "shell globs" "$(globs_of "bash scripts/a.test.sh")" "**/*.sh"
|
|
322
|
+
|
|
323
|
+
# ---- 5f. forge#4316: redirects, process substitution, $GITHUB_*, extra make targets and fixer forms are dropped ----
|
|
324
|
+
# (make needs a cwd for its globs: a workflow entry never gets a bare **)
|
|
325
|
+
wf_case unsafe <<'WF'
|
|
326
|
+
pytest > out.txt
|
|
327
|
+
pytest 2>&1
|
|
328
|
+
diff <(a) <(b)
|
|
329
|
+
tee >(x)
|
|
330
|
+
cd sub && make test deploy
|
|
331
|
+
eslint --fix .
|
|
332
|
+
prettier --write .
|
|
333
|
+
gofmt -w .
|
|
334
|
+
black .
|
|
335
|
+
ruff format .
|
|
336
|
+
cargo clippy --fix
|
|
337
|
+
pytest --junitxml=$GITHUB_WORKSPACE/r.xml
|
|
338
|
+
cd sub && make test lint
|
|
339
|
+
cd sub && make test V=1
|
|
340
|
+
black --check .
|
|
341
|
+
ruff format --check .
|
|
342
|
+
prettier --check .
|
|
343
|
+
gofmt -l .
|
|
344
|
+
eslint .
|
|
345
|
+
WF
|
|
346
|
+
eq "unsafe forms dropped, check forms kept" "$(cmds)" "black --check .|eslint .|gofmt -l .|make test V=1|make test lint|prettier --check .|ruff format --check ."
|
|
347
|
+
|
|
348
|
+
# ---- 6. usage ----
|
|
349
|
+
bash "$S" --repo-path "$TMP/missing" >/dev/null 2>&1; eq "bad repo path" "$?" 2
|
|
350
|
+
bash "$S" --nope >/dev/null 2>&1; eq "unknown option" "$?" 2
|
|
351
|
+
|
|
352
|
+
echo "test-map.test.sh: $PASS passed, $FAILN failed"
|
|
353
|
+
[ "$FAILN" -eq 0 ]
|