dev-cockpit 0.6.0 → 0.6.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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"composer-drift.d.ts","sourceRoot":"","sources":["../../../src/health/predicates/composer-drift.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;
|
|
1
|
+
{"version":3,"file":"composer-drift.d.ts","sourceRoot":"","sources":["../../../src/health/predicates/composer-drift.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,MAAM,WAAW,yBAAyB;IACxC;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAyBD,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,aAAa,EAClB,IAAI,GAAE,yBAA8B,GACnC,OAAO,CAAC,YAAY,CAAC,CA0CvB;AAeD,MAAM,WAAW,+BAAgC,SAAQ,yBAAyB;IAChF,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;IACnC,QAAQ,CAAC,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;IACnC,WAAW,CAAC,EAAE,WAAW,CAAC,aAAa,CAAC,CAAC;CAC1C;AAED,wBAAgB,wBAAwB,CACtC,IAAI,GAAE,+BAAoC,GACzC,WAAW,CA4Bb"}
|
|
@@ -24,4 +24,15 @@ export declare function runRemediation(key: RemediationKey, checks: HealthCheck[
|
|
|
24
24
|
*/
|
|
25
25
|
export declare function findRemediation(key: RemediationKey, checks: HealthCheck[]): HealthCheck | undefined;
|
|
26
26
|
export declare function dispatchRemediation(remediation: Remediation, ctx: HealthContext, workspaceRoot: string, sourceId: string): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Run a single command, streaming its stdout/stderr into the health output log
|
|
29
|
+
* under `health:<sourceId>`. Resolves with the process exit code once it exits.
|
|
30
|
+
*
|
|
31
|
+
* Shared by the `command`-shape dispatcher above and by `run`-shape
|
|
32
|
+
* remediations that need to invoke one or more commands with a proper per-call
|
|
33
|
+
* `cwd` (e.g. `composer install` in several package dirs). Keeping this the one
|
|
34
|
+
* way a remediation reaches a subprocess means commands stay plain argv — no
|
|
35
|
+
* shell string is ever parsed, so `&&` / `(cd …)` can't leak into argv.
|
|
36
|
+
*/
|
|
37
|
+
export declare function streamCommand(ctx: HealthContext, sourceId: string, program: string, args: string[], cwd: string): Promise<number>;
|
|
27
38
|
//# sourceMappingURL=remediations.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remediations.d.ts","sourceRoot":"","sources":["../../src/health/remediations.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"remediations.d.ts","sourceRoot":"","sources":["../../src/health/remediations.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,WAAW,EACX,aAAa,EAEb,WAAW,EACZ,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC;AAEpC;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,WAAW,EAAE,EACrB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GACrC,WAAW,EAAE,CASf;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE,CAevE;AAED,wBAAsB,cAAc,CAClC,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,WAAW,EAAE,EACrB,GAAG,EAAE,aAAa,EAClB,aAAa,EAAE,MAAM,EACrB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GACrC,OAAO,CAAC,IAAI,CAAC,CAQf;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,WAAW,EAAE,GACpB,WAAW,GAAG,SAAS,CAEzB;AAED,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,WAAW,EACxB,GAAG,EAAE,aAAa,EAClB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAef;AAED;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,aAAa,EAClB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,CAAC,CAmBjB"}
|
package/dist/index.js
CHANGED
|
@@ -88257,22 +88257,24 @@ async function dispatchRemediation(remediation, ctx, workspaceRoot, sourceId) {
|
|
|
88257
88257
|
if (!program2) return;
|
|
88258
88258
|
const args = parts.slice(1);
|
|
88259
88259
|
const cwd = remediation.cwd ?? workspaceRoot;
|
|
88260
|
+
await streamCommand(ctx, sourceId, program2, args, cwd);
|
|
88261
|
+
}
|
|
88262
|
+
async function streamCommand(ctx, sourceId, program2, args, cwd) {
|
|
88263
|
+
const emit = (severity, text) => ctx.appendOutput?.({ ts: Date.now(), source: `health:${sourceId}`, severity, text });
|
|
88260
88264
|
const handle = spawnStream(program2, args, {
|
|
88261
88265
|
cwd,
|
|
88262
|
-
|
|
88263
|
-
|
|
88264
|
-
|
|
88265
|
-
|
|
88266
|
-
|
|
88267
|
-
|
|
88268
|
-
onStderr: (line2) => ctx.appendOutput?.({
|
|
88269
|
-
ts: Date.now(),
|
|
88270
|
-
source: `health:${sourceId}`,
|
|
88271
|
-
severity: "warn",
|
|
88272
|
-
text: line2
|
|
88273
|
-
})
|
|
88266
|
+
// Stream both channels as info. Many CLIs (composer, git, npm) write all of
|
|
88267
|
+
// their normal progress to stderr, so the channel says nothing about
|
|
88268
|
+
// severity — treating stderr as a warning renders ordinary success output
|
|
88269
|
+
// as a wall of ⚠. Success vs failure is decided by the exit code below.
|
|
88270
|
+
onStdout: (line2) => emit("info", line2),
|
|
88271
|
+
onStderr: (line2) => emit("info", line2)
|
|
88274
88272
|
});
|
|
88275
|
-
await handle.exitCode;
|
|
88273
|
+
const code = await handle.exitCode;
|
|
88274
|
+
const label = [program2, ...args].join(" ");
|
|
88275
|
+
if (code === 0) emit("info", `\u2713 ${label}`);
|
|
88276
|
+
else emit("error", `\u2717 ${label} failed (exit ${code})`);
|
|
88277
|
+
return code;
|
|
88276
88278
|
}
|
|
88277
88279
|
|
|
88278
88280
|
// src/health/notify-resolver.ts
|
|
@@ -91134,7 +91136,12 @@ function resolveScopes(workspaceRoot, dirs) {
|
|
|
91134
91136
|
const base = rel ? path15.join(workspaceRoot, rel) : workspaceRoot;
|
|
91135
91137
|
return {
|
|
91136
91138
|
lock: path15.join(base, "composer.lock"),
|
|
91137
|
-
|
|
91139
|
+
// Compare against the autoload dump, which `composer install` regenerates
|
|
91140
|
+
// on EVERY run — even a no-op "Nothing to install". The `vendor/`
|
|
91141
|
+
// directory mtime only moves when entries are added/removed directly in
|
|
91142
|
+
// it, so a clean reinstall would never bump it and a drift flagged
|
|
91143
|
+
// against the dir could never clear.
|
|
91144
|
+
installed: path15.join(base, "vendor", "autoload.php"),
|
|
91138
91145
|
label: rel || "root"
|
|
91139
91146
|
};
|
|
91140
91147
|
});
|
|
@@ -91152,18 +91159,18 @@ async function checkComposerDrift(ctx, opts = {}) {
|
|
|
91152
91159
|
} catch {
|
|
91153
91160
|
continue;
|
|
91154
91161
|
}
|
|
91155
|
-
if (!fs19.existsSync(scope.
|
|
91162
|
+
if (!fs19.existsSync(scope.installed)) {
|
|
91156
91163
|
missing.push(scope.label);
|
|
91157
91164
|
continue;
|
|
91158
91165
|
}
|
|
91159
|
-
let
|
|
91166
|
+
let installedMtime;
|
|
91160
91167
|
try {
|
|
91161
|
-
|
|
91168
|
+
installedMtime = fs19.statSync(scope.installed).mtimeMs;
|
|
91162
91169
|
} catch {
|
|
91163
|
-
stale.push(`${scope.label} (
|
|
91170
|
+
stale.push(`${scope.label} (autoload unreadable)`);
|
|
91164
91171
|
continue;
|
|
91165
91172
|
}
|
|
91166
|
-
if (lockMtime >
|
|
91173
|
+
if (lockMtime > installedMtime) {
|
|
91167
91174
|
stale.push(scope.label);
|
|
91168
91175
|
}
|
|
91169
91176
|
}
|
|
@@ -91171,7 +91178,7 @@ async function checkComposerDrift(ctx, opts = {}) {
|
|
|
91171
91178
|
return status3("ok", "composer.lock and vendor/ are in sync");
|
|
91172
91179
|
}
|
|
91173
91180
|
const parts = [];
|
|
91174
|
-
if (missing.length > 0) parts.push(`
|
|
91181
|
+
if (missing.length > 0) parts.push(`dependencies not installed in: ${missing.join(", ")}`);
|
|
91175
91182
|
if (stale.length > 0) parts.push(`composer.lock newer than vendor/ in: ${stale.join(", ")}`);
|
|
91176
91183
|
return status3("error", `${parts.join("; ")} \u2014 run composer install`);
|
|
91177
91184
|
}
|
|
@@ -91186,17 +91193,29 @@ function status3(severity, detail) {
|
|
|
91186
91193
|
}
|
|
91187
91194
|
function createComposerDriftCheck(opts = {}) {
|
|
91188
91195
|
const dirs = opts.packageDirs ?? ["."];
|
|
91189
|
-
const
|
|
91196
|
+
const id = opts.id ?? "composer-drift";
|
|
91190
91197
|
return {
|
|
91191
|
-
id
|
|
91198
|
+
id,
|
|
91192
91199
|
label: opts.label ?? "Composer",
|
|
91193
91200
|
severity: opts.severity ?? "error",
|
|
91194
91201
|
triggers: opts.triggers ?? ["startup", "lockfile"],
|
|
91195
91202
|
predicate: (ctx) => checkComposerDrift(ctx, opts),
|
|
91203
|
+
// Run `composer install` once per package dir, each in its own cwd. A
|
|
91204
|
+
// declarative `command` string can't express this without shell syntax
|
|
91205
|
+
// (`&&`, `(cd …)`), and the dispatcher runs commands as plain argv — so
|
|
91206
|
+
// that syntax would reach composer as bogus package arguments. The `run`
|
|
91207
|
+
// shape keeps each invocation a clean argv in the right directory and
|
|
91208
|
+
// short-circuits on the first failure, mirroring `&&`.
|
|
91196
91209
|
remediation: opts.remediation ?? {
|
|
91197
91210
|
key: "R",
|
|
91198
91211
|
label: "Run composer install",
|
|
91199
|
-
|
|
91212
|
+
run: async (ctx, workspaceRoot) => {
|
|
91213
|
+
for (const d of dirs) {
|
|
91214
|
+
const cwd = d === "" || d === "." ? workspaceRoot : path15.join(workspaceRoot, d);
|
|
91215
|
+
const code = await streamCommand(ctx, id, "composer", ["install"], cwd);
|
|
91216
|
+
if (code !== 0) break;
|
|
91217
|
+
}
|
|
91218
|
+
}
|
|
91200
91219
|
}
|
|
91201
91220
|
};
|
|
91202
91221
|
}
|