vouchington-tooling 0.12.0 → 0.12.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/README.md
CHANGED
|
@@ -68,13 +68,15 @@ vouchington post-review
|
|
|
68
68
|
vouchington stage-review-payload optional|required <source> <destination>
|
|
69
69
|
```
|
|
70
70
|
|
|
71
|
-
For persistent `pnpm-install`,
|
|
71
|
+
For persistent `pnpm-install`, v5 metadata tracks structural inputs separately from the
|
|
72
72
|
`--install-scripts` policy. A warm scripts-enabled tree can therefore toggle
|
|
73
73
|
`true → false → true` without forced reconciliation; a tree first installed with scripts disabled
|
|
74
74
|
uses one script-suppressed verification install followed by `pnpm rebuild --pending --recursive`.
|
|
75
75
|
When only newly pending dependency package IDs remain, it instead rebuilds those exact IDs without
|
|
76
76
|
rerunning first-party workspace hooks.
|
|
77
|
-
|
|
77
|
+
If that generic rebuild leaves only pnpm's root importer marker, one root-only pending rebuild runs
|
|
78
|
+
the root lifecycle hook; every other residual ID remains a hard failure. An isolated native-binary
|
|
79
|
+
mismatch uses one strict forced install only when structural provenance
|
|
78
80
|
matches, workspace links are valid, and pnpm records empty `ignoredBuilds` and `pendingBuilds` ledgers;
|
|
79
81
|
otherwise it retains the script-free then strict reconciliation. Native and workspace-link health
|
|
80
82
|
are verified before its metadata stamp is refreshed.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { scheduler } from 'node:timers/promises';
|
|
2
2
|
import { runPnpm } from './exec.mjs';
|
|
3
3
|
import { nativeBinariesMatchRuntime, repairedNativeBinariesMatchRuntime } from './native-health.mjs';
|
|
4
|
-
import { buildLedgersAllowNativeRepair, pendingBuilds } from './pending-builds.mjs';
|
|
4
|
+
import { buildLedgersAllowNativeRepair, deduplicatePendingBuilds, pendingBuilds, } from './pending-builds.mjs';
|
|
5
5
|
import { INSTALL_TERMINATION_FAILED } from './process.mjs';
|
|
6
6
|
import { formatReleaseAgeFailure, isReleaseAgeViolation } from './release-age.mjs';
|
|
7
7
|
import { findWorkspaceLinkMismatches, forcedInstallArgs, logWorkspaceLinkMismatches, } from './support.mjs';
|
|
@@ -51,6 +51,9 @@ export async function finalizePendingBuilds(options, runCapture, phase) {
|
|
|
51
51
|
if (options.installScripts && before.kind === 'unknown')
|
|
52
52
|
fail(`${phase} completed without a clear pending build ledger`);
|
|
53
53
|
if (options.installScripts && before.kind === 'pending') {
|
|
54
|
+
const deduplicated = await deduplicatePendingBuilds();
|
|
55
|
+
if (deduplicated.kind !== 'pending')
|
|
56
|
+
fail(`${phase} completed without a clear pending build ledger`);
|
|
54
57
|
await install(['rebuild', '--pending', '--recursive'], options, 'pending scripts rebuild');
|
|
55
58
|
const after = await pendingBuilds();
|
|
56
59
|
if (after.kind !== 'clear')
|
|
@@ -7,4 +7,5 @@ export type PendingBuildState = {
|
|
|
7
7
|
kind: 'unknown';
|
|
8
8
|
};
|
|
9
9
|
export declare function pendingBuilds(): Promise<PendingBuildState>;
|
|
10
|
+
export declare function deduplicatePendingBuilds(): Promise<PendingBuildState>;
|
|
10
11
|
export declare function buildLedgersAllowNativeRepair(): Promise<boolean>;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { readFile } from 'node:fs/promises';
|
|
1
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import { parse } from 'yaml';
|
|
3
|
+
import { parse, stringify } from 'yaml';
|
|
4
|
+
const modulesPath = () => path.join(process.cwd(), 'node_modules', '.modules.yaml');
|
|
4
5
|
async function buildLedgers() {
|
|
5
6
|
try {
|
|
6
|
-
const value = parse(await readFile(
|
|
7
|
+
const value = parse(await readFile(modulesPath(), 'utf8'));
|
|
7
8
|
if (typeof value !== 'object' || value === null || Array.isArray(value))
|
|
8
9
|
return undefined;
|
|
9
10
|
// oxlint-disable-next-line no-mistakes/ts-no-const-aliases -- validate the parsed YAML object before reading its fields
|
|
@@ -18,6 +19,7 @@ async function buildLedgers() {
|
|
|
18
19
|
return {
|
|
19
20
|
ignoredBuilds: ignored,
|
|
20
21
|
pendingBuilds: pending.length === 0 ? { kind: 'clear' } : { ids: pending.toSorted(), kind: 'pending' },
|
|
22
|
+
record,
|
|
21
23
|
};
|
|
22
24
|
}
|
|
23
25
|
catch {
|
|
@@ -27,6 +29,22 @@ async function buildLedgers() {
|
|
|
27
29
|
export async function pendingBuilds() {
|
|
28
30
|
return (await buildLedgers())?.pendingBuilds ?? { kind: 'unknown' };
|
|
29
31
|
}
|
|
32
|
+
export async function deduplicatePendingBuilds() {
|
|
33
|
+
const ledgers = await buildLedgers();
|
|
34
|
+
if (ledgers === undefined || ledgers.pendingBuilds.kind !== 'pending')
|
|
35
|
+
return ledgers?.pendingBuilds ?? { kind: 'unknown' };
|
|
36
|
+
// `buildLedgers` has already verified every pending entry is a string.
|
|
37
|
+
const unique = [...new Set(ledgers.record.pendingBuilds)];
|
|
38
|
+
if (unique.length === ledgers.pendingBuilds.ids.length)
|
|
39
|
+
return ledgers.pendingBuilds;
|
|
40
|
+
try {
|
|
41
|
+
await writeFile(modulesPath(), stringify({ ...ledgers.record, pendingBuilds: unique }));
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return { kind: 'unknown' };
|
|
45
|
+
}
|
|
46
|
+
return pendingBuilds();
|
|
47
|
+
}
|
|
30
48
|
export async function buildLedgersAllowNativeRepair() {
|
|
31
49
|
const ledgers = await buildLedgers();
|
|
32
50
|
return (ledgers !== undefined &&
|
|
@@ -29,10 +29,10 @@ if [ "\${PNPM_FAIL_RELEASE_AGE_CALL:-0}" = "$calls" ]; then
|
|
|
29
29
|
exit 1
|
|
30
30
|
fi
|
|
31
31
|
if [ -n "\${PNPM_SLEEP_SECONDS:-}" ]; then sleep "$PNPM_SLEEP_SECONDS"; fi
|
|
32
|
-
if [ "\${PNPM_INVALID_PENDING_BUILDS:-0}" = 1 ]; then
|
|
32
|
+
if [ "\${1:-}" != rebuild ] && [ "\${PNPM_INVALID_PENDING_BUILDS:-0}" = 1 ]; then
|
|
33
33
|
mkdir -p "$PNPM_NODE_MODULES"
|
|
34
34
|
printf 'pendingBuilds: invalid\n' > "$PNPM_NODE_MODULES/.modules.yaml"
|
|
35
|
-
elif [ -n "\${PNPM_PENDING_BUILDS:-}" ]; then
|
|
35
|
+
elif [ "\${1:-}" != rebuild ] && [ -n "\${PNPM_PENDING_BUILDS:-}" ]; then
|
|
36
36
|
mkdir -p "$PNPM_NODE_MODULES"
|
|
37
37
|
printf 'pendingBuilds: [%s]\\n' "$PNPM_PENDING_BUILDS" > "$PNPM_NODE_MODULES/.modules.yaml"
|
|
38
38
|
elif [ ! -f "$PNPM_NODE_MODULES/.modules.yaml" ]; then
|
|
@@ -40,12 +40,19 @@ elif [ ! -f "$PNPM_NODE_MODULES/.modules.yaml" ]; then
|
|
|
40
40
|
printf 'pendingBuilds: []\\n' > "$PNPM_NODE_MODULES/.modules.yaml"
|
|
41
41
|
fi
|
|
42
42
|
case " $* " in
|
|
43
|
+
*' rebuild --pending --workspace-root '*)
|
|
44
|
+
printf 'pendingBuilds: [%s]\n' "\${PNPM_WORKSPACE_ROOT_REBUILD_PENDING_BUILDS:-}" > "$PNPM_NODE_MODULES/.modules.yaml"
|
|
45
|
+
;;
|
|
43
46
|
*' rebuild '*)
|
|
44
47
|
if [ "\${PNPM_REPAIR_NATIVE_ON_REBUILD:-0}" = 1 ]; then
|
|
45
48
|
cp "$PNPM_NATIVE_REPLACEMENT" "$PNPM_NATIVE_ADDON"
|
|
46
49
|
fi
|
|
47
50
|
if [ "\${PNPM_REBUILD_INVALID_LEDGER:-0}" = 1 ]; then
|
|
48
51
|
printf 'pendingBuilds: invalid\n' > "$PNPM_NODE_MODULES/.modules.yaml"
|
|
52
|
+
elif [ "\${PNPM_REBUILD_REQUIRES_DEDUPED:-0}" = 1 ] && sed -n 's/.*\\[\\(.*\\)\\].*/\\1/p' "$PNPM_NODE_MODULES/.modules.yaml" | tr ',' '\\n' | sed 's/^ *//; s/ *$//' | sort | uniq -d | grep -q .; then
|
|
53
|
+
cp "$PNPM_NODE_MODULES/.modules.yaml" "$PNPM_NODE_MODULES/.modules.yaml.rebuild-left-pending"
|
|
54
|
+
elif [ -n "\${PNPM_REBUILD_PENDING_BUILDS:-}" ]; then
|
|
55
|
+
printf 'pendingBuilds: [%s]\n' "$PNPM_REBUILD_PENDING_BUILDS" > "$PNPM_NODE_MODULES/.modules.yaml"
|
|
49
56
|
else
|
|
50
57
|
printf 'pendingBuilds: []\n' > "$PNPM_NODE_MODULES/.modules.yaml"
|
|
51
58
|
fi
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vouchington-tooling",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.2",
|
|
4
4
|
"description": "Vouchington CLI and extractable tooling libraries.",
|
|
5
5
|
"homepage": "https://github.com/vouchington/vouchington-tooling/tree/main/packages/vouchington-tooling#readme",
|
|
6
6
|
"bugs": {
|