@mnci/cli 4.49.0 → 4.50.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 +29 -0
- package/dist/cli.js +476 -228
- 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: [] },
|
|
@@ -7997,12 +8241,12 @@ function runKinds(options) {
|
|
|
7997
8241
|
|
|
7998
8242
|
// src/workspace-diagnostics/check-invariants.use-case.ts
|
|
7999
8243
|
var import_node_child_process = require("child_process");
|
|
8000
|
-
var
|
|
8001
|
-
var
|
|
8244
|
+
var import_node_fs32 = require("fs");
|
|
8245
|
+
var import_node_path37 = require("path");
|
|
8002
8246
|
|
|
8003
8247
|
// src/workspace-diagnostics/locate-stranded-release-tags.use-case.ts
|
|
8004
|
-
var
|
|
8005
|
-
var
|
|
8248
|
+
var import_node_fs31 = require("fs");
|
|
8249
|
+
var import_node_path36 = require("path");
|
|
8006
8250
|
|
|
8007
8251
|
// src/workspace-diagnostics/stranded-release-tags.algorithm.ts
|
|
8008
8252
|
function compareVersions2(left, right) {
|
|
@@ -8039,7 +8283,7 @@ function locateStrandedReleaseTags(workspaceRoot, tagPattern) {
|
|
|
8039
8283
|
if (listed.status !== 0) {
|
|
8040
8284
|
return [];
|
|
8041
8285
|
}
|
|
8042
|
-
const projects = (0,
|
|
8286
|
+
const projects = (0, import_node_fs31.globSync)("{apps,libs,packages}/*/package.json", { cwd: workspaceRoot }).map((path) => readJson((0, import_node_path36.join)(workspaceRoot, path))).filter((manifest) => manifest.private !== true && manifest.name !== void 0).map((manifest) => manifest.name);
|
|
8043
8287
|
return findStrandedReleaseTags(projects, listed.stdout.split(/\r?\n/).filter(Boolean));
|
|
8044
8288
|
}
|
|
8045
8289
|
|
|
@@ -8049,8 +8293,8 @@ function toPosix2(path) {
|
|
|
8049
8293
|
return path.replaceAll("\\", "/");
|
|
8050
8294
|
}
|
|
8051
8295
|
function checkEslintConfigs(workspaceRoot) {
|
|
8052
|
-
const rootConfigs = (0,
|
|
8053
|
-
const projectConfigs = (0,
|
|
8296
|
+
const rootConfigs = (0, import_node_fs32.globSync)("eslint.config.{js,mjs,cjs,ts,mts,cts}", { cwd: workspaceRoot });
|
|
8297
|
+
const projectConfigs = (0, import_node_fs32.globSync)("{apps,libs,packages}/*/eslint.config.{js,mjs,cjs,ts,mts,cts}", {
|
|
8054
8298
|
cwd: workspaceRoot
|
|
8055
8299
|
}).map((config) => toPosix2(config));
|
|
8056
8300
|
return [
|
|
@@ -8070,10 +8314,10 @@ function checkEslintConfigs(workspaceRoot) {
|
|
|
8070
8314
|
];
|
|
8071
8315
|
}
|
|
8072
8316
|
function checkEslintEntryPointReachesTheRules(workspaceRoot) {
|
|
8073
|
-
const rules = (0,
|
|
8074
|
-
if (!(0,
|
|
8075
|
-
const entryPoint = (0,
|
|
8076
|
-
const source = (0,
|
|
8317
|
+
const rules = (0, import_node_path37.join)(workspaceRoot, ESLINT_MNCI_FILENAME);
|
|
8318
|
+
if (!(0, import_node_fs32.existsSync)(rules)) return [];
|
|
8319
|
+
const entryPoint = (0, import_node_path37.join)(workspaceRoot, ESLINT_USER_FILENAME);
|
|
8320
|
+
const source = (0, import_node_fs32.existsSync)(entryPoint) ? (0, import_node_fs32.readFileSync)(entryPoint, "utf8") : "";
|
|
8077
8321
|
return [
|
|
8078
8322
|
{
|
|
8079
8323
|
check: `${ESLINT_USER_FILENAME} imports the mnci rules`,
|
|
@@ -8086,7 +8330,7 @@ function checkEslintEntryPointReachesTheRules(workspaceRoot) {
|
|
|
8086
8330
|
function declaredDevDependencies(workspaceRoot) {
|
|
8087
8331
|
try {
|
|
8088
8332
|
const manifest = readJson(
|
|
8089
|
-
(0,
|
|
8333
|
+
(0, import_node_path37.join)(workspaceRoot, "package.json")
|
|
8090
8334
|
);
|
|
8091
8335
|
return manifest.devDependencies ?? {};
|
|
8092
8336
|
} catch {
|
|
@@ -8094,7 +8338,7 @@ function declaredDevDependencies(workspaceRoot) {
|
|
|
8094
8338
|
}
|
|
8095
8339
|
}
|
|
8096
8340
|
function checkNoRetiredFormatter(workspaceRoot) {
|
|
8097
|
-
const files = RETIRED_FORMATTER_FILES.filter((file) => fileExists((0,
|
|
8341
|
+
const files = RETIRED_FORMATTER_FILES.filter((file) => fileExists((0, import_node_path37.join)(workspaceRoot, file)));
|
|
8098
8342
|
const declared = ["prettier", "eslint-config-prettier", "oxlint", "oxfmt", "@mnci/oxlint-config"].filter((name) => declaredDevDependencies(workspaceRoot)[name] !== void 0);
|
|
8099
8343
|
const stale = [...files, ...declared];
|
|
8100
8344
|
if (stale.length === 0) {
|
|
@@ -8120,7 +8364,7 @@ function checkEslintPlugin(nxJson) {
|
|
|
8120
8364
|
};
|
|
8121
8365
|
}
|
|
8122
8366
|
function checkResolvedEslint(workspaceRoot) {
|
|
8123
|
-
const manifestPath = (0,
|
|
8367
|
+
const manifestPath = (0, import_node_path37.join)(workspaceRoot, "node_modules/eslint/package.json");
|
|
8124
8368
|
if (!fileExists(manifestPath)) {
|
|
8125
8369
|
return void 0;
|
|
8126
8370
|
}
|
|
@@ -8138,11 +8382,11 @@ function checkResolvedEslint(workspaceRoot) {
|
|
|
8138
8382
|
}
|
|
8139
8383
|
}
|
|
8140
8384
|
function checkNpmrc(workspaceRoot, registry, scope) {
|
|
8141
|
-
const npmrcPath = (0,
|
|
8385
|
+
const npmrcPath = (0, import_node_path37.join)(workspaceRoot, ".npmrc");
|
|
8142
8386
|
if (!registry || !fileExists(npmrcPath)) {
|
|
8143
8387
|
return void 0;
|
|
8144
8388
|
}
|
|
8145
|
-
const npmrc = (0,
|
|
8389
|
+
const npmrc = (0, import_node_fs32.readFileSync)(npmrcPath, "utf8");
|
|
8146
8390
|
if (registry.kind === "npm") {
|
|
8147
8391
|
return {
|
|
8148
8392
|
check: ".npmrc authenticates the public registry",
|
|
@@ -8159,11 +8403,11 @@ function checkNpmrc(workspaceRoot, registry, scope) {
|
|
|
8159
8403
|
};
|
|
8160
8404
|
}
|
|
8161
8405
|
function checkNpmrcCredentialResolves(workspaceRoot, environment = process.env) {
|
|
8162
|
-
const npmrcPath = (0,
|
|
8406
|
+
const npmrcPath = (0, import_node_path37.join)(workspaceRoot, ".npmrc");
|
|
8163
8407
|
if (!fileExists(npmrcPath)) {
|
|
8164
8408
|
return void 0;
|
|
8165
8409
|
}
|
|
8166
|
-
const npmrc = (0,
|
|
8410
|
+
const npmrc = (0, import_node_fs32.readFileSync)(npmrcPath, "utf8");
|
|
8167
8411
|
const credentials = npmrc.split("\n").filter((line) => !line.trimStart().startsWith(";") && !line.trimStart().startsWith("#")).filter((line) => /(?:_authToken|_password|_auth)\s*=/u.test(line));
|
|
8168
8412
|
const referenced = [
|
|
8169
8413
|
...new Set(
|
|
@@ -8187,13 +8431,13 @@ function checkNpmrcCredentialResolves(workspaceRoot, environment = process.env)
|
|
|
8187
8431
|
};
|
|
8188
8432
|
}
|
|
8189
8433
|
function checkNpmAuthMatchesPipeline(workspaceRoot, registry) {
|
|
8190
|
-
const npmrcPath = (0,
|
|
8191
|
-
const pipelinePath = (0,
|
|
8434
|
+
const npmrcPath = (0, import_node_path37.join)(workspaceRoot, ".npmrc");
|
|
8435
|
+
const pipelinePath = (0, import_node_path37.join)(workspaceRoot, "azure-pipelines.yml");
|
|
8192
8436
|
if (registry?.kind !== "azure-artifacts" || !fileExists(npmrcPath) || !fileExists(pipelinePath)) {
|
|
8193
8437
|
return void 0;
|
|
8194
8438
|
}
|
|
8195
|
-
const holdsCredentials = (0,
|
|
8196
|
-
const runsTask = (0,
|
|
8439
|
+
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));
|
|
8440
|
+
const runsTask = (0, import_node_fs32.readFileSync)(pipelinePath, "utf8").includes("npmAuthenticate@0");
|
|
8197
8441
|
if (!holdsCredentials && !runsTask) {
|
|
8198
8442
|
return {
|
|
8199
8443
|
check: "npm auth: .npmrc and azure-pipelines.yml agree",
|
|
@@ -8238,13 +8482,13 @@ function npmjsCredentialShape(credentials, environment) {
|
|
|
8238
8482
|
}
|
|
8239
8483
|
function checkVersionActions(workspaceRoot) {
|
|
8240
8484
|
const candidates = [
|
|
8241
|
-
...(0,
|
|
8242
|
-
...(0,
|
|
8243
|
-
...(0,
|
|
8485
|
+
...(0, import_node_fs32.globSync)("packages/*/pubspec.yaml", { cwd: workspaceRoot }),
|
|
8486
|
+
...(0, import_node_fs32.globSync)("packages/*/*.csproj", { cwd: workspaceRoot }),
|
|
8487
|
+
...(0, import_node_fs32.globSync)("python-packages/*/pyproject.toml", { cwd: workspaceRoot })
|
|
8244
8488
|
].map((manifest) => toPosix2(manifest));
|
|
8245
8489
|
return candidates.flatMap((manifest) => {
|
|
8246
8490
|
const projectRoot = manifest.slice(0, manifest.lastIndexOf("/"));
|
|
8247
|
-
const projectJsonPath = (0,
|
|
8491
|
+
const projectJsonPath = (0, import_node_path37.join)(workspaceRoot, projectRoot, "project.json");
|
|
8248
8492
|
let hasOverride = false;
|
|
8249
8493
|
try {
|
|
8250
8494
|
const projectJson = readJson(projectJsonPath);
|
|
@@ -8273,7 +8517,7 @@ function declaredTargets(workspaceRoot, projectRoot) {
|
|
|
8273
8517
|
]) {
|
|
8274
8518
|
try {
|
|
8275
8519
|
const targets = extract(
|
|
8276
|
-
readJson((0,
|
|
8520
|
+
readJson((0, import_node_path37.join)(workspaceRoot, projectRoot, file))
|
|
8277
8521
|
);
|
|
8278
8522
|
if (targets && typeof targets === "object") {
|
|
8279
8523
|
sources.push({
|
|
@@ -8289,8 +8533,8 @@ function declaredTargets(workspaceRoot, projectRoot) {
|
|
|
8289
8533
|
function checkTargetFilesExist(workspaceRoot) {
|
|
8290
8534
|
const projectRoots = new Set(
|
|
8291
8535
|
[
|
|
8292
|
-
...(0,
|
|
8293
|
-
...(0,
|
|
8536
|
+
...(0, import_node_fs32.globSync)("{apps,libs,packages}/*/project.json", { cwd: workspaceRoot }),
|
|
8537
|
+
...(0, import_node_fs32.globSync)("{apps,libs,packages}/*/package.json", { cwd: workspaceRoot })
|
|
8294
8538
|
].map((manifest) => toPosix2(manifest).split("/").slice(0, 2).join("/"))
|
|
8295
8539
|
);
|
|
8296
8540
|
return [...projectRoots].flatMap(
|
|
@@ -8305,7 +8549,7 @@ function checkOneTargetsFiles(workspaceRoot, source, targetName, target) {
|
|
|
8305
8549
|
return TARGET_FILE_OPTIONS.flatMap((option) => {
|
|
8306
8550
|
const value = target?.options?.[option];
|
|
8307
8551
|
const checkable = typeof value === "string" && !value.includes("{");
|
|
8308
|
-
if (!checkable || fileExists((0,
|
|
8552
|
+
if (!checkable || fileExists((0, import_node_path37.join)(workspaceRoot, value))) {
|
|
8309
8553
|
return [];
|
|
8310
8554
|
}
|
|
8311
8555
|
return [
|
|
@@ -8344,15 +8588,15 @@ function checkGoPluginRegistered(workspaceRoot) {
|
|
|
8344
8588
|
};
|
|
8345
8589
|
}
|
|
8346
8590
|
function checkGoWorkInSync(workspaceRoot) {
|
|
8347
|
-
const goWorkPath = (0,
|
|
8591
|
+
const goWorkPath = (0, import_node_path37.join)(workspaceRoot, "go.work");
|
|
8348
8592
|
if (!fileExists(goWorkPath)) {
|
|
8349
8593
|
return void 0;
|
|
8350
8594
|
}
|
|
8351
|
-
const contents = (0,
|
|
8595
|
+
const contents = (0, import_node_fs32.existsSync)(goWorkPath) ? (0, import_node_fs32.readFileSync)(goWorkPath, "utf8") : "";
|
|
8352
8596
|
const blockEntries = Array.from(contents.matchAll(/(?:^|\n)\s*use\s+\(([^)]*)\)/g), (match) => match[1].split("\n")).flat();
|
|
8353
8597
|
const singleEntries = Array.from(contents.matchAll(/(?:^|\n)\s*use\s+(\.\S+)/g), (match) => match[1]);
|
|
8354
8598
|
const uses = [...blockEntries, ...singleEntries].map((entry) => entry.trim()).filter(Boolean);
|
|
8355
|
-
const stale = uses.filter((entry) => !(0,
|
|
8599
|
+
const stale = uses.filter((entry) => !(0, import_node_fs32.existsSync)((0, import_node_path37.join)(workspaceRoot, entry, "go.mod")));
|
|
8356
8600
|
return {
|
|
8357
8601
|
check: "every go.work `use` entry points to a module that still exists",
|
|
8358
8602
|
ok: stale.length === 0,
|
|
@@ -8368,9 +8612,9 @@ function checkNativeApps(workspaceRoot) {
|
|
|
8368
8612
|
{ file: ".github/workflows/ci.yml", marker: "native (${{ matrix.os }})" },
|
|
8369
8613
|
{ file: "azure-pipelines.yml", marker: "- job: native" }
|
|
8370
8614
|
];
|
|
8371
|
-
const findings = pipelines.filter(({ file }) => fileExists((0,
|
|
8615
|
+
const findings = pipelines.filter(({ file }) => fileExists((0, import_node_path37.join)(workspaceRoot, file))).map(({ file, marker }) => ({
|
|
8372
8616
|
check: `${file} builds the native apps on every OS`,
|
|
8373
|
-
ok: (0,
|
|
8617
|
+
ok: (0, import_node_fs32.readFileSync)((0, import_node_path37.join)(workspaceRoot, file), "utf8").includes(marker),
|
|
8374
8618
|
detail: `${file} has no native job: CI would verify a cgo app on the one agent that cannot build it`,
|
|
8375
8619
|
remedy: "run `mnci upgrade`"
|
|
8376
8620
|
}));
|
|
@@ -8383,7 +8627,7 @@ function checkNativeApps(workspaceRoot) {
|
|
|
8383
8627
|
return findings;
|
|
8384
8628
|
}
|
|
8385
8629
|
function checkNoRootRuntimeDependencies(workspaceRoot) {
|
|
8386
|
-
const manifestPath = (0,
|
|
8630
|
+
const manifestPath = (0, import_node_path37.join)(workspaceRoot, "package.json");
|
|
8387
8631
|
if (!fileExists(manifestPath)) {
|
|
8388
8632
|
return void 0;
|
|
8389
8633
|
}
|
|
@@ -8403,14 +8647,14 @@ function checkNoRootRuntimeDependencies(workspaceRoot) {
|
|
|
8403
8647
|
};
|
|
8404
8648
|
}
|
|
8405
8649
|
function checkRollupSourceMaps(workspaceRoot) {
|
|
8406
|
-
const configs = (0,
|
|
8650
|
+
const configs = (0, import_node_fs32.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
|
|
8407
8651
|
cwd: workspaceRoot
|
|
8408
8652
|
}).map((config) => toPosix2(config));
|
|
8409
8653
|
return configs.flatMap((relativePath) => {
|
|
8410
|
-
const configPath = (0,
|
|
8654
|
+
const configPath = (0, import_node_path37.join)(workspaceRoot, relativePath);
|
|
8411
8655
|
let config;
|
|
8412
8656
|
try {
|
|
8413
|
-
config = (0,
|
|
8657
|
+
config = (0, import_node_fs32.readFileSync)(configPath, "utf8");
|
|
8414
8658
|
} catch {
|
|
8415
8659
|
return [];
|
|
8416
8660
|
}
|
|
@@ -8425,11 +8669,11 @@ function checkRollupSourceMaps(workspaceRoot) {
|
|
|
8425
8669
|
});
|
|
8426
8670
|
}
|
|
8427
8671
|
function checkDeclarationSpecifiers(workspaceRoot) {
|
|
8428
|
-
const configs = (0,
|
|
8672
|
+
const configs = (0, import_node_fs32.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
|
|
8429
8673
|
cwd: workspaceRoot
|
|
8430
8674
|
}).map((config) => toPosix2(config));
|
|
8431
8675
|
return configs.flatMap((relativePath) => {
|
|
8432
|
-
const configPath = (0,
|
|
8676
|
+
const configPath = (0, import_node_path37.join)(workspaceRoot, relativePath);
|
|
8433
8677
|
if (!fileExists(configPath)) {
|
|
8434
8678
|
return [];
|
|
8435
8679
|
}
|
|
@@ -8444,7 +8688,7 @@ function checkDeclarationSpecifiers(workspaceRoot) {
|
|
|
8444
8688
|
// `plugins` array (what @nx/react:library writes). For any other shape it would no-op, and
|
|
8445
8689
|
// naming a command that silently does nothing is the failure mode the source-map check
|
|
8446
8690
|
// above goes out of its way to avoid, so the remedy depends on the shape.
|
|
8447
|
-
remedy: canAddDeclarationSpecifierPlugin((0,
|
|
8691
|
+
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
8692
|
}
|
|
8449
8693
|
];
|
|
8450
8694
|
}
|
|
@@ -8460,8 +8704,8 @@ function checkDeclarationSpecifiers(workspaceRoot) {
|
|
|
8460
8704
|
}
|
|
8461
8705
|
function checkPipelinePhases(workspaceRoot) {
|
|
8462
8706
|
const files = ["azure-pipelines.yml", ".github/workflows/ci.yml"];
|
|
8463
|
-
return files.filter((file) => fileExists((0,
|
|
8464
|
-
const { verifyActive, switchedOff } = inspectPipeline((0,
|
|
8707
|
+
return files.filter((file) => fileExists((0, import_node_path37.join)(workspaceRoot, file))).flatMap((file) => {
|
|
8708
|
+
const { verifyActive, switchedOff } = inspectPipeline((0, import_node_fs32.readFileSync)((0, import_node_path37.join)(workspaceRoot, file), "utf8"));
|
|
8465
8709
|
const verify = {
|
|
8466
8710
|
check: `${file} runs the enforced verify phase`,
|
|
8467
8711
|
ok: verifyActive,
|
|
@@ -8502,7 +8746,7 @@ function checkDependencyRangesNotPreserved(nxJson) {
|
|
|
8502
8746
|
};
|
|
8503
8747
|
}
|
|
8504
8748
|
function checkLockfileHasNoLocalRegistry(workspaceRoot) {
|
|
8505
|
-
if (!fileExists((0,
|
|
8749
|
+
if (!fileExists((0, import_node_path37.join)(workspaceRoot, "package-lock.json"))) {
|
|
8506
8750
|
return void 0;
|
|
8507
8751
|
}
|
|
8508
8752
|
return {
|
|
@@ -8522,7 +8766,7 @@ function checkReleaseTagsResolve(workspaceRoot, nxJson) {
|
|
|
8522
8766
|
};
|
|
8523
8767
|
}
|
|
8524
8768
|
function collectFindings(workspaceRoot) {
|
|
8525
|
-
const nxJsonPath = (0,
|
|
8769
|
+
const nxJsonPath = (0, import_node_path37.join)(workspaceRoot, "nx.json");
|
|
8526
8770
|
if (!fileExists(nxJsonPath)) {
|
|
8527
8771
|
throw new Error(
|
|
8528
8772
|
`No nx.json found in ${workspaceRoot} \u2014 run 'mnci doctor' from the workspace root.`
|
|
@@ -8587,8 +8831,8 @@ function runDoctor(workspaceRoot, options = {}) {
|
|
|
8587
8831
|
}
|
|
8588
8832
|
|
|
8589
8833
|
// src/repository-adoption/adopt-dependencies.use-case.ts
|
|
8590
|
-
var
|
|
8591
|
-
var
|
|
8834
|
+
var import_node_fs33 = require("fs");
|
|
8835
|
+
var import_node_path38 = require("path");
|
|
8592
8836
|
|
|
8593
8837
|
// src/repository-adoption/clean-working-tree.validator.ts
|
|
8594
8838
|
function requireCleanWorkingTree(repositoryRoot, capture = runCapture) {
|
|
@@ -8659,7 +8903,7 @@ var SOURCE_FILE = /\.(?:[cm]?[jt]s|[jt]sx)$/;
|
|
|
8659
8903
|
var TEST_FILE = /\.(?:spec|test)\.[^.]+$|[\\/](?:__tests__|tests?|e2e)[\\/]/;
|
|
8660
8904
|
var SKIPPED_DIRECTORIES = /* @__PURE__ */ new Set(["node_modules", "dist", "build", "coverage", "out", ".git", ".nx", "tmp"]);
|
|
8661
8905
|
function sourceFiles(directory, relative = "") {
|
|
8662
|
-
const entries = (0,
|
|
8906
|
+
const entries = (0, import_node_fs33.readdirSync)((0, import_node_path38.join)(directory, relative), { withFileTypes: true });
|
|
8663
8907
|
const found = [];
|
|
8664
8908
|
for (const entry of entries) {
|
|
8665
8909
|
const path = relative === "" ? entry.name : `${relative}/${entry.name}`;
|
|
@@ -8675,7 +8919,7 @@ function sourceFiles(directory, relative = "") {
|
|
|
8675
8919
|
}
|
|
8676
8920
|
function wantedImportsOf(path, wanted) {
|
|
8677
8921
|
try {
|
|
8678
|
-
const imported = [...extractImportedPackages((0,
|
|
8922
|
+
const imported = [...extractImportedPackages((0, import_node_fs33.readFileSync)(path, "utf8"))];
|
|
8679
8923
|
return imported.filter((name) => wanted.has(name));
|
|
8680
8924
|
} catch {
|
|
8681
8925
|
return [];
|
|
@@ -8686,7 +8930,7 @@ function importsOfProject(projectDirectory, wanted) {
|
|
|
8686
8930
|
const tested = /* @__PURE__ */ new Set();
|
|
8687
8931
|
const files = sourceFiles(projectDirectory);
|
|
8688
8932
|
for (const file of files) {
|
|
8689
|
-
const names = wantedImportsOf((0,
|
|
8933
|
+
const names = wantedImportsOf((0, import_node_path38.join)(projectDirectory, file), wanted);
|
|
8690
8934
|
const target = TEST_FILE.test(file) ? tested : shipped;
|
|
8691
8935
|
for (const name of names) {
|
|
8692
8936
|
target.add(name);
|
|
@@ -8698,7 +8942,7 @@ function importsOfProject(projectDirectory, wanted) {
|
|
|
8698
8942
|
function findUsage(repositoryRoot, projectDirectories, wanted) {
|
|
8699
8943
|
const usage = {};
|
|
8700
8944
|
for (const dir of projectDirectories) {
|
|
8701
|
-
const { shipped, testsOnly } = importsOfProject((0,
|
|
8945
|
+
const { shipped, testsOnly } = importsOfProject((0, import_node_path38.join)(repositoryRoot, dir), wanted);
|
|
8702
8946
|
for (const name of shipped) {
|
|
8703
8947
|
usage[name] ??= { runtime: [], testsOnly: [] };
|
|
8704
8948
|
usage[name].runtime.push(dir);
|
|
@@ -8713,7 +8957,7 @@ function findUsage(repositoryRoot, projectDirectories, wanted) {
|
|
|
8713
8957
|
function adoptDependencies(repositoryRoot, dependencies = {}) {
|
|
8714
8958
|
const run = dependencies.run ?? runShell;
|
|
8715
8959
|
requireCleanWorkingTree(repositoryRoot, dependencies.capture ?? runCapture);
|
|
8716
|
-
const rootPath = (0,
|
|
8960
|
+
const rootPath = (0, import_node_path38.join)(repositoryRoot, "package.json");
|
|
8717
8961
|
if (!fileExists(rootPath)) {
|
|
8718
8962
|
throw new Error("No package.json at the repository root.");
|
|
8719
8963
|
}
|
|
@@ -8748,8 +8992,8 @@ function adoptDependencies(repositoryRoot, dependencies = {}) {
|
|
|
8748
8992
|
}
|
|
8749
8993
|
|
|
8750
8994
|
// src/repository-adoption/adopt-kinds.use-case.ts
|
|
8751
|
-
var
|
|
8752
|
-
var
|
|
8995
|
+
var import_node_fs34 = require("fs");
|
|
8996
|
+
var import_node_path39 = require("path");
|
|
8753
8997
|
|
|
8754
8998
|
// src/repository-adoption/infer-project-kind.algorithm.ts
|
|
8755
8999
|
var SERVER_FRAMEWORKS = ["express", "koa", "fastify", "@nestjs/core"];
|
|
@@ -8850,32 +9094,32 @@ function inferProjectKind(evidence) {
|
|
|
8850
9094
|
// src/repository-adoption/adopt-kinds.use-case.ts
|
|
8851
9095
|
var TYPE_TAG = "type:";
|
|
8852
9096
|
function readEvidence(repositoryRoot, location) {
|
|
8853
|
-
const directory = (0,
|
|
8854
|
-
const files = (0,
|
|
9097
|
+
const directory = (0, import_node_path39.join)(repositoryRoot, location.dir);
|
|
9098
|
+
const files = (0, import_node_fs34.readdirSync)(directory);
|
|
8855
9099
|
const manifest = location.ecosystem === "npm" ? readJson(location.manifestPath) : {};
|
|
8856
|
-
const text = location.ecosystem === "npm" ? "" : (0,
|
|
9100
|
+
const text = location.ecosystem === "npm" ? "" : (0, import_node_fs34.readFileSync)(location.manifestPath, "utf8");
|
|
8857
9101
|
let hasProgram = false;
|
|
8858
9102
|
if (location.ecosystem === "go") {
|
|
8859
|
-
hasProgram = files.filter((file) => file.endsWith(".go")).some((file) => /^package main\b/m.test((0,
|
|
9103
|
+
hasProgram = files.filter((file) => file.endsWith(".go")).some((file) => /^package main\b/m.test((0, import_node_fs34.readFileSync)((0, import_node_path39.join)(directory, file), "utf8")));
|
|
8860
9104
|
} else if (location.ecosystem === "pub") {
|
|
8861
|
-
hasProgram = (0,
|
|
9105
|
+
hasProgram = (0, import_node_fs34.existsSync)((0, import_node_path39.join)(directory, "lib", "main.dart"));
|
|
8862
9106
|
}
|
|
8863
9107
|
return { ecosystem: location.ecosystem, manifest, text, files, hasProgram };
|
|
8864
9108
|
}
|
|
8865
9109
|
function existingKind(directory) {
|
|
8866
9110
|
const sources = [];
|
|
8867
|
-
if (fileExists((0,
|
|
8868
|
-
sources.push(readJson((0,
|
|
9111
|
+
if (fileExists((0, import_node_path39.join)(directory, "project.json"))) {
|
|
9112
|
+
sources.push(readJson((0, import_node_path39.join)(directory, "project.json")).tags ?? []);
|
|
8869
9113
|
}
|
|
8870
|
-
if (fileExists((0,
|
|
8871
|
-
sources.push(readJson((0,
|
|
9114
|
+
if (fileExists((0, import_node_path39.join)(directory, "package.json"))) {
|
|
9115
|
+
sources.push(readJson((0, import_node_path39.join)(directory, "package.json")).nx?.tags ?? []);
|
|
8872
9116
|
}
|
|
8873
9117
|
return sources.flat().find((tag) => tag.startsWith(TYPE_TAG))?.slice(TYPE_TAG.length);
|
|
8874
9118
|
}
|
|
8875
9119
|
function writeKindTag(directory, name, kind) {
|
|
8876
9120
|
const tag = `${TYPE_TAG}${kind}`;
|
|
8877
|
-
const projectJson = (0,
|
|
8878
|
-
const packageJson = (0,
|
|
9121
|
+
const projectJson = (0, import_node_path39.join)(directory, "project.json");
|
|
9122
|
+
const packageJson = (0, import_node_path39.join)(directory, "package.json");
|
|
8879
9123
|
if (fileExists(projectJson)) {
|
|
8880
9124
|
const project = readJson(projectJson);
|
|
8881
9125
|
writeFileEnsured(projectJson, toJson({ ...project, tags: [...project.tags ?? [], tag] }));
|
|
@@ -8899,7 +9143,7 @@ function adoptKinds(repositoryRoot, overrides = {}, dependencies = {}) {
|
|
|
8899
9143
|
}
|
|
8900
9144
|
}
|
|
8901
9145
|
return locations.map((location) => {
|
|
8902
|
-
const directory = (0,
|
|
9146
|
+
const directory = (0, import_node_path39.join)(repositoryRoot, location.dir);
|
|
8903
9147
|
const present = existingKind(directory);
|
|
8904
9148
|
if (present !== void 0) {
|
|
8905
9149
|
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 +9159,12 @@ function adoptKinds(repositoryRoot, overrides = {}, dependencies = {}) {
|
|
|
8915
9159
|
}
|
|
8916
9160
|
|
|
8917
9161
|
// src/repository-adoption/adopt-overlay.use-case.ts
|
|
8918
|
-
var
|
|
8919
|
-
var
|
|
9162
|
+
var import_node_fs36 = require("fs");
|
|
9163
|
+
var import_node_path41 = require("path");
|
|
8920
9164
|
|
|
8921
9165
|
// src/workspace-upgrade/upgrade-workspace.use-case.ts
|
|
8922
|
-
var
|
|
8923
|
-
var
|
|
9166
|
+
var import_node_fs35 = require("fs");
|
|
9167
|
+
var import_node_path40 = require("path");
|
|
8924
9168
|
function resolveRegistry(options, persisted) {
|
|
8925
9169
|
if (options.registry === "azure-artifacts" || options.organization && options.artifactsFeed) {
|
|
8926
9170
|
const persistedAzure = persisted?.kind === "azure-artifacts" ? persisted : void 0;
|
|
@@ -8949,7 +9193,7 @@ function resolveWorkspaceName(workspaceRoot, persisted) {
|
|
|
8949
9193
|
return persisted.workspaceName;
|
|
8950
9194
|
}
|
|
8951
9195
|
try {
|
|
8952
|
-
const existing = (0,
|
|
9196
|
+
const existing = (0, import_node_fs35.readdirSync)(workspaceRoot).find(
|
|
8953
9197
|
(file) => file.endsWith(".code-workspace") && file !== "undefined.code-workspace"
|
|
8954
9198
|
);
|
|
8955
9199
|
if (existing) {
|
|
@@ -8957,11 +9201,11 @@ function resolveWorkspaceName(workspaceRoot, persisted) {
|
|
|
8957
9201
|
}
|
|
8958
9202
|
} catch {
|
|
8959
9203
|
}
|
|
8960
|
-
return (0,
|
|
9204
|
+
return (0, import_node_path40.basename)(workspaceRoot);
|
|
8961
9205
|
}
|
|
8962
9206
|
function detectNpmAuth(workspaceRoot) {
|
|
8963
9207
|
try {
|
|
8964
|
-
return (0,
|
|
9208
|
+
return (0, import_node_fs35.readFileSync)((0, import_node_path40.join)(workspaceRoot, "azure-pipelines.yml"), "utf8").includes("npmAuthenticate@0") ? "build-identity" : void 0;
|
|
8965
9209
|
} catch {
|
|
8966
9210
|
return void 0;
|
|
8967
9211
|
}
|
|
@@ -9008,7 +9252,7 @@ function resolveOverlayOptions(workspaceRoot, options, persisted) {
|
|
|
9008
9252
|
};
|
|
9009
9253
|
}
|
|
9010
9254
|
function runUpgrade(workspaceRoot, options) {
|
|
9011
|
-
if (!fileExists((0,
|
|
9255
|
+
if (!fileExists((0, import_node_path40.join)(workspaceRoot, "nx.json"))) {
|
|
9012
9256
|
throw new Error(
|
|
9013
9257
|
`No nx.json found in ${workspaceRoot} \u2014 this does not look like an Nx workspace. Run 'mnci upgrade' from the workspace root.`
|
|
9014
9258
|
);
|
|
@@ -9056,6 +9300,10 @@ function runUpgrade(workspaceRoot, options) {
|
|
|
9056
9300
|
logger.step("Updating the VS Code extension packaging script");
|
|
9057
9301
|
logger.detail(`updated ${VSCODE_EXTENSION_SCRIPT_PATH}`);
|
|
9058
9302
|
}
|
|
9303
|
+
if (refreshContainerScript(workspaceRoot)) {
|
|
9304
|
+
logger.step("Updating the container image script");
|
|
9305
|
+
logger.detail("updated tools/container-image.cjs");
|
|
9306
|
+
}
|
|
9059
9307
|
if (refreshGoReleaseScript(workspaceRoot)) {
|
|
9060
9308
|
logger.step("Updating the releasable Go app script");
|
|
9061
9309
|
logger.detail(`updated ${GO_RELEASE_SCRIPT_PATH}`);
|
|
@@ -9082,7 +9330,7 @@ function runUpgrade(workspaceRoot, options) {
|
|
|
9082
9330
|
"Formatting the workspace (eslint --fix) \u2014 the slowest step, minutes on a large workspace"
|
|
9083
9331
|
);
|
|
9084
9332
|
runFormatter(workspaceRoot);
|
|
9085
|
-
const nxJson = readJson((0,
|
|
9333
|
+
const nxJson = readJson((0, import_node_path40.join)(workspaceRoot, "nx.json"));
|
|
9086
9334
|
const stranded = locateStrandedReleaseTags(workspaceRoot, nxJson.release?.releaseTag?.pattern);
|
|
9087
9335
|
for (const entry of stranded) {
|
|
9088
9336
|
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 +9341,9 @@ function runUpgrade(workspaceRoot, options) {
|
|
|
9093
9341
|
|
|
9094
9342
|
// src/repository-adoption/adopt-overlay.use-case.ts
|
|
9095
9343
|
function detectCiProvider(repositoryRoot) {
|
|
9096
|
-
const azure = (0,
|
|
9097
|
-
const workflows = (0,
|
|
9098
|
-
const github = (0,
|
|
9344
|
+
const azure = (0, import_node_fs36.existsSync)((0, import_node_path41.join)(repositoryRoot, "azure-pipelines.yml"));
|
|
9345
|
+
const workflows = (0, import_node_path41.join)(repositoryRoot, ".github", "workflows");
|
|
9346
|
+
const github = (0, import_node_fs36.existsSync)(workflows) && (0, import_node_fs36.readdirSync)(workflows).some((file) => /\.ya?ml$/.test(file));
|
|
9099
9347
|
if (azure && github) {
|
|
9100
9348
|
return "both";
|
|
9101
9349
|
}
|
|
@@ -9105,7 +9353,7 @@ function detectCiProvider(repositoryRoot) {
|
|
|
9105
9353
|
return github ? "github" : void 0;
|
|
9106
9354
|
}
|
|
9107
9355
|
function detectTestRunner(repositoryRoot) {
|
|
9108
|
-
const manifestPath = (0,
|
|
9356
|
+
const manifestPath = (0, import_node_path41.join)(repositoryRoot, "package.json");
|
|
9109
9357
|
if (!fileExists(manifestPath)) {
|
|
9110
9358
|
return void 0;
|
|
9111
9359
|
}
|
|
@@ -9118,7 +9366,7 @@ function detectTestRunner(repositoryRoot) {
|
|
|
9118
9366
|
}
|
|
9119
9367
|
function adoptOverlay(repositoryRoot, options, dependencies = {}) {
|
|
9120
9368
|
requireCleanWorkingTree(repositoryRoot, dependencies.capture ?? runCapture);
|
|
9121
|
-
if (!fileExists((0,
|
|
9369
|
+
if (!fileExists((0, import_node_path41.join)(repositoryRoot, "nx.json"))) {
|
|
9122
9370
|
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
9371
|
}
|
|
9124
9372
|
const persisted = readMnciConfig(repositoryRoot);
|
|
@@ -9131,7 +9379,7 @@ function adoptOverlay(repositoryRoot, options, dependencies = {}) {
|
|
|
9131
9379
|
}
|
|
9132
9380
|
|
|
9133
9381
|
// src/repository-adoption/adopt-toolchain.use-case.ts
|
|
9134
|
-
var
|
|
9382
|
+
var import_node_path43 = require("path");
|
|
9135
9383
|
|
|
9136
9384
|
// src/repository-adoption/align-nx-family.algorithm.ts
|
|
9137
9385
|
var VERSION = /^[\^~]?(\d+)\.(\d+)\.(\d+)$/;
|
|
@@ -9169,24 +9417,24 @@ function alignNxFamily(dependencies, version) {
|
|
|
9169
9417
|
}
|
|
9170
9418
|
|
|
9171
9419
|
// src/repository-adoption/retire-tooling.use-case.ts
|
|
9172
|
-
var
|
|
9173
|
-
var
|
|
9420
|
+
var import_node_fs37 = require("fs");
|
|
9421
|
+
var import_node_path42 = require("path");
|
|
9174
9422
|
var RETIRED_COMMAND = /\b(?:prettier|oxfmt|oxlint)\b/;
|
|
9175
9423
|
function retireTooling(repositoryRoot) {
|
|
9176
9424
|
const removed = [];
|
|
9177
9425
|
for (const file of RETIRED_FORMATTER_FILES) {
|
|
9178
|
-
if (!fileExists((0,
|
|
9426
|
+
if (!fileExists((0, import_node_path42.join)(repositoryRoot, file))) {
|
|
9179
9427
|
continue;
|
|
9180
9428
|
}
|
|
9181
|
-
(0,
|
|
9429
|
+
(0, import_node_fs37.rmSync)((0, import_node_path42.join)(repositoryRoot, file), { force: true });
|
|
9182
9430
|
removed.push(file);
|
|
9183
9431
|
}
|
|
9184
|
-
const hadRegistry = fileExists((0,
|
|
9432
|
+
const hadRegistry = fileExists((0, import_node_path42.join)(repositoryRoot, ".verdaccio"));
|
|
9185
9433
|
removeLocalRegistryScaffolding(repositoryRoot);
|
|
9186
9434
|
if (hadRegistry) {
|
|
9187
9435
|
removed.push(".verdaccio, its dependency and the local-registry target");
|
|
9188
9436
|
}
|
|
9189
|
-
const manifestPath = (0,
|
|
9437
|
+
const manifestPath = (0, import_node_path42.join)(repositoryRoot, "package.json");
|
|
9190
9438
|
if (!fileExists(manifestPath)) {
|
|
9191
9439
|
return removed;
|
|
9192
9440
|
}
|
|
@@ -9233,7 +9481,7 @@ function adoptToolchain(repositoryRoot, options = {}, dependencies = {}) {
|
|
|
9233
9481
|
console.log(message);
|
|
9234
9482
|
});
|
|
9235
9483
|
requireCleanWorkingTree(repositoryRoot, capture);
|
|
9236
|
-
const manifestPath = (0,
|
|
9484
|
+
const manifestPath = (0, import_node_path43.join)(repositoryRoot, "package.json");
|
|
9237
9485
|
if (!fileExists(manifestPath)) {
|
|
9238
9486
|
throw new Error("No package.json at the repository root.");
|
|
9239
9487
|
}
|
|
@@ -9283,8 +9531,8 @@ function createBaselineTags(repositoryRoot, stranded) {
|
|
|
9283
9531
|
}
|
|
9284
9532
|
|
|
9285
9533
|
// src/repository-adoption/inspect-repository.use-case.ts
|
|
9286
|
-
var
|
|
9287
|
-
var
|
|
9534
|
+
var import_node_fs38 = require("fs");
|
|
9535
|
+
var import_node_path44 = require("path");
|
|
9288
9536
|
var LOCKFILES = [
|
|
9289
9537
|
["package-lock.json", "npm"],
|
|
9290
9538
|
["pnpm-lock.yaml", "pnpm"],
|
|
@@ -9305,25 +9553,25 @@ function inspectRepository(repositoryRoot) {
|
|
|
9305
9553
|
const isGitRepo = inside.status === 0 && inside.stdout.trim() === "true";
|
|
9306
9554
|
const dirty = isGitRepo && runCapture("git", ["status", "--porcelain"], repositoryRoot).stdout.trim() !== "";
|
|
9307
9555
|
const tags = isGitRepo ? runCapture("git", ["tag", "--list"], repositoryRoot).stdout.split(/\r?\n/).filter(Boolean) : [];
|
|
9308
|
-
const manifestPath = (0,
|
|
9556
|
+
const manifestPath = (0, import_node_path44.join)(repositoryRoot, "package.json");
|
|
9309
9557
|
const manifest = fileExists(manifestPath) ? readJson(manifestPath) : {};
|
|
9310
|
-
const nxJsonPath = (0,
|
|
9558
|
+
const nxJsonPath = (0, import_node_path44.join)(repositoryRoot, "nx.json");
|
|
9311
9559
|
const nxJson = fileExists(nxJsonPath) ? readJson(nxJsonPath) : {};
|
|
9312
9560
|
const ci = [];
|
|
9313
9561
|
const pipelines = [];
|
|
9314
|
-
if ((0,
|
|
9562
|
+
if ((0, import_node_fs38.existsSync)((0, import_node_path44.join)(repositoryRoot, "azure-pipelines.yml"))) {
|
|
9315
9563
|
ci.push("azure");
|
|
9316
|
-
pipelines.push((0,
|
|
9564
|
+
pipelines.push((0, import_node_path44.join)(repositoryRoot, "azure-pipelines.yml"));
|
|
9317
9565
|
}
|
|
9318
|
-
const workflows = (0,
|
|
9319
|
-
if ((0,
|
|
9320
|
-
const files = (0,
|
|
9566
|
+
const workflows = (0, import_node_path44.join)(repositoryRoot, ".github", "workflows");
|
|
9567
|
+
if ((0, import_node_fs38.existsSync)(workflows)) {
|
|
9568
|
+
const files = (0, import_node_fs38.readdirSync)(workflows).filter((file) => /\.ya?ml$/.test(file));
|
|
9321
9569
|
if (files.length > 0) {
|
|
9322
9570
|
ci.push("github");
|
|
9323
|
-
pipelines.push(...files.map((file) => (0,
|
|
9571
|
+
pipelines.push(...files.map((file) => (0, import_node_path44.join)(workflows, file)));
|
|
9324
9572
|
}
|
|
9325
9573
|
}
|
|
9326
|
-
const rootFiles = (0,
|
|
9574
|
+
const rootFiles = (0, import_node_fs38.readdirSync)(repositoryRoot);
|
|
9327
9575
|
return {
|
|
9328
9576
|
isGitRepo,
|
|
9329
9577
|
dirty,
|
|
@@ -9334,7 +9582,7 @@ function inspectRepository(repositoryRoot) {
|
|
|
9334
9582
|
tagCount: tags.length,
|
|
9335
9583
|
strandedTags: isGitRepo ? locateStrandedReleaseTags(repositoryRoot, nxJson.release?.releaseTag?.pattern) : [],
|
|
9336
9584
|
ci,
|
|
9337
|
-
pipelineUsesMnci: pipelines.some((file) => /\bmnci ci\b/.test((0,
|
|
9585
|
+
pipelineUsesMnci: pipelines.some((file) => /\bmnci ci\b/.test((0, import_node_fs38.readFileSync)(file, "utf8"))),
|
|
9338
9586
|
retiredTooling: [.../* @__PURE__ */ new Set([...rootFiles.filter((file) => RETIRED_FILE_PATTERN.test(file) || file === ".verdaccio"), ...retiredNamesIn(manifest)])],
|
|
9339
9587
|
personalFiles: PERSONAL_FILES.filter((file) => rootFiles.includes(file))
|
|
9340
9588
|
};
|
|
@@ -9631,13 +9879,13 @@ function runCommands(program, options) {
|
|
|
9631
9879
|
}
|
|
9632
9880
|
|
|
9633
9881
|
// src/workspace-info/list-projects.use-case.ts
|
|
9634
|
-
var
|
|
9882
|
+
var import_node_path45 = require("path");
|
|
9635
9883
|
var TYPE_TAG_PREFIX = "type:";
|
|
9636
9884
|
function listProjects(workspaceRoot) {
|
|
9637
9885
|
return locateProjects(workspaceRoot).map((location) => {
|
|
9638
|
-
const projectJsonPath = (0,
|
|
9886
|
+
const projectJsonPath = (0, import_node_path45.join)(workspaceRoot, location.dir, "project.json");
|
|
9639
9887
|
const project = fileExists(projectJsonPath) ? readJson(projectJsonPath) : {};
|
|
9640
|
-
const manifestPath = (0,
|
|
9888
|
+
const manifestPath = (0, import_node_path45.join)(workspaceRoot, location.dir, "package.json");
|
|
9641
9889
|
const manifestTags = fileExists(manifestPath) ? readJson(manifestPath).nx?.tags ?? [] : [];
|
|
9642
9890
|
const typeTag = [...project.tags ?? [], ...manifestTags].find((tag) => tag.startsWith(TYPE_TAG_PREFIX));
|
|
9643
9891
|
return {
|
|
@@ -9650,7 +9898,7 @@ function listProjects(workspaceRoot) {
|
|
|
9650
9898
|
}).toSorted((a, b) => a.dir.localeCompare(b.dir));
|
|
9651
9899
|
}
|
|
9652
9900
|
function runProjects(workspaceRoot, options) {
|
|
9653
|
-
if (!fileExists((0,
|
|
9901
|
+
if (!fileExists((0, import_node_path45.join)(workspaceRoot, "nx.json"))) {
|
|
9654
9902
|
throw new Error("No nx.json found here. Run `projects` from the workspace root.");
|
|
9655
9903
|
}
|
|
9656
9904
|
const projects = listProjects(workspaceRoot);
|
|
@@ -9664,11 +9912,11 @@ function runProjects(workspaceRoot, options) {
|
|
|
9664
9912
|
}
|
|
9665
9913
|
|
|
9666
9914
|
// src/workspace-info/read-workspace-info.use-case.ts
|
|
9667
|
-
var
|
|
9915
|
+
var import_node_path47 = require("path");
|
|
9668
9916
|
|
|
9669
9917
|
// src/cli-version/check-for-update.use-case.ts
|
|
9670
|
-
var
|
|
9671
|
-
var
|
|
9918
|
+
var import_node_fs39 = require("fs");
|
|
9919
|
+
var import_node_path46 = require("path");
|
|
9672
9920
|
var import_cross_spawn3 = __toESM(require("cross-spawn"));
|
|
9673
9921
|
var PACKAGE_NAME2 = "@mnci/cli";
|
|
9674
9922
|
var REGISTRY_TIMEOUT_MS = 2e3;
|
|
@@ -9727,8 +9975,8 @@ function releaseTriple(version) {
|
|
|
9727
9975
|
}
|
|
9728
9976
|
function readCliVersion(packageDirectory) {
|
|
9729
9977
|
try {
|
|
9730
|
-
const manifestPath = (0,
|
|
9731
|
-
const manifest = JSON.parse((0,
|
|
9978
|
+
const manifestPath = (0, import_node_path46.join)(packageDirectory, "..", "package.json");
|
|
9979
|
+
const manifest = JSON.parse((0, import_node_fs39.readFileSync)(manifestPath, "utf8"));
|
|
9732
9980
|
return manifest.version ?? "0.0.0";
|
|
9733
9981
|
} catch {
|
|
9734
9982
|
return "0.0.0";
|
|
@@ -9738,7 +9986,7 @@ function readCliVersion(packageDirectory) {
|
|
|
9738
9986
|
// src/workspace-info/read-workspace-info.use-case.ts
|
|
9739
9987
|
function readWorkspaceInfo(workspaceRoot, cliVersion) {
|
|
9740
9988
|
const latest = fetchLatestVersion() ?? null;
|
|
9741
|
-
const isWorkspace = fileExists((0,
|
|
9989
|
+
const isWorkspace = fileExists((0, import_node_path47.join)(workspaceRoot, "nx.json"));
|
|
9742
9990
|
return {
|
|
9743
9991
|
cli: {
|
|
9744
9992
|
version: cliVersion,
|
|
@@ -9759,7 +10007,7 @@ function runInfo(workspaceRoot, cliVersion, options) {
|
|
|
9759
10007
|
}
|
|
9760
10008
|
|
|
9761
10009
|
// src/interactive-wizard/interactive-wizard.use-case.ts
|
|
9762
|
-
var
|
|
10010
|
+
var import_node_path48 = require("path");
|
|
9763
10011
|
|
|
9764
10012
|
// src/interactive-wizard/adopt-steps.config.ts
|
|
9765
10013
|
var ADOPT_GLOBAL_OPTIONS = ["json"];
|
|
@@ -9940,7 +10188,7 @@ function wizardMenu(commands, inWorkspace) {
|
|
|
9940
10188
|
}
|
|
9941
10189
|
async function runInteractive(program, prompter = createInquirerPrompter(), workingDirectory = process.cwd()) {
|
|
9942
10190
|
const commands = describeCommands(program);
|
|
9943
|
-
const inWorkspace = fileExists((0,
|
|
10191
|
+
const inWorkspace = fileExists((0, import_node_path48.join)(workingDirectory, "nx.json"));
|
|
9944
10192
|
const name = await prompter.select("What would you like to do?", wizardMenu(commands, inWorkspace));
|
|
9945
10193
|
const command = commands.find((candidate) => candidate.name === name);
|
|
9946
10194
|
const argv = buildArgv(command, await askCommand(command, prompter));
|
|
@@ -9953,8 +10201,8 @@ async function runInteractive(program, prompter = createInquirerPrompter(), work
|
|
|
9953
10201
|
}
|
|
9954
10202
|
|
|
9955
10203
|
// src/workspace-creation/adopt-directory.use-case.ts
|
|
9956
|
-
var
|
|
9957
|
-
var
|
|
10204
|
+
var import_node_fs40 = require("fs");
|
|
10205
|
+
var import_node_path49 = require("path");
|
|
9958
10206
|
var NEVER_COPIED = /* @__PURE__ */ new Set([".git", "node_modules"]);
|
|
9959
10207
|
var AGENT_AND_CI_ENTRIES = [
|
|
9960
10208
|
"AGENTS.md",
|
|
@@ -9985,13 +10233,13 @@ var PREFLIGHT_BLOCKERS = [
|
|
|
9985
10233
|
"packages"
|
|
9986
10234
|
];
|
|
9987
10235
|
function assertAdoptableDirectory(target) {
|
|
9988
|
-
if (!(0,
|
|
10236
|
+
if (!(0, import_node_fs40.existsSync)(target)) {
|
|
9989
10237
|
throw new Error(`--into '${target}' does not exist. Create or clone it first.`);
|
|
9990
10238
|
}
|
|
9991
|
-
if (!(0,
|
|
10239
|
+
if (!(0, import_node_fs40.statSync)(target).isDirectory()) {
|
|
9992
10240
|
throw new Error(`--into '${target}' is not a directory.`);
|
|
9993
10241
|
}
|
|
9994
|
-
const blockers = PREFLIGHT_BLOCKERS.filter((entry) => (0,
|
|
10242
|
+
const blockers = PREFLIGHT_BLOCKERS.filter((entry) => (0, import_node_fs40.existsSync)((0, import_node_path49.join)(target, entry)));
|
|
9995
10243
|
if (blockers.length > 0) {
|
|
9996
10244
|
throw new Error(
|
|
9997
10245
|
`--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 +10247,15 @@ function assertAdoptableDirectory(target) {
|
|
|
9999
10247
|
}
|
|
10000
10248
|
}
|
|
10001
10249
|
function mergeGitignore(generatedFile, targetFile) {
|
|
10002
|
-
const existing = (0,
|
|
10250
|
+
const existing = (0, import_node_fs40.readFileSync)(targetFile, "utf8");
|
|
10003
10251
|
const present = new Set(existing.split("\n").map((line) => line.trim()));
|
|
10004
|
-
const additions = (0,
|
|
10252
|
+
const additions = (0, import_node_fs40.readFileSync)(generatedFile, "utf8").split("\n").map((line) => line.trimEnd()).filter((line) => {
|
|
10005
10253
|
const trimmed = line.trim();
|
|
10006
10254
|
return trimmed !== "" && !trimmed.startsWith("#") && !present.has(trimmed);
|
|
10007
10255
|
});
|
|
10008
10256
|
if (additions.length === 0) return false;
|
|
10009
10257
|
const separator = existing.endsWith("\n") ? "" : "\n";
|
|
10010
|
-
(0,
|
|
10258
|
+
(0, import_node_fs40.writeFileSync)(
|
|
10011
10259
|
targetFile,
|
|
10012
10260
|
`${existing}${separator}
|
|
10013
10261
|
# Added by mnci (Nx workspace)
|
|
@@ -10017,9 +10265,9 @@ ${additions.join("\n")}
|
|
|
10017
10265
|
return true;
|
|
10018
10266
|
}
|
|
10019
10267
|
function adoptGeneratedWorkspace(generatedRoot, target) {
|
|
10020
|
-
const entries = (0,
|
|
10268
|
+
const entries = (0, import_node_fs40.readdirSync)(generatedRoot).filter((entry) => !NEVER_COPIED.has(entry));
|
|
10021
10269
|
const collisions = entries.filter(
|
|
10022
|
-
(entry) => (0,
|
|
10270
|
+
(entry) => (0, import_node_fs40.existsSync)((0, import_node_path49.join)(target, entry)) && !EXISTING_WINS.has(entry) && entry !== ".gitignore"
|
|
10023
10271
|
);
|
|
10024
10272
|
if (collisions.length > 0) {
|
|
10025
10273
|
throw new Error(
|
|
@@ -10028,28 +10276,28 @@ function adoptGeneratedWorkspace(generatedRoot, target) {
|
|
|
10028
10276
|
}
|
|
10029
10277
|
const result = { copied: [], kept: [], mergedGitignore: false };
|
|
10030
10278
|
for (const entry of entries) {
|
|
10031
|
-
const from = (0,
|
|
10032
|
-
const to = (0,
|
|
10033
|
-
if (entry === ".gitignore" && (0,
|
|
10279
|
+
const from = (0, import_node_path49.join)(generatedRoot, entry);
|
|
10280
|
+
const to = (0, import_node_path49.join)(target, entry);
|
|
10281
|
+
if (entry === ".gitignore" && (0, import_node_fs40.existsSync)(to)) {
|
|
10034
10282
|
result.mergedGitignore = mergeGitignore(from, to);
|
|
10035
10283
|
result.kept.push(entry);
|
|
10036
10284
|
continue;
|
|
10037
10285
|
}
|
|
10038
|
-
if ((0,
|
|
10286
|
+
if ((0, import_node_fs40.existsSync)(to)) {
|
|
10039
10287
|
result.kept.push(entry);
|
|
10040
10288
|
continue;
|
|
10041
10289
|
}
|
|
10042
|
-
(0,
|
|
10290
|
+
(0, import_node_fs40.cpSync)(from, to, { recursive: true });
|
|
10043
10291
|
result.copied.push(entry);
|
|
10044
10292
|
}
|
|
10045
|
-
(0,
|
|
10293
|
+
(0, import_node_fs40.rmSync)(generatedRoot, { recursive: true, force: true });
|
|
10046
10294
|
return result;
|
|
10047
10295
|
}
|
|
10048
10296
|
|
|
10049
10297
|
// src/workspace-creation/create-workspace.use-case.ts
|
|
10050
|
-
var
|
|
10298
|
+
var import_node_fs41 = require("fs");
|
|
10051
10299
|
var import_node_os2 = require("os");
|
|
10052
|
-
var
|
|
10300
|
+
var import_node_path50 = require("path");
|
|
10053
10301
|
function nxCloudProviderValue(ci) {
|
|
10054
10302
|
return ci === "azure" ? "azure" : "github";
|
|
10055
10303
|
}
|
|
@@ -10092,9 +10340,9 @@ async function resolveRegistry2(options) {
|
|
|
10092
10340
|
return await promptRegistry();
|
|
10093
10341
|
}
|
|
10094
10342
|
async function runNew(name, options) {
|
|
10095
|
-
const adoptTarget = options.into === void 0 ? void 0 : (0,
|
|
10343
|
+
const adoptTarget = options.into === void 0 ? void 0 : (0, import_node_path50.resolve)(process.cwd(), options.into);
|
|
10096
10344
|
if (adoptTarget !== void 0) assertAdoptableDirectory(adoptTarget);
|
|
10097
|
-
const workspaceName = name ?? (adoptTarget === void 0 ? await promptText("Workspace name") : (0,
|
|
10345
|
+
const workspaceName = name ?? (adoptTarget === void 0 ? await promptText("Workspace name") : (0, import_node_path50.basename)(adoptTarget));
|
|
10098
10346
|
assertValidProjectName(workspaceName, "Workspace name");
|
|
10099
10347
|
const scope = options.scope ?? (options.yes ? `@${workspaceName}` : await promptText("npm scope for publishable packages", `@${workspaceName}`));
|
|
10100
10348
|
const registry = await resolveRegistry2(options);
|
|
@@ -10107,8 +10355,8 @@ async function runNew(name, options) {
|
|
|
10107
10355
|
const npmAuth = resolveNpmAuth(options.npmAuth, registry, ci);
|
|
10108
10356
|
const stack = await resolveStack(options);
|
|
10109
10357
|
const nxCloud = options.nxCloud ?? (options.yes ? false : await promptNxCloud());
|
|
10110
|
-
const stagingParent = adoptTarget === void 0 ? process.cwd() : (0,
|
|
10111
|
-
let workspaceRoot = (0,
|
|
10358
|
+
const stagingParent = adoptTarget === void 0 ? process.cwd() : (0, import_node_fs41.mkdtempSync)((0, import_node_path50.join)((0, import_node_os2.tmpdir)(), "mnci-new-"));
|
|
10359
|
+
let workspaceRoot = (0, import_node_path50.join)(stagingParent, workspaceName);
|
|
10112
10360
|
try {
|
|
10113
10361
|
logger.step(`Creating Nx workspace '${workspaceName}' (preset: ts)`);
|
|
10114
10362
|
runNpx(
|
|
@@ -10131,7 +10379,7 @@ async function runNew(name, options) {
|
|
|
10131
10379
|
workspaceRoot = adoptTarget;
|
|
10132
10380
|
}
|
|
10133
10381
|
} finally {
|
|
10134
|
-
if (adoptTarget !== void 0) (0,
|
|
10382
|
+
if (adoptTarget !== void 0) (0, import_node_fs41.rmSync)(stagingParent, { recursive: true, force: true });
|
|
10135
10383
|
}
|
|
10136
10384
|
logger.step(
|
|
10137
10385
|
"Applying MoNecromanCI overlay (VS Code workspace, release config, .npmrc, commitlint, pipeline, stack)"
|
|
@@ -10141,8 +10389,8 @@ async function runNew(name, options) {
|
|
|
10141
10389
|
{ workspaceName, scope, registry, agent, variableGroup, ci, stack, ...npmAuth && { npmAuth } },
|
|
10142
10390
|
logger.detail
|
|
10143
10391
|
);
|
|
10144
|
-
(0,
|
|
10145
|
-
(0,
|
|
10392
|
+
(0, import_node_fs41.rmSync)((0, import_node_path50.join)(workspaceRoot, "node_modules"), { recursive: true, force: true });
|
|
10393
|
+
(0, import_node_fs41.rmSync)((0, import_node_path50.join)(workspaceRoot, "package-lock.json"), { force: true });
|
|
10146
10394
|
logger.step("Installing the toolchain (commitlint + husky + linting/formatting)");
|
|
10147
10395
|
const installStatus = runShell(
|
|
10148
10396
|
"npm",
|
|
@@ -10244,7 +10492,7 @@ function buildProgram(cliVersion) {
|
|
|
10244
10492
|
).option(
|
|
10245
10493
|
"--empty",
|
|
10246
10494
|
"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(
|
|
10495
|
+
).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
10496
|
"--e2e",
|
|
10249
10497
|
"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
10498
|
).option(
|