@mnci/cli 4.49.0 → 4.51.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 +45 -0
- package/dist/cli.js +605 -237
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -3187,7 +3187,7 @@ function runPhase(phase, workspaceRoot, dependencies) {
|
|
|
3187
3187
|
}
|
|
3188
3188
|
|
|
3189
3189
|
// src/project-scaffolding/add-project.use-case.ts
|
|
3190
|
-
var
|
|
3190
|
+
var import_node_path35 = require("path");
|
|
3191
3191
|
var import_prompts3 = require("@inquirer/prompts");
|
|
3192
3192
|
|
|
3193
3193
|
// src/project-name/project-name.validator.ts
|
|
@@ -3372,7 +3372,10 @@ function findCodeWorkspaceFile(workspaceRoot) {
|
|
|
3372
3372
|
function projectTask(name, kind) {
|
|
3373
3373
|
const script = `${name}:${kind}`;
|
|
3374
3374
|
const base = { label: `${name}: ${kind}`, type: "npm", script, problemMatcher: [] };
|
|
3375
|
-
|
|
3375
|
+
if (kind === "start") {
|
|
3376
|
+
return { ...base, isBackground: true };
|
|
3377
|
+
}
|
|
3378
|
+
return kind === "build" || kind === "qa" ? { ...base, group: kind } : base;
|
|
3376
3379
|
}
|
|
3377
3380
|
function renameScaffoldPlaceholder(projectRoot, name, empty = false) {
|
|
3378
3381
|
reshapeScaffoldSlice(projectRoot, name, "ts", "use-case", empty);
|
|
@@ -3529,6 +3532,10 @@ function registerProjectCommands(workspaceRoot, name, commands) {
|
|
|
3529
3532
|
if (commands.start) {
|
|
3530
3533
|
scripts[`${name}:start`] = commands.start;
|
|
3531
3534
|
}
|
|
3535
|
+
const extraScripts = Object.entries(commands.extra ?? {});
|
|
3536
|
+
for (const [suffix, command] of extraScripts) {
|
|
3537
|
+
scripts[`${name}:${suffix}`] = command;
|
|
3538
|
+
}
|
|
3532
3539
|
const dependabotPath = (0, import_node_path11.join)(workspaceRoot, ".github/dependabot.yml");
|
|
3533
3540
|
if ((0, import_node_fs13.existsSync)(dependabotPath)) {
|
|
3534
3541
|
writeFileEnsured(dependabotPath, dependabotConfig(workspaceRoot));
|
|
@@ -3555,7 +3562,8 @@ function registerProjectCommands(workspaceRoot, name, commands) {
|
|
|
3555
3562
|
const newTasks = [
|
|
3556
3563
|
projectTask(name, "qa"),
|
|
3557
3564
|
...commands.build ? [projectTask(name, "build")] : [],
|
|
3558
|
-
...commands.start ? [projectTask(name, "start")] : []
|
|
3565
|
+
...commands.start ? [projectTask(name, "start")] : [],
|
|
3566
|
+
...Object.keys(commands.extra ?? {}).map((suffix) => projectTask(name, suffix))
|
|
3559
3567
|
];
|
|
3560
3568
|
writeFileEnsured(
|
|
3561
3569
|
codeWorkspacePath,
|
|
@@ -5862,10 +5870,229 @@ async function addPythonVendor(workspaceRoot, consumer, options, kindProvided) {
|
|
|
5862
5870
|
);
|
|
5863
5871
|
}
|
|
5864
5872
|
|
|
5865
|
-
// src/project-scaffolding/
|
|
5873
|
+
// src/project-scaffolding/container.use-case.ts
|
|
5866
5874
|
var import_node_fs26 = require("fs");
|
|
5867
5875
|
var import_node_path27 = require("path");
|
|
5868
5876
|
|
|
5877
|
+
// src/project-scaffolding/container-image.algorithm.ts
|
|
5878
|
+
var CONTAINER_TARGETS = ["node-app", "react-app", "go-app"];
|
|
5879
|
+
var NGINX_SPA = `server {
|
|
5880
|
+
listen 80;
|
|
5881
|
+
root /usr/share/nginx/html;
|
|
5882
|
+
index index.html;
|
|
5883
|
+
|
|
5884
|
+
location / {
|
|
5885
|
+
try_files $uri $uri/ /index.html;
|
|
5886
|
+
}
|
|
5887
|
+
}
|
|
5888
|
+
`;
|
|
5889
|
+
function planNode(app, port) {
|
|
5890
|
+
const portLines = port === void 0 ? "" : `ENV HOST=0.0.0.0
|
|
5891
|
+
ENV PORT=${port}
|
|
5892
|
+
EXPOSE ${port}
|
|
5893
|
+
`;
|
|
5894
|
+
return {
|
|
5895
|
+
dockerfile: `# Written by MoNecromanCI. The build context is the app's pruned output (its manifest, lockfile and compiled
|
|
5896
|
+
# code), so the image holds only what the app needs to run.
|
|
5897
|
+
FROM node:24-alpine
|
|
5898
|
+
WORKDIR /app
|
|
5899
|
+
COPY . .
|
|
5900
|
+
RUN npm install --omit=dev --ignore-scripts --no-audit --no-fund
|
|
5901
|
+
ENV NODE_ENV=production
|
|
5902
|
+
${portLines}USER node
|
|
5903
|
+
CMD ["node", "main.js"]
|
|
5904
|
+
`,
|
|
5905
|
+
dockerignore: "node_modules\n",
|
|
5906
|
+
files: {},
|
|
5907
|
+
contextDirectory: `apps/${app}/dist`,
|
|
5908
|
+
dependsOn: "prune",
|
|
5909
|
+
...port !== void 0 && { publish: `${port}:${port}` }
|
|
5910
|
+
};
|
|
5911
|
+
}
|
|
5912
|
+
function planReact(app) {
|
|
5913
|
+
return {
|
|
5914
|
+
dockerfile: `# Written by MoNecromanCI. The build context is the app's production build.
|
|
5915
|
+
FROM nginx:1.27-alpine
|
|
5916
|
+
COPY --from=files default.conf /etc/nginx/conf.d/default.conf
|
|
5917
|
+
COPY . /usr/share/nginx/html
|
|
5918
|
+
EXPOSE 80
|
|
5919
|
+
`,
|
|
5920
|
+
dockerignore: "",
|
|
5921
|
+
files: { "default.conf": NGINX_SPA },
|
|
5922
|
+
contextDirectory: `apps/${app}/dist`,
|
|
5923
|
+
dependsOn: "build",
|
|
5924
|
+
publish: "8080:80"
|
|
5925
|
+
};
|
|
5926
|
+
}
|
|
5927
|
+
function planGo(app, port) {
|
|
5928
|
+
return {
|
|
5929
|
+
dockerfile: `# Written by MoNecromanCI. The build context holds the app's static linux-amd64 binary from build-all.
|
|
5930
|
+
FROM gcr.io/distroless/static-debian12:nonroot
|
|
5931
|
+
COPY ${app} /app
|
|
5932
|
+
${port === void 0 ? "" : `EXPOSE ${port}
|
|
5933
|
+
`}ENTRYPOINT ["/app"]
|
|
5934
|
+
`,
|
|
5935
|
+
dockerignore: "",
|
|
5936
|
+
files: {},
|
|
5937
|
+
contextDirectory: `dist/platforms/${app}/linux-amd64`,
|
|
5938
|
+
dependsOn: "build-all",
|
|
5939
|
+
...port !== void 0 && { publish: `${port}:${port}` }
|
|
5940
|
+
};
|
|
5941
|
+
}
|
|
5942
|
+
function planContainer(target, app, port) {
|
|
5943
|
+
switch (target) {
|
|
5944
|
+
case "node-app": {
|
|
5945
|
+
return planNode(app, port);
|
|
5946
|
+
}
|
|
5947
|
+
case "react-app": {
|
|
5948
|
+
return planReact(app);
|
|
5949
|
+
}
|
|
5950
|
+
case "go-app": {
|
|
5951
|
+
return planGo(app, port);
|
|
5952
|
+
}
|
|
5953
|
+
}
|
|
5954
|
+
}
|
|
5955
|
+
|
|
5956
|
+
// src/project-scaffolding/container.use-case.ts
|
|
5957
|
+
var CONTAINER_TAG = "type:container";
|
|
5958
|
+
var CONTAINER_SCRIPT_PATH = "tools/container-image.cjs";
|
|
5959
|
+
var CONTAINER_SCRIPT = `// Written by MoNecromanCI; \`mnci upgrade\` rewrites it. Builds and runs a container image.
|
|
5960
|
+
// node tools/container-image.cjs build --image <name> --file <Dockerfile> --context <dir> [--files <dir>]
|
|
5961
|
+
// node tools/container-image.cjs start --image <name> [--publish <host:container>]
|
|
5962
|
+
const { spawnSync } = require('node:child_process')
|
|
5963
|
+
const { existsSync } = require('node:fs')
|
|
5964
|
+
|
|
5965
|
+
const [command, ...rest] = process.argv.slice(2)
|
|
5966
|
+
const options = {}
|
|
5967
|
+
for (let index = 0; index < rest.length; index += 2) {
|
|
5968
|
+
options[rest[index].replace(/^--/, '')] = rest[index + 1]
|
|
5969
|
+
}
|
|
5970
|
+
const version = process.env.VERSION || 'dev'
|
|
5971
|
+
|
|
5972
|
+
/** Runs docker with the output shown, and exits with its status. */
|
|
5973
|
+
function docker (args) {
|
|
5974
|
+
const result = spawnSync('docker', args, { stdio: 'inherit' })
|
|
5975
|
+
if (result.error) {
|
|
5976
|
+
console.error('Docker is not available: ' + result.error.message)
|
|
5977
|
+
process.exit(1)
|
|
5978
|
+
}
|
|
5979
|
+
if (result.status !== 0) {
|
|
5980
|
+
process.exit(result.status ?? 1)
|
|
5981
|
+
}
|
|
5982
|
+
}
|
|
5983
|
+
|
|
5984
|
+
if (command === 'build') {
|
|
5985
|
+
const args = ['build', '-f', options.file, '-t', options.image + ':' + version, '-t', options.image + ':latest']
|
|
5986
|
+
if (options.files && existsSync(options.files)) {
|
|
5987
|
+
args.push('--build-context', 'files=' + options.files)
|
|
5988
|
+
}
|
|
5989
|
+
args.push(options.context)
|
|
5990
|
+
docker(args)
|
|
5991
|
+
} else if (command === 'start') {
|
|
5992
|
+
const args = ['run', '--rm', '--init']
|
|
5993
|
+
if (options.publish) {
|
|
5994
|
+
args.push('-p', options.publish)
|
|
5995
|
+
}
|
|
5996
|
+
args.push(options.image + ':latest')
|
|
5997
|
+
docker(args)
|
|
5998
|
+
} else {
|
|
5999
|
+
console.error('usage: container-image.cjs build|start --image <name> ...')
|
|
6000
|
+
process.exit(2)
|
|
6001
|
+
}
|
|
6002
|
+
`;
|
|
6003
|
+
function detectTarget(appRoot) {
|
|
6004
|
+
if (fileExists((0, import_node_path27.join)(appRoot, "go.mod"))) {
|
|
6005
|
+
return fileExists((0, import_node_path27.join)(appRoot, "host.json")) ? void 0 : "go-app";
|
|
6006
|
+
}
|
|
6007
|
+
const manifestPath = (0, import_node_path27.join)(appRoot, "package.json");
|
|
6008
|
+
if (!fileExists(manifestPath) || fileExists((0, import_node_path27.join)(appRoot, "host.json"))) {
|
|
6009
|
+
return void 0;
|
|
6010
|
+
}
|
|
6011
|
+
const manifest = readJson(manifestPath);
|
|
6012
|
+
const declared = Object.keys({ ...manifest.dependencies, ...manifest.devDependencies });
|
|
6013
|
+
if (declared.includes("react") && fileExists((0, import_node_path27.join)(appRoot, "index.html"))) {
|
|
6014
|
+
return "react-app";
|
|
6015
|
+
}
|
|
6016
|
+
return manifest.nx?.targets?.build?.executor === "@nx/esbuild:esbuild" ? "node-app" : void 0;
|
|
6017
|
+
}
|
|
6018
|
+
function containerTargets(name, appProject, plan) {
|
|
6019
|
+
const build = [
|
|
6020
|
+
"node",
|
|
6021
|
+
CONTAINER_SCRIPT_PATH,
|
|
6022
|
+
"build",
|
|
6023
|
+
"--image",
|
|
6024
|
+
name,
|
|
6025
|
+
"--file",
|
|
6026
|
+
`apps/${name}/Dockerfile`,
|
|
6027
|
+
"--context",
|
|
6028
|
+
plan.contextDirectory,
|
|
6029
|
+
"--files",
|
|
6030
|
+
`apps/${name}/files`
|
|
6031
|
+
].join(" ");
|
|
6032
|
+
const start = ["node", CONTAINER_SCRIPT_PATH, "start", "--image", name, ...plan.publish === void 0 ? [] : ["--publish", plan.publish]].join(" ");
|
|
6033
|
+
return {
|
|
6034
|
+
// Not called `build`: CI runs every project's `build`, and building an image needs a Docker engine that
|
|
6035
|
+
// an agent may not have (a Windows agent cannot run Linux images at all).
|
|
6036
|
+
image: { executor: "nx:run-commands", cache: false, dependsOn: [`${appProject}:${plan.dependsOn}`], options: { command: build } },
|
|
6037
|
+
start: { executor: "nx:run-commands", continuous: true, dependsOn: ["image"], options: { command: start } }
|
|
6038
|
+
};
|
|
6039
|
+
}
|
|
6040
|
+
function addContainer(workspaceRoot, name, options) {
|
|
6041
|
+
const appRoot = (0, import_node_path27.join)(workspaceRoot, "apps", options.app);
|
|
6042
|
+
if (!fileExists(appRoot)) {
|
|
6043
|
+
throw new Error(`--app ${options.app}: there is no apps/${options.app} to put in an image. Add the app first.`);
|
|
6044
|
+
}
|
|
6045
|
+
const target = detectTarget(appRoot);
|
|
6046
|
+
if (target === void 0) {
|
|
6047
|
+
throw new Error(`--app ${options.app}: apps/${options.app} is not an app an image is built for (${CONTAINER_TARGETS.join(", ")}). An Azure Functions app has its own host image and is not supported yet.`);
|
|
6048
|
+
}
|
|
6049
|
+
const plan = planContainer(target, options.app, options.port);
|
|
6050
|
+
const appManifestPath = (0, import_node_path27.join)(appRoot, "package.json");
|
|
6051
|
+
const appProject = fileExists(appManifestPath) ? readJson(appManifestPath).name : options.app;
|
|
6052
|
+
const scope = appProject.startsWith("@") ? `${appProject.split("/", 1)[0]}/` : "";
|
|
6053
|
+
const projectRoot = (0, import_node_path27.join)(workspaceRoot, "apps", name);
|
|
6054
|
+
writeFileEnsured((0, import_node_path27.join)(projectRoot, "Dockerfile"), plan.dockerfile);
|
|
6055
|
+
writeFileEnsured((0, import_node_path27.join)(projectRoot, "Dockerfile.dockerignore"), plan.dockerignore);
|
|
6056
|
+
for (const [file, text] of Object.entries(plan.files)) {
|
|
6057
|
+
writeFileEnsured((0, import_node_path27.join)(projectRoot, "files", file), text);
|
|
6058
|
+
}
|
|
6059
|
+
writeFileEnsured((0, import_node_path27.join)(workspaceRoot, CONTAINER_SCRIPT_PATH), CONTAINER_SCRIPT);
|
|
6060
|
+
writeFileEnsured((0, import_node_path27.join)(projectRoot, "package.json"), toJson({
|
|
6061
|
+
name: `${scope}${name}`,
|
|
6062
|
+
version: "0.0.1",
|
|
6063
|
+
private: true,
|
|
6064
|
+
nx: { tags: [CONTAINER_TAG], implicitDependencies: [appProject], targets: containerTargets(name, appProject, plan) }
|
|
6065
|
+
}));
|
|
6066
|
+
registerProjectCommands(workspaceRoot, name, {
|
|
6067
|
+
build: false,
|
|
6068
|
+
start: `nx run ${name}:start`,
|
|
6069
|
+
qa: `nx run ${name}:image`,
|
|
6070
|
+
extra: { image: `nx run ${name}:image` }
|
|
6071
|
+
});
|
|
6072
|
+
}
|
|
6073
|
+
function refreshContainerScript(workspaceRoot) {
|
|
6074
|
+
let entries;
|
|
6075
|
+
try {
|
|
6076
|
+
entries = (0, import_node_fs26.readdirSync)((0, import_node_path27.join)(workspaceRoot, "apps"));
|
|
6077
|
+
} catch {
|
|
6078
|
+
return false;
|
|
6079
|
+
}
|
|
6080
|
+
const hasContainer = entries.some((entry) => {
|
|
6081
|
+
const manifestPath = (0, import_node_path27.join)(workspaceRoot, "apps", entry, "package.json");
|
|
6082
|
+
return fileExists(manifestPath) && (readJson(manifestPath).nx?.tags ?? []).includes(CONTAINER_TAG);
|
|
6083
|
+
});
|
|
6084
|
+
const path = (0, import_node_path27.join)(workspaceRoot, CONTAINER_SCRIPT_PATH);
|
|
6085
|
+
if (!hasContainer || fileExists(path) && (0, import_node_fs26.readFileSync)(path, "utf8") === CONTAINER_SCRIPT) {
|
|
6086
|
+
return false;
|
|
6087
|
+
}
|
|
6088
|
+
writeFileEnsured(path, CONTAINER_SCRIPT);
|
|
6089
|
+
return true;
|
|
6090
|
+
}
|
|
6091
|
+
|
|
6092
|
+
// src/project-scaffolding/react-app.use-case.ts
|
|
6093
|
+
var import_node_fs27 = require("fs");
|
|
6094
|
+
var import_node_path28 = require("path");
|
|
6095
|
+
|
|
5869
6096
|
// src/project-scaffolding/react-app-example.algorithm.ts
|
|
5870
6097
|
function reactAppExampleFiles(name) {
|
|
5871
6098
|
return {
|
|
@@ -5990,12 +6217,12 @@ function reactAppTargets(name) {
|
|
|
5990
6217
|
return targets;
|
|
5991
6218
|
}
|
|
5992
6219
|
function allowEnvFiles(workspaceRoot) {
|
|
5993
|
-
const gitignorePath = (0,
|
|
6220
|
+
const gitignorePath = (0, import_node_path28.join)(workspaceRoot, ".gitignore");
|
|
5994
6221
|
if (!fileExists(gitignorePath)) {
|
|
5995
6222
|
return;
|
|
5996
6223
|
}
|
|
5997
6224
|
const marker = "# MoNecromanCI: keep the committed per-environment Vite config (public VITE_ values)";
|
|
5998
|
-
const current = (0,
|
|
6225
|
+
const current = (0, import_node_fs27.readFileSync)(gitignorePath, "utf8");
|
|
5999
6226
|
if (current.includes(marker)) {
|
|
6000
6227
|
return;
|
|
6001
6228
|
}
|
|
@@ -6022,17 +6249,17 @@ function addReactApp(workspaceRoot, name, stack, e2e = false) {
|
|
|
6022
6249
|
workspaceRoot
|
|
6023
6250
|
);
|
|
6024
6251
|
ensureAdmZip(workspaceRoot);
|
|
6025
|
-
const reactAppRoot = (0,
|
|
6252
|
+
const reactAppRoot = (0, import_node_path28.join)(workspaceRoot, "apps", name);
|
|
6026
6253
|
for (const environment of REACT_ENVIRONMENTS) {
|
|
6027
|
-
writeFileEnsured((0,
|
|
6254
|
+
writeFileEnsured((0, import_node_path28.join)(reactAppRoot, `.env.${environment}`), reactEnvironmentFile(environment));
|
|
6028
6255
|
}
|
|
6029
6256
|
allowEnvFiles(workspaceRoot);
|
|
6030
|
-
addNxTargets((0,
|
|
6257
|
+
addNxTargets((0, import_node_path28.join)(reactAppRoot, "package.json"), reactAppTargets(name));
|
|
6031
6258
|
reshapeReactAppScaffold(reactAppRoot);
|
|
6032
|
-
(0,
|
|
6259
|
+
(0, import_node_fs27.rmSync)((0, import_node_path28.join)(reactAppRoot, "src/app/nx-welcome.component.tsx"), { force: true });
|
|
6033
6260
|
const example = reactAppExampleFiles(name);
|
|
6034
6261
|
for (const [relative, contents] of Object.entries(example)) {
|
|
6035
|
-
writeFileEnsured((0,
|
|
6262
|
+
writeFileEnsured((0, import_node_path28.join)(reactAppRoot, "src", relative), contents);
|
|
6036
6263
|
}
|
|
6037
6264
|
removeGeneratedEslintConfig(workspaceRoot, `apps/${name}`);
|
|
6038
6265
|
registerProjectCommands(workspaceRoot, name, { build: true, start: `nx run ${name}:serve` });
|
|
@@ -6042,9 +6269,9 @@ function addReactApp(workspaceRoot, name, stack, e2e = false) {
|
|
|
6042
6269
|
}
|
|
6043
6270
|
function pairE2eProject(workspaceRoot, name) {
|
|
6044
6271
|
const e2eName = `${name}-e2e`;
|
|
6045
|
-
const e2eRoot = (0,
|
|
6046
|
-
(0,
|
|
6047
|
-
writeFileEnsured((0,
|
|
6272
|
+
const e2eRoot = (0, import_node_path28.join)(workspaceRoot, "apps", e2eName);
|
|
6273
|
+
(0, import_node_fs27.rmSync)((0, import_node_path28.join)(e2eRoot, "src/example.spec.ts"), { force: true });
|
|
6274
|
+
writeFileEnsured((0, import_node_path28.join)(e2eRoot, "src/greeting.e2e.spec.ts"), reactAppE2eSpec(name));
|
|
6048
6275
|
removeGeneratedEslintConfig(workspaceRoot, `apps/${e2eName}`);
|
|
6049
6276
|
registerProjectCommands(workspaceRoot, e2eName, {
|
|
6050
6277
|
build: false,
|
|
@@ -6053,13 +6280,13 @@ function pairE2eProject(workspaceRoot, name) {
|
|
|
6053
6280
|
}
|
|
6054
6281
|
|
|
6055
6282
|
// src/project-scaffolding/react-lib.use-case.ts
|
|
6056
|
-
var
|
|
6283
|
+
var import_node_path29 = require("path");
|
|
6057
6284
|
var REACT_LIB_BUNDLER = "rollup";
|
|
6058
6285
|
async function addReactLib(workspaceRoot, name, options, kindProvided, stack) {
|
|
6059
6286
|
ensurePlugin(workspaceRoot, "@nx/react");
|
|
6060
6287
|
const scope = options.scope ?? (kindProvided ? defaultScope(workspaceRoot) : await promptText("npm scope for the published package", defaultScope(workspaceRoot)));
|
|
6061
|
-
const projectRoot = (0,
|
|
6062
|
-
const publishableManifest = (0,
|
|
6288
|
+
const projectRoot = (0, import_node_path29.join)(workspaceRoot, "packages", name);
|
|
6289
|
+
const publishableManifest = (0, import_node_path29.join)(projectRoot, "package.json");
|
|
6063
6290
|
runGeneratorAndRepair(
|
|
6064
6291
|
workspaceRoot,
|
|
6065
6292
|
[
|
|
@@ -6103,8 +6330,8 @@ function dropNxProjectName(manifestPath) {
|
|
|
6103
6330
|
}
|
|
6104
6331
|
function addReactInternalLib(workspaceRoot, name, stack, empty = false) {
|
|
6105
6332
|
ensurePlugin(workspaceRoot, "@nx/react");
|
|
6106
|
-
const projectRoot = (0,
|
|
6107
|
-
const privateManifest = (0,
|
|
6333
|
+
const projectRoot = (0, import_node_path29.join)(workspaceRoot, "libs", name);
|
|
6334
|
+
const privateManifest = (0, import_node_path29.join)(projectRoot, "package.json");
|
|
6108
6335
|
runGeneratorAndRepair(
|
|
6109
6336
|
workspaceRoot,
|
|
6110
6337
|
[
|
|
@@ -6131,8 +6358,8 @@ function addReactInternalLib(workspaceRoot, name, stack, empty = false) {
|
|
|
6131
6358
|
}
|
|
6132
6359
|
|
|
6133
6360
|
// src/project-scaffolding/vscode-extension.use-case.ts
|
|
6134
|
-
var
|
|
6135
|
-
var
|
|
6361
|
+
var import_node_fs28 = require("fs");
|
|
6362
|
+
var import_node_path30 = require("path");
|
|
6136
6363
|
var VSCODE_EXTENSION_SCRIPT_PATH = "tools/vscode-extension.cjs";
|
|
6137
6364
|
var VSCODE_ENGINE_FLOOR = "1.96.0";
|
|
6138
6365
|
var VSCODE_SIDECAR_TARGETS = {
|
|
@@ -6317,8 +6544,8 @@ export const window = {
|
|
|
6317
6544
|
var VSCODE_STUB_PATH = "test/vscode.stub.ts";
|
|
6318
6545
|
function mapVscodeToStub(projectRoot, testRunner) {
|
|
6319
6546
|
const [file, anchor, mapping] = testRunner === "jest" ? ["jest.config.cts", "testEnvironment: 'node',", `moduleNameMapper: { '^vscode$': '<rootDir>/${VSCODE_STUB_PATH}' },`] : ["vitest.config.mts", "environment: 'node',", `alias: { vscode: \`\${import.meta.dirname}/${VSCODE_STUB_PATH}\` },`];
|
|
6320
|
-
const path = (0,
|
|
6321
|
-
const content = fileExists(path) ? (0,
|
|
6547
|
+
const path = (0, import_node_path30.join)(projectRoot, file);
|
|
6548
|
+
const content = fileExists(path) ? (0, import_node_fs28.readFileSync)(path, "utf8") : "";
|
|
6322
6549
|
const line = content.split("\n").find((candidate) => candidate.trim() === anchor);
|
|
6323
6550
|
if (line === void 0) {
|
|
6324
6551
|
throw new Error(`${file} has no "${anchor}" line to map the vscode module after; map 'vscode' to ${VSCODE_STUB_PATH} by hand.`);
|
|
@@ -6338,11 +6565,11 @@ function ensureVscodeToolchain(workspaceRoot) {
|
|
|
6338
6565
|
}
|
|
6339
6566
|
}
|
|
6340
6567
|
function defaultPublisher(workspaceRoot) {
|
|
6341
|
-
const { name } = readJson((0,
|
|
6568
|
+
const { name } = readJson((0, import_node_path30.join)(workspaceRoot, "package.json"));
|
|
6342
6569
|
return (name ?? "publisher").replace(/^@/, "").split("/", 1)[0];
|
|
6343
6570
|
}
|
|
6344
6571
|
function reshapeManifest(projectRoot, name, publisher) {
|
|
6345
|
-
const manifestPath = (0,
|
|
6572
|
+
const manifestPath = (0, import_node_path30.join)(projectRoot, "package.json");
|
|
6346
6573
|
const manifest = readJson(manifestPath);
|
|
6347
6574
|
const { nx = {}, ...rest } = manifest;
|
|
6348
6575
|
const targets = { ...nx.targets };
|
|
@@ -6406,11 +6633,11 @@ function vscodeExtensionPublishTarget(name, sidecar) {
|
|
|
6406
6633
|
};
|
|
6407
6634
|
}
|
|
6408
6635
|
function addDebugLaunch(workspaceRoot, name) {
|
|
6409
|
-
const file = (0,
|
|
6636
|
+
const file = (0, import_node_fs28.readdirSync)(workspaceRoot).find((entry) => entry.endsWith(".code-workspace"));
|
|
6410
6637
|
if (file === void 0) {
|
|
6411
6638
|
return;
|
|
6412
6639
|
}
|
|
6413
|
-
const path = (0,
|
|
6640
|
+
const path = (0, import_node_path30.join)(workspaceRoot, file);
|
|
6414
6641
|
const workspace = readCodeWorkspace(path) ?? {};
|
|
6415
6642
|
const folder = `\${workspaceFolder:${workspace.folders?.[0]?.name ?? file.replace(/\.code-workspace$/, "")}}`;
|
|
6416
6643
|
const taskLabel = `${name}: build (development)`;
|
|
@@ -6443,39 +6670,39 @@ function addDebugLaunch(workspaceRoot, name) {
|
|
|
6443
6670
|
);
|
|
6444
6671
|
}
|
|
6445
6672
|
function refreshVscodeExtensionScript(workspaceRoot) {
|
|
6446
|
-
const apps = (0,
|
|
6673
|
+
const apps = (0, import_node_path30.join)(workspaceRoot, "apps");
|
|
6447
6674
|
let entries;
|
|
6448
6675
|
try {
|
|
6449
|
-
entries = (0,
|
|
6676
|
+
entries = (0, import_node_fs28.readdirSync)(apps);
|
|
6450
6677
|
} catch {
|
|
6451
6678
|
return false;
|
|
6452
6679
|
}
|
|
6453
6680
|
const hasExtension = entries.some((entry) => {
|
|
6454
|
-
const manifestPath = (0,
|
|
6681
|
+
const manifestPath = (0, import_node_path30.join)(apps, entry, "package.json");
|
|
6455
6682
|
if (!fileExists(manifestPath)) {
|
|
6456
6683
|
return false;
|
|
6457
6684
|
}
|
|
6458
6685
|
const tags = readJson(manifestPath).nx?.tags ?? [];
|
|
6459
6686
|
return tags.includes(VSCODE_EXTENSION_TAG);
|
|
6460
6687
|
});
|
|
6461
|
-
const path = (0,
|
|
6462
|
-
if (!hasExtension || fileExists(path) && (0,
|
|
6688
|
+
const path = (0, import_node_path30.join)(workspaceRoot, VSCODE_EXTENSION_SCRIPT_PATH);
|
|
6689
|
+
if (!hasExtension || fileExists(path) && (0, import_node_fs28.readFileSync)(path, "utf8") === VSCODE_EXTENSION_SCRIPT) {
|
|
6463
6690
|
return false;
|
|
6464
6691
|
}
|
|
6465
6692
|
writeFileEnsured(path, VSCODE_EXTENSION_SCRIPT);
|
|
6466
6693
|
return true;
|
|
6467
6694
|
}
|
|
6468
6695
|
function pinVscodeExtensionProjectNames(workspaceRoot) {
|
|
6469
|
-
const apps = (0,
|
|
6696
|
+
const apps = (0, import_node_path30.join)(workspaceRoot, "apps");
|
|
6470
6697
|
let entries;
|
|
6471
6698
|
try {
|
|
6472
|
-
entries = (0,
|
|
6699
|
+
entries = (0, import_node_fs28.readdirSync)(apps);
|
|
6473
6700
|
} catch {
|
|
6474
6701
|
return [];
|
|
6475
6702
|
}
|
|
6476
6703
|
const updated = [];
|
|
6477
6704
|
for (const entry of entries) {
|
|
6478
|
-
const manifestPath = (0,
|
|
6705
|
+
const manifestPath = (0, import_node_path30.join)(apps, entry, "package.json");
|
|
6479
6706
|
if (!fileExists(manifestPath)) {
|
|
6480
6707
|
continue;
|
|
6481
6708
|
}
|
|
@@ -6495,22 +6722,22 @@ function refreshLockFile(workspaceRoot, name) {
|
|
|
6495
6722
|
}
|
|
6496
6723
|
function addVscodeExtension(workspaceRoot, name, stack, options = {}) {
|
|
6497
6724
|
const { sidecar } = options;
|
|
6498
|
-
if (sidecar !== void 0 && !fileExists((0,
|
|
6725
|
+
if (sidecar !== void 0 && !fileExists((0, import_node_path30.join)(workspaceRoot, "apps", sidecar, "project.json"))) {
|
|
6499
6726
|
throw new Error(`--sidecar ${sidecar}: no Go app at apps/${sidecar}. Add it first with \`mnci add go-app ${sidecar}\`.`);
|
|
6500
6727
|
}
|
|
6501
6728
|
runNodeApp(workspaceRoot, name, stack, "none");
|
|
6502
6729
|
ensureVscodeToolchain(workspaceRoot);
|
|
6503
|
-
const projectRoot = (0,
|
|
6730
|
+
const projectRoot = (0, import_node_path30.join)(workspaceRoot, "apps", name);
|
|
6504
6731
|
reshapeManifest(projectRoot, name, options.publisher ?? defaultPublisher(workspaceRoot));
|
|
6505
|
-
addVscodeTypes((0,
|
|
6506
|
-
addVscodeTypes((0,
|
|
6507
|
-
writeFileEnsured((0,
|
|
6508
|
-
writeFileEnsured((0,
|
|
6509
|
-
writeFileEnsured((0,
|
|
6732
|
+
addVscodeTypes((0, import_node_path30.join)(projectRoot, "tsconfig.app.json"));
|
|
6733
|
+
addVscodeTypes((0, import_node_path30.join)(projectRoot, "tsconfig.spec.json"));
|
|
6734
|
+
writeFileEnsured((0, import_node_path30.join)(projectRoot, "src/main.ts"), vscodeExtensionMain(name));
|
|
6735
|
+
writeFileEnsured((0, import_node_path30.join)(projectRoot, "src/main.spec.ts"), vscodeExtensionMainSpec(name));
|
|
6736
|
+
writeFileEnsured((0, import_node_path30.join)(projectRoot, VSCODE_STUB_PATH), VSCODE_STUB);
|
|
6510
6737
|
mapVscodeToStub(projectRoot, stack.testRunner);
|
|
6511
|
-
writeFileEnsured((0,
|
|
6512
|
-
writeFileEnsured((0,
|
|
6513
|
-
addNxTargets((0,
|
|
6738
|
+
writeFileEnsured((0, import_node_path30.join)(projectRoot, ".vscodeignore"), VSCODE_IGNORE);
|
|
6739
|
+
writeFileEnsured((0, import_node_path30.join)(workspaceRoot, VSCODE_EXTENSION_SCRIPT_PATH), VSCODE_EXTENSION_SCRIPT);
|
|
6740
|
+
addNxTargets((0, import_node_path30.join)(projectRoot, "package.json"), {
|
|
6514
6741
|
"package": vscodeExtensionPackageTarget(name, sidecar),
|
|
6515
6742
|
"nx-release-publish": vscodeExtensionPublishTarget(name, sidecar)
|
|
6516
6743
|
});
|
|
@@ -6521,12 +6748,12 @@ function addVscodeExtension(workspaceRoot, name, stack, options = {}) {
|
|
|
6521
6748
|
}
|
|
6522
6749
|
|
|
6523
6750
|
// src/dependency-management/install-dependencies.use-case.ts
|
|
6524
|
-
var
|
|
6525
|
-
var
|
|
6751
|
+
var import_node_fs30 = require("fs");
|
|
6752
|
+
var import_node_path32 = require("path");
|
|
6526
6753
|
|
|
6527
6754
|
// src/dependency-management/manifest.repository.ts
|
|
6528
|
-
var
|
|
6529
|
-
var
|
|
6755
|
+
var import_node_fs29 = require("fs");
|
|
6756
|
+
var import_node_path31 = require("path");
|
|
6530
6757
|
var ECOSYSTEMS = ["npm", "pip", "pub", "nuget", "go"];
|
|
6531
6758
|
var ROOT_LABEL = "(root)";
|
|
6532
6759
|
var MANIFEST_GLOBS = {
|
|
@@ -6559,23 +6786,23 @@ function projectOf(manifestRelativePath) {
|
|
|
6559
6786
|
}
|
|
6560
6787
|
function hasEcosystem(workspaceRoot, ecosystem) {
|
|
6561
6788
|
if (ecosystem === "go") {
|
|
6562
|
-
return fileExists((0,
|
|
6789
|
+
return fileExists((0, import_node_path31.join)(workspaceRoot, "go.mod"));
|
|
6563
6790
|
}
|
|
6564
6791
|
if (ecosystem === "nuget") {
|
|
6565
|
-
return (0,
|
|
6792
|
+
return (0, import_node_fs29.globSync)(MANIFEST_GLOBS.nuget, { cwd: workspaceRoot }).length > 0;
|
|
6566
6793
|
}
|
|
6567
6794
|
const rootMarker = {
|
|
6568
6795
|
npm: "package.json",
|
|
6569
6796
|
pip: "requirements-dev.txt",
|
|
6570
6797
|
pub: "pubspec.yaml"
|
|
6571
6798
|
};
|
|
6572
|
-
return fileExists((0,
|
|
6799
|
+
return fileExists((0, import_node_path31.join)(workspaceRoot, rootMarker[ecosystem])) || (0, import_node_fs29.globSync)(MANIFEST_GLOBS[ecosystem], { cwd: workspaceRoot }).length > 0;
|
|
6573
6800
|
}
|
|
6574
6801
|
function collectNpm(workspaceRoot) {
|
|
6575
6802
|
const sites = [];
|
|
6576
|
-
const relativePaths = ["package.json", ...(0,
|
|
6803
|
+
const relativePaths = ["package.json", ...(0, import_node_fs29.globSync)(MANIFEST_GLOBS.npm, { cwd: workspaceRoot })];
|
|
6577
6804
|
for (const relativePath of relativePaths) {
|
|
6578
|
-
const manifestPath = (0,
|
|
6805
|
+
const manifestPath = (0, import_node_path31.join)(workspaceRoot, relativePath);
|
|
6579
6806
|
try {
|
|
6580
6807
|
const manifest = readJson(manifestPath);
|
|
6581
6808
|
sites.push(...npmManifestSites(manifest, relativePath, manifestPath));
|
|
@@ -6636,17 +6863,17 @@ function collectPip(workspaceRoot) {
|
|
|
6636
6863
|
name: parsed.name,
|
|
6637
6864
|
ecosystem: "pip",
|
|
6638
6865
|
project: projectOf(relativePath),
|
|
6639
|
-
manifestPath: (0,
|
|
6866
|
+
manifestPath: (0, import_node_path31.join)(workspaceRoot, relativePath),
|
|
6640
6867
|
section,
|
|
6641
6868
|
spec: parsed.spec,
|
|
6642
6869
|
rewritable: parsed.rewritable && parsed.spec !== ""
|
|
6643
6870
|
});
|
|
6644
6871
|
};
|
|
6645
|
-
const pyprojectPaths = (0,
|
|
6872
|
+
const pyprojectPaths = (0, import_node_fs29.globSync)(MANIFEST_GLOBS.pip, { cwd: workspaceRoot });
|
|
6646
6873
|
for (const relativePath of pyprojectPaths) {
|
|
6647
6874
|
let content;
|
|
6648
6875
|
try {
|
|
6649
|
-
content = (0,
|
|
6876
|
+
content = (0, import_node_fs29.readFileSync)((0, import_node_path31.join)(workspaceRoot, relativePath), "utf8");
|
|
6650
6877
|
} catch {
|
|
6651
6878
|
continue;
|
|
6652
6879
|
}
|
|
@@ -6657,14 +6884,14 @@ function collectPip(workspaceRoot) {
|
|
|
6657
6884
|
}
|
|
6658
6885
|
const requirementsPaths = [
|
|
6659
6886
|
"requirements-dev.txt",
|
|
6660
|
-
...(0,
|
|
6887
|
+
...(0, import_node_fs29.globSync)("apps/*/requirements.txt", { cwd: workspaceRoot })
|
|
6661
6888
|
];
|
|
6662
6889
|
for (const relativePath of requirementsPaths) {
|
|
6663
|
-
if (!fileExists((0,
|
|
6890
|
+
if (!fileExists((0, import_node_path31.join)(workspaceRoot, relativePath))) {
|
|
6664
6891
|
continue;
|
|
6665
6892
|
}
|
|
6666
6893
|
const section = relativePath === "requirements-dev.txt" ? "devDep" : "dep";
|
|
6667
|
-
const lines = (0,
|
|
6894
|
+
const lines = (0, import_node_fs29.readFileSync)((0, import_node_path31.join)(workspaceRoot, relativePath), "utf8").split(/\r?\n/);
|
|
6668
6895
|
for (const line of lines) {
|
|
6669
6896
|
push(relativePath, section, line);
|
|
6670
6897
|
}
|
|
@@ -6702,11 +6929,11 @@ function pyprojectDependencies(content) {
|
|
|
6702
6929
|
}
|
|
6703
6930
|
function collectPub(workspaceRoot) {
|
|
6704
6931
|
const sites = [];
|
|
6705
|
-
const pubspecPaths = (0,
|
|
6932
|
+
const pubspecPaths = (0, import_node_fs29.globSync)(MANIFEST_GLOBS.pub, { cwd: workspaceRoot });
|
|
6706
6933
|
for (const relativePath of pubspecPaths) {
|
|
6707
6934
|
let content;
|
|
6708
6935
|
try {
|
|
6709
|
-
content = (0,
|
|
6936
|
+
content = (0, import_node_fs29.readFileSync)((0, import_node_path31.join)(workspaceRoot, relativePath), "utf8");
|
|
6710
6937
|
} catch {
|
|
6711
6938
|
continue;
|
|
6712
6939
|
}
|
|
@@ -6716,7 +6943,7 @@ function collectPub(workspaceRoot) {
|
|
|
6716
6943
|
name: entry.name,
|
|
6717
6944
|
ecosystem: "pub",
|
|
6718
6945
|
project: projectOf(relativePath),
|
|
6719
|
-
manifestPath: (0,
|
|
6946
|
+
manifestPath: (0, import_node_path31.join)(workspaceRoot, relativePath),
|
|
6720
6947
|
section: block === "dependencies" ? "dep" : "devDep",
|
|
6721
6948
|
spec: entry.spec,
|
|
6722
6949
|
rewritable: entry.spec !== ""
|
|
@@ -6766,11 +6993,11 @@ function stripQuotes(value) {
|
|
|
6766
6993
|
}
|
|
6767
6994
|
function collectNuget(workspaceRoot) {
|
|
6768
6995
|
const sites = [];
|
|
6769
|
-
const csprojPaths = (0,
|
|
6996
|
+
const csprojPaths = (0, import_node_fs29.globSync)(MANIFEST_GLOBS.nuget, { cwd: workspaceRoot });
|
|
6770
6997
|
for (const relativePath of csprojPaths) {
|
|
6771
6998
|
let content;
|
|
6772
6999
|
try {
|
|
6773
|
-
content = (0,
|
|
7000
|
+
content = (0, import_node_fs29.readFileSync)((0, import_node_path31.join)(workspaceRoot, relativePath), "utf8");
|
|
6774
7001
|
} catch {
|
|
6775
7002
|
continue;
|
|
6776
7003
|
}
|
|
@@ -6779,7 +7006,7 @@ function collectNuget(workspaceRoot) {
|
|
|
6779
7006
|
name: entry.name,
|
|
6780
7007
|
ecosystem: "nuget",
|
|
6781
7008
|
project: projectOf(relativePath),
|
|
6782
|
-
manifestPath: (0,
|
|
7009
|
+
manifestPath: (0, import_node_path31.join)(workspaceRoot, relativePath),
|
|
6783
7010
|
section: "dep",
|
|
6784
7011
|
spec: entry.spec,
|
|
6785
7012
|
// A plain SemVer string is rewritable; an MSBuild property reference
|
|
@@ -6804,13 +7031,13 @@ function csprojPackageReferences(content) {
|
|
|
6804
7031
|
return entries;
|
|
6805
7032
|
}
|
|
6806
7033
|
function collectGo(workspaceRoot) {
|
|
6807
|
-
const manifestPath = (0,
|
|
7034
|
+
const manifestPath = (0, import_node_path31.join)(workspaceRoot, "go.mod");
|
|
6808
7035
|
if (!fileExists(manifestPath)) {
|
|
6809
7036
|
return [];
|
|
6810
7037
|
}
|
|
6811
7038
|
let content;
|
|
6812
7039
|
try {
|
|
6813
|
-
content = (0,
|
|
7040
|
+
content = (0, import_node_fs29.readFileSync)(manifestPath, "utf8");
|
|
6814
7041
|
} catch {
|
|
6815
7042
|
return [];
|
|
6816
7043
|
}
|
|
@@ -6859,7 +7086,7 @@ var PROJECT_GLOBS = {
|
|
|
6859
7086
|
function locateProjects(workspaceRoot) {
|
|
6860
7087
|
const locations = [];
|
|
6861
7088
|
for (const ecosystem of ECOSYSTEMS) {
|
|
6862
|
-
const relativePaths = (0,
|
|
7089
|
+
const relativePaths = (0, import_node_fs29.globSync)(PROJECT_GLOBS[ecosystem], { cwd: workspaceRoot });
|
|
6863
7090
|
for (const relativePath of relativePaths) {
|
|
6864
7091
|
const posix = toPosix(relativePath);
|
|
6865
7092
|
const dir = posix.slice(0, posix.lastIndexOf("/"));
|
|
@@ -6867,7 +7094,7 @@ function locateProjects(workspaceRoot) {
|
|
|
6867
7094
|
ecosystem,
|
|
6868
7095
|
dir,
|
|
6869
7096
|
name: dir.slice(dir.lastIndexOf("/") + 1),
|
|
6870
|
-
manifestPath: (0,
|
|
7097
|
+
manifestPath: (0, import_node_path31.join)(workspaceRoot, relativePath)
|
|
6871
7098
|
});
|
|
6872
7099
|
}
|
|
6873
7100
|
}
|
|
@@ -6888,7 +7115,7 @@ function rewriteSpec(site, spec) {
|
|
|
6888
7115
|
writeFileEnsured(site.manifestPath, toJson(manifest));
|
|
6889
7116
|
return true;
|
|
6890
7117
|
}
|
|
6891
|
-
const before = (0,
|
|
7118
|
+
const before = (0, import_node_fs29.readFileSync)(site.manifestPath, "utf8");
|
|
6892
7119
|
const after = (() => {
|
|
6893
7120
|
switch (site.ecosystem) {
|
|
6894
7121
|
case "pip": {
|
|
@@ -6979,13 +7206,13 @@ function escapeForRegex(value) {
|
|
|
6979
7206
|
function isWorkspaceProject(workspaceRoot, name) {
|
|
6980
7207
|
const short = name.includes("/") ? name.split("/").at(-1) : name;
|
|
6981
7208
|
return ["apps", "libs", "packages"].some(
|
|
6982
|
-
(directory) => fileExists((0,
|
|
7209
|
+
(directory) => fileExists((0, import_node_path31.join)(workspaceRoot, directory, short ?? name, "package.json"))
|
|
6983
7210
|
);
|
|
6984
7211
|
}
|
|
6985
7212
|
function isAliasedInstall(workspaceRoot, name) {
|
|
6986
7213
|
try {
|
|
6987
7214
|
const installed = readJson(
|
|
6988
|
-
(0,
|
|
7215
|
+
(0, import_node_path31.join)(workspaceRoot, "node_modules", name, "package.json")
|
|
6989
7216
|
);
|
|
6990
7217
|
return installed.name !== void 0 && installed.name !== name;
|
|
6991
7218
|
} catch {
|
|
@@ -6996,14 +7223,14 @@ function resolvedVersion(workspaceRoot, ecosystem, name) {
|
|
|
6996
7223
|
if (ecosystem === "npm") {
|
|
6997
7224
|
try {
|
|
6998
7225
|
return readJson(
|
|
6999
|
-
(0,
|
|
7226
|
+
(0, import_node_path31.join)(workspaceRoot, "node_modules", name, "package.json")
|
|
7000
7227
|
).version;
|
|
7001
7228
|
} catch {
|
|
7002
7229
|
return void 0;
|
|
7003
7230
|
}
|
|
7004
7231
|
}
|
|
7005
7232
|
if (ecosystem === "pub") {
|
|
7006
|
-
const lockPath = (0,
|
|
7233
|
+
const lockPath = (0, import_node_path31.join)(workspaceRoot, "pubspec.lock");
|
|
7007
7234
|
if (!fileExists(lockPath)) {
|
|
7008
7235
|
return void 0;
|
|
7009
7236
|
}
|
|
@@ -7011,7 +7238,7 @@ function resolvedVersion(workspaceRoot, ecosystem, name) {
|
|
|
7011
7238
|
const match = new RegExp(
|
|
7012
7239
|
String.raw`^\s{2}${escapeForRegex(name)}:[^]*?^\s+version:\s*["']?([^"'\s]+)`,
|
|
7013
7240
|
"m"
|
|
7014
|
-
).exec((0,
|
|
7241
|
+
).exec((0, import_node_fs29.readFileSync)(lockPath, "utf8"));
|
|
7015
7242
|
return match?.[1];
|
|
7016
7243
|
} catch {
|
|
7017
7244
|
return void 0;
|
|
@@ -7077,7 +7304,7 @@ function resolveTarget(locations, target) {
|
|
|
7077
7304
|
return byName[0];
|
|
7078
7305
|
}
|
|
7079
7306
|
function installInto(workspaceRoot, location, packages, saveDev) {
|
|
7080
|
-
const projectDir = (0,
|
|
7307
|
+
const projectDir = (0, import_node_path32.join)(workspaceRoot, location.dir);
|
|
7081
7308
|
switch (location.ecosystem) {
|
|
7082
7309
|
case "npm": {
|
|
7083
7310
|
const flags = saveDev ? ["--save-dev"] : [];
|
|
@@ -7130,7 +7357,7 @@ function installInto(workspaceRoot, location, packages, saveDev) {
|
|
|
7130
7357
|
function addPythonDependency(manifestPath, specifier) {
|
|
7131
7358
|
let content;
|
|
7132
7359
|
try {
|
|
7133
|
-
content = (0,
|
|
7360
|
+
content = (0, import_node_fs30.readFileSync)(manifestPath, "utf8");
|
|
7134
7361
|
} catch {
|
|
7135
7362
|
logger.warn(`Could not read ${manifestPath} \u2014 skipped ${specifier}`);
|
|
7136
7363
|
return;
|
|
@@ -7159,7 +7386,7 @@ function installEverything(workspaceRoot, only) {
|
|
|
7159
7386
|
}
|
|
7160
7387
|
function ecosystemPresent(workspaceRoot, ecosystem) {
|
|
7161
7388
|
if (ecosystem === "go") {
|
|
7162
|
-
return fileExists((0,
|
|
7389
|
+
return fileExists((0, import_node_path32.join)(workspaceRoot, "go.work")) || fileExists((0, import_node_path32.join)(workspaceRoot, "go.mod"));
|
|
7163
7390
|
}
|
|
7164
7391
|
return hasEcosystem(workspaceRoot, ecosystem);
|
|
7165
7392
|
}
|
|
@@ -7178,7 +7405,7 @@ function splitAtLast(value, separator) {
|
|
|
7178
7405
|
}
|
|
7179
7406
|
|
|
7180
7407
|
// src/dependency-management/sync-dependencies.use-case.ts
|
|
7181
|
-
var
|
|
7408
|
+
var import_node_path33 = require("path");
|
|
7182
7409
|
|
|
7183
7410
|
// src/dependency-management/semver.algorithm.ts
|
|
7184
7411
|
var UPDATE_KINDS = ["patch", "minor", "major", "non-semver"];
|
|
@@ -7355,7 +7582,7 @@ function describe(finding) {
|
|
|
7355
7582
|
return `${finding.name} \u2192 ${finding.target} (${finding.reason}); disagreeing: ${sites}`;
|
|
7356
7583
|
}
|
|
7357
7584
|
function runSync(workspaceRoot, options) {
|
|
7358
|
-
if (!fileExists((0,
|
|
7585
|
+
if (!fileExists((0, import_node_path33.join)(workspaceRoot, "nx.json"))) {
|
|
7359
7586
|
throw new Error(
|
|
7360
7587
|
`No nx.json found in ${workspaceRoot} \u2014 run 'mnci sync' from the workspace root.`
|
|
7361
7588
|
);
|
|
@@ -7405,7 +7632,7 @@ function runSync(workspaceRoot, options) {
|
|
|
7405
7632
|
}
|
|
7406
7633
|
|
|
7407
7634
|
// src/dependency-management/update-dependencies.use-case.ts
|
|
7408
|
-
var
|
|
7635
|
+
var import_node_path34 = require("path");
|
|
7409
7636
|
var import_prompts2 = require("@inquirer/prompts");
|
|
7410
7637
|
|
|
7411
7638
|
// src/dependency-management/registry.client.ts
|
|
@@ -7688,7 +7915,7 @@ function reinstall(workspaceRoot, ecosystems) {
|
|
|
7688
7915
|
function hasPythonInstallScript(workspaceRoot) {
|
|
7689
7916
|
try {
|
|
7690
7917
|
const manifest = readJson(
|
|
7691
|
-
(0,
|
|
7918
|
+
(0, import_node_path34.join)(workspaceRoot, "package.json")
|
|
7692
7919
|
);
|
|
7693
7920
|
return manifest.scripts?.["python:install"] !== void 0;
|
|
7694
7921
|
} catch {
|
|
@@ -7704,7 +7931,7 @@ function applyGoUpdates(workspaceRoot, entries) {
|
|
|
7704
7931
|
}
|
|
7705
7932
|
}
|
|
7706
7933
|
async function runUp(workspaceRoot, options) {
|
|
7707
|
-
if (!fileExists((0,
|
|
7934
|
+
if (!fileExists((0, import_node_path34.join)(workspaceRoot, "nx.json"))) {
|
|
7708
7935
|
throw new Error(`No nx.json found in ${workspaceRoot} \u2014 run 'mnci up' from the workspace root.`);
|
|
7709
7936
|
}
|
|
7710
7937
|
const ecosystems = resolveEcosystems(options.ecosystem);
|
|
@@ -7776,12 +8003,13 @@ var PROJECT_KINDS = [
|
|
|
7776
8003
|
"csharp-function-app",
|
|
7777
8004
|
"csharp-lib",
|
|
7778
8005
|
"csharp-internal-lib",
|
|
7779
|
-
"vscode-extension"
|
|
8006
|
+
"vscode-extension",
|
|
8007
|
+
"container"
|
|
7780
8008
|
];
|
|
7781
8009
|
var EMPTY_KINDS = /* @__PURE__ */ new Set(["npm-lib", "internal-lib", "react-lib", "react-internal-lib", "node-function-app"]);
|
|
7782
8010
|
async function runAdd(kind, name, options) {
|
|
7783
8011
|
const workspaceRoot = process.cwd();
|
|
7784
|
-
if (!fileExists((0,
|
|
8012
|
+
if (!fileExists((0, import_node_path35.join)(workspaceRoot, "nx.json"))) {
|
|
7785
8013
|
throw new Error("No nx.json found here. Run `add` from the workspace root.");
|
|
7786
8014
|
}
|
|
7787
8015
|
const stack = readWorkspaceStack(workspaceRoot);
|
|
@@ -7810,6 +8038,17 @@ async function runAdd(kind, name, options) {
|
|
|
7810
8038
|
throw new Error(`--esm is not supported with --framework ${options.framework}: its layout (autoloaded routes, decorators) is mandated by the framework. Use express, koa or none.`);
|
|
7811
8039
|
}
|
|
7812
8040
|
}
|
|
8041
|
+
if (resolvedKind === "container" && options.app === void 0) {
|
|
8042
|
+
throw new Error("container needs --app <project>: the app to put in an image, for example `mnci add container api-image --app api`.");
|
|
8043
|
+
}
|
|
8044
|
+
for (const [flag, requested] of [["--app", options.app !== void 0], ["--port", options.port !== void 0]]) {
|
|
8045
|
+
if (resolvedKind !== "container" && requested) {
|
|
8046
|
+
throw new Error(`${flag} applies to container, not ${resolvedKind}.`);
|
|
8047
|
+
}
|
|
8048
|
+
}
|
|
8049
|
+
if (options.port !== void 0 && !/^\d+$/.test(options.port)) {
|
|
8050
|
+
throw new Error(`--port ${options.port}: a port is a whole number.`);
|
|
8051
|
+
}
|
|
7813
8052
|
if (resolvedKind !== "react-app" && options.e2e === true) {
|
|
7814
8053
|
throw new Error(`--e2e applies to react-app, not ${resolvedKind}.`);
|
|
7815
8054
|
}
|
|
@@ -7855,8 +8094,8 @@ async function runAdd(kind, name, options) {
|
|
|
7855
8094
|
],
|
|
7856
8095
|
workspaceRoot
|
|
7857
8096
|
);
|
|
7858
|
-
markPrivate((0,
|
|
7859
|
-
renameScaffoldPlaceholder((0,
|
|
8097
|
+
markPrivate((0, import_node_path35.join)(workspaceRoot, "libs", resolvedName, "package.json"));
|
|
8098
|
+
renameScaffoldPlaceholder((0, import_node_path35.join)(workspaceRoot, "libs", resolvedName), resolvedName, options.empty === true);
|
|
7860
8099
|
removeGeneratedEslintConfig(workspaceRoot, `libs/${resolvedName}`);
|
|
7861
8100
|
registerProjectCommands(workspaceRoot, resolvedName, { build: true });
|
|
7862
8101
|
break;
|
|
@@ -7877,6 +8116,10 @@ async function runAdd(kind, name, options) {
|
|
|
7877
8116
|
addPythonInternalLib(workspaceRoot, resolvedName);
|
|
7878
8117
|
break;
|
|
7879
8118
|
}
|
|
8119
|
+
case "container": {
|
|
8120
|
+
addContainer(workspaceRoot, resolvedName, { app: options.app, port: options.port === void 0 ? void 0 : Number(options.port) });
|
|
8121
|
+
break;
|
|
8122
|
+
}
|
|
7880
8123
|
case "go-app": {
|
|
7881
8124
|
addGoApp(workspaceRoot, resolvedName, { release: options.release, cgo: options.cgo, web: options.web });
|
|
7882
8125
|
break;
|
|
@@ -7948,7 +8191,7 @@ async function runAdd(kind, name, options) {
|
|
|
7948
8191
|
}
|
|
7949
8192
|
function readWorkspaceStack(workspaceRoot) {
|
|
7950
8193
|
const nxJson = readJson(
|
|
7951
|
-
(0,
|
|
8194
|
+
(0, import_node_path35.join)(workspaceRoot, "nx.json")
|
|
7952
8195
|
);
|
|
7953
8196
|
const stack = nxJson.mnci?.stack;
|
|
7954
8197
|
return {
|
|
@@ -7965,6 +8208,7 @@ var PROJECT_KIND_CATALOG = [
|
|
|
7965
8208
|
{ kind: "node-function-app", language: "typescript", label: "Node function app", description: "An Azure Functions (v4) app in TypeScript", flags: ["empty", "esm"], requiredFlags: [] },
|
|
7966
8209
|
{ kind: "npm-lib", language: "typescript", label: "npm library", description: "A library published to npm, bundled with Rollup", flags: ["scope", "empty"], requiredFlags: [] },
|
|
7967
8210
|
{ kind: "internal-lib", language: "typescript", label: "Internal library", description: "A private TypeScript library for apps in this workspace", flags: ["empty"], requiredFlags: [] },
|
|
8211
|
+
{ kind: "container", language: "container", label: "Container image", description: "A Dockerfile and image targets for an existing Node, React or Go app", flags: ["app", "port"], requiredFlags: ["app"] },
|
|
7968
8212
|
{ kind: "vscode-extension", language: "typescript", label: "VS Code extension", description: "A bundled Marketplace extension, optionally shipping a Go sidecar", flags: ["publisher", "sidecar"], requiredFlags: [] },
|
|
7969
8213
|
{ kind: "python-app", language: "python", label: "Python app", description: "A pip-native Python application (Ruff, pytest)", flags: [], requiredFlags: [] },
|
|
7970
8214
|
{ kind: "python-function-app", language: "python", label: "Python function app", description: "An Azure Functions (v2 model) app in Python", flags: [], requiredFlags: [] },
|
|
@@ -7995,14 +8239,130 @@ function runKinds(options) {
|
|
|
7995
8239
|
}
|
|
7996
8240
|
}
|
|
7997
8241
|
|
|
7998
|
-
// src/
|
|
8242
|
+
// src/dev-servers/run-dev.use-case.ts
|
|
8243
|
+
var import_prompts4 = require("@inquirer/prompts");
|
|
8244
|
+
|
|
8245
|
+
// src/dev-servers/spawn-project.client.ts
|
|
7999
8246
|
var import_node_child_process = require("child_process");
|
|
8000
|
-
var
|
|
8247
|
+
var import_node_readline = require("readline");
|
|
8248
|
+
var import_cross_spawn3 = __toESM(require("cross-spawn"));
|
|
8249
|
+
function spawnProject(workspaceRoot, project, target, onLine) {
|
|
8250
|
+
const windows = process.platform === "win32";
|
|
8251
|
+
const child = (0, import_cross_spawn3.default)("npx", ["nx", "run", `${project}:${target}`], { cwd: workspaceRoot, stdio: ["ignore", "pipe", "pipe"], detached: !windows });
|
|
8252
|
+
for (const stream of [child.stdout, child.stderr]) {
|
|
8253
|
+
if (stream !== null) {
|
|
8254
|
+
(0, import_node_readline.createInterface)({ input: stream }).on("line", onLine);
|
|
8255
|
+
}
|
|
8256
|
+
}
|
|
8257
|
+
const exited = new Promise((resolve2) => {
|
|
8258
|
+
child.on("error", () => {
|
|
8259
|
+
resolve2(1);
|
|
8260
|
+
});
|
|
8261
|
+
child.on("close", (code) => {
|
|
8262
|
+
resolve2(code ?? 1);
|
|
8263
|
+
});
|
|
8264
|
+
});
|
|
8265
|
+
const stop = () => {
|
|
8266
|
+
if (child.pid === void 0 || child.exitCode !== null) {
|
|
8267
|
+
return;
|
|
8268
|
+
}
|
|
8269
|
+
if (windows) {
|
|
8270
|
+
(0, import_node_child_process.spawnSync)("taskkill", ["/pid", String(child.pid), "/T", "/F"], { stdio: "ignore" });
|
|
8271
|
+
} else {
|
|
8272
|
+
try {
|
|
8273
|
+
process.kill(-child.pid, "SIGTERM");
|
|
8274
|
+
} catch {
|
|
8275
|
+
child.kill("SIGTERM");
|
|
8276
|
+
}
|
|
8277
|
+
}
|
|
8278
|
+
};
|
|
8279
|
+
return { stop, exited };
|
|
8280
|
+
}
|
|
8281
|
+
|
|
8282
|
+
// src/dev-servers/startable-projects.use-case.ts
|
|
8001
8283
|
var import_node_path36 = require("path");
|
|
8284
|
+
var START_SUFFIX = ":start";
|
|
8285
|
+
var NX_RUN = /\bnx run [^\s:]+:(\S+)/;
|
|
8286
|
+
function listStartableProjects(workspaceRoot) {
|
|
8287
|
+
const manifestPath = (0, import_node_path36.join)(workspaceRoot, "package.json");
|
|
8288
|
+
if (!fileExists(manifestPath)) {
|
|
8289
|
+
return [];
|
|
8290
|
+
}
|
|
8291
|
+
const scripts = readJson(manifestPath).scripts ?? {};
|
|
8292
|
+
return Object.entries(scripts).filter(([script]) => script.endsWith(START_SUFFIX)).map(([script, command]) => ({ project: script.slice(0, -START_SUFFIX.length), target: NX_RUN.exec(command)?.[1] ?? "start" })).toSorted((a, b) => a.project.localeCompare(b.project));
|
|
8293
|
+
}
|
|
8294
|
+
|
|
8295
|
+
// src/dev-servers/run-dev.use-case.ts
|
|
8296
|
+
async function chooseProjects(available) {
|
|
8297
|
+
return await (0, import_prompts4.checkbox)({
|
|
8298
|
+
message: "Which projects should start together?",
|
|
8299
|
+
choices: available.map((name) => ({ name, value: name })),
|
|
8300
|
+
required: true
|
|
8301
|
+
});
|
|
8302
|
+
}
|
|
8303
|
+
async function selectProjects(available, named, options, dependencies) {
|
|
8304
|
+
const names = available.map((entry) => entry.project);
|
|
8305
|
+
const unknown = named.filter((name) => !names.includes(name));
|
|
8306
|
+
if (unknown.length > 0) {
|
|
8307
|
+
throw new Error(`Cannot start ${unknown.join(", ")}: not a project with a start command. Startable: ${names.join(", ")}.`);
|
|
8308
|
+
}
|
|
8309
|
+
let chosen = named;
|
|
8310
|
+
if (chosen.length === 0) {
|
|
8311
|
+
if (options.all === true) {
|
|
8312
|
+
chosen = names;
|
|
8313
|
+
} else if (dependencies.interactive ?? process.stdin.isTTY) {
|
|
8314
|
+
chosen = await (dependencies.choose ?? chooseProjects)(names);
|
|
8315
|
+
} else {
|
|
8316
|
+
throw new Error(`Name the projects to start, or pass --all. Startable: ${names.join(", ")}.`);
|
|
8317
|
+
}
|
|
8318
|
+
}
|
|
8319
|
+
return available.filter((entry) => chosen.includes(entry.project));
|
|
8320
|
+
}
|
|
8321
|
+
async function runDev(workspaceRoot, named, options = {}, dependencies = {}) {
|
|
8322
|
+
const available = listStartableProjects(workspaceRoot);
|
|
8323
|
+
if (available.length === 0) {
|
|
8324
|
+
throw new Error("No project here has a start command. Add an app (`mnci add`) first; libraries are not started.");
|
|
8325
|
+
}
|
|
8326
|
+
const selected = await selectProjects(available, named, options, dependencies);
|
|
8327
|
+
for (const { project, target } of selected) {
|
|
8328
|
+
logger.info(`${project}: nx run ${project}:${target}`);
|
|
8329
|
+
}
|
|
8330
|
+
if (options.dryRun === true) {
|
|
8331
|
+
return;
|
|
8332
|
+
}
|
|
8333
|
+
const start = dependencies.start ?? ((project, target, onLine) => spawnProject(workspaceRoot, project, target, onLine));
|
|
8334
|
+
const print = dependencies.print ?? ((line) => {
|
|
8335
|
+
console.log(line);
|
|
8336
|
+
});
|
|
8337
|
+
const running = selected.map(({ project, target }) => start(project, target, (line) => {
|
|
8338
|
+
print(`[${project}] ${line}`);
|
|
8339
|
+
}));
|
|
8340
|
+
const stopAll = () => {
|
|
8341
|
+
for (const each of running) {
|
|
8342
|
+
each.stop();
|
|
8343
|
+
}
|
|
8344
|
+
};
|
|
8345
|
+
process.once("SIGINT", stopAll);
|
|
8346
|
+
process.once("SIGTERM", stopAll);
|
|
8347
|
+
const first = await Promise.race(running.map(async (each, index) => ({ index, status: await each.exited })));
|
|
8348
|
+
stopAll();
|
|
8349
|
+
await Promise.all(running.map(async (each) => await each.exited));
|
|
8350
|
+
process.removeListener("SIGINT", stopAll);
|
|
8351
|
+
process.removeListener("SIGTERM", stopAll);
|
|
8352
|
+
logger.info(`${selected[first.index].project} stopped (${first.status}), so the rest were stopped too.`);
|
|
8353
|
+
if (first.status !== 0) {
|
|
8354
|
+
process.exitCode = first.status;
|
|
8355
|
+
}
|
|
8356
|
+
}
|
|
8357
|
+
|
|
8358
|
+
// src/workspace-diagnostics/check-invariants.use-case.ts
|
|
8359
|
+
var import_node_child_process2 = require("child_process");
|
|
8360
|
+
var import_node_fs32 = require("fs");
|
|
8361
|
+
var import_node_path38 = require("path");
|
|
8002
8362
|
|
|
8003
8363
|
// src/workspace-diagnostics/locate-stranded-release-tags.use-case.ts
|
|
8004
|
-
var
|
|
8005
|
-
var
|
|
8364
|
+
var import_node_fs31 = require("fs");
|
|
8365
|
+
var import_node_path37 = require("path");
|
|
8006
8366
|
|
|
8007
8367
|
// src/workspace-diagnostics/stranded-release-tags.algorithm.ts
|
|
8008
8368
|
function compareVersions2(left, right) {
|
|
@@ -8039,7 +8399,7 @@ function locateStrandedReleaseTags(workspaceRoot, tagPattern) {
|
|
|
8039
8399
|
if (listed.status !== 0) {
|
|
8040
8400
|
return [];
|
|
8041
8401
|
}
|
|
8042
|
-
const projects = (0,
|
|
8402
|
+
const projects = (0, import_node_fs31.globSync)("{apps,libs,packages}/*/package.json", { cwd: workspaceRoot }).map((path) => readJson((0, import_node_path37.join)(workspaceRoot, path))).filter((manifest) => manifest.private !== true && manifest.name !== void 0).map((manifest) => manifest.name);
|
|
8043
8403
|
return findStrandedReleaseTags(projects, listed.stdout.split(/\r?\n/).filter(Boolean));
|
|
8044
8404
|
}
|
|
8045
8405
|
|
|
@@ -8049,8 +8409,8 @@ function toPosix2(path) {
|
|
|
8049
8409
|
return path.replaceAll("\\", "/");
|
|
8050
8410
|
}
|
|
8051
8411
|
function checkEslintConfigs(workspaceRoot) {
|
|
8052
|
-
const rootConfigs = (0,
|
|
8053
|
-
const projectConfigs = (0,
|
|
8412
|
+
const rootConfigs = (0, import_node_fs32.globSync)("eslint.config.{js,mjs,cjs,ts,mts,cts}", { cwd: workspaceRoot });
|
|
8413
|
+
const projectConfigs = (0, import_node_fs32.globSync)("{apps,libs,packages}/*/eslint.config.{js,mjs,cjs,ts,mts,cts}", {
|
|
8054
8414
|
cwd: workspaceRoot
|
|
8055
8415
|
}).map((config) => toPosix2(config));
|
|
8056
8416
|
return [
|
|
@@ -8070,10 +8430,10 @@ function checkEslintConfigs(workspaceRoot) {
|
|
|
8070
8430
|
];
|
|
8071
8431
|
}
|
|
8072
8432
|
function checkEslintEntryPointReachesTheRules(workspaceRoot) {
|
|
8073
|
-
const rules = (0,
|
|
8074
|
-
if (!(0,
|
|
8075
|
-
const entryPoint = (0,
|
|
8076
|
-
const source = (0,
|
|
8433
|
+
const rules = (0, import_node_path38.join)(workspaceRoot, ESLINT_MNCI_FILENAME);
|
|
8434
|
+
if (!(0, import_node_fs32.existsSync)(rules)) return [];
|
|
8435
|
+
const entryPoint = (0, import_node_path38.join)(workspaceRoot, ESLINT_USER_FILENAME);
|
|
8436
|
+
const source = (0, import_node_fs32.existsSync)(entryPoint) ? (0, import_node_fs32.readFileSync)(entryPoint, "utf8") : "";
|
|
8077
8437
|
return [
|
|
8078
8438
|
{
|
|
8079
8439
|
check: `${ESLINT_USER_FILENAME} imports the mnci rules`,
|
|
@@ -8086,7 +8446,7 @@ function checkEslintEntryPointReachesTheRules(workspaceRoot) {
|
|
|
8086
8446
|
function declaredDevDependencies(workspaceRoot) {
|
|
8087
8447
|
try {
|
|
8088
8448
|
const manifest = readJson(
|
|
8089
|
-
(0,
|
|
8449
|
+
(0, import_node_path38.join)(workspaceRoot, "package.json")
|
|
8090
8450
|
);
|
|
8091
8451
|
return manifest.devDependencies ?? {};
|
|
8092
8452
|
} catch {
|
|
@@ -8094,7 +8454,7 @@ function declaredDevDependencies(workspaceRoot) {
|
|
|
8094
8454
|
}
|
|
8095
8455
|
}
|
|
8096
8456
|
function checkNoRetiredFormatter(workspaceRoot) {
|
|
8097
|
-
const files = RETIRED_FORMATTER_FILES.filter((file) => fileExists((0,
|
|
8457
|
+
const files = RETIRED_FORMATTER_FILES.filter((file) => fileExists((0, import_node_path38.join)(workspaceRoot, file)));
|
|
8098
8458
|
const declared = ["prettier", "eslint-config-prettier", "oxlint", "oxfmt", "@mnci/oxlint-config"].filter((name) => declaredDevDependencies(workspaceRoot)[name] !== void 0);
|
|
8099
8459
|
const stale = [...files, ...declared];
|
|
8100
8460
|
if (stale.length === 0) {
|
|
@@ -8120,7 +8480,7 @@ function checkEslintPlugin(nxJson) {
|
|
|
8120
8480
|
};
|
|
8121
8481
|
}
|
|
8122
8482
|
function checkResolvedEslint(workspaceRoot) {
|
|
8123
|
-
const manifestPath = (0,
|
|
8483
|
+
const manifestPath = (0, import_node_path38.join)(workspaceRoot, "node_modules/eslint/package.json");
|
|
8124
8484
|
if (!fileExists(manifestPath)) {
|
|
8125
8485
|
return void 0;
|
|
8126
8486
|
}
|
|
@@ -8138,11 +8498,11 @@ function checkResolvedEslint(workspaceRoot) {
|
|
|
8138
8498
|
}
|
|
8139
8499
|
}
|
|
8140
8500
|
function checkNpmrc(workspaceRoot, registry, scope) {
|
|
8141
|
-
const npmrcPath = (0,
|
|
8501
|
+
const npmrcPath = (0, import_node_path38.join)(workspaceRoot, ".npmrc");
|
|
8142
8502
|
if (!registry || !fileExists(npmrcPath)) {
|
|
8143
8503
|
return void 0;
|
|
8144
8504
|
}
|
|
8145
|
-
const npmrc = (0,
|
|
8505
|
+
const npmrc = (0, import_node_fs32.readFileSync)(npmrcPath, "utf8");
|
|
8146
8506
|
if (registry.kind === "npm") {
|
|
8147
8507
|
return {
|
|
8148
8508
|
check: ".npmrc authenticates the public registry",
|
|
@@ -8159,11 +8519,11 @@ function checkNpmrc(workspaceRoot, registry, scope) {
|
|
|
8159
8519
|
};
|
|
8160
8520
|
}
|
|
8161
8521
|
function checkNpmrcCredentialResolves(workspaceRoot, environment = process.env) {
|
|
8162
|
-
const npmrcPath = (0,
|
|
8522
|
+
const npmrcPath = (0, import_node_path38.join)(workspaceRoot, ".npmrc");
|
|
8163
8523
|
if (!fileExists(npmrcPath)) {
|
|
8164
8524
|
return void 0;
|
|
8165
8525
|
}
|
|
8166
|
-
const npmrc = (0,
|
|
8526
|
+
const npmrc = (0, import_node_fs32.readFileSync)(npmrcPath, "utf8");
|
|
8167
8527
|
const credentials = npmrc.split("\n").filter((line) => !line.trimStart().startsWith(";") && !line.trimStart().startsWith("#")).filter((line) => /(?:_authToken|_password|_auth)\s*=/u.test(line));
|
|
8168
8528
|
const referenced = [
|
|
8169
8529
|
...new Set(
|
|
@@ -8187,13 +8547,13 @@ function checkNpmrcCredentialResolves(workspaceRoot, environment = process.env)
|
|
|
8187
8547
|
};
|
|
8188
8548
|
}
|
|
8189
8549
|
function checkNpmAuthMatchesPipeline(workspaceRoot, registry) {
|
|
8190
|
-
const npmrcPath = (0,
|
|
8191
|
-
const pipelinePath = (0,
|
|
8550
|
+
const npmrcPath = (0, import_node_path38.join)(workspaceRoot, ".npmrc");
|
|
8551
|
+
const pipelinePath = (0, import_node_path38.join)(workspaceRoot, "azure-pipelines.yml");
|
|
8192
8552
|
if (registry?.kind !== "azure-artifacts" || !fileExists(npmrcPath) || !fileExists(pipelinePath)) {
|
|
8193
8553
|
return void 0;
|
|
8194
8554
|
}
|
|
8195
|
-
const holdsCredentials = (0,
|
|
8196
|
-
const runsTask = (0,
|
|
8555
|
+
const holdsCredentials = (0, import_node_fs32.readFileSync)(npmrcPath, "utf8").split("\n").filter((line) => !line.trimStart().startsWith(";") && !line.trimStart().startsWith("#")).some((line) => /(?:_authToken|_password|_auth)\s*=/u.test(line));
|
|
8556
|
+
const runsTask = (0, import_node_fs32.readFileSync)(pipelinePath, "utf8").includes("npmAuthenticate@0");
|
|
8197
8557
|
if (!holdsCredentials && !runsTask) {
|
|
8198
8558
|
return {
|
|
8199
8559
|
check: "npm auth: .npmrc and azure-pipelines.yml agree",
|
|
@@ -8238,13 +8598,13 @@ function npmjsCredentialShape(credentials, environment) {
|
|
|
8238
8598
|
}
|
|
8239
8599
|
function checkVersionActions(workspaceRoot) {
|
|
8240
8600
|
const candidates = [
|
|
8241
|
-
...(0,
|
|
8242
|
-
...(0,
|
|
8243
|
-
...(0,
|
|
8601
|
+
...(0, import_node_fs32.globSync)("packages/*/pubspec.yaml", { cwd: workspaceRoot }),
|
|
8602
|
+
...(0, import_node_fs32.globSync)("packages/*/*.csproj", { cwd: workspaceRoot }),
|
|
8603
|
+
...(0, import_node_fs32.globSync)("python-packages/*/pyproject.toml", { cwd: workspaceRoot })
|
|
8244
8604
|
].map((manifest) => toPosix2(manifest));
|
|
8245
8605
|
return candidates.flatMap((manifest) => {
|
|
8246
8606
|
const projectRoot = manifest.slice(0, manifest.lastIndexOf("/"));
|
|
8247
|
-
const projectJsonPath = (0,
|
|
8607
|
+
const projectJsonPath = (0, import_node_path38.join)(workspaceRoot, projectRoot, "project.json");
|
|
8248
8608
|
let hasOverride = false;
|
|
8249
8609
|
try {
|
|
8250
8610
|
const projectJson = readJson(projectJsonPath);
|
|
@@ -8273,7 +8633,7 @@ function declaredTargets(workspaceRoot, projectRoot) {
|
|
|
8273
8633
|
]) {
|
|
8274
8634
|
try {
|
|
8275
8635
|
const targets = extract(
|
|
8276
|
-
readJson((0,
|
|
8636
|
+
readJson((0, import_node_path38.join)(workspaceRoot, projectRoot, file))
|
|
8277
8637
|
);
|
|
8278
8638
|
if (targets && typeof targets === "object") {
|
|
8279
8639
|
sources.push({
|
|
@@ -8289,8 +8649,8 @@ function declaredTargets(workspaceRoot, projectRoot) {
|
|
|
8289
8649
|
function checkTargetFilesExist(workspaceRoot) {
|
|
8290
8650
|
const projectRoots = new Set(
|
|
8291
8651
|
[
|
|
8292
|
-
...(0,
|
|
8293
|
-
...(0,
|
|
8652
|
+
...(0, import_node_fs32.globSync)("{apps,libs,packages}/*/project.json", { cwd: workspaceRoot }),
|
|
8653
|
+
...(0, import_node_fs32.globSync)("{apps,libs,packages}/*/package.json", { cwd: workspaceRoot })
|
|
8294
8654
|
].map((manifest) => toPosix2(manifest).split("/").slice(0, 2).join("/"))
|
|
8295
8655
|
);
|
|
8296
8656
|
return [...projectRoots].flatMap(
|
|
@@ -8305,7 +8665,7 @@ function checkOneTargetsFiles(workspaceRoot, source, targetName, target) {
|
|
|
8305
8665
|
return TARGET_FILE_OPTIONS.flatMap((option) => {
|
|
8306
8666
|
const value = target?.options?.[option];
|
|
8307
8667
|
const checkable = typeof value === "string" && !value.includes("{");
|
|
8308
|
-
if (!checkable || fileExists((0,
|
|
8668
|
+
if (!checkable || fileExists((0, import_node_path38.join)(workspaceRoot, value))) {
|
|
8309
8669
|
return [];
|
|
8310
8670
|
}
|
|
8311
8671
|
return [
|
|
@@ -8330,7 +8690,7 @@ ${result.stdout.trim()}` : ""}`,
|
|
|
8330
8690
|
}
|
|
8331
8691
|
function hasCCompiler() {
|
|
8332
8692
|
const candidates = [process.env.CC?.split(" ", 1)[0], "gcc", "clang", "cc"];
|
|
8333
|
-
return candidates.some((command) => command !== void 0 && command !== "" && (0,
|
|
8693
|
+
return candidates.some((command) => command !== void 0 && command !== "" && (0, import_node_child_process2.spawnSync)(command, ["--version"], { stdio: "ignore" }).status === 0);
|
|
8334
8694
|
}
|
|
8335
8695
|
function checkGoPluginRegistered(workspaceRoot) {
|
|
8336
8696
|
if (!hasGoProject(workspaceRoot)) {
|
|
@@ -8344,15 +8704,15 @@ function checkGoPluginRegistered(workspaceRoot) {
|
|
|
8344
8704
|
};
|
|
8345
8705
|
}
|
|
8346
8706
|
function checkGoWorkInSync(workspaceRoot) {
|
|
8347
|
-
const goWorkPath = (0,
|
|
8707
|
+
const goWorkPath = (0, import_node_path38.join)(workspaceRoot, "go.work");
|
|
8348
8708
|
if (!fileExists(goWorkPath)) {
|
|
8349
8709
|
return void 0;
|
|
8350
8710
|
}
|
|
8351
|
-
const contents = (0,
|
|
8711
|
+
const contents = (0, import_node_fs32.existsSync)(goWorkPath) ? (0, import_node_fs32.readFileSync)(goWorkPath, "utf8") : "";
|
|
8352
8712
|
const blockEntries = Array.from(contents.matchAll(/(?:^|\n)\s*use\s+\(([^)]*)\)/g), (match) => match[1].split("\n")).flat();
|
|
8353
8713
|
const singleEntries = Array.from(contents.matchAll(/(?:^|\n)\s*use\s+(\.\S+)/g), (match) => match[1]);
|
|
8354
8714
|
const uses = [...blockEntries, ...singleEntries].map((entry) => entry.trim()).filter(Boolean);
|
|
8355
|
-
const stale = uses.filter((entry) => !(0,
|
|
8715
|
+
const stale = uses.filter((entry) => !(0, import_node_fs32.existsSync)((0, import_node_path38.join)(workspaceRoot, entry, "go.mod")));
|
|
8356
8716
|
return {
|
|
8357
8717
|
check: "every go.work `use` entry points to a module that still exists",
|
|
8358
8718
|
ok: stale.length === 0,
|
|
@@ -8368,9 +8728,9 @@ function checkNativeApps(workspaceRoot) {
|
|
|
8368
8728
|
{ file: ".github/workflows/ci.yml", marker: "native (${{ matrix.os }})" },
|
|
8369
8729
|
{ file: "azure-pipelines.yml", marker: "- job: native" }
|
|
8370
8730
|
];
|
|
8371
|
-
const findings = pipelines.filter(({ file }) => fileExists((0,
|
|
8731
|
+
const findings = pipelines.filter(({ file }) => fileExists((0, import_node_path38.join)(workspaceRoot, file))).map(({ file, marker }) => ({
|
|
8372
8732
|
check: `${file} builds the native apps on every OS`,
|
|
8373
|
-
ok: (0,
|
|
8733
|
+
ok: (0, import_node_fs32.readFileSync)((0, import_node_path38.join)(workspaceRoot, file), "utf8").includes(marker),
|
|
8374
8734
|
detail: `${file} has no native job: CI would verify a cgo app on the one agent that cannot build it`,
|
|
8375
8735
|
remedy: "run `mnci upgrade`"
|
|
8376
8736
|
}));
|
|
@@ -8383,7 +8743,7 @@ function checkNativeApps(workspaceRoot) {
|
|
|
8383
8743
|
return findings;
|
|
8384
8744
|
}
|
|
8385
8745
|
function checkNoRootRuntimeDependencies(workspaceRoot) {
|
|
8386
|
-
const manifestPath = (0,
|
|
8746
|
+
const manifestPath = (0, import_node_path38.join)(workspaceRoot, "package.json");
|
|
8387
8747
|
if (!fileExists(manifestPath)) {
|
|
8388
8748
|
return void 0;
|
|
8389
8749
|
}
|
|
@@ -8403,14 +8763,14 @@ function checkNoRootRuntimeDependencies(workspaceRoot) {
|
|
|
8403
8763
|
};
|
|
8404
8764
|
}
|
|
8405
8765
|
function checkRollupSourceMaps(workspaceRoot) {
|
|
8406
|
-
const configs = (0,
|
|
8766
|
+
const configs = (0, import_node_fs32.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
|
|
8407
8767
|
cwd: workspaceRoot
|
|
8408
8768
|
}).map((config) => toPosix2(config));
|
|
8409
8769
|
return configs.flatMap((relativePath) => {
|
|
8410
|
-
const configPath = (0,
|
|
8770
|
+
const configPath = (0, import_node_path38.join)(workspaceRoot, relativePath);
|
|
8411
8771
|
let config;
|
|
8412
8772
|
try {
|
|
8413
|
-
config = (0,
|
|
8773
|
+
config = (0, import_node_fs32.readFileSync)(configPath, "utf8");
|
|
8414
8774
|
} catch {
|
|
8415
8775
|
return [];
|
|
8416
8776
|
}
|
|
@@ -8425,11 +8785,11 @@ function checkRollupSourceMaps(workspaceRoot) {
|
|
|
8425
8785
|
});
|
|
8426
8786
|
}
|
|
8427
8787
|
function checkDeclarationSpecifiers(workspaceRoot) {
|
|
8428
|
-
const configs = (0,
|
|
8788
|
+
const configs = (0, import_node_fs32.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
|
|
8429
8789
|
cwd: workspaceRoot
|
|
8430
8790
|
}).map((config) => toPosix2(config));
|
|
8431
8791
|
return configs.flatMap((relativePath) => {
|
|
8432
|
-
const configPath = (0,
|
|
8792
|
+
const configPath = (0, import_node_path38.join)(workspaceRoot, relativePath);
|
|
8433
8793
|
if (!fileExists(configPath)) {
|
|
8434
8794
|
return [];
|
|
8435
8795
|
}
|
|
@@ -8444,7 +8804,7 @@ function checkDeclarationSpecifiers(workspaceRoot) {
|
|
|
8444
8804
|
// `plugins` array (what @nx/react:library writes). For any other shape it would no-op, and
|
|
8445
8805
|
// naming a command that silently does nothing is the failure mode the source-map check
|
|
8446
8806
|
// above goes out of its way to avoid, so the remedy depends on the shape.
|
|
8447
|
-
remedy: canAddDeclarationSpecifierPlugin((0,
|
|
8807
|
+
remedy: canAddDeclarationSpecifierPlugin((0, import_node_fs32.readFileSync)(configPath, "utf8")) ? "run `mnci upgrade`, which adds the plugin to the plugins array of withNx's second argument" : "add the plugin to withNx's second argument by hand (copy it from a freshly `mnci add npm-lib`'d project) \u2014 mnci does not recognise the shape of this config, so `mnci upgrade` cannot add it"
|
|
8448
8808
|
}
|
|
8449
8809
|
];
|
|
8450
8810
|
}
|
|
@@ -8460,8 +8820,8 @@ function checkDeclarationSpecifiers(workspaceRoot) {
|
|
|
8460
8820
|
}
|
|
8461
8821
|
function checkPipelinePhases(workspaceRoot) {
|
|
8462
8822
|
const files = ["azure-pipelines.yml", ".github/workflows/ci.yml"];
|
|
8463
|
-
return files.filter((file) => fileExists((0,
|
|
8464
|
-
const { verifyActive, switchedOff } = inspectPipeline((0,
|
|
8823
|
+
return files.filter((file) => fileExists((0, import_node_path38.join)(workspaceRoot, file))).flatMap((file) => {
|
|
8824
|
+
const { verifyActive, switchedOff } = inspectPipeline((0, import_node_fs32.readFileSync)((0, import_node_path38.join)(workspaceRoot, file), "utf8"));
|
|
8465
8825
|
const verify = {
|
|
8466
8826
|
check: `${file} runs the enforced verify phase`,
|
|
8467
8827
|
ok: verifyActive,
|
|
@@ -8502,7 +8862,7 @@ function checkDependencyRangesNotPreserved(nxJson) {
|
|
|
8502
8862
|
};
|
|
8503
8863
|
}
|
|
8504
8864
|
function checkLockfileHasNoLocalRegistry(workspaceRoot) {
|
|
8505
|
-
if (!fileExists((0,
|
|
8865
|
+
if (!fileExists((0, import_node_path38.join)(workspaceRoot, "package-lock.json"))) {
|
|
8506
8866
|
return void 0;
|
|
8507
8867
|
}
|
|
8508
8868
|
return {
|
|
@@ -8522,7 +8882,7 @@ function checkReleaseTagsResolve(workspaceRoot, nxJson) {
|
|
|
8522
8882
|
};
|
|
8523
8883
|
}
|
|
8524
8884
|
function collectFindings(workspaceRoot) {
|
|
8525
|
-
const nxJsonPath = (0,
|
|
8885
|
+
const nxJsonPath = (0, import_node_path38.join)(workspaceRoot, "nx.json");
|
|
8526
8886
|
if (!fileExists(nxJsonPath)) {
|
|
8527
8887
|
throw new Error(
|
|
8528
8888
|
`No nx.json found in ${workspaceRoot} \u2014 run 'mnci doctor' from the workspace root.`
|
|
@@ -8587,8 +8947,8 @@ function runDoctor(workspaceRoot, options = {}) {
|
|
|
8587
8947
|
}
|
|
8588
8948
|
|
|
8589
8949
|
// src/repository-adoption/adopt-dependencies.use-case.ts
|
|
8590
|
-
var
|
|
8591
|
-
var
|
|
8950
|
+
var import_node_fs33 = require("fs");
|
|
8951
|
+
var import_node_path39 = require("path");
|
|
8592
8952
|
|
|
8593
8953
|
// src/repository-adoption/clean-working-tree.validator.ts
|
|
8594
8954
|
function requireCleanWorkingTree(repositoryRoot, capture = runCapture) {
|
|
@@ -8659,7 +9019,7 @@ var SOURCE_FILE = /\.(?:[cm]?[jt]s|[jt]sx)$/;
|
|
|
8659
9019
|
var TEST_FILE = /\.(?:spec|test)\.[^.]+$|[\\/](?:__tests__|tests?|e2e)[\\/]/;
|
|
8660
9020
|
var SKIPPED_DIRECTORIES = /* @__PURE__ */ new Set(["node_modules", "dist", "build", "coverage", "out", ".git", ".nx", "tmp"]);
|
|
8661
9021
|
function sourceFiles(directory, relative = "") {
|
|
8662
|
-
const entries = (0,
|
|
9022
|
+
const entries = (0, import_node_fs33.readdirSync)((0, import_node_path39.join)(directory, relative), { withFileTypes: true });
|
|
8663
9023
|
const found = [];
|
|
8664
9024
|
for (const entry of entries) {
|
|
8665
9025
|
const path = relative === "" ? entry.name : `${relative}/${entry.name}`;
|
|
@@ -8675,7 +9035,7 @@ function sourceFiles(directory, relative = "") {
|
|
|
8675
9035
|
}
|
|
8676
9036
|
function wantedImportsOf(path, wanted) {
|
|
8677
9037
|
try {
|
|
8678
|
-
const imported = [...extractImportedPackages((0,
|
|
9038
|
+
const imported = [...extractImportedPackages((0, import_node_fs33.readFileSync)(path, "utf8"))];
|
|
8679
9039
|
return imported.filter((name) => wanted.has(name));
|
|
8680
9040
|
} catch {
|
|
8681
9041
|
return [];
|
|
@@ -8686,7 +9046,7 @@ function importsOfProject(projectDirectory, wanted) {
|
|
|
8686
9046
|
const tested = /* @__PURE__ */ new Set();
|
|
8687
9047
|
const files = sourceFiles(projectDirectory);
|
|
8688
9048
|
for (const file of files) {
|
|
8689
|
-
const names = wantedImportsOf((0,
|
|
9049
|
+
const names = wantedImportsOf((0, import_node_path39.join)(projectDirectory, file), wanted);
|
|
8690
9050
|
const target = TEST_FILE.test(file) ? tested : shipped;
|
|
8691
9051
|
for (const name of names) {
|
|
8692
9052
|
target.add(name);
|
|
@@ -8698,7 +9058,7 @@ function importsOfProject(projectDirectory, wanted) {
|
|
|
8698
9058
|
function findUsage(repositoryRoot, projectDirectories, wanted) {
|
|
8699
9059
|
const usage = {};
|
|
8700
9060
|
for (const dir of projectDirectories) {
|
|
8701
|
-
const { shipped, testsOnly } = importsOfProject((0,
|
|
9061
|
+
const { shipped, testsOnly } = importsOfProject((0, import_node_path39.join)(repositoryRoot, dir), wanted);
|
|
8702
9062
|
for (const name of shipped) {
|
|
8703
9063
|
usage[name] ??= { runtime: [], testsOnly: [] };
|
|
8704
9064
|
usage[name].runtime.push(dir);
|
|
@@ -8713,7 +9073,7 @@ function findUsage(repositoryRoot, projectDirectories, wanted) {
|
|
|
8713
9073
|
function adoptDependencies(repositoryRoot, dependencies = {}) {
|
|
8714
9074
|
const run = dependencies.run ?? runShell;
|
|
8715
9075
|
requireCleanWorkingTree(repositoryRoot, dependencies.capture ?? runCapture);
|
|
8716
|
-
const rootPath = (0,
|
|
9076
|
+
const rootPath = (0, import_node_path39.join)(repositoryRoot, "package.json");
|
|
8717
9077
|
if (!fileExists(rootPath)) {
|
|
8718
9078
|
throw new Error("No package.json at the repository root.");
|
|
8719
9079
|
}
|
|
@@ -8748,8 +9108,8 @@ function adoptDependencies(repositoryRoot, dependencies = {}) {
|
|
|
8748
9108
|
}
|
|
8749
9109
|
|
|
8750
9110
|
// src/repository-adoption/adopt-kinds.use-case.ts
|
|
8751
|
-
var
|
|
8752
|
-
var
|
|
9111
|
+
var import_node_fs34 = require("fs");
|
|
9112
|
+
var import_node_path40 = require("path");
|
|
8753
9113
|
|
|
8754
9114
|
// src/repository-adoption/infer-project-kind.algorithm.ts
|
|
8755
9115
|
var SERVER_FRAMEWORKS = ["express", "koa", "fastify", "@nestjs/core"];
|
|
@@ -8850,32 +9210,32 @@ function inferProjectKind(evidence) {
|
|
|
8850
9210
|
// src/repository-adoption/adopt-kinds.use-case.ts
|
|
8851
9211
|
var TYPE_TAG = "type:";
|
|
8852
9212
|
function readEvidence(repositoryRoot, location) {
|
|
8853
|
-
const directory = (0,
|
|
8854
|
-
const files = (0,
|
|
9213
|
+
const directory = (0, import_node_path40.join)(repositoryRoot, location.dir);
|
|
9214
|
+
const files = (0, import_node_fs34.readdirSync)(directory);
|
|
8855
9215
|
const manifest = location.ecosystem === "npm" ? readJson(location.manifestPath) : {};
|
|
8856
|
-
const text = location.ecosystem === "npm" ? "" : (0,
|
|
9216
|
+
const text = location.ecosystem === "npm" ? "" : (0, import_node_fs34.readFileSync)(location.manifestPath, "utf8");
|
|
8857
9217
|
let hasProgram = false;
|
|
8858
9218
|
if (location.ecosystem === "go") {
|
|
8859
|
-
hasProgram = files.filter((file) => file.endsWith(".go")).some((file) => /^package main\b/m.test((0,
|
|
9219
|
+
hasProgram = files.filter((file) => file.endsWith(".go")).some((file) => /^package main\b/m.test((0, import_node_fs34.readFileSync)((0, import_node_path40.join)(directory, file), "utf8")));
|
|
8860
9220
|
} else if (location.ecosystem === "pub") {
|
|
8861
|
-
hasProgram = (0,
|
|
9221
|
+
hasProgram = (0, import_node_fs34.existsSync)((0, import_node_path40.join)(directory, "lib", "main.dart"));
|
|
8862
9222
|
}
|
|
8863
9223
|
return { ecosystem: location.ecosystem, manifest, text, files, hasProgram };
|
|
8864
9224
|
}
|
|
8865
9225
|
function existingKind(directory) {
|
|
8866
9226
|
const sources = [];
|
|
8867
|
-
if (fileExists((0,
|
|
8868
|
-
sources.push(readJson((0,
|
|
9227
|
+
if (fileExists((0, import_node_path40.join)(directory, "project.json"))) {
|
|
9228
|
+
sources.push(readJson((0, import_node_path40.join)(directory, "project.json")).tags ?? []);
|
|
8869
9229
|
}
|
|
8870
|
-
if (fileExists((0,
|
|
8871
|
-
sources.push(readJson((0,
|
|
9230
|
+
if (fileExists((0, import_node_path40.join)(directory, "package.json"))) {
|
|
9231
|
+
sources.push(readJson((0, import_node_path40.join)(directory, "package.json")).nx?.tags ?? []);
|
|
8872
9232
|
}
|
|
8873
9233
|
return sources.flat().find((tag) => tag.startsWith(TYPE_TAG))?.slice(TYPE_TAG.length);
|
|
8874
9234
|
}
|
|
8875
9235
|
function writeKindTag(directory, name, kind) {
|
|
8876
9236
|
const tag = `${TYPE_TAG}${kind}`;
|
|
8877
|
-
const projectJson = (0,
|
|
8878
|
-
const packageJson = (0,
|
|
9237
|
+
const projectJson = (0, import_node_path40.join)(directory, "project.json");
|
|
9238
|
+
const packageJson = (0, import_node_path40.join)(directory, "package.json");
|
|
8879
9239
|
if (fileExists(projectJson)) {
|
|
8880
9240
|
const project = readJson(projectJson);
|
|
8881
9241
|
writeFileEnsured(projectJson, toJson({ ...project, tags: [...project.tags ?? [], tag] }));
|
|
@@ -8899,7 +9259,7 @@ function adoptKinds(repositoryRoot, overrides = {}, dependencies = {}) {
|
|
|
8899
9259
|
}
|
|
8900
9260
|
}
|
|
8901
9261
|
return locations.map((location) => {
|
|
8902
|
-
const directory = (0,
|
|
9262
|
+
const directory = (0, import_node_path40.join)(repositoryRoot, location.dir);
|
|
8903
9263
|
const present = existingKind(directory);
|
|
8904
9264
|
if (present !== void 0) {
|
|
8905
9265
|
return { dir: location.dir, outcome: "already", kind: present, reason: PROJECT_KINDS.includes(present) ? "it already has a type tag" : "it already has a type tag of its own, which is not an mnci kind name; left as it is" };
|
|
@@ -8915,12 +9275,12 @@ function adoptKinds(repositoryRoot, overrides = {}, dependencies = {}) {
|
|
|
8915
9275
|
}
|
|
8916
9276
|
|
|
8917
9277
|
// src/repository-adoption/adopt-overlay.use-case.ts
|
|
8918
|
-
var
|
|
8919
|
-
var
|
|
9278
|
+
var import_node_fs36 = require("fs");
|
|
9279
|
+
var import_node_path42 = require("path");
|
|
8920
9280
|
|
|
8921
9281
|
// src/workspace-upgrade/upgrade-workspace.use-case.ts
|
|
8922
|
-
var
|
|
8923
|
-
var
|
|
9282
|
+
var import_node_fs35 = require("fs");
|
|
9283
|
+
var import_node_path41 = require("path");
|
|
8924
9284
|
function resolveRegistry(options, persisted) {
|
|
8925
9285
|
if (options.registry === "azure-artifacts" || options.organization && options.artifactsFeed) {
|
|
8926
9286
|
const persistedAzure = persisted?.kind === "azure-artifacts" ? persisted : void 0;
|
|
@@ -8949,7 +9309,7 @@ function resolveWorkspaceName(workspaceRoot, persisted) {
|
|
|
8949
9309
|
return persisted.workspaceName;
|
|
8950
9310
|
}
|
|
8951
9311
|
try {
|
|
8952
|
-
const existing = (0,
|
|
9312
|
+
const existing = (0, import_node_fs35.readdirSync)(workspaceRoot).find(
|
|
8953
9313
|
(file) => file.endsWith(".code-workspace") && file !== "undefined.code-workspace"
|
|
8954
9314
|
);
|
|
8955
9315
|
if (existing) {
|
|
@@ -8957,11 +9317,11 @@ function resolveWorkspaceName(workspaceRoot, persisted) {
|
|
|
8957
9317
|
}
|
|
8958
9318
|
} catch {
|
|
8959
9319
|
}
|
|
8960
|
-
return (0,
|
|
9320
|
+
return (0, import_node_path41.basename)(workspaceRoot);
|
|
8961
9321
|
}
|
|
8962
9322
|
function detectNpmAuth(workspaceRoot) {
|
|
8963
9323
|
try {
|
|
8964
|
-
return (0,
|
|
9324
|
+
return (0, import_node_fs35.readFileSync)((0, import_node_path41.join)(workspaceRoot, "azure-pipelines.yml"), "utf8").includes("npmAuthenticate@0") ? "build-identity" : void 0;
|
|
8965
9325
|
} catch {
|
|
8966
9326
|
return void 0;
|
|
8967
9327
|
}
|
|
@@ -9008,7 +9368,7 @@ function resolveOverlayOptions(workspaceRoot, options, persisted) {
|
|
|
9008
9368
|
};
|
|
9009
9369
|
}
|
|
9010
9370
|
function runUpgrade(workspaceRoot, options) {
|
|
9011
|
-
if (!fileExists((0,
|
|
9371
|
+
if (!fileExists((0, import_node_path41.join)(workspaceRoot, "nx.json"))) {
|
|
9012
9372
|
throw new Error(
|
|
9013
9373
|
`No nx.json found in ${workspaceRoot} \u2014 this does not look like an Nx workspace. Run 'mnci upgrade' from the workspace root.`
|
|
9014
9374
|
);
|
|
@@ -9056,6 +9416,10 @@ function runUpgrade(workspaceRoot, options) {
|
|
|
9056
9416
|
logger.step("Updating the VS Code extension packaging script");
|
|
9057
9417
|
logger.detail(`updated ${VSCODE_EXTENSION_SCRIPT_PATH}`);
|
|
9058
9418
|
}
|
|
9419
|
+
if (refreshContainerScript(workspaceRoot)) {
|
|
9420
|
+
logger.step("Updating the container image script");
|
|
9421
|
+
logger.detail("updated tools/container-image.cjs");
|
|
9422
|
+
}
|
|
9059
9423
|
if (refreshGoReleaseScript(workspaceRoot)) {
|
|
9060
9424
|
logger.step("Updating the releasable Go app script");
|
|
9061
9425
|
logger.detail(`updated ${GO_RELEASE_SCRIPT_PATH}`);
|
|
@@ -9082,7 +9446,7 @@ function runUpgrade(workspaceRoot, options) {
|
|
|
9082
9446
|
"Formatting the workspace (eslint --fix) \u2014 the slowest step, minutes on a large workspace"
|
|
9083
9447
|
);
|
|
9084
9448
|
runFormatter(workspaceRoot);
|
|
9085
|
-
const nxJson = readJson((0,
|
|
9449
|
+
const nxJson = readJson((0, import_node_path41.join)(workspaceRoot, "nx.json"));
|
|
9086
9450
|
const stranded = locateStrandedReleaseTags(workspaceRoot, nxJson.release?.releaseTag?.pattern);
|
|
9087
9451
|
for (const entry of stranded) {
|
|
9088
9452
|
logger.warn(`${entry.project} has release tags only under ${entry.oldTag}: nx release would restart it from its disk version. Run \`mnci adopt --tags\` before the next release to create ${entry.newTag} locally (\`mnci doctor\` lists them all).`);
|
|
@@ -9093,9 +9457,9 @@ function runUpgrade(workspaceRoot, options) {
|
|
|
9093
9457
|
|
|
9094
9458
|
// src/repository-adoption/adopt-overlay.use-case.ts
|
|
9095
9459
|
function detectCiProvider(repositoryRoot) {
|
|
9096
|
-
const azure = (0,
|
|
9097
|
-
const workflows = (0,
|
|
9098
|
-
const github = (0,
|
|
9460
|
+
const azure = (0, import_node_fs36.existsSync)((0, import_node_path42.join)(repositoryRoot, "azure-pipelines.yml"));
|
|
9461
|
+
const workflows = (0, import_node_path42.join)(repositoryRoot, ".github", "workflows");
|
|
9462
|
+
const github = (0, import_node_fs36.existsSync)(workflows) && (0, import_node_fs36.readdirSync)(workflows).some((file) => /\.ya?ml$/.test(file));
|
|
9099
9463
|
if (azure && github) {
|
|
9100
9464
|
return "both";
|
|
9101
9465
|
}
|
|
@@ -9105,7 +9469,7 @@ function detectCiProvider(repositoryRoot) {
|
|
|
9105
9469
|
return github ? "github" : void 0;
|
|
9106
9470
|
}
|
|
9107
9471
|
function detectTestRunner(repositoryRoot) {
|
|
9108
|
-
const manifestPath = (0,
|
|
9472
|
+
const manifestPath = (0, import_node_path42.join)(repositoryRoot, "package.json");
|
|
9109
9473
|
if (!fileExists(manifestPath)) {
|
|
9110
9474
|
return void 0;
|
|
9111
9475
|
}
|
|
@@ -9118,7 +9482,7 @@ function detectTestRunner(repositoryRoot) {
|
|
|
9118
9482
|
}
|
|
9119
9483
|
function adoptOverlay(repositoryRoot, options, dependencies = {}) {
|
|
9120
9484
|
requireCleanWorkingTree(repositoryRoot, dependencies.capture ?? runCapture);
|
|
9121
|
-
if (!fileExists((0,
|
|
9485
|
+
if (!fileExists((0, import_node_path42.join)(repositoryRoot, "nx.json"))) {
|
|
9122
9486
|
throw new Error("There is no nx.json, so Nx is not set up here. Set it up first (`npx nx@latest init`); adopt does not install Nx yet.");
|
|
9123
9487
|
}
|
|
9124
9488
|
const persisted = readMnciConfig(repositoryRoot);
|
|
@@ -9131,7 +9495,7 @@ function adoptOverlay(repositoryRoot, options, dependencies = {}) {
|
|
|
9131
9495
|
}
|
|
9132
9496
|
|
|
9133
9497
|
// src/repository-adoption/adopt-toolchain.use-case.ts
|
|
9134
|
-
var
|
|
9498
|
+
var import_node_path44 = require("path");
|
|
9135
9499
|
|
|
9136
9500
|
// src/repository-adoption/align-nx-family.algorithm.ts
|
|
9137
9501
|
var VERSION = /^[\^~]?(\d+)\.(\d+)\.(\d+)$/;
|
|
@@ -9169,24 +9533,24 @@ function alignNxFamily(dependencies, version) {
|
|
|
9169
9533
|
}
|
|
9170
9534
|
|
|
9171
9535
|
// src/repository-adoption/retire-tooling.use-case.ts
|
|
9172
|
-
var
|
|
9173
|
-
var
|
|
9536
|
+
var import_node_fs37 = require("fs");
|
|
9537
|
+
var import_node_path43 = require("path");
|
|
9174
9538
|
var RETIRED_COMMAND = /\b(?:prettier|oxfmt|oxlint)\b/;
|
|
9175
9539
|
function retireTooling(repositoryRoot) {
|
|
9176
9540
|
const removed = [];
|
|
9177
9541
|
for (const file of RETIRED_FORMATTER_FILES) {
|
|
9178
|
-
if (!fileExists((0,
|
|
9542
|
+
if (!fileExists((0, import_node_path43.join)(repositoryRoot, file))) {
|
|
9179
9543
|
continue;
|
|
9180
9544
|
}
|
|
9181
|
-
(0,
|
|
9545
|
+
(0, import_node_fs37.rmSync)((0, import_node_path43.join)(repositoryRoot, file), { force: true });
|
|
9182
9546
|
removed.push(file);
|
|
9183
9547
|
}
|
|
9184
|
-
const hadRegistry = fileExists((0,
|
|
9548
|
+
const hadRegistry = fileExists((0, import_node_path43.join)(repositoryRoot, ".verdaccio"));
|
|
9185
9549
|
removeLocalRegistryScaffolding(repositoryRoot);
|
|
9186
9550
|
if (hadRegistry) {
|
|
9187
9551
|
removed.push(".verdaccio, its dependency and the local-registry target");
|
|
9188
9552
|
}
|
|
9189
|
-
const manifestPath = (0,
|
|
9553
|
+
const manifestPath = (0, import_node_path43.join)(repositoryRoot, "package.json");
|
|
9190
9554
|
if (!fileExists(manifestPath)) {
|
|
9191
9555
|
return removed;
|
|
9192
9556
|
}
|
|
@@ -9233,7 +9597,7 @@ function adoptToolchain(repositoryRoot, options = {}, dependencies = {}) {
|
|
|
9233
9597
|
console.log(message);
|
|
9234
9598
|
});
|
|
9235
9599
|
requireCleanWorkingTree(repositoryRoot, capture);
|
|
9236
|
-
const manifestPath = (0,
|
|
9600
|
+
const manifestPath = (0, import_node_path44.join)(repositoryRoot, "package.json");
|
|
9237
9601
|
if (!fileExists(manifestPath)) {
|
|
9238
9602
|
throw new Error("No package.json at the repository root.");
|
|
9239
9603
|
}
|
|
@@ -9283,8 +9647,8 @@ function createBaselineTags(repositoryRoot, stranded) {
|
|
|
9283
9647
|
}
|
|
9284
9648
|
|
|
9285
9649
|
// src/repository-adoption/inspect-repository.use-case.ts
|
|
9286
|
-
var
|
|
9287
|
-
var
|
|
9650
|
+
var import_node_fs38 = require("fs");
|
|
9651
|
+
var import_node_path45 = require("path");
|
|
9288
9652
|
var LOCKFILES = [
|
|
9289
9653
|
["package-lock.json", "npm"],
|
|
9290
9654
|
["pnpm-lock.yaml", "pnpm"],
|
|
@@ -9305,25 +9669,25 @@ function inspectRepository(repositoryRoot) {
|
|
|
9305
9669
|
const isGitRepo = inside.status === 0 && inside.stdout.trim() === "true";
|
|
9306
9670
|
const dirty = isGitRepo && runCapture("git", ["status", "--porcelain"], repositoryRoot).stdout.trim() !== "";
|
|
9307
9671
|
const tags = isGitRepo ? runCapture("git", ["tag", "--list"], repositoryRoot).stdout.split(/\r?\n/).filter(Boolean) : [];
|
|
9308
|
-
const manifestPath = (0,
|
|
9672
|
+
const manifestPath = (0, import_node_path45.join)(repositoryRoot, "package.json");
|
|
9309
9673
|
const manifest = fileExists(manifestPath) ? readJson(manifestPath) : {};
|
|
9310
|
-
const nxJsonPath = (0,
|
|
9674
|
+
const nxJsonPath = (0, import_node_path45.join)(repositoryRoot, "nx.json");
|
|
9311
9675
|
const nxJson = fileExists(nxJsonPath) ? readJson(nxJsonPath) : {};
|
|
9312
9676
|
const ci = [];
|
|
9313
9677
|
const pipelines = [];
|
|
9314
|
-
if ((0,
|
|
9678
|
+
if ((0, import_node_fs38.existsSync)((0, import_node_path45.join)(repositoryRoot, "azure-pipelines.yml"))) {
|
|
9315
9679
|
ci.push("azure");
|
|
9316
|
-
pipelines.push((0,
|
|
9680
|
+
pipelines.push((0, import_node_path45.join)(repositoryRoot, "azure-pipelines.yml"));
|
|
9317
9681
|
}
|
|
9318
|
-
const workflows = (0,
|
|
9319
|
-
if ((0,
|
|
9320
|
-
const files = (0,
|
|
9682
|
+
const workflows = (0, import_node_path45.join)(repositoryRoot, ".github", "workflows");
|
|
9683
|
+
if ((0, import_node_fs38.existsSync)(workflows)) {
|
|
9684
|
+
const files = (0, import_node_fs38.readdirSync)(workflows).filter((file) => /\.ya?ml$/.test(file));
|
|
9321
9685
|
if (files.length > 0) {
|
|
9322
9686
|
ci.push("github");
|
|
9323
|
-
pipelines.push(...files.map((file) => (0,
|
|
9687
|
+
pipelines.push(...files.map((file) => (0, import_node_path45.join)(workflows, file)));
|
|
9324
9688
|
}
|
|
9325
9689
|
}
|
|
9326
|
-
const rootFiles = (0,
|
|
9690
|
+
const rootFiles = (0, import_node_fs38.readdirSync)(repositoryRoot);
|
|
9327
9691
|
return {
|
|
9328
9692
|
isGitRepo,
|
|
9329
9693
|
dirty,
|
|
@@ -9334,7 +9698,7 @@ function inspectRepository(repositoryRoot) {
|
|
|
9334
9698
|
tagCount: tags.length,
|
|
9335
9699
|
strandedTags: isGitRepo ? locateStrandedReleaseTags(repositoryRoot, nxJson.release?.releaseTag?.pattern) : [],
|
|
9336
9700
|
ci,
|
|
9337
|
-
pipelineUsesMnci: pipelines.some((file) => /\bmnci ci\b/.test((0,
|
|
9701
|
+
pipelineUsesMnci: pipelines.some((file) => /\bmnci ci\b/.test((0, import_node_fs38.readFileSync)(file, "utf8"))),
|
|
9338
9702
|
retiredTooling: [.../* @__PURE__ */ new Set([...rootFiles.filter((file) => RETIRED_FILE_PATTERN.test(file) || file === ".verdaccio"), ...retiredNamesIn(manifest)])],
|
|
9339
9703
|
personalFiles: PERSONAL_FILES.filter((file) => rootFiles.includes(file))
|
|
9340
9704
|
};
|
|
@@ -9567,6 +9931,7 @@ var COMMAND_GROUPS = {
|
|
|
9567
9931
|
doctor: "workspace",
|
|
9568
9932
|
adopt: "inspect",
|
|
9569
9933
|
add: "projects",
|
|
9934
|
+
dev: "projects",
|
|
9570
9935
|
install: "dependencies",
|
|
9571
9936
|
sync: "dependencies",
|
|
9572
9937
|
up: "dependencies",
|
|
@@ -9631,13 +9996,13 @@ function runCommands(program, options) {
|
|
|
9631
9996
|
}
|
|
9632
9997
|
|
|
9633
9998
|
// src/workspace-info/list-projects.use-case.ts
|
|
9634
|
-
var
|
|
9999
|
+
var import_node_path46 = require("path");
|
|
9635
10000
|
var TYPE_TAG_PREFIX = "type:";
|
|
9636
10001
|
function listProjects(workspaceRoot) {
|
|
9637
10002
|
return locateProjects(workspaceRoot).map((location) => {
|
|
9638
|
-
const projectJsonPath = (0,
|
|
10003
|
+
const projectJsonPath = (0, import_node_path46.join)(workspaceRoot, location.dir, "project.json");
|
|
9639
10004
|
const project = fileExists(projectJsonPath) ? readJson(projectJsonPath) : {};
|
|
9640
|
-
const manifestPath = (0,
|
|
10005
|
+
const manifestPath = (0, import_node_path46.join)(workspaceRoot, location.dir, "package.json");
|
|
9641
10006
|
const manifestTags = fileExists(manifestPath) ? readJson(manifestPath).nx?.tags ?? [] : [];
|
|
9642
10007
|
const typeTag = [...project.tags ?? [], ...manifestTags].find((tag) => tag.startsWith(TYPE_TAG_PREFIX));
|
|
9643
10008
|
return {
|
|
@@ -9650,7 +10015,7 @@ function listProjects(workspaceRoot) {
|
|
|
9650
10015
|
}).toSorted((a, b) => a.dir.localeCompare(b.dir));
|
|
9651
10016
|
}
|
|
9652
10017
|
function runProjects(workspaceRoot, options) {
|
|
9653
|
-
if (!fileExists((0,
|
|
10018
|
+
if (!fileExists((0, import_node_path46.join)(workspaceRoot, "nx.json"))) {
|
|
9654
10019
|
throw new Error("No nx.json found here. Run `projects` from the workspace root.");
|
|
9655
10020
|
}
|
|
9656
10021
|
const projects = listProjects(workspaceRoot);
|
|
@@ -9664,12 +10029,12 @@ function runProjects(workspaceRoot, options) {
|
|
|
9664
10029
|
}
|
|
9665
10030
|
|
|
9666
10031
|
// src/workspace-info/read-workspace-info.use-case.ts
|
|
9667
|
-
var
|
|
10032
|
+
var import_node_path48 = require("path");
|
|
9668
10033
|
|
|
9669
10034
|
// src/cli-version/check-for-update.use-case.ts
|
|
9670
|
-
var
|
|
9671
|
-
var
|
|
9672
|
-
var
|
|
10035
|
+
var import_node_fs39 = require("fs");
|
|
10036
|
+
var import_node_path47 = require("path");
|
|
10037
|
+
var import_cross_spawn4 = __toESM(require("cross-spawn"));
|
|
9673
10038
|
var PACKAGE_NAME2 = "@mnci/cli";
|
|
9674
10039
|
var REGISTRY_TIMEOUT_MS = 2e3;
|
|
9675
10040
|
function checkForUpdate(currentVersion2) {
|
|
@@ -9687,7 +10052,7 @@ function checkForUpdate(currentVersion2) {
|
|
|
9687
10052
|
}
|
|
9688
10053
|
}
|
|
9689
10054
|
function fetchLatestVersion() {
|
|
9690
|
-
const result =
|
|
10055
|
+
const result = import_cross_spawn4.default.sync("npm", ["view", PACKAGE_NAME2, "version"], {
|
|
9691
10056
|
encoding: "utf8",
|
|
9692
10057
|
timeout: REGISTRY_TIMEOUT_MS,
|
|
9693
10058
|
stdio: ["ignore", "pipe", "ignore"]
|
|
@@ -9727,8 +10092,8 @@ function releaseTriple(version) {
|
|
|
9727
10092
|
}
|
|
9728
10093
|
function readCliVersion(packageDirectory) {
|
|
9729
10094
|
try {
|
|
9730
|
-
const manifestPath = (0,
|
|
9731
|
-
const manifest = JSON.parse((0,
|
|
10095
|
+
const manifestPath = (0, import_node_path47.join)(packageDirectory, "..", "package.json");
|
|
10096
|
+
const manifest = JSON.parse((0, import_node_fs39.readFileSync)(manifestPath, "utf8"));
|
|
9732
10097
|
return manifest.version ?? "0.0.0";
|
|
9733
10098
|
} catch {
|
|
9734
10099
|
return "0.0.0";
|
|
@@ -9738,7 +10103,7 @@ function readCliVersion(packageDirectory) {
|
|
|
9738
10103
|
// src/workspace-info/read-workspace-info.use-case.ts
|
|
9739
10104
|
function readWorkspaceInfo(workspaceRoot, cliVersion) {
|
|
9740
10105
|
const latest = fetchLatestVersion() ?? null;
|
|
9741
|
-
const isWorkspace = fileExists((0,
|
|
10106
|
+
const isWorkspace = fileExists((0, import_node_path48.join)(workspaceRoot, "nx.json"));
|
|
9742
10107
|
return {
|
|
9743
10108
|
cli: {
|
|
9744
10109
|
version: cliVersion,
|
|
@@ -9759,7 +10124,7 @@ function runInfo(workspaceRoot, cliVersion, options) {
|
|
|
9759
10124
|
}
|
|
9760
10125
|
|
|
9761
10126
|
// src/interactive-wizard/interactive-wizard.use-case.ts
|
|
9762
|
-
var
|
|
10127
|
+
var import_node_path49 = require("path");
|
|
9763
10128
|
|
|
9764
10129
|
// src/interactive-wizard/adopt-steps.config.ts
|
|
9765
10130
|
var ADOPT_GLOBAL_OPTIONS = ["json"];
|
|
@@ -9895,14 +10260,14 @@ function formatCommandLine(argv) {
|
|
|
9895
10260
|
}
|
|
9896
10261
|
|
|
9897
10262
|
// src/interactive-wizard/inquirer-prompter.client.ts
|
|
9898
|
-
var
|
|
10263
|
+
var import_prompts5 = require("@inquirer/prompts");
|
|
9899
10264
|
function toRows(choices) {
|
|
9900
10265
|
const rows = [];
|
|
9901
10266
|
let current;
|
|
9902
10267
|
for (const choice of choices) {
|
|
9903
10268
|
if (choice.group !== void 0 && choice.group !== current) {
|
|
9904
10269
|
current = choice.group;
|
|
9905
|
-
rows.push(new
|
|
10270
|
+
rows.push(new import_prompts5.Separator(`-- ${choice.group} --`));
|
|
9906
10271
|
}
|
|
9907
10272
|
rows.push({ name: choice.name, value: choice.value, description: choice.description });
|
|
9908
10273
|
}
|
|
@@ -9910,10 +10275,10 @@ function toRows(choices) {
|
|
|
9910
10275
|
}
|
|
9911
10276
|
function createInquirerPrompter() {
|
|
9912
10277
|
return {
|
|
9913
|
-
select: async (message, choices) => await (0,
|
|
9914
|
-
checkbox: async (message, choices) => await (0,
|
|
9915
|
-
input: async (message, required) => await (0,
|
|
9916
|
-
confirm: async (message, fallback) => await (0,
|
|
10278
|
+
select: async (message, choices) => await (0, import_prompts5.select)({ message, choices: toRows(choices), pageSize: 18 }),
|
|
10279
|
+
checkbox: async (message, choices) => await (0, import_prompts5.checkbox)({ message, choices: toRows(choices), pageSize: 18 }),
|
|
10280
|
+
input: async (message, required) => await (0, import_prompts5.input)({ message, validate: (value) => !required || value.trim().length > 0 || "A value is required" }),
|
|
10281
|
+
confirm: async (message, fallback) => await (0, import_prompts5.confirm)({ message, default: fallback })
|
|
9917
10282
|
};
|
|
9918
10283
|
}
|
|
9919
10284
|
|
|
@@ -9940,7 +10305,7 @@ function wizardMenu(commands, inWorkspace) {
|
|
|
9940
10305
|
}
|
|
9941
10306
|
async function runInteractive(program, prompter = createInquirerPrompter(), workingDirectory = process.cwd()) {
|
|
9942
10307
|
const commands = describeCommands(program);
|
|
9943
|
-
const inWorkspace = fileExists((0,
|
|
10308
|
+
const inWorkspace = fileExists((0, import_node_path49.join)(workingDirectory, "nx.json"));
|
|
9944
10309
|
const name = await prompter.select("What would you like to do?", wizardMenu(commands, inWorkspace));
|
|
9945
10310
|
const command = commands.find((candidate) => candidate.name === name);
|
|
9946
10311
|
const argv = buildArgv(command, await askCommand(command, prompter));
|
|
@@ -9953,8 +10318,8 @@ async function runInteractive(program, prompter = createInquirerPrompter(), work
|
|
|
9953
10318
|
}
|
|
9954
10319
|
|
|
9955
10320
|
// src/workspace-creation/adopt-directory.use-case.ts
|
|
9956
|
-
var
|
|
9957
|
-
var
|
|
10321
|
+
var import_node_fs40 = require("fs");
|
|
10322
|
+
var import_node_path50 = require("path");
|
|
9958
10323
|
var NEVER_COPIED = /* @__PURE__ */ new Set([".git", "node_modules"]);
|
|
9959
10324
|
var AGENT_AND_CI_ENTRIES = [
|
|
9960
10325
|
"AGENTS.md",
|
|
@@ -9985,13 +10350,13 @@ var PREFLIGHT_BLOCKERS = [
|
|
|
9985
10350
|
"packages"
|
|
9986
10351
|
];
|
|
9987
10352
|
function assertAdoptableDirectory(target) {
|
|
9988
|
-
if (!(0,
|
|
10353
|
+
if (!(0, import_node_fs40.existsSync)(target)) {
|
|
9989
10354
|
throw new Error(`--into '${target}' does not exist. Create or clone it first.`);
|
|
9990
10355
|
}
|
|
9991
|
-
if (!(0,
|
|
10356
|
+
if (!(0, import_node_fs40.statSync)(target).isDirectory()) {
|
|
9992
10357
|
throw new Error(`--into '${target}' is not a directory.`);
|
|
9993
10358
|
}
|
|
9994
|
-
const blockers = PREFLIGHT_BLOCKERS.filter((entry) => (0,
|
|
10359
|
+
const blockers = PREFLIGHT_BLOCKERS.filter((entry) => (0, import_node_fs40.existsSync)((0, import_node_path50.join)(target, entry)));
|
|
9995
10360
|
if (blockers.length > 0) {
|
|
9996
10361
|
throw new Error(
|
|
9997
10362
|
`--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.`
|
|
@@ -9999,15 +10364,15 @@ function assertAdoptableDirectory(target) {
|
|
|
9999
10364
|
}
|
|
10000
10365
|
}
|
|
10001
10366
|
function mergeGitignore(generatedFile, targetFile) {
|
|
10002
|
-
const existing = (0,
|
|
10367
|
+
const existing = (0, import_node_fs40.readFileSync)(targetFile, "utf8");
|
|
10003
10368
|
const present = new Set(existing.split("\n").map((line) => line.trim()));
|
|
10004
|
-
const additions = (0,
|
|
10369
|
+
const additions = (0, import_node_fs40.readFileSync)(generatedFile, "utf8").split("\n").map((line) => line.trimEnd()).filter((line) => {
|
|
10005
10370
|
const trimmed = line.trim();
|
|
10006
10371
|
return trimmed !== "" && !trimmed.startsWith("#") && !present.has(trimmed);
|
|
10007
10372
|
});
|
|
10008
10373
|
if (additions.length === 0) return false;
|
|
10009
10374
|
const separator = existing.endsWith("\n") ? "" : "\n";
|
|
10010
|
-
(0,
|
|
10375
|
+
(0, import_node_fs40.writeFileSync)(
|
|
10011
10376
|
targetFile,
|
|
10012
10377
|
`${existing}${separator}
|
|
10013
10378
|
# Added by mnci (Nx workspace)
|
|
@@ -10017,9 +10382,9 @@ ${additions.join("\n")}
|
|
|
10017
10382
|
return true;
|
|
10018
10383
|
}
|
|
10019
10384
|
function adoptGeneratedWorkspace(generatedRoot, target) {
|
|
10020
|
-
const entries = (0,
|
|
10385
|
+
const entries = (0, import_node_fs40.readdirSync)(generatedRoot).filter((entry) => !NEVER_COPIED.has(entry));
|
|
10021
10386
|
const collisions = entries.filter(
|
|
10022
|
-
(entry) => (0,
|
|
10387
|
+
(entry) => (0, import_node_fs40.existsSync)((0, import_node_path50.join)(target, entry)) && !EXISTING_WINS.has(entry) && entry !== ".gitignore"
|
|
10023
10388
|
);
|
|
10024
10389
|
if (collisions.length > 0) {
|
|
10025
10390
|
throw new Error(
|
|
@@ -10028,28 +10393,28 @@ function adoptGeneratedWorkspace(generatedRoot, target) {
|
|
|
10028
10393
|
}
|
|
10029
10394
|
const result = { copied: [], kept: [], mergedGitignore: false };
|
|
10030
10395
|
for (const entry of entries) {
|
|
10031
|
-
const from = (0,
|
|
10032
|
-
const to = (0,
|
|
10033
|
-
if (entry === ".gitignore" && (0,
|
|
10396
|
+
const from = (0, import_node_path50.join)(generatedRoot, entry);
|
|
10397
|
+
const to = (0, import_node_path50.join)(target, entry);
|
|
10398
|
+
if (entry === ".gitignore" && (0, import_node_fs40.existsSync)(to)) {
|
|
10034
10399
|
result.mergedGitignore = mergeGitignore(from, to);
|
|
10035
10400
|
result.kept.push(entry);
|
|
10036
10401
|
continue;
|
|
10037
10402
|
}
|
|
10038
|
-
if ((0,
|
|
10403
|
+
if ((0, import_node_fs40.existsSync)(to)) {
|
|
10039
10404
|
result.kept.push(entry);
|
|
10040
10405
|
continue;
|
|
10041
10406
|
}
|
|
10042
|
-
(0,
|
|
10407
|
+
(0, import_node_fs40.cpSync)(from, to, { recursive: true });
|
|
10043
10408
|
result.copied.push(entry);
|
|
10044
10409
|
}
|
|
10045
|
-
(0,
|
|
10410
|
+
(0, import_node_fs40.rmSync)(generatedRoot, { recursive: true, force: true });
|
|
10046
10411
|
return result;
|
|
10047
10412
|
}
|
|
10048
10413
|
|
|
10049
10414
|
// src/workspace-creation/create-workspace.use-case.ts
|
|
10050
|
-
var
|
|
10415
|
+
var import_node_fs41 = require("fs");
|
|
10051
10416
|
var import_node_os2 = require("os");
|
|
10052
|
-
var
|
|
10417
|
+
var import_node_path51 = require("path");
|
|
10053
10418
|
function nxCloudProviderValue(ci) {
|
|
10054
10419
|
return ci === "azure" ? "azure" : "github";
|
|
10055
10420
|
}
|
|
@@ -10092,9 +10457,9 @@ async function resolveRegistry2(options) {
|
|
|
10092
10457
|
return await promptRegistry();
|
|
10093
10458
|
}
|
|
10094
10459
|
async function runNew(name, options) {
|
|
10095
|
-
const adoptTarget = options.into === void 0 ? void 0 : (0,
|
|
10460
|
+
const adoptTarget = options.into === void 0 ? void 0 : (0, import_node_path51.resolve)(process.cwd(), options.into);
|
|
10096
10461
|
if (adoptTarget !== void 0) assertAdoptableDirectory(adoptTarget);
|
|
10097
|
-
const workspaceName = name ?? (adoptTarget === void 0 ? await promptText("Workspace name") : (0,
|
|
10462
|
+
const workspaceName = name ?? (adoptTarget === void 0 ? await promptText("Workspace name") : (0, import_node_path51.basename)(adoptTarget));
|
|
10098
10463
|
assertValidProjectName(workspaceName, "Workspace name");
|
|
10099
10464
|
const scope = options.scope ?? (options.yes ? `@${workspaceName}` : await promptText("npm scope for publishable packages", `@${workspaceName}`));
|
|
10100
10465
|
const registry = await resolveRegistry2(options);
|
|
@@ -10107,8 +10472,8 @@ async function runNew(name, options) {
|
|
|
10107
10472
|
const npmAuth = resolveNpmAuth(options.npmAuth, registry, ci);
|
|
10108
10473
|
const stack = await resolveStack(options);
|
|
10109
10474
|
const nxCloud = options.nxCloud ?? (options.yes ? false : await promptNxCloud());
|
|
10110
|
-
const stagingParent = adoptTarget === void 0 ? process.cwd() : (0,
|
|
10111
|
-
let workspaceRoot = (0,
|
|
10475
|
+
const stagingParent = adoptTarget === void 0 ? process.cwd() : (0, import_node_fs41.mkdtempSync)((0, import_node_path51.join)((0, import_node_os2.tmpdir)(), "mnci-new-"));
|
|
10476
|
+
let workspaceRoot = (0, import_node_path51.join)(stagingParent, workspaceName);
|
|
10112
10477
|
try {
|
|
10113
10478
|
logger.step(`Creating Nx workspace '${workspaceName}' (preset: ts)`);
|
|
10114
10479
|
runNpx(
|
|
@@ -10131,7 +10496,7 @@ async function runNew(name, options) {
|
|
|
10131
10496
|
workspaceRoot = adoptTarget;
|
|
10132
10497
|
}
|
|
10133
10498
|
} finally {
|
|
10134
|
-
if (adoptTarget !== void 0) (0,
|
|
10499
|
+
if (adoptTarget !== void 0) (0, import_node_fs41.rmSync)(stagingParent, { recursive: true, force: true });
|
|
10135
10500
|
}
|
|
10136
10501
|
logger.step(
|
|
10137
10502
|
"Applying MoNecromanCI overlay (VS Code workspace, release config, .npmrc, commitlint, pipeline, stack)"
|
|
@@ -10141,8 +10506,8 @@ async function runNew(name, options) {
|
|
|
10141
10506
|
{ workspaceName, scope, registry, agent, variableGroup, ci, stack, ...npmAuth && { npmAuth } },
|
|
10142
10507
|
logger.detail
|
|
10143
10508
|
);
|
|
10144
|
-
(0,
|
|
10145
|
-
(0,
|
|
10509
|
+
(0, import_node_fs41.rmSync)((0, import_node_path51.join)(workspaceRoot, "node_modules"), { recursive: true, force: true });
|
|
10510
|
+
(0, import_node_fs41.rmSync)((0, import_node_path51.join)(workspaceRoot, "package-lock.json"), { force: true });
|
|
10146
10511
|
logger.step("Installing the toolchain (commitlint + husky + linting/formatting)");
|
|
10147
10512
|
const installStatus = runShell(
|
|
10148
10513
|
"npm",
|
|
@@ -10206,6 +10571,9 @@ function buildProgram(cliVersion) {
|
|
|
10206
10571
|
).action((options) => {
|
|
10207
10572
|
runUpgrade(process.cwd(), options);
|
|
10208
10573
|
});
|
|
10574
|
+
program.command("dev").argument("[projects...]", "the projects to start (those with a start command)").description("Start several projects together, such as a frontend and the API it calls: runs their start targets as one Nx command, so Ctrl+C stops them all. Name the projects, pass --all, or pick from a list").option("--all", "start every project that has a start command").option("--dry-run", "print the Nx command and start nothing").action(async (projects, options) => {
|
|
10575
|
+
await runDev(process.cwd(), projects, options);
|
|
10576
|
+
});
|
|
10209
10577
|
program.command("doctor").description(
|
|
10210
10578
|
"Check this workspace against the invariants mnci maintains (one ESLint config, no stray .prettierrc, the eslint plugin registered, the resolved eslint major, .npmrc vs the recorded registry, versionActions overrides, nx sync) \u2014 read-only; exits non-zero if anything failed"
|
|
10211
10579
|
).option("--json", "print the findings as one JSON document, each with its remedy").action((options) => {
|
|
@@ -10244,7 +10612,7 @@ function buildProgram(cliVersion) {
|
|
|
10244
10612
|
).option(
|
|
10245
10613
|
"--empty",
|
|
10246
10614
|
"npm-lib, internal-lib, react-lib, react-internal-lib, node-function-app: scaffold the slice skeleton only, with no sample code or spec"
|
|
10247
|
-
).option(
|
|
10615
|
+
).option("--app <project>", "container only: the app to put in an image (a node-app, react-app or go-app)").option("--port <port>", "container only: the port the app listens on, exposed by the image and published by start").option(
|
|
10248
10616
|
"--e2e",
|
|
10249
10617
|
"react-app only: also scaffold a Playwright end-to-end project, <name>-e2e, that runs the app and checks its greeting; its e2e target needs a browser (npx playwright install) and is not part of CI verify"
|
|
10250
10618
|
).option(
|