@mnci/cli 4.17.6 → 4.19.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/README.md +18 -9
- package/dist/cli.js +380 -95
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -2342,7 +2342,7 @@ function runCiPhase(phase, workspaceRoot, dependencies = {}) {
|
|
|
2342
2342
|
}
|
|
2343
2343
|
|
|
2344
2344
|
// src/project-scaffolding/add-project.use-case.ts
|
|
2345
|
-
var
|
|
2345
|
+
var import_node_path24 = require("path");
|
|
2346
2346
|
var import_prompts3 = require("@inquirer/prompts");
|
|
2347
2347
|
|
|
2348
2348
|
// src/project-name/project-name.validator.ts
|
|
@@ -2971,13 +2971,47 @@ function isNxGoPluginRegistered(workspaceRoot) {
|
|
|
2971
2971
|
}
|
|
2972
2972
|
return (readJson(nxJsonPath).plugins ?? []).some((entry) => (typeof entry === "string" ? entry : entry.plugin) === NX_GO_PLUGIN);
|
|
2973
2973
|
}
|
|
2974
|
+
function modulePrefixFromRemoteUrl(url) {
|
|
2975
|
+
const trimmed = url.trim();
|
|
2976
|
+
const scpLike = /^[^@/]+@([^:]+):(.+)$/.exec(trimmed);
|
|
2977
|
+
const withScheme = /^[a-z][\w+.-]*:\/\/(?:[^@/]+@)?(.+)$/i.exec(trimmed);
|
|
2978
|
+
let path;
|
|
2979
|
+
if (scpLike) {
|
|
2980
|
+
path = `${scpLike[1]}/${scpLike[2]}`;
|
|
2981
|
+
} else if (withScheme) {
|
|
2982
|
+
path = withScheme[1];
|
|
2983
|
+
}
|
|
2984
|
+
if (path === void 0) {
|
|
2985
|
+
return void 0;
|
|
2986
|
+
}
|
|
2987
|
+
const cleaned = path.replace(/\.git$/, "").replace(/\/+$/, "");
|
|
2988
|
+
return cleaned === "" ? void 0 : cleaned;
|
|
2989
|
+
}
|
|
2990
|
+
function goModulePrefix(workspaceRoot) {
|
|
2991
|
+
const result = runCapture("git", ["remote", "get-url", "origin"], workspaceRoot);
|
|
2992
|
+
return result.status === 0 ? modulePrefixFromRemoteUrl(result.stdout) : void 0;
|
|
2993
|
+
}
|
|
2974
2994
|
function registerNxGoPlugin(workspaceRoot) {
|
|
2975
2995
|
const nxJsonPath = (0, import_node_path7.join)(workspaceRoot, "nx.json");
|
|
2976
|
-
if (!fileExists(nxJsonPath)
|
|
2996
|
+
if (!fileExists(nxJsonPath)) {
|
|
2977
2997
|
return false;
|
|
2978
2998
|
}
|
|
2999
|
+
const modulePrefix = goModulePrefix(workspaceRoot);
|
|
3000
|
+
const entry = modulePrefix === void 0 ? NX_GO_PLUGIN : { plugin: NX_GO_PLUGIN, options: { modulePrefix } };
|
|
2979
3001
|
const nxJson = readJson(nxJsonPath);
|
|
2980
|
-
|
|
3002
|
+
const plugins = [...nxJson.plugins ?? []];
|
|
3003
|
+
const index = plugins.findIndex((plugin) => (typeof plugin === "string" ? plugin : plugin.plugin) === NX_GO_PLUGIN);
|
|
3004
|
+
if (index === -1) {
|
|
3005
|
+
plugins.push(entry);
|
|
3006
|
+
} else {
|
|
3007
|
+
const current = plugins[index];
|
|
3008
|
+
const currentPrefix = typeof current === "string" ? void 0 : current.options?.modulePrefix;
|
|
3009
|
+
if (modulePrefix === void 0 || currentPrefix === modulePrefix) {
|
|
3010
|
+
return false;
|
|
3011
|
+
}
|
|
3012
|
+
plugins[index] = entry;
|
|
3013
|
+
}
|
|
3014
|
+
writeFileEnsured(nxJsonPath, toJson({ ...nxJson, plugins }));
|
|
2981
3015
|
return true;
|
|
2982
3016
|
}
|
|
2983
3017
|
|
|
@@ -3322,21 +3356,36 @@ function ensureNxGoPlugin(workspaceRoot) {
|
|
|
3322
3356
|
}
|
|
3323
3357
|
}
|
|
3324
3358
|
function ensureGoModule(workspaceRoot) {
|
|
3325
|
-
if (fileExists((0, import_node_path10.join)(workspaceRoot, "go.mod"))) {
|
|
3359
|
+
if (fileExists((0, import_node_path10.join)(workspaceRoot, "go.work")) || fileExists((0, import_node_path10.join)(workspaceRoot, "go.mod"))) {
|
|
3326
3360
|
return;
|
|
3327
3361
|
}
|
|
3328
|
-
logger.step("Bootstrapping the workspace
|
|
3362
|
+
logger.step("Bootstrapping the Go workspace (go.work, one module per project)");
|
|
3329
3363
|
runNx(["g", "@nx-go/nx-go:init", "--no-interactive"], workspaceRoot);
|
|
3330
|
-
runNx(["g", "@nx-go/nx-go:convert-to-one-mod", "--no-interactive"], workspaceRoot);
|
|
3331
3364
|
}
|
|
3332
|
-
function
|
|
3365
|
+
function readGoModModule(goModPath) {
|
|
3333
3366
|
try {
|
|
3334
|
-
|
|
3335
|
-
return /^module\s+(\S+)/m.exec(contents)?.[1];
|
|
3367
|
+
return /^module\s+(\S+)/m.exec((0, import_node_fs9.readFileSync)(goModPath, "utf8"))?.[1];
|
|
3336
3368
|
} catch {
|
|
3337
3369
|
return void 0;
|
|
3338
3370
|
}
|
|
3339
3371
|
}
|
|
3372
|
+
function goModulePathFor(workspaceRoot, projectDir) {
|
|
3373
|
+
const projectModule = readGoModModule((0, import_node_path10.join)(workspaceRoot, projectDir, "go.mod"));
|
|
3374
|
+
if (projectModule !== void 0) {
|
|
3375
|
+
return projectModule;
|
|
3376
|
+
}
|
|
3377
|
+
const rootModule = readGoModModule((0, import_node_path10.join)(workspaceRoot, "go.mod"));
|
|
3378
|
+
return rootModule === void 0 ? void 0 : `${rootModule}/${projectDir}`;
|
|
3379
|
+
}
|
|
3380
|
+
function setGoModulePath(workspaceRoot, projectDir) {
|
|
3381
|
+
const prefix = goModulePrefix(workspaceRoot);
|
|
3382
|
+
const goModPath = (0, import_node_path10.join)(workspaceRoot, projectDir, "go.mod");
|
|
3383
|
+
if (prefix === void 0 || !fileExists(goModPath)) {
|
|
3384
|
+
return;
|
|
3385
|
+
}
|
|
3386
|
+
const rewritten = (0, import_node_fs9.readFileSync)(goModPath, "utf8").replace(/^module\s+\S+/m, () => `module ${prefix}/${projectDir}`);
|
|
3387
|
+
writeFileEnsured(goModPath, rewritten);
|
|
3388
|
+
}
|
|
3340
3389
|
function goTestTarget() {
|
|
3341
3390
|
return { executor: "@nx-go/nx-go:test" };
|
|
3342
3391
|
}
|
|
@@ -3533,6 +3582,7 @@ function addGoApp(workspaceRoot, name, options = {}) {
|
|
|
3533
3582
|
],
|
|
3534
3583
|
workspaceRoot
|
|
3535
3584
|
);
|
|
3585
|
+
setGoModulePath(workspaceRoot, `apps/${name}`);
|
|
3536
3586
|
addProjectJsonTargets((0, import_node_path10.join)(workspaceRoot, "apps", name, "project.json"), {
|
|
3537
3587
|
build: goBuildTarget(name),
|
|
3538
3588
|
test: goTestTarget(),
|
|
@@ -3571,6 +3621,7 @@ function addGoFunctionApp(workspaceRoot, name) {
|
|
|
3571
3621
|
],
|
|
3572
3622
|
workspaceRoot
|
|
3573
3623
|
);
|
|
3624
|
+
setGoModulePath(workspaceRoot, `apps/${name}`);
|
|
3574
3625
|
addProjectJsonTargets((0, import_node_path10.join)(workspaceRoot, "apps", name, "project.json"), {
|
|
3575
3626
|
"build": goBuildTarget(name),
|
|
3576
3627
|
"test": goTestTarget(),
|
|
@@ -3594,15 +3645,16 @@ function addGoLib(workspaceRoot, name) {
|
|
|
3594
3645
|
],
|
|
3595
3646
|
workspaceRoot
|
|
3596
3647
|
);
|
|
3648
|
+
setGoModulePath(workspaceRoot, `packages/${name}`);
|
|
3597
3649
|
addProjectJsonTargets((0, import_node_path10.join)(workspaceRoot, "packages", name, "project.json"), {
|
|
3598
3650
|
test: goTestTarget(),
|
|
3599
3651
|
lint: goLintTarget()
|
|
3600
3652
|
});
|
|
3601
3653
|
const slice = reshapeGoLibraryScaffold((0, import_node_path10.join)(workspaceRoot, "packages", name), name);
|
|
3602
3654
|
registerProjectCommands(workspaceRoot, name, { build: false });
|
|
3603
|
-
const module2 =
|
|
3655
|
+
const module2 = goModulePathFor(workspaceRoot, `packages/${name}`);
|
|
3604
3656
|
if (module2) {
|
|
3605
|
-
logger.step(`Import its starter slice as ${module2}
|
|
3657
|
+
logger.step(`Import its starter slice as ${module2}/${slice}`);
|
|
3606
3658
|
}
|
|
3607
3659
|
}
|
|
3608
3660
|
function addGoInternalLib(workspaceRoot, name) {
|
|
@@ -3618,15 +3670,16 @@ function addGoInternalLib(workspaceRoot, name) {
|
|
|
3618
3670
|
],
|
|
3619
3671
|
workspaceRoot
|
|
3620
3672
|
);
|
|
3673
|
+
setGoModulePath(workspaceRoot, `libs/${name}`);
|
|
3621
3674
|
addProjectJsonTargets((0, import_node_path10.join)(workspaceRoot, "libs", name, "project.json"), {
|
|
3622
3675
|
test: goTestTarget(),
|
|
3623
3676
|
lint: goLintTarget()
|
|
3624
3677
|
});
|
|
3625
3678
|
const slice = reshapeGoLibraryScaffold((0, import_node_path10.join)(workspaceRoot, "libs", name), name);
|
|
3626
3679
|
registerProjectCommands(workspaceRoot, name, { build: false });
|
|
3627
|
-
const module2 =
|
|
3680
|
+
const module2 = goModulePathFor(workspaceRoot, `libs/${name}`);
|
|
3628
3681
|
if (module2) {
|
|
3629
|
-
logger.step(`Import its starter slice as ${module2}
|
|
3682
|
+
logger.step(`Import its starter slice as ${module2}/${slice}`);
|
|
3630
3683
|
}
|
|
3631
3684
|
}
|
|
3632
3685
|
|
|
@@ -4946,7 +4999,8 @@ function addVscodeExtension(workspaceRoot, name, stack, options = {}) {
|
|
|
4946
4999
|
refreshLockFile(workspaceRoot, name);
|
|
4947
5000
|
}
|
|
4948
5001
|
|
|
4949
|
-
// src/dependency-management/
|
|
5002
|
+
// src/dependency-management/install-dependencies.use-case.ts
|
|
5003
|
+
var import_node_fs17 = require("fs");
|
|
4950
5004
|
var import_node_path21 = require("path");
|
|
4951
5005
|
|
|
4952
5006
|
// src/dependency-management/manifest.repository.ts
|
|
@@ -5277,6 +5331,27 @@ function collectInventory(workspaceRoot, ecosystems = ECOSYSTEMS) {
|
|
|
5277
5331
|
}
|
|
5278
5332
|
return inventory;
|
|
5279
5333
|
}
|
|
5334
|
+
var PROJECT_GLOBS = {
|
|
5335
|
+
...MANIFEST_GLOBS,
|
|
5336
|
+
go: ["apps/*/go.mod", "libs/*/go.mod", "packages/*/go.mod"]
|
|
5337
|
+
};
|
|
5338
|
+
function locateProjects(workspaceRoot) {
|
|
5339
|
+
const locations = [];
|
|
5340
|
+
for (const ecosystem of ECOSYSTEMS) {
|
|
5341
|
+
const relativePaths = (0, import_node_fs16.globSync)(PROJECT_GLOBS[ecosystem], { cwd: workspaceRoot });
|
|
5342
|
+
for (const relativePath of relativePaths) {
|
|
5343
|
+
const posix = toPosix(relativePath);
|
|
5344
|
+
const dir = posix.slice(0, posix.lastIndexOf("/"));
|
|
5345
|
+
locations.push({
|
|
5346
|
+
ecosystem,
|
|
5347
|
+
dir,
|
|
5348
|
+
name: dir.slice(dir.lastIndexOf("/") + 1),
|
|
5349
|
+
manifestPath: (0, import_node_path20.join)(workspaceRoot, relativePath)
|
|
5350
|
+
});
|
|
5351
|
+
}
|
|
5352
|
+
}
|
|
5353
|
+
return locations;
|
|
5354
|
+
}
|
|
5280
5355
|
function rewriteSpec(site, spec) {
|
|
5281
5356
|
if (!site.rewritable || spec === site.spec) {
|
|
5282
5357
|
return false;
|
|
@@ -5326,6 +5401,41 @@ function replacePipSpec(content, name, spec) {
|
|
|
5326
5401
|
(match, lead, matched) => `${lead}${matched}${spec}`
|
|
5327
5402
|
);
|
|
5328
5403
|
}
|
|
5404
|
+
function addPipDependency(content, entry) {
|
|
5405
|
+
const name = parseRequirement(entry)?.name;
|
|
5406
|
+
const already = name !== void 0 && pyprojectDependencies(content).some((existing) => parseRequirement(existing)?.name === name);
|
|
5407
|
+
if (already) {
|
|
5408
|
+
return content;
|
|
5409
|
+
}
|
|
5410
|
+
const newline = content.includes("\r\n") ? "\r\n" : "\n";
|
|
5411
|
+
const lines = content.split(/\r?\n/);
|
|
5412
|
+
const quoted = `"${entry}"`;
|
|
5413
|
+
let inProjectTable = false;
|
|
5414
|
+
for (let index = 0; index < lines.length; index++) {
|
|
5415
|
+
const trimmed = lines[index].trim();
|
|
5416
|
+
if (trimmed.startsWith("[")) {
|
|
5417
|
+
inProjectTable = trimmed === "[project]";
|
|
5418
|
+
continue;
|
|
5419
|
+
}
|
|
5420
|
+
if (!inProjectTable) {
|
|
5421
|
+
continue;
|
|
5422
|
+
}
|
|
5423
|
+
const opener = /^(\s*)dependencies\s*=\s*\[(.*)$/.exec(lines[index]);
|
|
5424
|
+
if (!opener) {
|
|
5425
|
+
continue;
|
|
5426
|
+
}
|
|
5427
|
+
const [, indent, rest] = opener;
|
|
5428
|
+
if (rest.includes("]")) {
|
|
5429
|
+
const inner = rest.slice(0, rest.lastIndexOf("]")).trim().replace(/,+\s*$/, "");
|
|
5430
|
+
const list = inner.length > 0 ? `${inner}, ${quoted}` : quoted;
|
|
5431
|
+
lines[index] = `${indent}dependencies = [${list}]`;
|
|
5432
|
+
} else {
|
|
5433
|
+
lines.splice(index + 1, 0, `${indent} ${quoted},`);
|
|
5434
|
+
}
|
|
5435
|
+
return lines.join(newline);
|
|
5436
|
+
}
|
|
5437
|
+
return content;
|
|
5438
|
+
}
|
|
5329
5439
|
function replacePubSpec(content, name, spec) {
|
|
5330
5440
|
return content.replaceAll(
|
|
5331
5441
|
new RegExp(String.raw`^(\s+${escapeForRegex(name)}:[^\S\n]*)\S[^\n]*$`, "gm"),
|
|
@@ -5397,6 +5507,158 @@ function resolvedVersion(workspaceRoot, ecosystem, name) {
|
|
|
5397
5507
|
return void 0;
|
|
5398
5508
|
}
|
|
5399
5509
|
|
|
5510
|
+
// src/dependency-management/install-dependencies.use-case.ts
|
|
5511
|
+
var WHOLE_WORKSPACE_INSTALL = [
|
|
5512
|
+
["npm", "npm", ["install"]],
|
|
5513
|
+
["pip", "npm", ["run", "python:install"]],
|
|
5514
|
+
["pub", "flutter", ["pub", "get"]],
|
|
5515
|
+
["nuget", "npx", ["nx", "run-many", "-t", "restore"]],
|
|
5516
|
+
["go", "go", ["work", "sync"]]
|
|
5517
|
+
];
|
|
5518
|
+
function runInstall(workspaceRoot, packages, options = {}) {
|
|
5519
|
+
const targets = options.workspace ?? [];
|
|
5520
|
+
if (targets.length === 0) {
|
|
5521
|
+
if (packages.length > 0) {
|
|
5522
|
+
logger.error(
|
|
5523
|
+
"Adding a package needs a target project \u2014 'mnci install -w <project> <package>'. A bare 'mnci install' (no package) installs the whole workspace"
|
|
5524
|
+
);
|
|
5525
|
+
process.exitCode = 1;
|
|
5526
|
+
return;
|
|
5527
|
+
}
|
|
5528
|
+
installEverything(workspaceRoot);
|
|
5529
|
+
return;
|
|
5530
|
+
}
|
|
5531
|
+
const locations = locateProjects(workspaceRoot);
|
|
5532
|
+
for (const target of targets) {
|
|
5533
|
+
const location = resolveTarget(locations, target);
|
|
5534
|
+
if (location === void 0) {
|
|
5535
|
+
logger.error(
|
|
5536
|
+
`No project '${target}' \u2014 looked for a manifest under apps/, libs/, packages/ (and python-packages/). Name it by directory (apps/${target}) or by its basename`
|
|
5537
|
+
);
|
|
5538
|
+
process.exitCode = 1;
|
|
5539
|
+
continue;
|
|
5540
|
+
}
|
|
5541
|
+
installInto(workspaceRoot, location, packages, Boolean(options.saveDev));
|
|
5542
|
+
}
|
|
5543
|
+
}
|
|
5544
|
+
function resolveTarget(locations, target) {
|
|
5545
|
+
const byDir = locations.find((location) => location.dir === target);
|
|
5546
|
+
if (byDir !== void 0) {
|
|
5547
|
+
return byDir;
|
|
5548
|
+
}
|
|
5549
|
+
const byName = locations.filter((location) => location.name === target);
|
|
5550
|
+
if (byName.length > 1) {
|
|
5551
|
+
logger.error(
|
|
5552
|
+
`'${target}' matches ${byName.length} projects (${byName.map((match) => match.dir).join(", ")}) \u2014 name it by directory`
|
|
5553
|
+
);
|
|
5554
|
+
return void 0;
|
|
5555
|
+
}
|
|
5556
|
+
return byName[0];
|
|
5557
|
+
}
|
|
5558
|
+
function installInto(workspaceRoot, location, packages, saveDev) {
|
|
5559
|
+
const projectDir = (0, import_node_path21.join)(workspaceRoot, location.dir);
|
|
5560
|
+
switch (location.ecosystem) {
|
|
5561
|
+
case "npm": {
|
|
5562
|
+
const flags = saveDev ? ["--save-dev"] : [];
|
|
5563
|
+
shell(workspaceRoot, "npm", ["install", ...packages, ...flags, "-w", location.dir], location);
|
|
5564
|
+
return;
|
|
5565
|
+
}
|
|
5566
|
+
case "go": {
|
|
5567
|
+
shell(projectDir, "go", packages.length > 0 ? ["get", ...packages] : ["mod", "download"], location);
|
|
5568
|
+
if (packages.length > 0) {
|
|
5569
|
+
runShell("go", ["work", "sync"], workspaceRoot);
|
|
5570
|
+
}
|
|
5571
|
+
return;
|
|
5572
|
+
}
|
|
5573
|
+
case "nuget": {
|
|
5574
|
+
if (packages.length === 0) {
|
|
5575
|
+
shell(workspaceRoot, "dotnet", ["restore", location.manifestPath], location);
|
|
5576
|
+
return;
|
|
5577
|
+
}
|
|
5578
|
+
for (const specifier of packages) {
|
|
5579
|
+
const [name, version] = splitAtLast(specifier, "@");
|
|
5580
|
+
const versionFlag = version === void 0 ? [] : ["--version", version];
|
|
5581
|
+
shell(workspaceRoot, "dotnet", ["add", location.manifestPath, "package", name, ...versionFlag], location);
|
|
5582
|
+
}
|
|
5583
|
+
return;
|
|
5584
|
+
}
|
|
5585
|
+
case "pub": {
|
|
5586
|
+
const devFlag = saveDev ? ["--dev"] : [];
|
|
5587
|
+
shell(
|
|
5588
|
+
projectDir,
|
|
5589
|
+
"flutter",
|
|
5590
|
+
packages.length > 0 ? ["pub", "add", ...devFlag, ...packages] : ["pub", "get"],
|
|
5591
|
+
location
|
|
5592
|
+
);
|
|
5593
|
+
return;
|
|
5594
|
+
}
|
|
5595
|
+
case "pip": {
|
|
5596
|
+
if (saveDev) {
|
|
5597
|
+
logger.warn(
|
|
5598
|
+
"pip has no per-project dev-dependency section \u2014 adding to [project].dependencies (dev tools live in the root requirements-dev.txt)"
|
|
5599
|
+
);
|
|
5600
|
+
}
|
|
5601
|
+
for (const specifier of packages) {
|
|
5602
|
+
addPythonDependency(location.manifestPath, specifier);
|
|
5603
|
+
}
|
|
5604
|
+
installEverything(workspaceRoot, ["pip"]);
|
|
5605
|
+
return;
|
|
5606
|
+
}
|
|
5607
|
+
}
|
|
5608
|
+
}
|
|
5609
|
+
function addPythonDependency(manifestPath, specifier) {
|
|
5610
|
+
let content;
|
|
5611
|
+
try {
|
|
5612
|
+
content = (0, import_node_fs17.readFileSync)(manifestPath, "utf8");
|
|
5613
|
+
} catch {
|
|
5614
|
+
logger.warn(`Could not read ${manifestPath} \u2014 skipped ${specifier}`);
|
|
5615
|
+
return;
|
|
5616
|
+
}
|
|
5617
|
+
const updated = addPipDependency(content, specifier);
|
|
5618
|
+
if (updated === content) {
|
|
5619
|
+
logger.info(`${specifier} is already declared \u2014 left as is`);
|
|
5620
|
+
return;
|
|
5621
|
+
}
|
|
5622
|
+
writeFileEnsured(manifestPath, updated);
|
|
5623
|
+
logger.step(`Added ${specifier} to ${manifestPath}`);
|
|
5624
|
+
}
|
|
5625
|
+
function installEverything(workspaceRoot, only) {
|
|
5626
|
+
for (const [ecosystem, command, arguments_] of WHOLE_WORKSPACE_INSTALL) {
|
|
5627
|
+
if (only !== void 0 && !only.includes(ecosystem)) {
|
|
5628
|
+
continue;
|
|
5629
|
+
}
|
|
5630
|
+
if (!ecosystemPresent(workspaceRoot, ecosystem)) {
|
|
5631
|
+
continue;
|
|
5632
|
+
}
|
|
5633
|
+
logger.step(`Installing ${ecosystem} dependencies (${command} ${arguments_.join(" ")})`);
|
|
5634
|
+
if (runShell(command, [...arguments_], workspaceRoot) !== 0) {
|
|
5635
|
+
logger.warn(`${command} ${arguments_.join(" ")} failed \u2014 re-run it once the cause is fixed`);
|
|
5636
|
+
}
|
|
5637
|
+
}
|
|
5638
|
+
}
|
|
5639
|
+
function ecosystemPresent(workspaceRoot, ecosystem) {
|
|
5640
|
+
if (ecosystem === "go") {
|
|
5641
|
+
return fileExists((0, import_node_path21.join)(workspaceRoot, "go.work")) || fileExists((0, import_node_path21.join)(workspaceRoot, "go.mod"));
|
|
5642
|
+
}
|
|
5643
|
+
return hasEcosystem(workspaceRoot, ecosystem);
|
|
5644
|
+
}
|
|
5645
|
+
function shell(cwd, command, arguments_, location) {
|
|
5646
|
+
logger.step(`${location.dir}: ${command} ${arguments_.join(" ")}`);
|
|
5647
|
+
if (runShell(command, [...arguments_], cwd) !== 0) {
|
|
5648
|
+
logger.warn(`${command} ${arguments_.join(" ")} failed in ${location.dir}`);
|
|
5649
|
+
}
|
|
5650
|
+
}
|
|
5651
|
+
function splitAtLast(value, separator) {
|
|
5652
|
+
const at = value.lastIndexOf(separator);
|
|
5653
|
+
if (at <= 0) {
|
|
5654
|
+
return [value, void 0];
|
|
5655
|
+
}
|
|
5656
|
+
return [value.slice(0, at), value.slice(at + 1)];
|
|
5657
|
+
}
|
|
5658
|
+
|
|
5659
|
+
// src/dependency-management/sync-dependencies.use-case.ts
|
|
5660
|
+
var import_node_path22 = require("path");
|
|
5661
|
+
|
|
5400
5662
|
// src/dependency-management/semver.algorithm.ts
|
|
5401
5663
|
var UPDATE_KINDS = ["patch", "minor", "major", "non-semver"];
|
|
5402
5664
|
var UPDATE_KIND_LABELS = {
|
|
@@ -5572,7 +5834,7 @@ function describe(finding) {
|
|
|
5572
5834
|
return `${finding.name} \u2192 ${finding.target} (${finding.reason}); disagreeing: ${sites}`;
|
|
5573
5835
|
}
|
|
5574
5836
|
function runSync(workspaceRoot, options) {
|
|
5575
|
-
if (!fileExists((0,
|
|
5837
|
+
if (!fileExists((0, import_node_path22.join)(workspaceRoot, "nx.json"))) {
|
|
5576
5838
|
throw new Error(
|
|
5577
5839
|
`No nx.json found in ${workspaceRoot} \u2014 run 'mnci sync' from the workspace root.`
|
|
5578
5840
|
);
|
|
@@ -5622,7 +5884,7 @@ function runSync(workspaceRoot, options) {
|
|
|
5622
5884
|
}
|
|
5623
5885
|
|
|
5624
5886
|
// src/dependency-management/update-dependencies.use-case.ts
|
|
5625
|
-
var
|
|
5887
|
+
var import_node_path23 = require("path");
|
|
5626
5888
|
var import_prompts2 = require("@inquirer/prompts");
|
|
5627
5889
|
|
|
5628
5890
|
// src/dependency-management/registry.client.ts
|
|
@@ -5905,7 +6167,7 @@ function reinstall(workspaceRoot, ecosystems) {
|
|
|
5905
6167
|
function hasPythonInstallScript(workspaceRoot) {
|
|
5906
6168
|
try {
|
|
5907
6169
|
const manifest = readJson(
|
|
5908
|
-
(0,
|
|
6170
|
+
(0, import_node_path23.join)(workspaceRoot, "package.json")
|
|
5909
6171
|
);
|
|
5910
6172
|
return manifest.scripts?.["python:install"] !== void 0;
|
|
5911
6173
|
} catch {
|
|
@@ -5921,7 +6183,7 @@ function applyGoUpdates(workspaceRoot, entries) {
|
|
|
5921
6183
|
}
|
|
5922
6184
|
}
|
|
5923
6185
|
async function runUp(workspaceRoot, options) {
|
|
5924
|
-
if (!fileExists((0,
|
|
6186
|
+
if (!fileExists((0, import_node_path23.join)(workspaceRoot, "nx.json"))) {
|
|
5925
6187
|
throw new Error(`No nx.json found in ${workspaceRoot} \u2014 run 'mnci up' from the workspace root.`);
|
|
5926
6188
|
}
|
|
5927
6189
|
const ecosystems = resolveEcosystems(options.ecosystem);
|
|
@@ -5997,7 +6259,7 @@ var PROJECT_KINDS = [
|
|
|
5997
6259
|
];
|
|
5998
6260
|
async function runAdd(kind, name, options) {
|
|
5999
6261
|
const workspaceRoot = process.cwd();
|
|
6000
|
-
if (!fileExists((0,
|
|
6262
|
+
if (!fileExists((0, import_node_path24.join)(workspaceRoot, "nx.json"))) {
|
|
6001
6263
|
throw new Error("No nx.json found here. Run `add` from the workspace root.");
|
|
6002
6264
|
}
|
|
6003
6265
|
const stack = readWorkspaceStack(workspaceRoot);
|
|
@@ -6057,8 +6319,8 @@ async function runAdd(kind, name, options) {
|
|
|
6057
6319
|
],
|
|
6058
6320
|
workspaceRoot
|
|
6059
6321
|
);
|
|
6060
|
-
markPrivate((0,
|
|
6061
|
-
renameScaffoldPlaceholder((0,
|
|
6322
|
+
markPrivate((0, import_node_path24.join)(workspaceRoot, "libs", resolvedName, "package.json"));
|
|
6323
|
+
renameScaffoldPlaceholder((0, import_node_path24.join)(workspaceRoot, "libs", resolvedName), resolvedName);
|
|
6062
6324
|
removeGeneratedEslintConfig(workspaceRoot, `libs/${resolvedName}`);
|
|
6063
6325
|
registerProjectCommands(workspaceRoot, resolvedName, { build: true });
|
|
6064
6326
|
break;
|
|
@@ -6150,7 +6412,7 @@ async function runAdd(kind, name, options) {
|
|
|
6150
6412
|
}
|
|
6151
6413
|
function readWorkspaceStack(workspaceRoot) {
|
|
6152
6414
|
const nxJson = readJson(
|
|
6153
|
-
(0,
|
|
6415
|
+
(0, import_node_path24.join)(workspaceRoot, "nx.json")
|
|
6154
6416
|
);
|
|
6155
6417
|
const stack = nxJson.mnci?.stack;
|
|
6156
6418
|
return {
|
|
@@ -6160,15 +6422,15 @@ function readWorkspaceStack(workspaceRoot) {
|
|
|
6160
6422
|
|
|
6161
6423
|
// src/workspace-diagnostics/check-invariants.use-case.ts
|
|
6162
6424
|
var import_node_child_process = require("child_process");
|
|
6163
|
-
var
|
|
6164
|
-
var
|
|
6425
|
+
var import_node_fs18 = require("fs");
|
|
6426
|
+
var import_node_path25 = require("path");
|
|
6165
6427
|
var SUPPORTED_ESLINT_MAJOR = ESLINT_VERSION.replace(/^\D*/, "").split(".", 1)[0];
|
|
6166
6428
|
function toPosix2(path) {
|
|
6167
6429
|
return path.replaceAll("\\", "/");
|
|
6168
6430
|
}
|
|
6169
6431
|
function checkEslintConfigs(workspaceRoot) {
|
|
6170
|
-
const rootConfigs = (0,
|
|
6171
|
-
const projectConfigs = (0,
|
|
6432
|
+
const rootConfigs = (0, import_node_fs18.globSync)("eslint.config.{js,mjs,cjs,ts,mts,cts}", { cwd: workspaceRoot });
|
|
6433
|
+
const projectConfigs = (0, import_node_fs18.globSync)("{apps,libs,packages}/*/eslint.config.{js,mjs,cjs,ts,mts,cts}", {
|
|
6172
6434
|
cwd: workspaceRoot
|
|
6173
6435
|
}).map((config) => toPosix2(config));
|
|
6174
6436
|
return [
|
|
@@ -6188,10 +6450,10 @@ function checkEslintConfigs(workspaceRoot) {
|
|
|
6188
6450
|
];
|
|
6189
6451
|
}
|
|
6190
6452
|
function checkEslintEntryPointReachesTheRules(workspaceRoot) {
|
|
6191
|
-
const rules = (0,
|
|
6192
|
-
if (!(0,
|
|
6193
|
-
const entryPoint = (0,
|
|
6194
|
-
const source = (0,
|
|
6453
|
+
const rules = (0, import_node_path25.join)(workspaceRoot, ESLINT_MNCI_FILENAME);
|
|
6454
|
+
if (!(0, import_node_fs18.existsSync)(rules)) return [];
|
|
6455
|
+
const entryPoint = (0, import_node_path25.join)(workspaceRoot, ESLINT_USER_FILENAME);
|
|
6456
|
+
const source = (0, import_node_fs18.existsSync)(entryPoint) ? (0, import_node_fs18.readFileSync)(entryPoint, "utf8") : "";
|
|
6195
6457
|
return [
|
|
6196
6458
|
{
|
|
6197
6459
|
check: `${ESLINT_USER_FILENAME} imports the mnci rules`,
|
|
@@ -6204,7 +6466,7 @@ function checkEslintEntryPointReachesTheRules(workspaceRoot) {
|
|
|
6204
6466
|
function declaredDevDependencies(workspaceRoot) {
|
|
6205
6467
|
try {
|
|
6206
6468
|
const manifest = readJson(
|
|
6207
|
-
(0,
|
|
6469
|
+
(0, import_node_path25.join)(workspaceRoot, "package.json")
|
|
6208
6470
|
);
|
|
6209
6471
|
return manifest.devDependencies ?? {};
|
|
6210
6472
|
} catch {
|
|
@@ -6212,7 +6474,7 @@ function declaredDevDependencies(workspaceRoot) {
|
|
|
6212
6474
|
}
|
|
6213
6475
|
}
|
|
6214
6476
|
function checkNoRetiredFormatter(workspaceRoot) {
|
|
6215
|
-
const files = RETIRED_FORMATTER_FILES.filter((file) => fileExists((0,
|
|
6477
|
+
const files = RETIRED_FORMATTER_FILES.filter((file) => fileExists((0, import_node_path25.join)(workspaceRoot, file)));
|
|
6216
6478
|
const declared = ["prettier", "eslint-config-prettier", "oxlint", "oxfmt", "@mnci/oxlint-config"].filter((name) => declaredDevDependencies(workspaceRoot)[name] !== void 0);
|
|
6217
6479
|
const stale = [...files, ...declared];
|
|
6218
6480
|
if (stale.length === 0) {
|
|
@@ -6238,7 +6500,7 @@ function checkEslintPlugin(nxJson) {
|
|
|
6238
6500
|
};
|
|
6239
6501
|
}
|
|
6240
6502
|
function checkResolvedEslint(workspaceRoot) {
|
|
6241
|
-
const manifestPath = (0,
|
|
6503
|
+
const manifestPath = (0, import_node_path25.join)(workspaceRoot, "node_modules/eslint/package.json");
|
|
6242
6504
|
if (!fileExists(manifestPath)) {
|
|
6243
6505
|
return void 0;
|
|
6244
6506
|
}
|
|
@@ -6256,11 +6518,11 @@ function checkResolvedEslint(workspaceRoot) {
|
|
|
6256
6518
|
}
|
|
6257
6519
|
}
|
|
6258
6520
|
function checkNpmrc(workspaceRoot, registry, scope) {
|
|
6259
|
-
const npmrcPath = (0,
|
|
6521
|
+
const npmrcPath = (0, import_node_path25.join)(workspaceRoot, ".npmrc");
|
|
6260
6522
|
if (!registry || !fileExists(npmrcPath)) {
|
|
6261
6523
|
return void 0;
|
|
6262
6524
|
}
|
|
6263
|
-
const npmrc = (0,
|
|
6525
|
+
const npmrc = (0, import_node_fs18.readFileSync)(npmrcPath, "utf8");
|
|
6264
6526
|
if (registry.kind === "npm") {
|
|
6265
6527
|
return {
|
|
6266
6528
|
check: ".npmrc authenticates the public registry",
|
|
@@ -6277,11 +6539,11 @@ function checkNpmrc(workspaceRoot, registry, scope) {
|
|
|
6277
6539
|
};
|
|
6278
6540
|
}
|
|
6279
6541
|
function checkNpmrcCredentialResolves(workspaceRoot, environment = process.env) {
|
|
6280
|
-
const npmrcPath = (0,
|
|
6542
|
+
const npmrcPath = (0, import_node_path25.join)(workspaceRoot, ".npmrc");
|
|
6281
6543
|
if (!fileExists(npmrcPath)) {
|
|
6282
6544
|
return void 0;
|
|
6283
6545
|
}
|
|
6284
|
-
const npmrc = (0,
|
|
6546
|
+
const npmrc = (0, import_node_fs18.readFileSync)(npmrcPath, "utf8");
|
|
6285
6547
|
const credentials = npmrc.split("\n").filter((line) => !line.trimStart().startsWith(";") && !line.trimStart().startsWith("#")).filter((line) => /(?:_authToken|_password|_auth)\s*=/u.test(line));
|
|
6286
6548
|
const referenced = [
|
|
6287
6549
|
...new Set(
|
|
@@ -6305,13 +6567,13 @@ function checkNpmrcCredentialResolves(workspaceRoot, environment = process.env)
|
|
|
6305
6567
|
};
|
|
6306
6568
|
}
|
|
6307
6569
|
function checkNpmAuthMatchesPipeline(workspaceRoot, registry) {
|
|
6308
|
-
const npmrcPath = (0,
|
|
6309
|
-
const pipelinePath = (0,
|
|
6570
|
+
const npmrcPath = (0, import_node_path25.join)(workspaceRoot, ".npmrc");
|
|
6571
|
+
const pipelinePath = (0, import_node_path25.join)(workspaceRoot, "azure-pipelines.yml");
|
|
6310
6572
|
if (registry?.kind !== "azure-artifacts" || !fileExists(npmrcPath) || !fileExists(pipelinePath)) {
|
|
6311
6573
|
return void 0;
|
|
6312
6574
|
}
|
|
6313
|
-
const holdsCredentials = (0,
|
|
6314
|
-
const runsTask = (0,
|
|
6575
|
+
const holdsCredentials = (0, import_node_fs18.readFileSync)(npmrcPath, "utf8").split("\n").filter((line) => !line.trimStart().startsWith(";") && !line.trimStart().startsWith("#")).some((line) => /(?:_authToken|_password|_auth)\s*=/u.test(line));
|
|
6576
|
+
const runsTask = (0, import_node_fs18.readFileSync)(pipelinePath, "utf8").includes("npmAuthenticate@0");
|
|
6315
6577
|
if (!holdsCredentials && !runsTask) {
|
|
6316
6578
|
return {
|
|
6317
6579
|
check: "npm auth: .npmrc and azure-pipelines.yml agree",
|
|
@@ -6356,13 +6618,13 @@ function npmjsCredentialShape(credentials, environment) {
|
|
|
6356
6618
|
}
|
|
6357
6619
|
function checkVersionActions(workspaceRoot) {
|
|
6358
6620
|
const candidates = [
|
|
6359
|
-
...(0,
|
|
6360
|
-
...(0,
|
|
6361
|
-
...(0,
|
|
6621
|
+
...(0, import_node_fs18.globSync)("packages/*/pubspec.yaml", { cwd: workspaceRoot }),
|
|
6622
|
+
...(0, import_node_fs18.globSync)("packages/*/*.csproj", { cwd: workspaceRoot }),
|
|
6623
|
+
...(0, import_node_fs18.globSync)("python-packages/*/pyproject.toml", { cwd: workspaceRoot })
|
|
6362
6624
|
].map((manifest) => toPosix2(manifest));
|
|
6363
6625
|
return candidates.flatMap((manifest) => {
|
|
6364
6626
|
const projectRoot = manifest.slice(0, manifest.lastIndexOf("/"));
|
|
6365
|
-
const projectJsonPath = (0,
|
|
6627
|
+
const projectJsonPath = (0, import_node_path25.join)(workspaceRoot, projectRoot, "project.json");
|
|
6366
6628
|
let hasOverride = false;
|
|
6367
6629
|
try {
|
|
6368
6630
|
const projectJson = readJson(projectJsonPath);
|
|
@@ -6391,7 +6653,7 @@ function declaredTargets(workspaceRoot, projectRoot) {
|
|
|
6391
6653
|
]) {
|
|
6392
6654
|
try {
|
|
6393
6655
|
const targets = extract(
|
|
6394
|
-
readJson((0,
|
|
6656
|
+
readJson((0, import_node_path25.join)(workspaceRoot, projectRoot, file))
|
|
6395
6657
|
);
|
|
6396
6658
|
if (targets && typeof targets === "object") {
|
|
6397
6659
|
sources.push({
|
|
@@ -6407,8 +6669,8 @@ function declaredTargets(workspaceRoot, projectRoot) {
|
|
|
6407
6669
|
function checkTargetFilesExist(workspaceRoot) {
|
|
6408
6670
|
const projectRoots = new Set(
|
|
6409
6671
|
[
|
|
6410
|
-
...(0,
|
|
6411
|
-
...(0,
|
|
6672
|
+
...(0, import_node_fs18.globSync)("{apps,libs,packages}/*/project.json", { cwd: workspaceRoot }),
|
|
6673
|
+
...(0, import_node_fs18.globSync)("{apps,libs,packages}/*/package.json", { cwd: workspaceRoot })
|
|
6412
6674
|
].map((manifest) => toPosix2(manifest).split("/").slice(0, 2).join("/"))
|
|
6413
6675
|
);
|
|
6414
6676
|
return [...projectRoots].flatMap(
|
|
@@ -6423,7 +6685,7 @@ function checkOneTargetsFiles(workspaceRoot, source, targetName, target) {
|
|
|
6423
6685
|
return TARGET_FILE_OPTIONS.flatMap((option) => {
|
|
6424
6686
|
const value = target?.options?.[option];
|
|
6425
6687
|
const checkable = typeof value === "string" && !value.includes("{");
|
|
6426
|
-
if (!checkable || fileExists((0,
|
|
6688
|
+
if (!checkable || fileExists((0, import_node_path25.join)(workspaceRoot, value))) {
|
|
6427
6689
|
return [];
|
|
6428
6690
|
}
|
|
6429
6691
|
return [
|
|
@@ -6459,6 +6721,23 @@ function checkGoPluginRegistered(workspaceRoot) {
|
|
|
6459
6721
|
remedy: "run `mnci upgrade`"
|
|
6460
6722
|
};
|
|
6461
6723
|
}
|
|
6724
|
+
function checkGoWorkInSync(workspaceRoot) {
|
|
6725
|
+
const goWorkPath = (0, import_node_path25.join)(workspaceRoot, "go.work");
|
|
6726
|
+
if (!fileExists(goWorkPath)) {
|
|
6727
|
+
return void 0;
|
|
6728
|
+
}
|
|
6729
|
+
const contents = (0, import_node_fs18.existsSync)(goWorkPath) ? (0, import_node_fs18.readFileSync)(goWorkPath, "utf8") : "";
|
|
6730
|
+
const blockEntries = Array.from(contents.matchAll(/(?:^|\n)\s*use\s+\(([^)]*)\)/g), (match) => match[1].split("\n")).flat();
|
|
6731
|
+
const singleEntries = Array.from(contents.matchAll(/(?:^|\n)\s*use\s+(\.\S+)/g), (match) => match[1]);
|
|
6732
|
+
const uses = [...blockEntries, ...singleEntries].map((entry) => entry.trim()).filter(Boolean);
|
|
6733
|
+
const stale = uses.filter((entry) => !(0, import_node_fs18.existsSync)((0, import_node_path25.join)(workspaceRoot, entry, "go.mod")));
|
|
6734
|
+
return {
|
|
6735
|
+
check: "every go.work `use` entry points to a module that still exists",
|
|
6736
|
+
ok: stale.length === 0,
|
|
6737
|
+
detail: `go.work lists ${stale.join(", ")} but there is no go.mod there \u2014 \`go list -m\` fails, which breaks the whole Nx project graph`,
|
|
6738
|
+
remedy: "drop the stale `use` line(s) from go.work (mnci owns the file; a removed Go project should have its entry removed)"
|
|
6739
|
+
};
|
|
6740
|
+
}
|
|
6462
6741
|
function checkNativeApps(workspaceRoot) {
|
|
6463
6742
|
if (!hasNativeGoApp(workspaceRoot)) {
|
|
6464
6743
|
return [];
|
|
@@ -6467,9 +6746,9 @@ function checkNativeApps(workspaceRoot) {
|
|
|
6467
6746
|
{ file: ".github/workflows/ci.yml", marker: "native (${{ matrix.os }})" },
|
|
6468
6747
|
{ file: "azure-pipelines.yml", marker: "- job: native" }
|
|
6469
6748
|
];
|
|
6470
|
-
const findings = pipelines.filter(({ file }) => fileExists((0,
|
|
6749
|
+
const findings = pipelines.filter(({ file }) => fileExists((0, import_node_path25.join)(workspaceRoot, file))).map(({ file, marker }) => ({
|
|
6471
6750
|
check: `${file} builds the native apps on every OS`,
|
|
6472
|
-
ok: (0,
|
|
6751
|
+
ok: (0, import_node_fs18.readFileSync)((0, import_node_path25.join)(workspaceRoot, file), "utf8").includes(marker),
|
|
6473
6752
|
detail: `${file} has no native job: CI would verify a cgo app on the one agent that cannot build it`,
|
|
6474
6753
|
remedy: "run `mnci upgrade`"
|
|
6475
6754
|
}));
|
|
@@ -6482,7 +6761,7 @@ function checkNativeApps(workspaceRoot) {
|
|
|
6482
6761
|
return findings;
|
|
6483
6762
|
}
|
|
6484
6763
|
function checkNoRootRuntimeDependencies(workspaceRoot) {
|
|
6485
|
-
const manifestPath = (0,
|
|
6764
|
+
const manifestPath = (0, import_node_path25.join)(workspaceRoot, "package.json");
|
|
6486
6765
|
if (!fileExists(manifestPath)) {
|
|
6487
6766
|
return void 0;
|
|
6488
6767
|
}
|
|
@@ -6502,14 +6781,14 @@ function checkNoRootRuntimeDependencies(workspaceRoot) {
|
|
|
6502
6781
|
};
|
|
6503
6782
|
}
|
|
6504
6783
|
function checkRollupSourceMaps(workspaceRoot) {
|
|
6505
|
-
const configs = (0,
|
|
6784
|
+
const configs = (0, import_node_fs18.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
|
|
6506
6785
|
cwd: workspaceRoot
|
|
6507
6786
|
}).map((config) => toPosix2(config));
|
|
6508
6787
|
return configs.flatMap((relativePath) => {
|
|
6509
|
-
const configPath = (0,
|
|
6788
|
+
const configPath = (0, import_node_path25.join)(workspaceRoot, relativePath);
|
|
6510
6789
|
let config;
|
|
6511
6790
|
try {
|
|
6512
|
-
config = (0,
|
|
6791
|
+
config = (0, import_node_fs18.readFileSync)(configPath, "utf8");
|
|
6513
6792
|
} catch {
|
|
6514
6793
|
return [];
|
|
6515
6794
|
}
|
|
@@ -6524,11 +6803,11 @@ function checkRollupSourceMaps(workspaceRoot) {
|
|
|
6524
6803
|
});
|
|
6525
6804
|
}
|
|
6526
6805
|
function checkDeclarationSpecifiers(workspaceRoot) {
|
|
6527
|
-
const configs = (0,
|
|
6806
|
+
const configs = (0, import_node_fs18.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
|
|
6528
6807
|
cwd: workspaceRoot
|
|
6529
6808
|
}).map((config) => toPosix2(config));
|
|
6530
6809
|
return configs.flatMap((relativePath) => {
|
|
6531
|
-
const configPath = (0,
|
|
6810
|
+
const configPath = (0, import_node_path25.join)(workspaceRoot, relativePath);
|
|
6532
6811
|
if (!fileExists(configPath)) {
|
|
6533
6812
|
return [];
|
|
6534
6813
|
}
|
|
@@ -6562,7 +6841,7 @@ function checkDeclarationSpecifiers(workspaceRoot) {
|
|
|
6562
6841
|
});
|
|
6563
6842
|
}
|
|
6564
6843
|
function collectFindings(workspaceRoot) {
|
|
6565
|
-
const nxJsonPath = (0,
|
|
6844
|
+
const nxJsonPath = (0, import_node_path25.join)(workspaceRoot, "nx.json");
|
|
6566
6845
|
if (!fileExists(nxJsonPath)) {
|
|
6567
6846
|
throw new Error(
|
|
6568
6847
|
`No nx.json found in ${workspaceRoot} \u2014 run 'mnci doctor' from the workspace root.`
|
|
@@ -6584,6 +6863,7 @@ function collectFindings(workspaceRoot) {
|
|
|
6584
6863
|
...checkTargetFilesExist(workspaceRoot),
|
|
6585
6864
|
checkSync(workspaceRoot),
|
|
6586
6865
|
checkGoPluginRegistered(workspaceRoot),
|
|
6866
|
+
checkGoWorkInSync(workspaceRoot),
|
|
6587
6867
|
...checkNativeApps(workspaceRoot)
|
|
6588
6868
|
].filter((finding) => finding !== void 0);
|
|
6589
6869
|
}
|
|
@@ -6609,8 +6889,8 @@ function runDoctor(workspaceRoot) {
|
|
|
6609
6889
|
}
|
|
6610
6890
|
|
|
6611
6891
|
// src/workspace-creation/adopt-directory.use-case.ts
|
|
6612
|
-
var
|
|
6613
|
-
var
|
|
6892
|
+
var import_node_fs19 = require("fs");
|
|
6893
|
+
var import_node_path26 = require("path");
|
|
6614
6894
|
var NEVER_COPIED = /* @__PURE__ */ new Set([".git", "node_modules"]);
|
|
6615
6895
|
var AGENT_AND_CI_ENTRIES = [
|
|
6616
6896
|
"AGENTS.md",
|
|
@@ -6641,13 +6921,13 @@ var PREFLIGHT_BLOCKERS = [
|
|
|
6641
6921
|
"packages"
|
|
6642
6922
|
];
|
|
6643
6923
|
function assertAdoptableDirectory(target) {
|
|
6644
|
-
if (!(0,
|
|
6924
|
+
if (!(0, import_node_fs19.existsSync)(target)) {
|
|
6645
6925
|
throw new Error(`--into '${target}' does not exist. Create or clone it first.`);
|
|
6646
6926
|
}
|
|
6647
|
-
if (!(0,
|
|
6927
|
+
if (!(0, import_node_fs19.statSync)(target).isDirectory()) {
|
|
6648
6928
|
throw new Error(`--into '${target}' is not a directory.`);
|
|
6649
6929
|
}
|
|
6650
|
-
const blockers = PREFLIGHT_BLOCKERS.filter((entry) => (0,
|
|
6930
|
+
const blockers = PREFLIGHT_BLOCKERS.filter((entry) => (0, import_node_fs19.existsSync)((0, import_node_path26.join)(target, entry)));
|
|
6651
6931
|
if (blockers.length > 0) {
|
|
6652
6932
|
throw new Error(
|
|
6653
6933
|
`--into '${target}' already holds ${blockers.join(", ")}, so it is a project already. Use \`mnci upgrade\` to re-apply the overlay to an existing workspace, or point --into at an empty checkout.`
|
|
@@ -6655,15 +6935,15 @@ function assertAdoptableDirectory(target) {
|
|
|
6655
6935
|
}
|
|
6656
6936
|
}
|
|
6657
6937
|
function mergeGitignore(generatedFile, targetFile) {
|
|
6658
|
-
const existing = (0,
|
|
6938
|
+
const existing = (0, import_node_fs19.readFileSync)(targetFile, "utf8");
|
|
6659
6939
|
const present = new Set(existing.split("\n").map((line) => line.trim()));
|
|
6660
|
-
const additions = (0,
|
|
6940
|
+
const additions = (0, import_node_fs19.readFileSync)(generatedFile, "utf8").split("\n").map((line) => line.trimEnd()).filter((line) => {
|
|
6661
6941
|
const trimmed = line.trim();
|
|
6662
6942
|
return trimmed !== "" && !trimmed.startsWith("#") && !present.has(trimmed);
|
|
6663
6943
|
});
|
|
6664
6944
|
if (additions.length === 0) return false;
|
|
6665
6945
|
const separator = existing.endsWith("\n") ? "" : "\n";
|
|
6666
|
-
(0,
|
|
6946
|
+
(0, import_node_fs19.writeFileSync)(
|
|
6667
6947
|
targetFile,
|
|
6668
6948
|
`${existing}${separator}
|
|
6669
6949
|
# Added by mnci (Nx workspace)
|
|
@@ -6673,9 +6953,9 @@ ${additions.join("\n")}
|
|
|
6673
6953
|
return true;
|
|
6674
6954
|
}
|
|
6675
6955
|
function adoptGeneratedWorkspace(generatedRoot, target) {
|
|
6676
|
-
const entries = (0,
|
|
6956
|
+
const entries = (0, import_node_fs19.readdirSync)(generatedRoot).filter((entry) => !NEVER_COPIED.has(entry));
|
|
6677
6957
|
const collisions = entries.filter(
|
|
6678
|
-
(entry) => (0,
|
|
6958
|
+
(entry) => (0, import_node_fs19.existsSync)((0, import_node_path26.join)(target, entry)) && !EXISTING_WINS.has(entry) && entry !== ".gitignore"
|
|
6679
6959
|
);
|
|
6680
6960
|
if (collisions.length > 0) {
|
|
6681
6961
|
throw new Error(
|
|
@@ -6684,28 +6964,28 @@ function adoptGeneratedWorkspace(generatedRoot, target) {
|
|
|
6684
6964
|
}
|
|
6685
6965
|
const result = { copied: [], kept: [], mergedGitignore: false };
|
|
6686
6966
|
for (const entry of entries) {
|
|
6687
|
-
const from = (0,
|
|
6688
|
-
const to = (0,
|
|
6689
|
-
if (entry === ".gitignore" && (0,
|
|
6967
|
+
const from = (0, import_node_path26.join)(generatedRoot, entry);
|
|
6968
|
+
const to = (0, import_node_path26.join)(target, entry);
|
|
6969
|
+
if (entry === ".gitignore" && (0, import_node_fs19.existsSync)(to)) {
|
|
6690
6970
|
result.mergedGitignore = mergeGitignore(from, to);
|
|
6691
6971
|
result.kept.push(entry);
|
|
6692
6972
|
continue;
|
|
6693
6973
|
}
|
|
6694
|
-
if ((0,
|
|
6974
|
+
if ((0, import_node_fs19.existsSync)(to)) {
|
|
6695
6975
|
result.kept.push(entry);
|
|
6696
6976
|
continue;
|
|
6697
6977
|
}
|
|
6698
|
-
(0,
|
|
6978
|
+
(0, import_node_fs19.cpSync)(from, to, { recursive: true });
|
|
6699
6979
|
result.copied.push(entry);
|
|
6700
6980
|
}
|
|
6701
|
-
(0,
|
|
6981
|
+
(0, import_node_fs19.rmSync)(generatedRoot, { recursive: true, force: true });
|
|
6702
6982
|
return result;
|
|
6703
6983
|
}
|
|
6704
6984
|
|
|
6705
6985
|
// src/workspace-creation/create-workspace.use-case.ts
|
|
6706
|
-
var
|
|
6986
|
+
var import_node_fs20 = require("fs");
|
|
6707
6987
|
var import_node_os = require("os");
|
|
6708
|
-
var
|
|
6988
|
+
var import_node_path27 = require("path");
|
|
6709
6989
|
function nxCloudProviderValue(ci) {
|
|
6710
6990
|
return ci === "azure" ? "azure" : "github";
|
|
6711
6991
|
}
|
|
@@ -6748,9 +7028,9 @@ async function resolveRegistry(options) {
|
|
|
6748
7028
|
return await promptRegistry();
|
|
6749
7029
|
}
|
|
6750
7030
|
async function runNew(name, options) {
|
|
6751
|
-
const adoptTarget = options.into === void 0 ? void 0 : (0,
|
|
7031
|
+
const adoptTarget = options.into === void 0 ? void 0 : (0, import_node_path27.resolve)(process.cwd(), options.into);
|
|
6752
7032
|
if (adoptTarget !== void 0) assertAdoptableDirectory(adoptTarget);
|
|
6753
|
-
const workspaceName = name ?? (adoptTarget === void 0 ? await promptText("Workspace name") : (0,
|
|
7033
|
+
const workspaceName = name ?? (adoptTarget === void 0 ? await promptText("Workspace name") : (0, import_node_path27.basename)(adoptTarget));
|
|
6754
7034
|
assertValidProjectName(workspaceName, "Workspace name");
|
|
6755
7035
|
const scope = options.scope ?? (options.yes ? `@${workspaceName}` : await promptText("npm scope for publishable packages", `@${workspaceName}`));
|
|
6756
7036
|
const registry = await resolveRegistry(options);
|
|
@@ -6763,8 +7043,8 @@ async function runNew(name, options) {
|
|
|
6763
7043
|
const npmAuth = resolveNpmAuth(options.npmAuth, registry, ci);
|
|
6764
7044
|
const stack = await resolveStack(options);
|
|
6765
7045
|
const nxCloud = options.nxCloud ?? (options.yes ? false : await promptNxCloud());
|
|
6766
|
-
const stagingParent = adoptTarget === void 0 ? process.cwd() : (0,
|
|
6767
|
-
let workspaceRoot = (0,
|
|
7046
|
+
const stagingParent = adoptTarget === void 0 ? process.cwd() : (0, import_node_fs20.mkdtempSync)((0, import_node_path27.join)((0, import_node_os.tmpdir)(), "mnci-new-"));
|
|
7047
|
+
let workspaceRoot = (0, import_node_path27.join)(stagingParent, workspaceName);
|
|
6768
7048
|
try {
|
|
6769
7049
|
logger.step(`Creating Nx workspace '${workspaceName}' (preset: ts)`);
|
|
6770
7050
|
runNpx(
|
|
@@ -6787,7 +7067,7 @@ async function runNew(name, options) {
|
|
|
6787
7067
|
workspaceRoot = adoptTarget;
|
|
6788
7068
|
}
|
|
6789
7069
|
} finally {
|
|
6790
|
-
if (adoptTarget !== void 0) (0,
|
|
7070
|
+
if (adoptTarget !== void 0) (0, import_node_fs20.rmSync)(stagingParent, { recursive: true, force: true });
|
|
6791
7071
|
}
|
|
6792
7072
|
logger.step(
|
|
6793
7073
|
"Applying MoNecromanCI overlay (VS Code workspace, release config, .npmrc, commitlint, pipeline, stack)"
|
|
@@ -6797,8 +7077,8 @@ async function runNew(name, options) {
|
|
|
6797
7077
|
{ workspaceName, scope, registry, agent, variableGroup, ci, stack, ...npmAuth && { npmAuth } },
|
|
6798
7078
|
logger.detail
|
|
6799
7079
|
);
|
|
6800
|
-
(0,
|
|
6801
|
-
(0,
|
|
7080
|
+
(0, import_node_fs20.rmSync)((0, import_node_path27.join)(workspaceRoot, "node_modules"), { recursive: true, force: true });
|
|
7081
|
+
(0, import_node_fs20.rmSync)((0, import_node_path27.join)(workspaceRoot, "package-lock.json"), { force: true });
|
|
6802
7082
|
logger.step("Installing the toolchain (commitlint + husky + linting/formatting)");
|
|
6803
7083
|
const installStatus = runShell(
|
|
6804
7084
|
"npm",
|
|
@@ -6836,12 +7116,12 @@ function projectKindHintLines(kinds = PROJECT_KINDS) {
|
|
|
6836
7116
|
}
|
|
6837
7117
|
|
|
6838
7118
|
// src/workspace-creation/interactive-wizard.use-case.ts
|
|
6839
|
-
var
|
|
7119
|
+
var import_node_path29 = require("path");
|
|
6840
7120
|
var import_prompts4 = require("@inquirer/prompts");
|
|
6841
7121
|
|
|
6842
7122
|
// src/workspace-upgrade/upgrade-workspace.use-case.ts
|
|
6843
|
-
var
|
|
6844
|
-
var
|
|
7123
|
+
var import_node_fs21 = require("fs");
|
|
7124
|
+
var import_node_path28 = require("path");
|
|
6845
7125
|
function resolveRegistry2(options, persisted) {
|
|
6846
7126
|
if (options.registry === "azure-artifacts" || options.organization && options.artifactsFeed) {
|
|
6847
7127
|
const persistedAzure = persisted?.kind === "azure-artifacts" ? persisted : void 0;
|
|
@@ -6870,7 +7150,7 @@ function resolveWorkspaceName(workspaceRoot, persisted) {
|
|
|
6870
7150
|
return persisted.workspaceName;
|
|
6871
7151
|
}
|
|
6872
7152
|
try {
|
|
6873
|
-
const existing = (0,
|
|
7153
|
+
const existing = (0, import_node_fs21.readdirSync)(workspaceRoot).find(
|
|
6874
7154
|
(file) => file.endsWith(".code-workspace") && file !== "undefined.code-workspace"
|
|
6875
7155
|
);
|
|
6876
7156
|
if (existing) {
|
|
@@ -6878,11 +7158,11 @@ function resolveWorkspaceName(workspaceRoot, persisted) {
|
|
|
6878
7158
|
}
|
|
6879
7159
|
} catch {
|
|
6880
7160
|
}
|
|
6881
|
-
return (0,
|
|
7161
|
+
return (0, import_node_path28.basename)(workspaceRoot);
|
|
6882
7162
|
}
|
|
6883
7163
|
function detectNpmAuth(workspaceRoot) {
|
|
6884
7164
|
try {
|
|
6885
|
-
return (0,
|
|
7165
|
+
return (0, import_node_fs21.readFileSync)((0, import_node_path28.join)(workspaceRoot, "azure-pipelines.yml"), "utf8").includes("npmAuthenticate@0") ? "build-identity" : void 0;
|
|
6886
7166
|
} catch {
|
|
6887
7167
|
return void 0;
|
|
6888
7168
|
}
|
|
@@ -6929,7 +7209,7 @@ function resolveOverlayOptions(workspaceRoot, options, persisted) {
|
|
|
6929
7209
|
};
|
|
6930
7210
|
}
|
|
6931
7211
|
function runUpgrade(workspaceRoot, options) {
|
|
6932
|
-
if (!fileExists((0,
|
|
7212
|
+
if (!fileExists((0, import_node_path28.join)(workspaceRoot, "nx.json"))) {
|
|
6933
7213
|
throw new Error(
|
|
6934
7214
|
`No nx.json found in ${workspaceRoot} \u2014 this does not look like an Nx workspace. Run 'mnci upgrade' from the workspace root.`
|
|
6935
7215
|
);
|
|
@@ -6994,7 +7274,7 @@ function runUpgrade(workspaceRoot, options) {
|
|
|
6994
7274
|
|
|
6995
7275
|
// src/workspace-creation/interactive-wizard.use-case.ts
|
|
6996
7276
|
async function runInteractive() {
|
|
6997
|
-
const inWorkspace = fileExists((0,
|
|
7277
|
+
const inWorkspace = fileExists((0, import_node_path29.join)(process.cwd(), "nx.json"));
|
|
6998
7278
|
const choiceNew = { name: "Create a new monorepo", value: "new" };
|
|
6999
7279
|
const choiceAdd = { name: "Add a project to this workspace", value: "add" };
|
|
7000
7280
|
const choiceUpgrade = {
|
|
@@ -7015,8 +7295,8 @@ async function runInteractive() {
|
|
|
7015
7295
|
}
|
|
7016
7296
|
|
|
7017
7297
|
// src/cli-version/check-for-update.use-case.ts
|
|
7018
|
-
var
|
|
7019
|
-
var
|
|
7298
|
+
var import_node_fs22 = require("fs");
|
|
7299
|
+
var import_node_path30 = require("path");
|
|
7020
7300
|
var import_cross_spawn2 = __toESM(require("cross-spawn"));
|
|
7021
7301
|
var PACKAGE_NAME = "@mnci/cli";
|
|
7022
7302
|
var REGISTRY_TIMEOUT_MS = 2e3;
|
|
@@ -7072,8 +7352,8 @@ function releaseTriple(version) {
|
|
|
7072
7352
|
}
|
|
7073
7353
|
function readCliVersion(packageDirectory) {
|
|
7074
7354
|
try {
|
|
7075
|
-
const manifestPath = (0,
|
|
7076
|
-
const manifest = JSON.parse((0,
|
|
7355
|
+
const manifestPath = (0, import_node_path30.join)(packageDirectory, "..", "package.json");
|
|
7356
|
+
const manifest = JSON.parse((0, import_node_fs22.readFileSync)(manifestPath, "utf8"));
|
|
7077
7357
|
return manifest.version ?? "0.0.0";
|
|
7078
7358
|
} catch {
|
|
7079
7359
|
return "0.0.0";
|
|
@@ -7127,6 +7407,11 @@ function buildProgram(cliVersion) {
|
|
|
7127
7407
|
).option("--check", "report only; never prompt and never write (the default when piped)").option("-y, --yes", "select every available update without prompting").option("--ecosystem <name>", "restrict to one ecosystem: npm | pip | pub | go").option("--no-install", "update the manifests but skip the reinstall step").action(async (options) => {
|
|
7128
7408
|
await runUp(process.cwd(), options);
|
|
7129
7409
|
});
|
|
7410
|
+
program.command("install").alias("i").argument("[packages...]", "packages to add (a bare name or a pinned spec); omit to install only").description(
|
|
7411
|
+
"Add a dependency to a specific project using its own toolchain (npm/pip/pub/nuget/go), or \u2014 with no package \u2014 install everything. Each project owns its dependencies, so a package needs a target: 'mnci i -w <project> <package>'"
|
|
7412
|
+
).option("-w, --workspace <project...>", "target project, by directory (apps/foo) or basename (foo); repeatable").option("-D, --save-dev", "add as a development dependency, where the ecosystem distinguishes one").action((packages, options) => {
|
|
7413
|
+
runInstall(process.cwd(), packages, options);
|
|
7414
|
+
});
|
|
7130
7415
|
program.command("add").addArgument(new import_commander.Argument("[kind]", "project kind").choices(PROJECT_KINDS)).argument("[name]", "project name").description("Add a project by delegating to the matching Nx plugin generator").option("--scope <scope>", "npm scope for a publishable lib (defaults to @<workspace name>)").option(
|
|
7131
7416
|
"--framework <framework>",
|
|
7132
7417
|
"node-app only: express | fastify | koa | nest | none (default: none)"
|