@voxgig/create-sdkgen 0.23.0 → 0.24.0
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/package.json
CHANGED
|
@@ -14,6 +14,40 @@ builds or tests, contact package registries, fetch Git refs, or change files.
|
|
|
14
14
|
`--github` also reads recent workflow runs and Pages status through `gh`.
|
|
15
15
|
Install the `.sdk` dependencies before using it.
|
|
16
16
|
|
|
17
|
+
## Is the committed tree what the generator produces?
|
|
18
|
+
|
|
19
|
+
```sh
|
|
20
|
+
cd .sdk && npm run check-drift
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
`check-drift.sh` answers a question nothing else asks. Generation has two
|
|
24
|
+
failure modes that are **completely silent** — neither breaks a build or a
|
|
25
|
+
test, and the only symptom is a tree that disagrees with the model:
|
|
26
|
+
|
|
27
|
+
- **Regeneration never DELETES.** A file the generator has stopped emitting
|
|
28
|
+
stays in the tree. Narrow the secrets plugin selection, drop a target,
|
|
29
|
+
rename an entity, and the superseded output is still committed. One SDK
|
|
30
|
+
carried seven orphaned provider clients in `scala/` and seven in `zig/`;
|
|
31
|
+
the scala ones surfaced only because a test cross-checks the tree against
|
|
32
|
+
the model, and zig's were caught by nothing.
|
|
33
|
+
- **`voxgig-model --no-config` writes a REDUCED model.** It skips the
|
|
34
|
+
`.model-config` build that registers the apidef and sdkgen actions, so
|
|
35
|
+
neither runs — and `model/sdk.json` is still written, now missing the name
|
|
36
|
+
case variants and `main.api` / `main.custom`. Use `npm run dry-generate`
|
|
37
|
+
to inspect a model without side effects, and never `--no-config` in
|
|
38
|
+
anything whose output might be committed.
|
|
39
|
+
|
|
40
|
+
The script deletes every target tree, regenerates, and reports what differs —
|
|
41
|
+
which is the only way to see output the generator no longer emits. It refuses
|
|
42
|
+
to run on a dirty tree, restores the target's own build artifacts and
|
|
43
|
+
lockfiles (which the generator never writes), and leaves the regenerated tree
|
|
44
|
+
in place so the diff can be read.
|
|
45
|
+
|
|
46
|
+
It **detects**; it does not prevent. Run it before a release, or after
|
|
47
|
+
changing the model or the toolchain. It is deliberately not in CI: it
|
|
48
|
+
regenerates every target, which is minutes of work and needs the `.sdk`
|
|
49
|
+
dependencies installed.
|
|
50
|
+
|
|
17
51
|
When a GitHub Pages edition and its CI workflow are enabled, docgen generates
|
|
18
52
|
`setup-github-pages.sh` here. Preview its changes, then configure Pages:
|
|
19
53
|
|
|
@@ -26,6 +60,7 @@ The setup script configures GitHub Actions as the publishing source. It does
|
|
|
26
60
|
not commit, push, merge, or deploy. Push the documentation workflow and project
|
|
27
61
|
changes to its configured deployment branch to publish the website.
|
|
28
62
|
|
|
29
|
-
The status launcher
|
|
30
|
-
sdkgen. Docgen owns the generated Pages setup
|
|
31
|
-
administration scripts beside them with
|
|
63
|
+
The status launcher and the drift check come from create-sdkgen; the status
|
|
64
|
+
reporting code comes from sdkgen. Docgen owns the generated Pages setup
|
|
65
|
+
script. Put project-specific administration scripts beside them with
|
|
66
|
+
different names.
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Is the committed tree what the generator actually produces?
|
|
3
|
+
#
|
|
4
|
+
# BOTH FAILURE MODES THIS CATCHES ARE SILENT. Nothing breaks when generated
|
|
5
|
+
# output drifts from the model, so nothing reports it:
|
|
6
|
+
#
|
|
7
|
+
# - STALE OUTPUT. Regeneration never DELETES a file it has stopped
|
|
8
|
+
# emitting. Narrow the model's secrets plugin selection, drop a target,
|
|
9
|
+
# rename an entity - the superseded files stay in the tree. Seen in one
|
|
10
|
+
# SDK as seven orphaned provider clients in scala and seven in zig: the
|
|
11
|
+
# scala ones surfaced only because one test cross-checks the tree
|
|
12
|
+
# against the model, and zig's were caught by nothing at all.
|
|
13
|
+
#
|
|
14
|
+
# - MODEL DRIFT. The committed .sdk/model/sdk.json can go round a loop,
|
|
15
|
+
# gaining and losing the name case variants and main.api / main.custom
|
|
16
|
+
# depending on which command last wrote it. `voxgig-model --no-config`
|
|
17
|
+
# writes a REDUCED model - it skips the .model-config build that
|
|
18
|
+
# registers the apidef and sdkgen actions, so neither runs, and sdk.json
|
|
19
|
+
# is still written without what they contribute. The only symptom is a
|
|
20
|
+
# dirty tree after regenerating, which is easy to commit past. To
|
|
21
|
+
# inspect a model with no side effects: `npm run dry-generate`.
|
|
22
|
+
#
|
|
23
|
+
# THE TARGET TREES ARE DELETED FIRST, and that is the whole point. A plain
|
|
24
|
+
# regeneration cannot find stale output: the file is committed, generation
|
|
25
|
+
# leaves it alone, and `git status` is silent. Only forcing the generator to
|
|
26
|
+
# reproduce the tree from nothing shows what it no longer emits.
|
|
27
|
+
#
|
|
28
|
+
# This DETECTS, it does not prevent. Run it before a release, or after
|
|
29
|
+
# changing the model or the toolchain.
|
|
30
|
+
#
|
|
31
|
+
# Not wired into CI on purpose: it regenerates every target, which is
|
|
32
|
+
# minutes of work and needs the .sdk dependencies installed - too heavy for
|
|
33
|
+
# a per-push job, and it would only tell CI what one command finds here.
|
|
34
|
+
set -euo pipefail
|
|
35
|
+
|
|
36
|
+
sdk_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
37
|
+
root="$(cd -- "$sdk_dir/.." && pwd)"
|
|
38
|
+
cd "$root"
|
|
39
|
+
|
|
40
|
+
# What each target's OWN toolchain produces - a TypeScript build, a
|
|
41
|
+
# resolved lockfile - which the generator does not emit and must not be
|
|
42
|
+
# reported as stale. Everything else under a target directory is generated.
|
|
43
|
+
keep='(^|/)(dist|dist-test|node_modules)/|(^|/)(package-lock\.json|composer\.lock|go\.sum|Cargo\.lock|yarn\.lock)$'
|
|
44
|
+
|
|
45
|
+
# A dirty tree makes the answer meaningless - every uncommitted edit would
|
|
46
|
+
# read as drift - and this deletes directories, so it must not run over
|
|
47
|
+
# work that is not in git.
|
|
48
|
+
if [[ -n "$(git status --porcelain)" ]]; then
|
|
49
|
+
echo 'check-drift: the working tree has uncommitted changes.' >&2
|
|
50
|
+
echo 'Commit or stash them first: this deletes and regenerates every' >&2
|
|
51
|
+
echo 'target, and uncommitted work would be lost and read as drift.' >&2
|
|
52
|
+
exit 2
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
targets="$(node -e '
|
|
56
|
+
const m = require("./.sdk/model/sdk.json")
|
|
57
|
+
const t = (m.main && m.main.kit && m.main.kit.target) || {}
|
|
58
|
+
console.log(Object.keys(t).sort().join("\n"))
|
|
59
|
+
')"
|
|
60
|
+
|
|
61
|
+
echo 'check-drift: deleting and regenerating every target ...'
|
|
62
|
+
while IFS= read -r t; do
|
|
63
|
+
[[ -n "$t" && -d "$t" ]] && rm -rf -- "$t"
|
|
64
|
+
done <<< "$targets"
|
|
65
|
+
|
|
66
|
+
log="$(mktemp)"
|
|
67
|
+
trap 'rm -f "$log"' EXIT
|
|
68
|
+
if ! ( cd "$sdk_dir" && npm run generate ) >"$log" 2>&1; then
|
|
69
|
+
echo 'check-drift: generation FAILED. Restoring the tree.' >&2
|
|
70
|
+
cat "$log" >&2
|
|
71
|
+
git checkout -- . || true
|
|
72
|
+
exit 2
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
# Put back what the generator was never going to write.
|
|
76
|
+
git status --porcelain | awk '"D" == $1 { print $2 }' | grep -E "$keep" \
|
|
77
|
+
| while IFS= read -r f; do git checkout -- "$f"; done || true
|
|
78
|
+
|
|
79
|
+
drift="$(git status --porcelain)"
|
|
80
|
+
|
|
81
|
+
if [[ -z "$drift" ]]; then
|
|
82
|
+
echo 'check-drift: clean. The committed tree is what the generator produces.'
|
|
83
|
+
exit 0
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
echo >&2
|
|
87
|
+
echo 'check-drift: DRIFT. These differ from what the generator produces:' >&2
|
|
88
|
+
echo >&2
|
|
89
|
+
echo "$drift" >&2
|
|
90
|
+
echo >&2
|
|
91
|
+
echo 'D output the generator no longer emits - delete it.' >&2
|
|
92
|
+
echo 'M output that changed - commit it.' >&2
|
|
93
|
+
echo '?? output not committed - commit it.' >&2
|
|
94
|
+
echo >&2
|
|
95
|
+
echo 'The regenerated tree is left in place so the diff can be read.' >&2
|
|
96
|
+
echo 'Restore with: git checkout -- .' >&2
|
|
97
|
+
exit 1
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
"add-edition": "voxgig-sdkgen edition add",
|
|
22
22
|
"text-qa": "cd .. && voxgig-docgen qa",
|
|
23
23
|
"postinstall": "node build/docgen.js",
|
|
24
|
-
"status": "bash admin/status.sh"
|
|
24
|
+
"status": "bash admin/status.sh",
|
|
25
|
+
"check-drift": "bash admin/check-drift.sh"
|
|
25
26
|
},
|
|
26
27
|
"author": "$$const.Name$$",
|
|
27
28
|
"license": "$$const.License$$",
|