rvlib-shipkit 2.0.0 → 2.0.2
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/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## 2.0.2
|
|
2
|
+
|
|
3
|
+
- **SK001 clears its own lint shadow.** A `lint` or `fmt` script that routes through `shipkit ci` beside the bunfig section of the same name is deleted by the repair, with its `:raw` half, so `bun lint` runs the built-in. A script whose body is a tool stays named for a human.
|
|
4
|
+
|
|
5
|
+
## 2.0.1
|
|
6
|
+
|
|
7
|
+
- **`sk fleet --update --major` crosses the major again.** Each repo's guarded run now stays in its own process (`SHIPKIT_NO_HOME`), because a check the home answered never saw `SHIPKIT_ALLOW_MAJOR` and refused the breaking jump, naming the very command that was running.
|
|
8
|
+
|
|
1
9
|
## 2.0.0
|
|
2
10
|
|
|
3
11
|
- **A clean commit prints one line**, `ok: N commit gate(s) clean`. A gate that fails still prints whole, and a WARN or a waived hit inside a passing gate still prints.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rvlib-shipkit",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"funding": "https://github.com/sponsors/rvion",
|
|
5
5
|
"description": "All-in-one repo companion: ci gate (task DAG), auto-discovered health checks, release-contract fulfillness, asks queue, md-wiki tools, asset atelier, live tui",
|
|
6
6
|
"license": "MIT",
|
|
@@ -282,6 +282,19 @@ export const packageJsonShape = check({
|
|
|
282
282
|
// none, so scaffolding this into a repo without any turns the gate red
|
|
283
283
|
// on work the fixer itself did. a fixer must never manufacture a failure.
|
|
284
284
|
if (pkg.scripts['test'] == null && hasTestFiles(testFiles(c))) { pkg.scripts['test'] = 'bun test'; changes.push(`script 'test' added`) }
|
|
285
|
+
// a script beside its declared bunfig section only shadows the built-in.
|
|
286
|
+
// A routed body and its `<id>:raw` are house wiring, so they go. A tool
|
|
287
|
+
// body is a repo's own answer and stays named
|
|
288
|
+
const bunfig = c.read('bunfig.toml')
|
|
289
|
+
for (const n of ['lint', 'fmt'] as const) {
|
|
290
|
+
const body = pkg.scripts[n]
|
|
291
|
+
if (body == null || !bunfigDeclares(bunfig, n)) continue
|
|
292
|
+
if (!routesToShipkit(body)) { notes.push(`'${n}' shadows \`bun ${n}\` — its body is a tool, left for a human`); continue }
|
|
293
|
+
delete pkg.scripts[n]
|
|
294
|
+
const gone: string[] = [n]
|
|
295
|
+
if (pkg.scripts[rawName(n)] != null) { delete pkg.scripts[rawName(n)]; gone.push(rawName(n)) }
|
|
296
|
+
changes.push(`script ${gone.map((g) => `'${g}'`).join(' and ')} deleted (bunfig.toml [${n}] runs \`bun ${n}\`)`)
|
|
297
|
+
}
|
|
285
298
|
// ONE WAY IN, last so it also routes whatever this pass just added:
|
|
286
299
|
// the tool body slides to `<id>:raw` and `<id>` becomes the shipkit
|
|
287
300
|
// call. Both keys keep their place in the file, so the diff a human
|
|
@@ -30,6 +30,16 @@ export type FleetUpdateOpts = {
|
|
|
30
30
|
/** returns how many repos did not update. A repo whose gate refused (dirty
|
|
31
31
|
* tree, frozen, a lease held elsewhere) is a REPORT, not a failure of the
|
|
32
32
|
* command: SK005 defers on purpose */
|
|
33
|
+
/** the env of one repo's guarded run. It stays in its own process
|
|
34
|
+
* (SHIPKIT_NO_HOME): a check the home daemon answers never sees this env, so
|
|
35
|
+
* --major would be dropped on the way */
|
|
36
|
+
export function fleetEnv(base: Record<string, string | undefined>, major: boolean): Record<string, string> {
|
|
37
|
+
const env: Record<string, string> = Object.fromEntries(Object.entries(base).filter((e): e is [string, string] => e[1] != null && e[0] !== 'SHIPKIT_SELF_UPDATED' && e[0] !== ALLOW_MAJOR_ENV))
|
|
38
|
+
env['SHIPKIT_NO_HOME'] = '1'
|
|
39
|
+
if (major) env[ALLOW_MAJOR_ENV] = '1'
|
|
40
|
+
return env
|
|
41
|
+
}
|
|
42
|
+
|
|
33
43
|
export async function updateFleet(behind: FleetRepo[], o: FleetUpdateOpts): Promise<number> {
|
|
34
44
|
const w = o.print
|
|
35
45
|
let failed = 0
|
|
@@ -61,8 +71,7 @@ export async function updateFleet(behind: FleetRepo[], o: FleetUpdateOpts): Prom
|
|
|
61
71
|
// way around it: SK005 has no autofix, so the binary refuses the id.
|
|
62
72
|
// The re-exec guard is dropped so the repo's own startup self-update
|
|
63
73
|
// can still fire, and --major travels as the one env the policy reads.
|
|
64
|
-
const env
|
|
65
|
-
if (o.major) env[ALLOW_MAJOR_ENV] = '1'
|
|
74
|
+
const env = fleetEnv(process.env, o.major === true)
|
|
66
75
|
const res = await spawnWithTimeout(['bun', cli, 'check', '--fresh'], { cwd: r.dir, env, timeoutMs: o.timeoutMs ?? 600_000 })
|
|
67
76
|
// judge by what node_modules carries now (the pin, for a linked dep),
|
|
68
77
|
// never by the exit code or a printed line: the code covers every rule
|