@mnci/cli 4.40.8 → 4.41.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/dist/cli.js +65 -6
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -299,27 +299,35 @@ function planIsEmpty(stdout) {
|
|
|
299
299
|
return false;
|
|
300
300
|
}
|
|
301
301
|
}
|
|
302
|
-
function auditNpm(result, dryRun, log) {
|
|
302
|
+
function auditNpm(result, production, dryRun, log) {
|
|
303
303
|
let report;
|
|
304
|
+
let shipped;
|
|
304
305
|
try {
|
|
305
306
|
report = JSON.parse(result.stdout);
|
|
307
|
+
shipped = JSON.parse(production.stdout);
|
|
306
308
|
} catch {
|
|
307
309
|
log(`npm audit produced no JSON (exit ${result.status}) - not blocking on a broken audit.`);
|
|
308
310
|
return 0;
|
|
309
311
|
}
|
|
310
|
-
const {
|
|
312
|
+
const { notes } = classifyNpmAudit(report);
|
|
313
|
+
const { blocking, total } = classifyNpmAudit(shipped);
|
|
314
|
+
const productionNames = new Set(Object.keys(shipped.vulnerabilities ?? {}));
|
|
315
|
+
const developmentOnly = classifyNpmAudit(report).blocking.filter((advisory) => !productionNames.has(advisory.name));
|
|
311
316
|
for (const note of notes) {
|
|
312
317
|
log(note);
|
|
313
318
|
}
|
|
319
|
+
for (const advisory of developmentOnly) {
|
|
320
|
+
log(` note [${advisory.severity}] ${advisory.name} - reaches only dev dependencies, which no consumer receives, so it does not block`);
|
|
321
|
+
}
|
|
314
322
|
if (blocking.length === 0) {
|
|
315
|
-
log(`npm audit - ${
|
|
323
|
+
log(`npm audit - ${Object.keys(report.vulnerabilities ?? {}).length} advisory(ies), none actionable at moderate or above in production dependencies.`);
|
|
316
324
|
return 0;
|
|
317
325
|
}
|
|
318
326
|
if (planIsEmpty(dryRun().stdout)) {
|
|
319
327
|
for (const advisory of blocking) {
|
|
320
328
|
log(` note [${advisory.severity}] ${advisory.name} - npm reports a fix, but npm audit fix has nothing to apply`);
|
|
321
329
|
}
|
|
322
|
-
log(`npm audit - ${total} advisory(ies); ${blocking.length} reported as fixable, but no patched release is reachable, so there is nothing to do here.`);
|
|
330
|
+
log(`npm audit - ${total} production advisory(ies); ${blocking.length} reported as fixable, but no patched release is reachable, so there is nothing to do here.`);
|
|
323
331
|
return 0;
|
|
324
332
|
}
|
|
325
333
|
for (const advisory of blocking) {
|
|
@@ -348,7 +356,12 @@ function runAudit(workspaceRoot, dependencies = {}) {
|
|
|
348
356
|
}
|
|
349
357
|
};
|
|
350
358
|
log(groupStart(host, "npm audit"));
|
|
351
|
-
const npm = auditNpm(
|
|
359
|
+
const npm = auditNpm(
|
|
360
|
+
processes.capture("npm", ["audit", "--json"]),
|
|
361
|
+
processes.capture("npm", ["audit", "--omit=dev", "--json"]),
|
|
362
|
+
() => processes.capture("npm", ["audit", "fix", "--omit=dev", "--dry-run", "--json"]),
|
|
363
|
+
log
|
|
364
|
+
);
|
|
352
365
|
closeGroup();
|
|
353
366
|
if (npm !== 0) {
|
|
354
367
|
return npm;
|
|
@@ -7885,6 +7898,33 @@ function runKinds(options) {
|
|
|
7885
7898
|
var import_node_child_process = require("child_process");
|
|
7886
7899
|
var import_node_fs29 = require("fs");
|
|
7887
7900
|
var import_node_path34 = require("path");
|
|
7901
|
+
|
|
7902
|
+
// src/workspace-diagnostics/stranded-release-tags.algorithm.ts
|
|
7903
|
+
function compareVersions2(left, right) {
|
|
7904
|
+
const a = left.split(".").map(Number);
|
|
7905
|
+
const b = right.split(".").map(Number);
|
|
7906
|
+
return a[0] - b[0] || a[1] - b[1] || a[2] - b[2] || 0;
|
|
7907
|
+
}
|
|
7908
|
+
function versionsOf(tags, name) {
|
|
7909
|
+
return tags.filter((tag) => tag.startsWith(`${name}@`)).map((tag) => tag.slice(name.length + 1)).filter((version) => /^\d+\.\d+\.\d+$/.test(version));
|
|
7910
|
+
}
|
|
7911
|
+
function findStrandedReleaseTags(projects, tags) {
|
|
7912
|
+
const stranded = [];
|
|
7913
|
+
for (const project of projects) {
|
|
7914
|
+
const unscoped = /^@[^/]+\/(.+)$/.exec(project)?.[1];
|
|
7915
|
+
if (unscoped === void 0) {
|
|
7916
|
+
continue;
|
|
7917
|
+
}
|
|
7918
|
+
const current = versionsOf(tags, project).sort(compareVersions2).at(-1);
|
|
7919
|
+
const newest = versionsOf(tags, unscoped).sort(compareVersions2).at(-1);
|
|
7920
|
+
if (newest !== void 0 && (current === void 0 || compareVersions2(newest, current) > 0)) {
|
|
7921
|
+
stranded.push({ project, oldTag: `${unscoped}@${newest}`, newTag: `${project}@${newest}` });
|
|
7922
|
+
}
|
|
7923
|
+
}
|
|
7924
|
+
return stranded;
|
|
7925
|
+
}
|
|
7926
|
+
|
|
7927
|
+
// src/workspace-diagnostics/check-invariants.use-case.ts
|
|
7888
7928
|
var SUPPORTED_ESLINT_MAJOR = ESLINT_VERSION.replace(/^\D*/, "").split(".", 1)[0];
|
|
7889
7929
|
function toPosix2(path) {
|
|
7890
7930
|
return path.replaceAll("\\", "/");
|
|
@@ -8353,6 +8393,24 @@ function checkLockfileHasNoLocalRegistry(workspaceRoot) {
|
|
|
8353
8393
|
remedy: "run `mnci upgrade`, which removes it, then commit package-lock.json"
|
|
8354
8394
|
};
|
|
8355
8395
|
}
|
|
8396
|
+
function checkReleaseTagsResolve(workspaceRoot, nxJson) {
|
|
8397
|
+
const pattern = nxJson.release?.releaseTag?.pattern;
|
|
8398
|
+
if (pattern !== void 0 && pattern !== "{projectName}@{version}") {
|
|
8399
|
+
return void 0;
|
|
8400
|
+
}
|
|
8401
|
+
const listed = runCapture("git", ["tag", "--list"], workspaceRoot);
|
|
8402
|
+
if (listed.status !== 0) {
|
|
8403
|
+
return void 0;
|
|
8404
|
+
}
|
|
8405
|
+
const projects = (0, import_node_fs29.globSync)("{apps,libs,packages}/*/package.json", { cwd: workspaceRoot }).map((path) => readJson((0, import_node_path34.join)(workspaceRoot, path))).filter((manifest) => manifest.private !== true && manifest.name !== void 0).map((manifest) => manifest.name);
|
|
8406
|
+
const stranded = findStrandedReleaseTags(projects, listed.stdout.split(/\r?\n/).filter(Boolean));
|
|
8407
|
+
return {
|
|
8408
|
+
check: "release tags resolve under each project's current name",
|
|
8409
|
+
ok: stranded.length === 0,
|
|
8410
|
+
detail: `${stranded.map((entry) => `${entry.project} has only ${entry.oldTag}`).join("; ")} - nx release finds no tag under the new name and would release from the disk version, a downgrade`,
|
|
8411
|
+
remedy: `on the commit of each old tag run: ${stranded.map((entry) => `git tag ${entry.newTag} ${entry.oldTag}^{commit}`).join(" ; ")} - then push the tags`
|
|
8412
|
+
};
|
|
8413
|
+
}
|
|
8356
8414
|
function collectFindings(workspaceRoot) {
|
|
8357
8415
|
const nxJsonPath = (0, import_node_path34.join)(workspaceRoot, "nx.json");
|
|
8358
8416
|
if (!fileExists(nxJsonPath)) {
|
|
@@ -8381,7 +8439,8 @@ function collectFindings(workspaceRoot) {
|
|
|
8381
8439
|
...checkPipelinePhases(workspaceRoot),
|
|
8382
8440
|
...checkNativeBuildConfig(workspaceRoot),
|
|
8383
8441
|
checkDependencyRangesNotPreserved(nxJson),
|
|
8384
|
-
checkLockfileHasNoLocalRegistry(workspaceRoot)
|
|
8442
|
+
checkLockfileHasNoLocalRegistry(workspaceRoot),
|
|
8443
|
+
checkReleaseTagsResolve(workspaceRoot, nxJson)
|
|
8385
8444
|
].filter((finding) => finding !== void 0);
|
|
8386
8445
|
}
|
|
8387
8446
|
function runDoctor(workspaceRoot, options = {}) {
|