@mnci/cli 1.9.0 → 1.10.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 +165 -24
- package/dist/cli.js +338 -83
- package/dist/cli.js.map +1 -1
- package/package.json +6 -3
package/dist/cli.js
CHANGED
|
@@ -38,7 +38,7 @@ module.exports = __toCommonJS(cli_exports);
|
|
|
38
38
|
var import_commander = require("commander");
|
|
39
39
|
|
|
40
40
|
// src/commands/add.ts
|
|
41
|
-
var
|
|
41
|
+
var import_node_path9 = require("path");
|
|
42
42
|
var import_prompts4 = require("@inquirer/prompts");
|
|
43
43
|
|
|
44
44
|
// src/nx.ts
|
|
@@ -164,11 +164,11 @@ function assertValidProjectName(name, label) {
|
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
-
// src/commands/add/
|
|
168
|
-
var import_node_fs2 = require("fs");
|
|
167
|
+
// src/commands/add/flutter.ts
|
|
169
168
|
var import_node_path3 = require("path");
|
|
170
169
|
|
|
171
170
|
// src/commands/add/shared.ts
|
|
171
|
+
var import_node_fs2 = require("fs");
|
|
172
172
|
var import_node_path2 = require("path");
|
|
173
173
|
function hasPlugin(workspaceRoot, packageName) {
|
|
174
174
|
const manifest = readJson((0, import_node_path2.join)(workspaceRoot, "package.json"));
|
|
@@ -202,8 +202,126 @@ function addNxTargets(manifestPath, newTargets) {
|
|
|
202
202
|
toJson({ ...manifest, nx: { ...nx, targets: { ...targets, ...newTargets } } })
|
|
203
203
|
);
|
|
204
204
|
}
|
|
205
|
+
function findCodeWorkspaceFile(workspaceRoot) {
|
|
206
|
+
try {
|
|
207
|
+
const entry = (0, import_node_fs2.readdirSync)(workspaceRoot).find((file) => file.endsWith(".code-workspace"));
|
|
208
|
+
return entry ? (0, import_node_path2.join)(workspaceRoot, entry) : void 0;
|
|
209
|
+
} catch {
|
|
210
|
+
return void 0;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
function readCodeWorkspaceFile(path) {
|
|
214
|
+
const contents = (0, import_node_fs2.readFileSync)(path, "utf8").replaceAll(/,(\s*[}\]])/g, "$1");
|
|
215
|
+
return JSON.parse(contents);
|
|
216
|
+
}
|
|
217
|
+
function projectTask(name, kind) {
|
|
218
|
+
const script = `${name}:${kind}`;
|
|
219
|
+
const base = { label: `${name}: ${kind}`, type: "npm", script, problemMatcher: [] };
|
|
220
|
+
return kind === "start" ? { ...base, isBackground: true } : { ...base, group: kind };
|
|
221
|
+
}
|
|
222
|
+
function registerProjectCommands(workspaceRoot, name, commands) {
|
|
223
|
+
const scripts = {
|
|
224
|
+
[`${name}:qa`]: `nx run ${name}:lint && nx run ${name}:test`
|
|
225
|
+
};
|
|
226
|
+
if (commands.build) {
|
|
227
|
+
scripts[`${name}:build`] = `nx run ${name}:build`;
|
|
228
|
+
}
|
|
229
|
+
if (commands.start) {
|
|
230
|
+
scripts[`${name}:start`] = commands.start;
|
|
231
|
+
}
|
|
232
|
+
const manifestPath = (0, import_node_path2.join)(workspaceRoot, "package.json");
|
|
233
|
+
const manifest = readJson(manifestPath);
|
|
234
|
+
const existingScripts = manifest.scripts ?? {};
|
|
235
|
+
writeFileEnsured(
|
|
236
|
+
manifestPath,
|
|
237
|
+
toJson({ ...manifest, scripts: { ...existingScripts, ...scripts } })
|
|
238
|
+
);
|
|
239
|
+
const codeWorkspacePath = findCodeWorkspaceFile(workspaceRoot);
|
|
240
|
+
if (!codeWorkspacePath) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
const workspaceFile = readCodeWorkspaceFile(codeWorkspacePath);
|
|
244
|
+
const label = (task) => task.label ?? "";
|
|
245
|
+
const existingTasks = (workspaceFile.tasks?.tasks ?? []).filter(
|
|
246
|
+
(task) => !label(task).startsWith(`${name}: `)
|
|
247
|
+
);
|
|
248
|
+
const newTasks = [
|
|
249
|
+
projectTask(name, "qa"),
|
|
250
|
+
...commands.build ? [projectTask(name, "build")] : [],
|
|
251
|
+
...commands.start ? [projectTask(name, "start")] : []
|
|
252
|
+
];
|
|
253
|
+
writeFileEnsured(
|
|
254
|
+
codeWorkspacePath,
|
|
255
|
+
toJson({
|
|
256
|
+
...workspaceFile,
|
|
257
|
+
tasks: {
|
|
258
|
+
version: workspaceFile.tasks?.version ?? "2.0.0",
|
|
259
|
+
tasks: [...existingTasks, ...newTasks]
|
|
260
|
+
}
|
|
261
|
+
})
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// src/commands/add/flutter.ts
|
|
266
|
+
function addProjectJsonTargets(projectJsonPath, newTargets) {
|
|
267
|
+
const project = readJson(projectJsonPath);
|
|
268
|
+
const targets = project.targets ?? {};
|
|
269
|
+
writeFileEnsured(projectJsonPath, toJson({ ...project, targets: { ...targets, ...newTargets } }));
|
|
270
|
+
}
|
|
271
|
+
function flutterAppStartTarget(name) {
|
|
272
|
+
return {
|
|
273
|
+
executor: "nx:run-commands",
|
|
274
|
+
continuous: true,
|
|
275
|
+
options: { command: "flutter run -d chrome", cwd: `apps/${name}` }
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
function ensureFlutter(workspaceRoot) {
|
|
279
|
+
if (runShell("flutter", ["--version"], workspaceRoot) !== 0) {
|
|
280
|
+
throw new Error(
|
|
281
|
+
"Flutter not found. Install the Flutter SDK first (3.27+, for Dart 3.6+ pub workspaces): https://docs.flutter.dev/get-started/install"
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
function nxFlutterPluginSpec() {
|
|
286
|
+
return process.env.MNCI_NX_FLUTTER_SPEC ?? "@mnci/nx-flutter";
|
|
287
|
+
}
|
|
288
|
+
function ensureNxFlutterPlugin(workspaceRoot) {
|
|
289
|
+
if (hasPlugin(workspaceRoot, "@mnci/nx-flutter")) {
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
const spec = nxFlutterPluginSpec();
|
|
293
|
+
logger.step(`Installing the Flutter toolchain plugin (${spec})`);
|
|
294
|
+
if (runShell("npm", ["install", "--save-dev", spec, "--no-audit", "--no-fund"], workspaceRoot) !== 0) {
|
|
295
|
+
throw new Error("npm install of @mnci/nx-flutter failed");
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
function prepareFlutter(workspaceRoot) {
|
|
299
|
+
ensureFlutter(workspaceRoot);
|
|
300
|
+
ensureNxFlutterPlugin(workspaceRoot);
|
|
301
|
+
}
|
|
302
|
+
function addFlutterApp(workspaceRoot, name) {
|
|
303
|
+
prepareFlutter(workspaceRoot);
|
|
304
|
+
ensureAdmZip(workspaceRoot);
|
|
305
|
+
runNx(["g", "@mnci/nx-flutter:application", name, "--no-interactive"], workspaceRoot);
|
|
306
|
+
addProjectJsonTargets((0, import_node_path3.join)(workspaceRoot, "apps", name, "project.json"), {
|
|
307
|
+
start: flutterAppStartTarget(name)
|
|
308
|
+
});
|
|
309
|
+
registerProjectCommands(workspaceRoot, name, { build: true, start: `nx run ${name}:start` });
|
|
310
|
+
}
|
|
311
|
+
function addFlutterLib(workspaceRoot, name) {
|
|
312
|
+
prepareFlutter(workspaceRoot);
|
|
313
|
+
runNx(["g", "@mnci/nx-flutter:library", name, "--no-interactive"], workspaceRoot);
|
|
314
|
+
registerProjectCommands(workspaceRoot, name, { build: false });
|
|
315
|
+
}
|
|
316
|
+
function addFlutterInternalLib(workspaceRoot, name) {
|
|
317
|
+
prepareFlutter(workspaceRoot);
|
|
318
|
+
runNx(["g", "@mnci/nx-flutter:internal-library", name, "--no-interactive"], workspaceRoot);
|
|
319
|
+
registerProjectCommands(workspaceRoot, name, { build: false });
|
|
320
|
+
}
|
|
205
321
|
|
|
206
322
|
// src/commands/add/go.ts
|
|
323
|
+
var import_node_fs3 = require("fs");
|
|
324
|
+
var import_node_path4 = require("path");
|
|
207
325
|
function ensureGo(workspaceRoot) {
|
|
208
326
|
if (runShell("go", ["version"], workspaceRoot) !== 0) {
|
|
209
327
|
throw new Error("Go not found. Install Go 1.21+ first: https://go.dev/dl/");
|
|
@@ -230,7 +348,7 @@ function ensureNxGoPlugin(workspaceRoot) {
|
|
|
230
348
|
}
|
|
231
349
|
}
|
|
232
350
|
function ensureGoModule(workspaceRoot) {
|
|
233
|
-
if (fileExists((0,
|
|
351
|
+
if (fileExists((0, import_node_path4.join)(workspaceRoot, "go.mod"))) {
|
|
234
352
|
return;
|
|
235
353
|
}
|
|
236
354
|
logger.step("Bootstrapping the workspace Go module (single root go.mod)");
|
|
@@ -239,13 +357,13 @@ function ensureGoModule(workspaceRoot) {
|
|
|
239
357
|
}
|
|
240
358
|
function goModulePath(workspaceRoot) {
|
|
241
359
|
try {
|
|
242
|
-
const contents = (0,
|
|
360
|
+
const contents = (0, import_node_fs3.readFileSync)((0, import_node_path4.join)(workspaceRoot, "go.mod"), "utf8");
|
|
243
361
|
return /^module\s+(\S+)/m.exec(contents)?.[1];
|
|
244
362
|
} catch {
|
|
245
363
|
return void 0;
|
|
246
364
|
}
|
|
247
365
|
}
|
|
248
|
-
function
|
|
366
|
+
function addProjectJsonTargets2(projectJsonPath, newTargets) {
|
|
249
367
|
const project = readJson(projectJsonPath);
|
|
250
368
|
const targets = project.targets ?? {};
|
|
251
369
|
writeFileEnsured(projectJsonPath, toJson({ ...project, targets: { ...targets, ...newTargets } }));
|
|
@@ -275,6 +393,13 @@ function goPackageTarget(tag, name) {
|
|
|
275
393
|
options: { command }
|
|
276
394
|
};
|
|
277
395
|
}
|
|
396
|
+
function goStartTarget(name) {
|
|
397
|
+
return {
|
|
398
|
+
executor: "nx:run-commands",
|
|
399
|
+
continuous: true,
|
|
400
|
+
options: { command: "go run .", cwd: `apps/${name}` }
|
|
401
|
+
};
|
|
402
|
+
}
|
|
278
403
|
function prepareGo(workspaceRoot) {
|
|
279
404
|
ensureGo(workspaceRoot);
|
|
280
405
|
warnIfNoGolangciLint(workspaceRoot);
|
|
@@ -295,12 +420,14 @@ function addGoApp(workspaceRoot, name) {
|
|
|
295
420
|
],
|
|
296
421
|
workspaceRoot
|
|
297
422
|
);
|
|
298
|
-
|
|
423
|
+
addProjectJsonTargets2((0, import_node_path4.join)(workspaceRoot, "apps", name, "project.json"), {
|
|
299
424
|
build: goBuildTarget(name),
|
|
300
425
|
test: goTestTarget(),
|
|
301
426
|
lint: goLintTarget(),
|
|
302
|
-
package: goPackageTarget("go-app", name)
|
|
427
|
+
package: goPackageTarget("go-app", name),
|
|
428
|
+
start: goStartTarget(name)
|
|
303
429
|
});
|
|
430
|
+
registerProjectCommands(workspaceRoot, name, { build: true, start: `nx run ${name}:start` });
|
|
304
431
|
}
|
|
305
432
|
function addGoFunctionApp(workspaceRoot, name) {
|
|
306
433
|
prepareGo(workspaceRoot);
|
|
@@ -316,12 +443,13 @@ function addGoFunctionApp(workspaceRoot, name) {
|
|
|
316
443
|
],
|
|
317
444
|
workspaceRoot
|
|
318
445
|
);
|
|
319
|
-
|
|
446
|
+
addProjectJsonTargets2((0, import_node_path4.join)(workspaceRoot, "apps", name, "project.json"), {
|
|
320
447
|
build: goBuildTarget(name),
|
|
321
448
|
test: goTestTarget(),
|
|
322
449
|
lint: goLintTarget(),
|
|
323
450
|
package: goPackageTarget("go-function-app", name)
|
|
324
451
|
});
|
|
452
|
+
registerProjectCommands(workspaceRoot, name, { build: true });
|
|
325
453
|
}
|
|
326
454
|
function addGoLib(workspaceRoot, name) {
|
|
327
455
|
prepareGo(workspaceRoot);
|
|
@@ -336,10 +464,11 @@ function addGoLib(workspaceRoot, name) {
|
|
|
336
464
|
],
|
|
337
465
|
workspaceRoot
|
|
338
466
|
);
|
|
339
|
-
|
|
467
|
+
addProjectJsonTargets2((0, import_node_path4.join)(workspaceRoot, "packages", name, "project.json"), {
|
|
340
468
|
test: goTestTarget(),
|
|
341
469
|
lint: goLintTarget()
|
|
342
470
|
});
|
|
471
|
+
registerProjectCommands(workspaceRoot, name, { build: false });
|
|
343
472
|
const module2 = goModulePath(workspaceRoot);
|
|
344
473
|
if (module2) {
|
|
345
474
|
logger.step(`Import it as ${module2}/packages/${name}`);
|
|
@@ -358,10 +487,11 @@ function addGoInternalLib(workspaceRoot, name) {
|
|
|
358
487
|
],
|
|
359
488
|
workspaceRoot
|
|
360
489
|
);
|
|
361
|
-
|
|
490
|
+
addProjectJsonTargets2((0, import_node_path4.join)(workspaceRoot, "libs", name, "project.json"), {
|
|
362
491
|
test: goTestTarget(),
|
|
363
492
|
lint: goLintTarget()
|
|
364
493
|
});
|
|
494
|
+
registerProjectCommands(workspaceRoot, name, { build: false });
|
|
365
495
|
const module2 = goModulePath(workspaceRoot);
|
|
366
496
|
if (module2) {
|
|
367
497
|
logger.step(`Import it as ${module2}/libs/${name}`);
|
|
@@ -369,7 +499,7 @@ function addGoInternalLib(workspaceRoot, name) {
|
|
|
369
499
|
}
|
|
370
500
|
|
|
371
501
|
// src/commands/add/node.ts
|
|
372
|
-
var
|
|
502
|
+
var import_node_path5 = require("path");
|
|
373
503
|
function ensurePlugin(workspaceRoot, packageName) {
|
|
374
504
|
if (hasPlugin(workspaceRoot, packageName)) {
|
|
375
505
|
return;
|
|
@@ -408,9 +538,10 @@ function nodeAppPackageTarget(name) {
|
|
|
408
538
|
function addNodeApp(workspaceRoot, name, stack, framework = "none") {
|
|
409
539
|
runNodeApp(workspaceRoot, name, stack, framework);
|
|
410
540
|
ensureAdmZip(workspaceRoot);
|
|
411
|
-
addNxTargets((0,
|
|
541
|
+
addNxTargets((0, import_node_path5.join)(workspaceRoot, "apps", name, "package.json"), {
|
|
412
542
|
package: nodeAppPackageTarget(name)
|
|
413
543
|
});
|
|
544
|
+
registerProjectCommands(workspaceRoot, name, { build: true, start: `nx run ${name}:serve` });
|
|
414
545
|
}
|
|
415
546
|
function ensureAzureFunctionsPackage(workspaceRoot) {
|
|
416
547
|
if (hasPlugin(workspaceRoot, "@azure/functions")) {
|
|
@@ -461,17 +592,17 @@ describe('buildGreeting', () => {
|
|
|
461
592
|
})
|
|
462
593
|
`;
|
|
463
594
|
function repairNodeFunctionAppManifest(nodeFunctionAppRoot, workspaceRoot) {
|
|
464
|
-
const manifestPath = (0,
|
|
595
|
+
const manifestPath = (0, import_node_path5.join)(nodeFunctionAppRoot, "package.json");
|
|
465
596
|
const manifest = readJson(manifestPath);
|
|
466
597
|
const azureFunctionsVersion = readJson(
|
|
467
|
-
(0,
|
|
598
|
+
(0, import_node_path5.join)(workspaceRoot, "node_modules/@azure/functions/package.json")
|
|
468
599
|
).version;
|
|
469
600
|
const dependencies = manifest.dependencies ?? {};
|
|
470
601
|
writeFileEnsured(
|
|
471
602
|
manifestPath,
|
|
472
603
|
toJson({
|
|
473
604
|
...manifest,
|
|
474
|
-
main: "main.js",
|
|
605
|
+
main: "dist/main.js",
|
|
475
606
|
dependencies: { ...dependencies, "@azure/functions": `^${azureFunctionsVersion}` }
|
|
476
607
|
})
|
|
477
608
|
);
|
|
@@ -479,7 +610,7 @@ function repairNodeFunctionAppManifest(nodeFunctionAppRoot, workspaceRoot) {
|
|
|
479
610
|
function nodeFunctionAppPackageTarget(name) {
|
|
480
611
|
const zip = `dist/drop/node-function-app-${name}.zip`;
|
|
481
612
|
const root = `apps/${name}`;
|
|
482
|
-
const command = `node -e "const fs=require('node:fs');fs.mkdirSync('dist/drop',{recursive:true});const A=require('adm-zip');const z=new A();z.addLocalFolder('${root}/dist');z.addLocalFile('${root}/host.json');z.addLocalFile('${root}/package.json');z.writeZip('${zip}')"`;
|
|
613
|
+
const command = `node -e "const fs=require('node:fs');fs.mkdirSync('dist/drop',{recursive:true});const A=require('adm-zip');const z=new A();z.addLocalFolder('${root}/dist','dist');z.addLocalFile('${root}/host.json');z.addLocalFile('${root}/package.json');z.writeZip('${zip}')"`;
|
|
483
614
|
return {
|
|
484
615
|
executor: "nx:run-commands",
|
|
485
616
|
dependsOn: ["build"],
|
|
@@ -488,30 +619,40 @@ function nodeFunctionAppPackageTarget(name) {
|
|
|
488
619
|
options: { command }
|
|
489
620
|
};
|
|
490
621
|
}
|
|
622
|
+
function nodeFunctionAppStartTarget(name) {
|
|
623
|
+
return {
|
|
624
|
+
executor: "nx:run-commands",
|
|
625
|
+
dependsOn: ["build"],
|
|
626
|
+
continuous: true,
|
|
627
|
+
options: { command: "func start", cwd: `apps/${name}` }
|
|
628
|
+
};
|
|
629
|
+
}
|
|
491
630
|
function addNodeFunctionApp(workspaceRoot, name, stack) {
|
|
492
631
|
runNodeApp(workspaceRoot, name, stack, "none");
|
|
493
632
|
ensureAzureFunctionsPackage(workspaceRoot);
|
|
494
|
-
const nodeFunctionAppRoot = (0,
|
|
495
|
-
writeFileEnsured((0,
|
|
496
|
-
writeFileEnsured((0,
|
|
633
|
+
const nodeFunctionAppRoot = (0, import_node_path5.join)(workspaceRoot, "apps", name);
|
|
634
|
+
writeFileEnsured((0, import_node_path5.join)(nodeFunctionAppRoot, "src/main.ts"), NODE_FUNCTION_APP_MAIN);
|
|
635
|
+
writeFileEnsured((0, import_node_path5.join)(nodeFunctionAppRoot, "src/functions/hello.ts"), NODE_FUNCTION_APP_HELLO);
|
|
497
636
|
writeFileEnsured(
|
|
498
|
-
(0,
|
|
637
|
+
(0, import_node_path5.join)(nodeFunctionAppRoot, "src/functions/greeting.ts"),
|
|
499
638
|
NODE_FUNCTION_APP_GREETING
|
|
500
639
|
);
|
|
501
640
|
writeFileEnsured(
|
|
502
|
-
(0,
|
|
641
|
+
(0, import_node_path5.join)(nodeFunctionAppRoot, "src/functions/greeting.spec.ts"),
|
|
503
642
|
NODE_FUNCTION_APP_GREETING_SPEC
|
|
504
643
|
);
|
|
505
|
-
writeFileEnsured((0,
|
|
644
|
+
writeFileEnsured((0, import_node_path5.join)(nodeFunctionAppRoot, "host.json"), NODE_FUNCTION_APP_HOST_JSON);
|
|
506
645
|
repairNodeFunctionAppManifest(nodeFunctionAppRoot, workspaceRoot);
|
|
507
646
|
ensureAdmZip(workspaceRoot);
|
|
508
|
-
addNxTargets((0,
|
|
509
|
-
package: nodeFunctionAppPackageTarget(name)
|
|
647
|
+
addNxTargets((0, import_node_path5.join)(nodeFunctionAppRoot, "package.json"), {
|
|
648
|
+
package: nodeFunctionAppPackageTarget(name),
|
|
649
|
+
start: nodeFunctionAppStartTarget(name)
|
|
510
650
|
});
|
|
651
|
+
registerProjectCommands(workspaceRoot, name, { build: true, start: `nx run ${name}:start` });
|
|
511
652
|
}
|
|
512
653
|
|
|
513
654
|
// src/commands/add/npmLib.ts
|
|
514
|
-
var
|
|
655
|
+
var import_node_path6 = require("path");
|
|
515
656
|
var NPM_LIB_ESLINT_CONFIG = `import { globSync, readFileSync } from 'node:fs';
|
|
516
657
|
import { dirname, join } from 'node:path';
|
|
517
658
|
import { fileURLToPath } from 'node:url';
|
|
@@ -539,6 +680,17 @@ export default [
|
|
|
539
680
|
ignoredFiles: [
|
|
540
681
|
'{projectRoot}/eslint.config.{js,cjs,mjs,ts,cts,mts}',
|
|
541
682
|
'{projectRoot}/rollup.config.{js,ts,mjs,mts,cjs,cts}',
|
|
683
|
+
// Same reasoning as the two config files above, extended to the test
|
|
684
|
+
// toolchain: rollup bundles from the entry point only, so neither the
|
|
685
|
+
// Vitest config nor the spec files reach the published package \u2014 their
|
|
686
|
+
// imports must not drive the published manifest.
|
|
687
|
+
//
|
|
688
|
+
// Without this, a vitest-stack workspace fails \`npm run lint\` on a
|
|
689
|
+
// freshly generated npm-lib: Nx's own spec imports \`vitest\`, and
|
|
690
|
+
// @nx/dependency-checks then demands it be declared as a runtime
|
|
691
|
+
// dependency of a package that never uses it at runtime.
|
|
692
|
+
'{projectRoot}/vitest.config.{js,ts,mjs,mts,cjs,cts}',
|
|
693
|
+
'{projectRoot}/**/*.spec.{js,ts,jsx,tsx}',
|
|
542
694
|
],
|
|
543
695
|
},
|
|
544
696
|
],
|
|
@@ -568,11 +720,12 @@ async function addNpmLib(workspaceRoot, name, options, kindProvided, stack) {
|
|
|
568
720
|
],
|
|
569
721
|
workspaceRoot
|
|
570
722
|
);
|
|
571
|
-
markPublic((0,
|
|
723
|
+
markPublic((0, import_node_path6.join)(workspaceRoot, "packages", name, "package.json"));
|
|
572
724
|
writeFileEnsured(
|
|
573
|
-
(0,
|
|
725
|
+
(0, import_node_path6.join)(workspaceRoot, "packages", name, "eslint.config.mjs"),
|
|
574
726
|
NPM_LIB_ESLINT_CONFIG
|
|
575
727
|
);
|
|
728
|
+
registerProjectCommands(workspaceRoot, name, { build: true });
|
|
576
729
|
}
|
|
577
730
|
function markPublic(manifestPath) {
|
|
578
731
|
const manifest = readJson(manifestPath);
|
|
@@ -580,8 +733,8 @@ function markPublic(manifestPath) {
|
|
|
580
733
|
}
|
|
581
734
|
|
|
582
735
|
// src/commands/add/python.ts
|
|
583
|
-
var
|
|
584
|
-
var
|
|
736
|
+
var import_node_fs4 = require("fs");
|
|
737
|
+
var import_node_path7 = require("path");
|
|
585
738
|
function ensurePython(workspaceRoot) {
|
|
586
739
|
const hasPython = runShell("python3", ["--version"], workspaceRoot) === 0 || runShell("python", ["--version"], workspaceRoot) === 0;
|
|
587
740
|
if (!hasPython) {
|
|
@@ -610,7 +763,7 @@ pytest
|
|
|
610
763
|
pip-audit
|
|
611
764
|
`;
|
|
612
765
|
function ensureRequirementsDev(workspaceRoot) {
|
|
613
|
-
const requirementsDevPath = (0,
|
|
766
|
+
const requirementsDevPath = (0, import_node_path7.join)(workspaceRoot, "requirements-dev.txt");
|
|
614
767
|
if (!fileExists(requirementsDevPath)) {
|
|
615
768
|
writeFileEnsured(requirementsDevPath, PYTHON_REQUIREMENTS_DEV);
|
|
616
769
|
}
|
|
@@ -618,11 +771,34 @@ function ensureRequirementsDev(workspaceRoot) {
|
|
|
618
771
|
function pythonModuleDirectory(name) {
|
|
619
772
|
return name.replaceAll("-", "_");
|
|
620
773
|
}
|
|
621
|
-
function
|
|
774
|
+
function addProjectJsonTargets3(projectJsonPath, newTargets) {
|
|
622
775
|
const project = readJson(projectJsonPath);
|
|
623
776
|
const targets = project.targets ?? {};
|
|
624
777
|
writeFileEnsured(projectJsonPath, toJson({ ...project, targets: { ...targets, ...newTargets } }));
|
|
625
778
|
}
|
|
779
|
+
function pythonAppMain(name) {
|
|
780
|
+
return `def main() -> None:
|
|
781
|
+
print('${name} is running')
|
|
782
|
+
|
|
783
|
+
|
|
784
|
+
if __name__ == '__main__':
|
|
785
|
+
main()
|
|
786
|
+
`;
|
|
787
|
+
}
|
|
788
|
+
function pythonAppStartTarget(name) {
|
|
789
|
+
return {
|
|
790
|
+
executor: "nx:run-commands",
|
|
791
|
+
continuous: true,
|
|
792
|
+
options: { command: "python3 main.py", cwd: `apps/${name}` }
|
|
793
|
+
};
|
|
794
|
+
}
|
|
795
|
+
function pythonFunctionAppStartTarget(name) {
|
|
796
|
+
return {
|
|
797
|
+
executor: "nx:run-commands",
|
|
798
|
+
continuous: true,
|
|
799
|
+
options: { command: "func start", cwd: `apps/${name}` }
|
|
800
|
+
};
|
|
801
|
+
}
|
|
626
802
|
function pythonAppPackageTarget(name) {
|
|
627
803
|
const zip = `dist/drop/python-app-${name}.zip`;
|
|
628
804
|
const command = `node -e "const fs=require('node:fs');fs.mkdirSync('dist/drop',{recursive:true});const A=require('adm-zip');const z=new A();z.addLocalFolder('apps/${name}/dist');z.writeZip('${zip}')"`;
|
|
@@ -654,9 +830,12 @@ function addPythonApp(workspaceRoot, name) {
|
|
|
654
830
|
["g", "@mnci/nx-python-pip:application", name, `--directory=apps/${name}`, "--no-interactive"],
|
|
655
831
|
workspaceRoot
|
|
656
832
|
);
|
|
657
|
-
|
|
658
|
-
|
|
833
|
+
writeFileEnsured((0, import_node_path7.join)(workspaceRoot, "apps", name, "main.py"), pythonAppMain(name));
|
|
834
|
+
addProjectJsonTargets3((0, import_node_path7.join)(workspaceRoot, "apps", name, "project.json"), {
|
|
835
|
+
package: pythonAppPackageTarget(name),
|
|
836
|
+
start: pythonAppStartTarget(name)
|
|
659
837
|
});
|
|
838
|
+
registerProjectCommands(workspaceRoot, name, { build: true, start: `nx run ${name}:start` });
|
|
660
839
|
}
|
|
661
840
|
function addPythonFunctionApp(workspaceRoot, name) {
|
|
662
841
|
ensurePython(workspaceRoot);
|
|
@@ -674,9 +853,11 @@ function addPythonFunctionApp(workspaceRoot, name) {
|
|
|
674
853
|
workspaceRoot
|
|
675
854
|
);
|
|
676
855
|
const moduleDirectory = pythonModuleDirectory(name);
|
|
677
|
-
|
|
678
|
-
package: pythonFunctionAppPackageTarget(name, moduleDirectory)
|
|
856
|
+
addProjectJsonTargets3((0, import_node_path7.join)(workspaceRoot, "apps", name, "project.json"), {
|
|
857
|
+
package: pythonFunctionAppPackageTarget(name, moduleDirectory),
|
|
858
|
+
start: pythonFunctionAppStartTarget(name)
|
|
679
859
|
});
|
|
860
|
+
registerProjectCommands(workspaceRoot, name, { build: false, start: `nx run ${name}:start` });
|
|
680
861
|
}
|
|
681
862
|
function addPythonLib(workspaceRoot, name) {
|
|
682
863
|
ensurePython(workspaceRoot);
|
|
@@ -692,6 +873,7 @@ function addPythonLib(workspaceRoot, name) {
|
|
|
692
873
|
],
|
|
693
874
|
workspaceRoot
|
|
694
875
|
);
|
|
876
|
+
registerProjectCommands(workspaceRoot, name, { build: true });
|
|
695
877
|
}
|
|
696
878
|
function addPythonInternalLib(workspaceRoot, name) {
|
|
697
879
|
ensurePython(workspaceRoot);
|
|
@@ -707,11 +889,12 @@ function addPythonInternalLib(workspaceRoot, name) {
|
|
|
707
889
|
],
|
|
708
890
|
workspaceRoot
|
|
709
891
|
);
|
|
892
|
+
registerProjectCommands(workspaceRoot, name, { build: false });
|
|
710
893
|
}
|
|
711
894
|
var PYTHON_PROJECT_DIRS = ["apps", "python-packages", "libs"];
|
|
712
895
|
function findPythonProjectDirectory(workspaceRoot, name) {
|
|
713
896
|
return PYTHON_PROJECT_DIRS.find(
|
|
714
|
-
(directory) => fileExists((0,
|
|
897
|
+
(directory) => fileExists((0, import_node_path7.join)(workspaceRoot, directory, name, "pyproject.toml"))
|
|
715
898
|
);
|
|
716
899
|
}
|
|
717
900
|
function parseVendorEntries(pyprojectToml) {
|
|
@@ -750,7 +933,7 @@ async function addPythonVendor(workspaceRoot, consumer, options, kindProvided) {
|
|
|
750
933
|
`No Python project named '${consumer}' with a pyproject.toml found (checked apps/, python-packages/, libs/). A Python function app has no pyproject.toml \u2014 there is nothing to vendor into.`
|
|
751
934
|
);
|
|
752
935
|
}
|
|
753
|
-
if (!fileExists((0,
|
|
936
|
+
if (!fileExists((0, import_node_path7.join)(workspaceRoot, "libs", lib, "pyproject.toml"))) {
|
|
754
937
|
throw new Error(
|
|
755
938
|
`No internal Python library named '${lib}' found at libs/${lib}/pyproject.toml. Only an internal library (added via 'mnci add python-internal-lib') can be vendored.`
|
|
756
939
|
);
|
|
@@ -758,8 +941,8 @@ async function addPythonVendor(workspaceRoot, consumer, options, kindProvided) {
|
|
|
758
941
|
if (consumerDirectory === "libs" && consumer === lib) {
|
|
759
942
|
throw new Error(`'${consumer}' cannot vendor itself.`);
|
|
760
943
|
}
|
|
761
|
-
const pyprojectPath = (0,
|
|
762
|
-
const pyprojectToml = (0,
|
|
944
|
+
const pyprojectPath = (0, import_node_path7.join)(workspaceRoot, consumerDirectory, consumer, "pyproject.toml");
|
|
945
|
+
const pyprojectToml = (0, import_node_fs4.readFileSync)(pyprojectPath, "utf8");
|
|
763
946
|
if (parseVendorEntries(pyprojectToml).includes(lib)) {
|
|
764
947
|
logger.info(`'${consumer}' already vendors '${lib}' \u2014 nothing to do.`);
|
|
765
948
|
return;
|
|
@@ -771,8 +954,8 @@ async function addPythonVendor(workspaceRoot, consumer, options, kindProvided) {
|
|
|
771
954
|
}
|
|
772
955
|
|
|
773
956
|
// src/commands/add/reactApp.ts
|
|
774
|
-
var
|
|
775
|
-
var
|
|
957
|
+
var import_node_fs5 = require("fs");
|
|
958
|
+
var import_node_path8 = require("path");
|
|
776
959
|
function ensurePlugin2(workspaceRoot, packageName) {
|
|
777
960
|
if (hasPlugin(workspaceRoot, packageName)) {
|
|
778
961
|
return;
|
|
@@ -818,12 +1001,12 @@ function reactAppTargets(name) {
|
|
|
818
1001
|
return targets;
|
|
819
1002
|
}
|
|
820
1003
|
function allowEnvFiles(workspaceRoot) {
|
|
821
|
-
const gitignorePath = (0,
|
|
1004
|
+
const gitignorePath = (0, import_node_path8.join)(workspaceRoot, ".gitignore");
|
|
822
1005
|
if (!fileExists(gitignorePath)) {
|
|
823
1006
|
return;
|
|
824
1007
|
}
|
|
825
1008
|
const marker = "# MoNecromanCI: keep the committed per-environment Vite config (public VITE_ values)";
|
|
826
|
-
const current = (0,
|
|
1009
|
+
const current = (0, import_node_fs5.readFileSync)(gitignorePath, "utf8");
|
|
827
1010
|
if (current.includes(marker)) {
|
|
828
1011
|
return;
|
|
829
1012
|
}
|
|
@@ -850,12 +1033,13 @@ function addReactApp(workspaceRoot, name, stack) {
|
|
|
850
1033
|
workspaceRoot
|
|
851
1034
|
);
|
|
852
1035
|
ensureAdmZip(workspaceRoot);
|
|
853
|
-
const reactAppRoot = (0,
|
|
1036
|
+
const reactAppRoot = (0, import_node_path8.join)(workspaceRoot, "apps", name);
|
|
854
1037
|
for (const environment of REACT_ENVIRONMENTS) {
|
|
855
|
-
writeFileEnsured((0,
|
|
1038
|
+
writeFileEnsured((0, import_node_path8.join)(reactAppRoot, `.env.${environment}`), reactEnvironmentFile(environment));
|
|
856
1039
|
}
|
|
857
1040
|
allowEnvFiles(workspaceRoot);
|
|
858
|
-
addNxTargets((0,
|
|
1041
|
+
addNxTargets((0, import_node_path8.join)(reactAppRoot, "package.json"), reactAppTargets(name));
|
|
1042
|
+
registerProjectCommands(workspaceRoot, name, { build: true, start: `nx run ${name}:serve` });
|
|
859
1043
|
}
|
|
860
1044
|
|
|
861
1045
|
// src/commands/add.ts
|
|
@@ -873,11 +1057,14 @@ var PROJECT_KINDS = [
|
|
|
873
1057
|
"go-app",
|
|
874
1058
|
"go-function-app",
|
|
875
1059
|
"go-lib",
|
|
876
|
-
"go-internal-lib"
|
|
1060
|
+
"go-internal-lib",
|
|
1061
|
+
"flutter-app",
|
|
1062
|
+
"flutter-lib",
|
|
1063
|
+
"flutter-internal-lib"
|
|
877
1064
|
];
|
|
878
1065
|
async function runAdd(kind, name, options) {
|
|
879
1066
|
const workspaceRoot = process.cwd();
|
|
880
|
-
if (!fileExists((0,
|
|
1067
|
+
if (!fileExists((0, import_node_path9.join)(workspaceRoot, "nx.json"))) {
|
|
881
1068
|
throw new Error("No nx.json found here. Run `add` from the workspace root.");
|
|
882
1069
|
}
|
|
883
1070
|
const stack = readWorkspaceStack(workspaceRoot);
|
|
@@ -918,7 +1105,8 @@ async function runAdd(kind, name, options) {
|
|
|
918
1105
|
],
|
|
919
1106
|
workspaceRoot
|
|
920
1107
|
);
|
|
921
|
-
markPrivate((0,
|
|
1108
|
+
markPrivate((0, import_node_path9.join)(workspaceRoot, "libs", resolvedName, "package.json"));
|
|
1109
|
+
registerProjectCommands(workspaceRoot, resolvedName, { build: true });
|
|
922
1110
|
break;
|
|
923
1111
|
}
|
|
924
1112
|
case "python-app": {
|
|
@@ -953,6 +1141,18 @@ async function runAdd(kind, name, options) {
|
|
|
953
1141
|
addGoInternalLib(workspaceRoot, resolvedName);
|
|
954
1142
|
break;
|
|
955
1143
|
}
|
|
1144
|
+
case "flutter-app": {
|
|
1145
|
+
addFlutterApp(workspaceRoot, resolvedName);
|
|
1146
|
+
break;
|
|
1147
|
+
}
|
|
1148
|
+
case "flutter-lib": {
|
|
1149
|
+
addFlutterLib(workspaceRoot, resolvedName);
|
|
1150
|
+
break;
|
|
1151
|
+
}
|
|
1152
|
+
case "flutter-internal-lib": {
|
|
1153
|
+
addFlutterInternalLib(workspaceRoot, resolvedName);
|
|
1154
|
+
break;
|
|
1155
|
+
}
|
|
956
1156
|
case "python-vendor": {
|
|
957
1157
|
await addPythonVendor(workspaceRoot, resolvedName, options, kindProvided);
|
|
958
1158
|
syncProjectReferences(workspaceRoot);
|
|
@@ -978,7 +1178,7 @@ function syncProjectReferences(workspaceRoot) {
|
|
|
978
1178
|
}
|
|
979
1179
|
function readWorkspaceStack(workspaceRoot) {
|
|
980
1180
|
const nxJson = readJson(
|
|
981
|
-
(0,
|
|
1181
|
+
(0, import_node_path9.join)(workspaceRoot, "nx.json")
|
|
982
1182
|
);
|
|
983
1183
|
const stack = nxJson.mnci?.stack;
|
|
984
1184
|
return {
|
|
@@ -991,14 +1191,14 @@ function markPrivate(manifestPath) {
|
|
|
991
1191
|
}
|
|
992
1192
|
|
|
993
1193
|
// src/commands/interactive.ts
|
|
994
|
-
var
|
|
1194
|
+
var import_node_path13 = require("path");
|
|
995
1195
|
var import_prompts7 = require("@inquirer/prompts");
|
|
996
1196
|
|
|
997
1197
|
// src/commands/new.ts
|
|
998
|
-
var
|
|
1198
|
+
var import_node_path11 = require("path");
|
|
999
1199
|
|
|
1000
1200
|
// src/overlay.ts
|
|
1001
|
-
var
|
|
1201
|
+
var import_node_path10 = require("path");
|
|
1002
1202
|
var DEFAULT_STACK = { testRunner: "jest" };
|
|
1003
1203
|
var PRETTIER_VERSION = "^3.8.1";
|
|
1004
1204
|
var TS_COMPILER_DEPENDENCIES = {
|
|
@@ -1038,7 +1238,7 @@ function releaseConfig(ci) {
|
|
|
1038
1238
|
const githubReleases = ci === "github";
|
|
1039
1239
|
return {
|
|
1040
1240
|
projectsRelationship: "independent",
|
|
1041
|
-
projects: ["packages/*", "python-packages/*"],
|
|
1241
|
+
projects: ["packages/*", "python-packages/*", "!tag:type:go-lib"],
|
|
1042
1242
|
releaseTag: { pattern: "{projectName}@{version}" },
|
|
1043
1243
|
git: { commit: false, tag: true, push: githubReleases },
|
|
1044
1244
|
version: {
|
|
@@ -1092,12 +1292,7 @@ package-lock.json
|
|
|
1092
1292
|
function vscodeWorkspace(workspaceName) {
|
|
1093
1293
|
return JSON.stringify(
|
|
1094
1294
|
{
|
|
1095
|
-
folders: [
|
|
1096
|
-
{ path: ".", name: workspaceName },
|
|
1097
|
-
{ path: "packages/cli", name: "@mnci/cli" },
|
|
1098
|
-
{ path: "packages/nx-python-pip", name: "@mnci/nx-python-pip" },
|
|
1099
|
-
{ path: "libs/monecromanci-v2", name: "@mnci/monecromanci" }
|
|
1100
|
-
],
|
|
1295
|
+
folders: [{ path: ".", name: workspaceName }],
|
|
1101
1296
|
settings: {
|
|
1102
1297
|
"eslint.validate": [
|
|
1103
1298
|
"javascript",
|
|
@@ -1131,7 +1326,8 @@ function vscodeWorkspace(workspaceName) {
|
|
|
1131
1326
|
"nrwl.angular-console",
|
|
1132
1327
|
"firsttris.vscode-jest-runner"
|
|
1133
1328
|
]
|
|
1134
|
-
}
|
|
1329
|
+
},
|
|
1330
|
+
tasks: { version: "2.0.0", tasks: [] }
|
|
1135
1331
|
},
|
|
1136
1332
|
null,
|
|
1137
1333
|
2
|
|
@@ -1176,7 +1372,7 @@ function mnciConfig(options) {
|
|
|
1176
1372
|
};
|
|
1177
1373
|
}
|
|
1178
1374
|
function readMnciConfig(workspaceRoot) {
|
|
1179
|
-
const nxJson = readJson((0,
|
|
1375
|
+
const nxJson = readJson((0, import_node_path10.join)(workspaceRoot, "nx.json"));
|
|
1180
1376
|
return nxJson.mnci ?? {};
|
|
1181
1377
|
}
|
|
1182
1378
|
function pythonPublishUrl(registry) {
|
|
@@ -1193,6 +1389,13 @@ var GOLANGCI_LINT_INSTALL_GUARD = `node -e "const fs=require('node:fs'),cp=requi
|
|
|
1193
1389
|
var GO_TOOL_PATH_PRELUDE = `const fs=require('node:fs'),cp=require('node:child_process');if(!fs.existsSync('go.mod')){console.log('No Go projects - skipping.');process.exit(0)}const r=cp.spawnSync('go',['env','GOPATH'],{encoding:'utf8'});if(r.status!==0){console.log('Could not resolve GOPATH - skipping.');process.exit(0)}const bin=require('node:path').join(r.stdout.trim(),'bin');`;
|
|
1194
1390
|
var GO_TOOL_PATH_AZURE = `node -e "${GO_TOOL_PATH_PRELUDE}console.log('##vso[task.prependpath]'+bin)"`;
|
|
1195
1391
|
var GO_TOOL_PATH_GITHUB = `node -e "${GO_TOOL_PATH_PRELUDE}if(!process.env.GITHUB_PATH){console.log('Not running in GitHub Actions - skipping.');process.exit(0)}fs.appendFileSync(process.env.GITHUB_PATH,bin+${String.raw`'\n'`})"`;
|
|
1392
|
+
var FLUTTER_SDK_VERSION = "3.44.8";
|
|
1393
|
+
var FLUTTER_SDK_DIRECTORY_EXPRESSION = `require('node:path').join(require('node:os').homedir(),'.mnci-flutter-${FLUTTER_SDK_VERSION}')`;
|
|
1394
|
+
var FLUTTER_SDK_INSTALL_GUARD = `node -e "const fs=require('node:fs'),cp=require('node:child_process');if(!fs.existsSync('pubspec.yaml')){console.log('No Flutter projects - skipping.');process.exit(0)}if(cp.spawnSync('flutter',['--version'],{stdio:'ignore',shell:process.platform==='win32'}).status===0){console.log('Flutter SDK already on PATH - skipping.');process.exit(0)}const sdk=${FLUTTER_SDK_DIRECTORY_EXPRESSION};if(fs.existsSync(sdk)){console.log('Flutter SDK already installed at '+sdk+' - skipping.');process.exit(0)}process.exit(cp.spawnSync('git',['clone','--depth','1','--branch','${FLUTTER_SDK_VERSION}','https://github.com/flutter/flutter.git',sdk],{stdio:'inherit'}).status ?? 1)"`;
|
|
1395
|
+
var FLUTTER_TOOL_PATH_PRELUDE = `const fs=require('node:fs'),path=require('node:path');if(!fs.existsSync('pubspec.yaml')){console.log('No Flutter projects - skipping.');process.exit(0)}const sdk=${FLUTTER_SDK_DIRECTORY_EXPRESSION};if(!fs.existsSync(sdk)){console.log('Flutter SDK was not installed by mnci (already on PATH) - skipping.');process.exit(0)}const bin=path.join(sdk,'bin');`;
|
|
1396
|
+
var FLUTTER_TOOL_PATH_AZURE = `node -e "${FLUTTER_TOOL_PATH_PRELUDE}console.log('##vso[task.prependpath]'+bin)"`;
|
|
1397
|
+
var FLUTTER_TOOL_PATH_GITHUB = `node -e "${FLUTTER_TOOL_PATH_PRELUDE}if(!process.env.GITHUB_PATH){console.log('Not running in GitHub Actions - skipping.');process.exit(0)}fs.appendFileSync(process.env.GITHUB_PATH,bin+${String.raw`'\n'`})"`;
|
|
1398
|
+
var FLUTTER_PUB_GET_GUARD = `node -e "const fs=require('node:fs');if(!fs.existsSync('pubspec.yaml')){console.log('No Flutter projects - skipping.');process.exit(0)}process.exit(require('node:child_process').spawnSync('flutter',['pub','get'],{stdio:'inherit',shell:process.platform==='win32'}).status ?? 1)"`;
|
|
1196
1399
|
var NPM_AUDIT_STEP = "npm audit --audit-level=high || echo npm audit found vulnerabilities, see log above - non-blocking, run npm audit locally to inspect";
|
|
1197
1400
|
var PACK_APPS_GUARD = `node -e "const fs=require('node:fs');fs.mkdirSync('dist/drop',{recursive:true});if(fs.globSync('apps/*/project.json').length===0){console.log('No apps to pack - skipping.');process.exit(0)}process.exit(require('node:child_process').spawnSync('npx nx run-many -t package',{stdio:'inherit',shell:true}).status ?? 1)"`;
|
|
1198
1401
|
function releaseGuard(pythonPublishEnv) {
|
|
@@ -1308,6 +1511,23 @@ steps:
|
|
|
1308
1511
|
- script: ${GO_TOOL_PATH_AZURE}
|
|
1309
1512
|
displayName: Add Go tool bin to PATH
|
|
1310
1513
|
|
|
1514
|
+
# Flutter, if the workspace has any. Unlike Python and Go, hosted agents do
|
|
1515
|
+
# NOT ship the Flutter SDK, so this installs it (shallow git clone at a
|
|
1516
|
+
# pinned tag) and puts it on PATH. All three guards skip cleanly on a
|
|
1517
|
+
# workspace with no root pubspec.yaml, and the install also skips when an
|
|
1518
|
+
# SDK is already on PATH.
|
|
1519
|
+
- script: ${FLUTTER_SDK_INSTALL_GUARD}
|
|
1520
|
+
displayName: Install the Flutter SDK (${FLUTTER_SDK_VERSION})
|
|
1521
|
+
|
|
1522
|
+
- script: ${FLUTTER_TOOL_PATH_AZURE}
|
|
1523
|
+
displayName: Add the Flutter SDK to PATH
|
|
1524
|
+
|
|
1525
|
+
# One command resolves EVERY Dart dependency, internal and external, for the
|
|
1526
|
+
# whole workspace: the projects are pub workspace members, so this writes a
|
|
1527
|
+
# single root pubspec.lock they all share.
|
|
1528
|
+
- script: ${FLUTTER_PUB_GET_GUARD}
|
|
1529
|
+
displayName: Resolve Dart dependencies (one pub get for the whole workspace)
|
|
1530
|
+
|
|
1311
1531
|
# Fails fast, with an unambiguous message, when a stale TypeScript project
|
|
1312
1532
|
# reference (or another sync generator's drift) was never synced+committed
|
|
1313
1533
|
# locally \u2014 sync.applyChanges (nx.json) only auto-applies interactively, so
|
|
@@ -1462,6 +1682,23 @@ jobs:
|
|
|
1462
1682
|
- run: ${GO_TOOL_PATH_GITHUB}
|
|
1463
1683
|
name: Add Go tool bin to PATH
|
|
1464
1684
|
|
|
1685
|
+
# Flutter, if the workspace has any. Unlike Python and Go, hosted runners
|
|
1686
|
+
# do NOT ship the Flutter SDK, so this installs it (shallow git clone at
|
|
1687
|
+
# a pinned tag) and puts it on PATH. All three guards skip cleanly on a
|
|
1688
|
+
# workspace with no root pubspec.yaml, and the install also skips when an
|
|
1689
|
+
# SDK is already on PATH.
|
|
1690
|
+
- run: ${FLUTTER_SDK_INSTALL_GUARD}
|
|
1691
|
+
name: Install the Flutter SDK (${FLUTTER_SDK_VERSION})
|
|
1692
|
+
|
|
1693
|
+
- run: ${FLUTTER_TOOL_PATH_GITHUB}
|
|
1694
|
+
name: Add the Flutter SDK to PATH
|
|
1695
|
+
|
|
1696
|
+
# One command resolves EVERY Dart dependency, internal and external, for
|
|
1697
|
+
# the whole workspace: the projects are pub workspace members, so this
|
|
1698
|
+
# writes a single root pubspec.lock they all share.
|
|
1699
|
+
- run: ${FLUTTER_PUB_GET_GUARD}
|
|
1700
|
+
name: Resolve Dart dependencies (one pub get for the whole workspace)
|
|
1701
|
+
|
|
1465
1702
|
# Fails fast, with an unambiguous message, when a stale TypeScript project
|
|
1466
1703
|
# reference (or another sync generator's drift) was never synced+committed
|
|
1467
1704
|
# locally \u2014 sync.applyChanges (nx.json) only auto-applies interactively, so
|
|
@@ -1547,9 +1784,21 @@ updates:
|
|
|
1547
1784
|
- "/libs/*"
|
|
1548
1785
|
schedule:
|
|
1549
1786
|
interval: weekly
|
|
1787
|
+
|
|
1788
|
+
# Same glob reasoning as pip above. Dart projects are pub workspace members,
|
|
1789
|
+
# so each one declares its own dependencies even though they all resolve
|
|
1790
|
+
# through the single root pubspec.lock \u2014 hence the per-project directories
|
|
1791
|
+
# rather than just "/".
|
|
1792
|
+
- package-ecosystem: pub
|
|
1793
|
+
directories:
|
|
1794
|
+
- "/apps/*"
|
|
1795
|
+
- "/packages/*"
|
|
1796
|
+
- "/libs/*"
|
|
1797
|
+
schedule:
|
|
1798
|
+
interval: weekly
|
|
1550
1799
|
`;
|
|
1551
1800
|
function applyOverlay(workspaceRoot, options) {
|
|
1552
|
-
const nxJsonPath = (0,
|
|
1801
|
+
const nxJsonPath = (0, import_node_path10.join)(workspaceRoot, "nx.json");
|
|
1553
1802
|
const nxJson = readJson(nxJsonPath);
|
|
1554
1803
|
const generators = {
|
|
1555
1804
|
...nxJson.generators,
|
|
@@ -1561,7 +1810,7 @@ function applyOverlay(workspaceRoot, options) {
|
|
|
1561
1810
|
nxJsonPath,
|
|
1562
1811
|
toJson({ ...withReleaseConfig(nxJson, options.ci), generators, sync, mnci })
|
|
1563
1812
|
);
|
|
1564
|
-
const manifestPath = (0,
|
|
1813
|
+
const manifestPath = (0, import_node_path10.join)(workspaceRoot, "package.json");
|
|
1565
1814
|
const manifest = readJson(manifestPath);
|
|
1566
1815
|
const scripts = {
|
|
1567
1816
|
...manifest.scripts,
|
|
@@ -1576,30 +1825,30 @@ function applyOverlay(workspaceRoot, options) {
|
|
|
1576
1825
|
manifestPath,
|
|
1577
1826
|
toJson({ ...manifest, name: `${options.scope}/source`, scripts, devDependencies: devDeps })
|
|
1578
1827
|
);
|
|
1579
|
-
writeFileEnsured((0,
|
|
1580
|
-
writeFileEnsured((0,
|
|
1581
|
-
const hookPath = (0,
|
|
1828
|
+
writeFileEnsured((0, import_node_path10.join)(workspaceRoot, ".npmrc"), npmrcContent(options.registry, options.scope));
|
|
1829
|
+
writeFileEnsured((0, import_node_path10.join)(workspaceRoot, "commitlint.config.mjs"), COMMITLINT_CONFIG);
|
|
1830
|
+
const hookPath = (0, import_node_path10.join)(workspaceRoot, ".husky/commit-msg");
|
|
1582
1831
|
writeFileEnsured(hookPath, COMMIT_MSG_HOOK);
|
|
1583
1832
|
markExecutable(hookPath);
|
|
1584
|
-
writeFileEnsured((0,
|
|
1585
|
-
writeFileEnsured((0,
|
|
1833
|
+
writeFileEnsured((0, import_node_path10.join)(workspaceRoot, ".prettierrc.json"), PRETTIER_CONFIG);
|
|
1834
|
+
writeFileEnsured((0, import_node_path10.join)(workspaceRoot, ".prettierignore"), PRETTIER_IGNORE);
|
|
1586
1835
|
writeFileEnsured(
|
|
1587
|
-
(0,
|
|
1836
|
+
(0, import_node_path10.join)(workspaceRoot, `${options.workspaceName}.code-workspace`),
|
|
1588
1837
|
vscodeWorkspace(options.workspaceName)
|
|
1589
1838
|
);
|
|
1590
1839
|
const publishUrl = pythonPublishUrl(options.registry);
|
|
1591
1840
|
if (options.ci === "azure" || options.ci === "both") {
|
|
1592
1841
|
writeFileEnsured(
|
|
1593
|
-
(0,
|
|
1842
|
+
(0, import_node_path10.join)(workspaceRoot, "azure-pipelines.yml"),
|
|
1594
1843
|
azurePipelinesYaml(options.agent, options.variableGroup, publishUrl, options.registry.kind)
|
|
1595
1844
|
);
|
|
1596
1845
|
}
|
|
1597
1846
|
if (options.ci === "github" || options.ci === "both") {
|
|
1598
1847
|
writeFileEnsured(
|
|
1599
|
-
(0,
|
|
1848
|
+
(0, import_node_path10.join)(workspaceRoot, ".github/workflows/ci.yml"),
|
|
1600
1849
|
githubActionsYaml(options.agent, publishUrl, options.registry.kind, options.ci)
|
|
1601
1850
|
);
|
|
1602
|
-
writeFileEnsured((0,
|
|
1851
|
+
writeFileEnsured((0, import_node_path10.join)(workspaceRoot, ".github/dependabot.yml"), DEPENDABOT_CONFIG);
|
|
1603
1852
|
}
|
|
1604
1853
|
}
|
|
1605
1854
|
|
|
@@ -1668,7 +1917,7 @@ async function runNew(name, options) {
|
|
|
1668
1917
|
],
|
|
1669
1918
|
process.cwd()
|
|
1670
1919
|
);
|
|
1671
|
-
const workspaceRoot = (0,
|
|
1920
|
+
const workspaceRoot = (0, import_node_path11.join)(process.cwd(), workspaceName);
|
|
1672
1921
|
logger.step(
|
|
1673
1922
|
"Applying MoNecromanCI overlay (VS Code workspace, release config, .npmrc, commitlint, pipeline, stack)"
|
|
1674
1923
|
);
|
|
@@ -1689,13 +1938,19 @@ async function runNew(name, options) {
|
|
|
1689
1938
|
" mnci add react-app web # or: node-app, node-function-app, npm-lib, internal-lib,"
|
|
1690
1939
|
);
|
|
1691
1940
|
logger.info(
|
|
1692
|
-
" # python-app, python-function-app, python-lib, python-internal-lib"
|
|
1941
|
+
" # python-app, python-function-app, python-lib, python-internal-lib,"
|
|
1942
|
+
);
|
|
1943
|
+
logger.info(
|
|
1944
|
+
" # go-app, go-function-app, go-lib, go-internal-lib,"
|
|
1945
|
+
);
|
|
1946
|
+
logger.info(
|
|
1947
|
+
" # flutter-app, flutter-lib, flutter-internal-lib"
|
|
1693
1948
|
);
|
|
1694
1949
|
logger.info(' git add -A && git commit -m "feat: initial workspace"');
|
|
1695
1950
|
}
|
|
1696
1951
|
|
|
1697
1952
|
// src/commands/upgrade.ts
|
|
1698
|
-
var
|
|
1953
|
+
var import_node_path12 = require("path");
|
|
1699
1954
|
function resolveRegistry2(options, persisted) {
|
|
1700
1955
|
if (options.registry === "azure-artifacts" || options.organization && options.artifactsFeed) {
|
|
1701
1956
|
const persistedAzure = persisted?.kind === "azure-artifacts" ? persisted : void 0;
|
|
@@ -1747,7 +2002,7 @@ function resolveOverlayOptions(options, persisted) {
|
|
|
1747
2002
|
return { scope, registry, agent, variableGroup, ci, stack: { testRunner } };
|
|
1748
2003
|
}
|
|
1749
2004
|
function runUpgrade(workspaceRoot, options) {
|
|
1750
|
-
if (!fileExists((0,
|
|
2005
|
+
if (!fileExists((0, import_node_path12.join)(workspaceRoot, "nx.json"))) {
|
|
1751
2006
|
throw new Error(
|
|
1752
2007
|
`No nx.json found in ${workspaceRoot} \u2014 this does not look like an Nx workspace. Run 'mnci upgrade' from the workspace root.`
|
|
1753
2008
|
);
|
|
@@ -1763,7 +2018,7 @@ function runUpgrade(workspaceRoot, options) {
|
|
|
1763
2018
|
|
|
1764
2019
|
// src/commands/interactive.ts
|
|
1765
2020
|
async function runInteractive() {
|
|
1766
|
-
const inWorkspace = fileExists((0,
|
|
2021
|
+
const inWorkspace = fileExists((0, import_node_path13.join)(process.cwd(), "nx.json"));
|
|
1767
2022
|
const newChoice = { name: "Create a new monorepo", value: "new" };
|
|
1768
2023
|
const addChoice = { name: "Add a project to this workspace", value: "add" };
|
|
1769
2024
|
const upgradeChoice = {
|
|
@@ -1784,8 +2039,8 @@ async function runInteractive() {
|
|
|
1784
2039
|
}
|
|
1785
2040
|
|
|
1786
2041
|
// src/util/versionChecker.ts
|
|
1787
|
-
var
|
|
1788
|
-
var
|
|
2042
|
+
var import_node_fs6 = require("fs");
|
|
2043
|
+
var import_node_path14 = require("path");
|
|
1789
2044
|
var import_cross_spawn2 = __toESM(require("cross-spawn"));
|
|
1790
2045
|
var PACKAGE_NAME = "@mnci/cli";
|
|
1791
2046
|
var REGISTRY_TIMEOUT_MS = 2e3;
|
|
@@ -1841,8 +2096,8 @@ function releaseTriple(version) {
|
|
|
1841
2096
|
}
|
|
1842
2097
|
function readCliVersion(packageDirectory) {
|
|
1843
2098
|
try {
|
|
1844
|
-
const manifestPath = (0,
|
|
1845
|
-
const manifest = JSON.parse((0,
|
|
2099
|
+
const manifestPath = (0, import_node_path14.join)(packageDirectory, "..", "package.json");
|
|
2100
|
+
const manifest = JSON.parse((0, import_node_fs6.readFileSync)(manifestPath, "utf8"));
|
|
1846
2101
|
return manifest.version ?? "0.0.0";
|
|
1847
2102
|
} catch {
|
|
1848
2103
|
return "0.0.0";
|