@mnci/cli 4.0.6 → 4.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +145 -25
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1136,9 +1136,39 @@ ${githubReleases ? "" : `
|
|
|
1136
1136
|
if: \${{ ${onMain} }}
|
|
1137
1137
|
`}`;
|
|
1138
1138
|
}
|
|
1139
|
-
var
|
|
1139
|
+
var PIP_PROJECT_GLOBS = ["apps", "python-packages", "libs"];
|
|
1140
|
+
var PUB_PROJECT_GLOBS = ["apps", "packages", "libs"];
|
|
1141
|
+
var ECOSYSTEM_MANIFESTS = {
|
|
1142
|
+
pip: ["pyproject.toml", "requirements.txt"],
|
|
1143
|
+
pub: ["pubspec.yaml"]
|
|
1144
|
+
};
|
|
1145
|
+
function hasEcosystemProject(workspaceRoot, roots, manifests) {
|
|
1146
|
+
return roots.some((root) => {
|
|
1147
|
+
const base = (0, import_node_path2.join)(workspaceRoot, root);
|
|
1148
|
+
if (!(0, import_node_fs2.existsSync)(base)) {
|
|
1149
|
+
return false;
|
|
1150
|
+
}
|
|
1151
|
+
return (0, import_node_fs2.readdirSync)(base, { withFileTypes: true }).some(
|
|
1152
|
+
(entry) => entry.isDirectory() && manifests.some((manifest) => (0, import_node_fs2.existsSync)((0, import_node_path2.join)(base, entry.name, manifest)))
|
|
1153
|
+
);
|
|
1154
|
+
});
|
|
1155
|
+
}
|
|
1156
|
+
function dependabotBlock(ecosystem, roots) {
|
|
1157
|
+
return `
|
|
1158
|
+
- package-ecosystem: ${ecosystem}
|
|
1159
|
+
directories:
|
|
1160
|
+
` + roots.map((root) => ` - "/${root}/*"
|
|
1161
|
+
`).join("") + " schedule:\n interval: weekly\n";
|
|
1162
|
+
}
|
|
1163
|
+
function dependabotConfig(workspaceRoot) {
|
|
1164
|
+
let config = `# Generated by MoNecromanCI. Weekly dependency-update PRs so vulnerable or
|
|
1140
1165
|
# stale dependencies surface as a reviewable PR instead of only a push-time
|
|
1141
1166
|
# warning.
|
|
1167
|
+
#
|
|
1168
|
+
# pip and pub appear here only once the workspace HAS a Python or Dart project.
|
|
1169
|
+
# An ecosystem entry whose directories match no manifest is a hard Dependabot
|
|
1170
|
+
# failure, not a no-op, so emitting them unconditionally cost every workspace
|
|
1171
|
+
# two red runs a week over projects it does not have.
|
|
1142
1172
|
version: 2
|
|
1143
1173
|
updates:
|
|
1144
1174
|
- package-ecosystem: npm
|
|
@@ -1150,30 +1180,15 @@ updates:
|
|
|
1150
1180
|
directory: "/"
|
|
1151
1181
|
schedule:
|
|
1152
1182
|
interval: weekly
|
|
1153
|
-
|
|
1154
|
-
# Globs, not one entry per project: Python projects are added later via
|
|
1155
|
-
# 'mnci add python-*', so this starts covering them automatically the
|
|
1156
|
-
# moment the first one exists \u2014 a glob matching nothing yet is not an error.
|
|
1157
|
-
- package-ecosystem: pip
|
|
1158
|
-
directories:
|
|
1159
|
-
- "/apps/*"
|
|
1160
|
-
- "/python-packages/*"
|
|
1161
|
-
- "/libs/*"
|
|
1162
|
-
schedule:
|
|
1163
|
-
interval: weekly
|
|
1164
|
-
|
|
1165
|
-
# Same glob reasoning as pip above. Dart projects are pub workspace members,
|
|
1166
|
-
# so each one declares its own dependencies even though they all resolve
|
|
1167
|
-
# through the single root pubspec.lock \u2014 hence the per-project directories
|
|
1168
|
-
# rather than just "/".
|
|
1169
|
-
- package-ecosystem: pub
|
|
1170
|
-
directories:
|
|
1171
|
-
- "/apps/*"
|
|
1172
|
-
- "/packages/*"
|
|
1173
|
-
- "/libs/*"
|
|
1174
|
-
schedule:
|
|
1175
|
-
interval: weekly
|
|
1176
1183
|
`;
|
|
1184
|
+
if (hasEcosystemProject(workspaceRoot, PIP_PROJECT_GLOBS, ECOSYSTEM_MANIFESTS.pip)) {
|
|
1185
|
+
config += dependabotBlock("pip", PIP_PROJECT_GLOBS);
|
|
1186
|
+
}
|
|
1187
|
+
if (hasEcosystemProject(workspaceRoot, PUB_PROJECT_GLOBS, ECOSYSTEM_MANIFESTS.pub)) {
|
|
1188
|
+
config += dependabotBlock("pub", PUB_PROJECT_GLOBS);
|
|
1189
|
+
}
|
|
1190
|
+
return config;
|
|
1191
|
+
}
|
|
1177
1192
|
var NX_SCAFFOLDING_TO_REMOVE = [".prettierrc", ".prettierrc.json", ".vscode"];
|
|
1178
1193
|
function removeNxScaffolding(workspaceRoot) {
|
|
1179
1194
|
for (const entry of NX_SCAFFOLDING_TO_REMOVE) {
|
|
@@ -1300,7 +1315,7 @@ function applyOverlay(workspaceRoot, options, onProgress = () => {
|
|
|
1300
1315
|
(0, import_node_path2.join)(workspaceRoot, ".github/workflows/ci.yml"),
|
|
1301
1316
|
githubActionsYaml(options.agent, publishUrl, options.registry.kind, options.ci)
|
|
1302
1317
|
);
|
|
1303
|
-
writeFileEnsured((0, import_node_path2.join)(workspaceRoot, ".github/dependabot.yml"),
|
|
1318
|
+
writeFileEnsured((0, import_node_path2.join)(workspaceRoot, ".github/dependabot.yml"), dependabotConfig(workspaceRoot));
|
|
1304
1319
|
}
|
|
1305
1320
|
}
|
|
1306
1321
|
|
|
@@ -1328,6 +1343,100 @@ function markPublic(manifestPath) {
|
|
|
1328
1343
|
var WRONG_TYPES_PATH = "./dist/index.esm.d.ts";
|
|
1329
1344
|
var ACTUAL_TYPES_PATH = "./dist/src/index.d.ts";
|
|
1330
1345
|
var DECLARATION_MAP_EXCLUSION = "!**/*.d.ts.map";
|
|
1346
|
+
var ROLLUP_CONFIG_PLACEHOLDER = [
|
|
1347
|
+
" {",
|
|
1348
|
+
" // Provide additional rollup configuration here. See: https://rollupjs.org/configuration-options",
|
|
1349
|
+
" // e.g.",
|
|
1350
|
+
" // output: { sourcemap: true },",
|
|
1351
|
+
" }"
|
|
1352
|
+
].join("\n");
|
|
1353
|
+
var ROLLUP_CONFIG_WITH_DTS_FIX = [
|
|
1354
|
+
" {",
|
|
1355
|
+
" // Added by MoNecromanCI. @nx/rollup's dts-bundle plugin writes dist/index.d.ts",
|
|
1356
|
+
" // as a stub re-exporting the real declarations, and builds that specifier with",
|
|
1357
|
+
" // path.relative() - an OS-NATIVE path. On Windows it emits",
|
|
1358
|
+
String.raw` // export * from "./src\\index";`,
|
|
1359
|
+
" // which is not a valid module specifier on ANY platform: a specifier is",
|
|
1360
|
+
" // URL-style, so / is correct everywhere and a backslash nowhere. It resolves on",
|
|
1361
|
+
" // Windows only because the resolver normalises separators there, leaving the",
|
|
1362
|
+
" // package untyped on Linux and macOS.",
|
|
1363
|
+
" //",
|
|
1364
|
+
" // mnci also points `types` past this stub, so nothing depends on it being",
|
|
1365
|
+
" // correct; this makes the emitted file correct too. Remove once Nx fixes the",
|
|
1366
|
+
" // plugin - its own devkit already exports normalizePath for exactly this.",
|
|
1367
|
+
" plugins: [",
|
|
1368
|
+
" {",
|
|
1369
|
+
" name: 'mnci-normalise-declaration-specifiers',",
|
|
1370
|
+
" writeBundle (outputOptions) {",
|
|
1371
|
+
" const { readFileSync, writeFileSync } = require('node:fs')",
|
|
1372
|
+
" const { join } = require('node:path')",
|
|
1373
|
+
" const stub = join(outputOptions.dir ?? './dist', 'index.d.ts')",
|
|
1374
|
+
" let source",
|
|
1375
|
+
" try {",
|
|
1376
|
+
" source = readFileSync(stub, 'utf8')",
|
|
1377
|
+
" } catch {",
|
|
1378
|
+
" return",
|
|
1379
|
+
" }",
|
|
1380
|
+
" // The stub carries a TWO-character escape (JSON.stringify escaped one",
|
|
1381
|
+
" // backslash), so this must not match a single one - that would turn",
|
|
1382
|
+
String.raw` // "./src\index" into "./src//index". Built from char codes so there is`,
|
|
1383
|
+
" // no escaping in this file to get wrong.",
|
|
1384
|
+
" const separator = String.fromCodePoint(92, 92)",
|
|
1385
|
+
" const normalised = source.replaceAll(separator, '/')",
|
|
1386
|
+
" if (normalised !== source) writeFileSync(stub, normalised)",
|
|
1387
|
+
" }",
|
|
1388
|
+
" }",
|
|
1389
|
+
" ]",
|
|
1390
|
+
" }"
|
|
1391
|
+
].join("\n");
|
|
1392
|
+
function repairDeclarationSpecifiers(projectRoot) {
|
|
1393
|
+
const configPath = (0, import_node_path3.join)(projectRoot, "rollup.config.cjs");
|
|
1394
|
+
if (!fileExists(configPath)) {
|
|
1395
|
+
return;
|
|
1396
|
+
}
|
|
1397
|
+
const config = (0, import_node_fs3.readFileSync)(configPath, "utf8");
|
|
1398
|
+
if (!config.includes(ROLLUP_CONFIG_PLACEHOLDER)) {
|
|
1399
|
+
return;
|
|
1400
|
+
}
|
|
1401
|
+
writeFileEnsured(
|
|
1402
|
+
configPath,
|
|
1403
|
+
config.split(ROLLUP_CONFIG_PLACEHOLDER).join(ROLLUP_CONFIG_WITH_DTS_FIX)
|
|
1404
|
+
);
|
|
1405
|
+
}
|
|
1406
|
+
function writeProjectReadme(projectRoot, projectName, testRunner) {
|
|
1407
|
+
const runner = testRunner === "vitest" ? "[Vitest](https://vitest.dev)" : "[Jest](https://jestjs.io)";
|
|
1408
|
+
writeFileEnsured(
|
|
1409
|
+
(0, import_node_path3.join)(projectRoot, "README.md"),
|
|
1410
|
+
[
|
|
1411
|
+
`# ${projectName}`,
|
|
1412
|
+
"",
|
|
1413
|
+
"Generated by [MoNecromanCI](https://github.com/russoedu/MoNecromanCi).",
|
|
1414
|
+
"",
|
|
1415
|
+
"## Building",
|
|
1416
|
+
"",
|
|
1417
|
+
`Run \`nx build ${projectName}\` to build this project.`,
|
|
1418
|
+
"",
|
|
1419
|
+
"## Running unit tests",
|
|
1420
|
+
"",
|
|
1421
|
+
`Run \`nx test ${projectName}\` to execute the unit tests via ${runner}.`,
|
|
1422
|
+
""
|
|
1423
|
+
].join("\n")
|
|
1424
|
+
);
|
|
1425
|
+
}
|
|
1426
|
+
function removeStaleGitkeeps(workspaceRoot) {
|
|
1427
|
+
for (const scaffold of ["apps", "libs", "packages"]) {
|
|
1428
|
+
const directory = (0, import_node_path3.join)(workspaceRoot, scaffold);
|
|
1429
|
+
try {
|
|
1430
|
+
const holdsAProject = (0, import_node_fs3.readdirSync)(directory, { withFileTypes: true }).some(
|
|
1431
|
+
(entry) => entry.isDirectory()
|
|
1432
|
+
);
|
|
1433
|
+
if (holdsAProject) {
|
|
1434
|
+
(0, import_node_fs3.rmSync)((0, import_node_path3.join)(directory, ".gitkeep"), { force: true });
|
|
1435
|
+
}
|
|
1436
|
+
} catch {
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1331
1440
|
function repairPublishableManifest(manifestPath) {
|
|
1332
1441
|
const manifest = readJson(manifestPath);
|
|
1333
1442
|
if (manifest.types === WRONG_TYPES_PATH) {
|
|
@@ -1397,6 +1506,7 @@ function projectTask(name, kind) {
|
|
|
1397
1506
|
return kind === "start" ? { ...base, isBackground: true } : { ...base, group: kind };
|
|
1398
1507
|
}
|
|
1399
1508
|
function registerProjectCommands(workspaceRoot, name, commands) {
|
|
1509
|
+
removeStaleGitkeeps(workspaceRoot);
|
|
1400
1510
|
const scripts = {
|
|
1401
1511
|
[`${name}:qa`]: `nx run ${name}:lint && nx run ${name}:test`
|
|
1402
1512
|
};
|
|
@@ -1406,6 +1516,10 @@ function registerProjectCommands(workspaceRoot, name, commands) {
|
|
|
1406
1516
|
if (commands.start) {
|
|
1407
1517
|
scripts[`${name}:start`] = commands.start;
|
|
1408
1518
|
}
|
|
1519
|
+
const dependabotPath = (0, import_node_path3.join)(workspaceRoot, ".github/dependabot.yml");
|
|
1520
|
+
if ((0, import_node_fs3.existsSync)(dependabotPath)) {
|
|
1521
|
+
writeFileEnsured(dependabotPath, dependabotConfig(workspaceRoot));
|
|
1522
|
+
}
|
|
1409
1523
|
const manifestPath = (0, import_node_path3.join)(workspaceRoot, "package.json");
|
|
1410
1524
|
const manifest = readJson(manifestPath);
|
|
1411
1525
|
const existingScripts = manifest.scripts ?? {};
|
|
@@ -1860,6 +1974,8 @@ async function addNpmLib(workspaceRoot, name, options, kindProvided, stack) {
|
|
|
1860
1974
|
const manifestPath = (0, import_node_path7.join)(workspaceRoot, "packages", name, "package.json");
|
|
1861
1975
|
markPublic(manifestPath);
|
|
1862
1976
|
repairPublishableManifest(manifestPath);
|
|
1977
|
+
repairDeclarationSpecifiers((0, import_node_path7.join)(workspaceRoot, `packages/${name}`));
|
|
1978
|
+
writeProjectReadme((0, import_node_path7.join)(workspaceRoot, `packages/${name}`), `${scope}/${name}`, stack.testRunner);
|
|
1863
1979
|
removeGeneratedEslintConfig(workspaceRoot, `packages/${name}`);
|
|
1864
1980
|
registerProjectCommands(workspaceRoot, name, { build: true });
|
|
1865
1981
|
}
|
|
@@ -2188,6 +2304,8 @@ async function addReactLib(workspaceRoot, name, options, kindProvided, stack) {
|
|
|
2188
2304
|
const publishableManifest = (0, import_node_path10.join)(workspaceRoot, "packages", name, "package.json");
|
|
2189
2305
|
markPublic(publishableManifest);
|
|
2190
2306
|
repairPublishableManifest(publishableManifest);
|
|
2307
|
+
repairDeclarationSpecifiers((0, import_node_path10.join)(workspaceRoot, "packages", name));
|
|
2308
|
+
writeProjectReadme((0, import_node_path10.join)(workspaceRoot, "packages", name), `${scope}/${name}`, stack.testRunner);
|
|
2191
2309
|
removeGeneratedEslintConfig(workspaceRoot, `packages/${name}`);
|
|
2192
2310
|
registerProjectCommands(workspaceRoot, name, { build: true });
|
|
2193
2311
|
}
|
|
@@ -2209,6 +2327,8 @@ function addReactInternalLib(workspaceRoot, name, stack) {
|
|
|
2209
2327
|
const privateManifest = (0, import_node_path10.join)(workspaceRoot, "libs", name, "package.json");
|
|
2210
2328
|
markPrivate(privateManifest);
|
|
2211
2329
|
repairPublishableManifest(privateManifest);
|
|
2330
|
+
repairDeclarationSpecifiers((0, import_node_path10.join)(workspaceRoot, "libs", name));
|
|
2331
|
+
writeProjectReadme((0, import_node_path10.join)(workspaceRoot, "libs", name), name, stack.testRunner);
|
|
2212
2332
|
removeGeneratedEslintConfig(workspaceRoot, `libs/${name}`);
|
|
2213
2333
|
registerProjectCommands(workspaceRoot, name, { build: true });
|
|
2214
2334
|
}
|