@pagopa/dx-cli 0.7.0 → 0.8.1
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/bin/index.js +154 -58
- package/package.json +2 -2
package/bin/index.js
CHANGED
|
@@ -25,6 +25,7 @@ var LocalCodemodRegistry = class {
|
|
|
25
25
|
// src/adapters/codemods/update-code-review.ts
|
|
26
26
|
import { getLogger as getLogger2 } from "@logtape/logtape";
|
|
27
27
|
import { replaceInFile } from "replace-in-file";
|
|
28
|
+
import * as YAML2 from "yaml";
|
|
28
29
|
|
|
29
30
|
// src/adapters/codemods/git.ts
|
|
30
31
|
import { getLogger } from "@logtape/logtape";
|
|
@@ -49,20 +50,48 @@ var getLatestCommitShaOrRef = async (owner, repo, ref = "main") => {
|
|
|
49
50
|
});
|
|
50
51
|
};
|
|
51
52
|
|
|
53
|
+
// src/adapters/codemods/yaml.ts
|
|
54
|
+
import * as YAML from "yaml";
|
|
55
|
+
var isChildOf = (path2, key) => {
|
|
56
|
+
const ancestor = path2.at(-1);
|
|
57
|
+
return YAML.isPair(ancestor) && YAML.isScalar(ancestor.key) && typeof ancestor.key.value === "string" && ancestor.key.value === key;
|
|
58
|
+
};
|
|
59
|
+
|
|
52
60
|
// src/adapters/codemods/update-code-review.ts
|
|
53
|
-
var
|
|
61
|
+
var updateJSCodeReviewJob = (sha) => (workflow, filename) => {
|
|
54
62
|
const logger2 = getLogger2(["dx-cli", "codemod"]);
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
63
|
+
const document = YAML2.parseDocument(workflow);
|
|
64
|
+
let updated = false;
|
|
65
|
+
YAML2.visit(document, {
|
|
66
|
+
Map(_, map, path2) {
|
|
67
|
+
if (map.has("jobs") || isChildOf(path2, "jobs")) {
|
|
68
|
+
return void 0;
|
|
69
|
+
}
|
|
70
|
+
if (map.has("uses")) {
|
|
71
|
+
const uses = map.get("uses");
|
|
72
|
+
if (typeof uses === "string" && uses.startsWith("pagopa/dx/.github/workflows/js_code_review.yaml@")) {
|
|
73
|
+
map.set("secrets", "inherit");
|
|
74
|
+
map.set("permissions", {
|
|
75
|
+
contents: "read",
|
|
76
|
+
"pull-requests": "write"
|
|
77
|
+
});
|
|
78
|
+
map.set(
|
|
79
|
+
"uses",
|
|
80
|
+
`pagopa/dx/.github/workflows/js_code_review.yaml@${sha}`
|
|
81
|
+
);
|
|
82
|
+
updated = true;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return YAML2.visit.SKIP;
|
|
86
|
+
}
|
|
64
87
|
});
|
|
65
|
-
|
|
88
|
+
if (updated) {
|
|
89
|
+
logger2.info("Workflow {filename} updated", {
|
|
90
|
+
filename
|
|
91
|
+
});
|
|
92
|
+
return YAML2.stringify(document);
|
|
93
|
+
}
|
|
94
|
+
return workflow;
|
|
66
95
|
};
|
|
67
96
|
var updateCodeReview = {
|
|
68
97
|
apply: async () => {
|
|
@@ -70,13 +99,16 @@ var updateCodeReview = {
|
|
|
70
99
|
const owner = "pagopa";
|
|
71
100
|
const repo = "dx";
|
|
72
101
|
return getLatestCommitSha(owner, repo).then(async (sha) => {
|
|
73
|
-
await
|
|
102
|
+
await replaceInFile({
|
|
103
|
+
allowEmptyPaths: true,
|
|
104
|
+
files: [".github/workflows/*.yaml"],
|
|
105
|
+
processor: updateJSCodeReviewJob(sha)
|
|
106
|
+
});
|
|
74
107
|
}).catch(() => {
|
|
75
108
|
logger2.error(
|
|
76
|
-
"Failed to fetch the latest commit sha from {
|
|
109
|
+
"Failed to fetch the latest commit sha from {repository}",
|
|
77
110
|
{
|
|
78
|
-
owner
|
|
79
|
-
repo
|
|
111
|
+
repository: `${owner}/${repo}`
|
|
80
112
|
}
|
|
81
113
|
);
|
|
82
114
|
});
|
|
@@ -88,17 +120,13 @@ var updateCodeReview = {
|
|
|
88
120
|
// src/adapters/codemods/use-azure-appsvc.ts
|
|
89
121
|
import { getLogger as getLogger3 } from "@logtape/logtape";
|
|
90
122
|
import { replaceInFile as replaceInFile2 } from "replace-in-file";
|
|
91
|
-
import
|
|
92
|
-
var isChildOf = (path2, key) => {
|
|
93
|
-
const ancestor = path2.at(-1);
|
|
94
|
-
return YAML.isPair(ancestor) && YAML.isScalar(ancestor.key) && typeof ancestor.key.value === "string" && ancestor.key.value === key;
|
|
95
|
-
};
|
|
123
|
+
import YAML3 from "yaml";
|
|
96
124
|
var migrateWorkflow = (sha) => (workflow, filename) => {
|
|
97
125
|
const logger2 = getLogger3(["dx-cli", "codemod"]);
|
|
98
126
|
logger2.debug("Processing {filename} file", { filename });
|
|
99
|
-
const document =
|
|
127
|
+
const document = YAML3.parseDocument(workflow);
|
|
100
128
|
let updated = false;
|
|
101
|
-
|
|
129
|
+
YAML3.visit(document, {
|
|
102
130
|
Map(_, map, path2) {
|
|
103
131
|
if (isChildOf(path2, "jobs") || isChildOf(path2, "with")) {
|
|
104
132
|
return void 0;
|
|
@@ -113,28 +141,33 @@ var migrateWorkflow = (sha) => (workflow, filename) => {
|
|
|
113
141
|
)) {
|
|
114
142
|
logger2.debug("Adding disable_auto_staging_deploy");
|
|
115
143
|
map.addIn(["with", "disable_auto_staging_deploy"], true);
|
|
144
|
+
map.set("permissions", {
|
|
145
|
+
attestations: "write",
|
|
146
|
+
contents: "read",
|
|
147
|
+
"id-token": "write"
|
|
148
|
+
});
|
|
116
149
|
updated = true;
|
|
117
150
|
return void 0;
|
|
118
151
|
}
|
|
119
152
|
}
|
|
120
|
-
return
|
|
153
|
+
return YAML3.visit.SKIP;
|
|
121
154
|
},
|
|
122
155
|
Pair(_, pair) {
|
|
123
|
-
if (
|
|
156
|
+
if (YAML3.isScalar(pair.key)) {
|
|
124
157
|
if (pair.key.value === "function_app_name") {
|
|
125
158
|
updated = true;
|
|
126
159
|
logger2.debug("Updating function_app_name to web_app_name");
|
|
127
|
-
return new
|
|
160
|
+
return new YAML3.Pair("web_app_name", pair.value);
|
|
128
161
|
}
|
|
129
162
|
if (pair.key.value === "use_staging_slot") {
|
|
130
163
|
updated = true;
|
|
131
164
|
logger2.debug("Removing use_staging_slot");
|
|
132
|
-
return
|
|
165
|
+
return YAML3.visit.REMOVE;
|
|
133
166
|
}
|
|
134
167
|
if (pair.key.value === "uses") {
|
|
135
168
|
updated = true;
|
|
136
169
|
logger2.debug("Updating uses value");
|
|
137
|
-
return new
|
|
170
|
+
return new YAML3.Pair(
|
|
138
171
|
"uses",
|
|
139
172
|
`pagopa/dx/.github/workflows/release-azure-appsvc.yaml@${sha}`
|
|
140
173
|
);
|
|
@@ -146,7 +179,7 @@ var migrateWorkflow = (sha) => (workflow, filename) => {
|
|
|
146
179
|
logger2.info("Workflow {filename} updated", {
|
|
147
180
|
filename
|
|
148
181
|
});
|
|
149
|
-
return
|
|
182
|
+
return YAML3.stringify(document);
|
|
150
183
|
}
|
|
151
184
|
logger2.debug("No changes applied to {filename}", { filename });
|
|
152
185
|
return workflow;
|
|
@@ -169,7 +202,48 @@ import { getLogger as getLogger4 } from "@logtape/logtape";
|
|
|
169
202
|
import { $ } from "execa";
|
|
170
203
|
import * as fs from "fs/promises";
|
|
171
204
|
import { replaceInFile as replaceInFile3 } from "replace-in-file";
|
|
172
|
-
import
|
|
205
|
+
import YAML4 from "yaml";
|
|
206
|
+
var NPM = class {
|
|
207
|
+
lockFileName = "package-lock.json";
|
|
208
|
+
async listWorkspaces() {
|
|
209
|
+
const { stdout } = await $`npm query .workspace`;
|
|
210
|
+
const workspaces = JSON.parse(stdout);
|
|
211
|
+
const workspaceNames = [];
|
|
212
|
+
if (Array.isArray(workspaces)) {
|
|
213
|
+
for (const ws of workspaces) {
|
|
214
|
+
if (Object.hasOwn(ws, "name")) {
|
|
215
|
+
workspaceNames.push(ws.name);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return workspaceNames;
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
var Yarn = class {
|
|
223
|
+
lockFileName = "yarn.lock";
|
|
224
|
+
async listWorkspaces() {
|
|
225
|
+
const { stdout } = await $({ lines: true })`yarn workspaces list --json`;
|
|
226
|
+
const workspaceNames = [];
|
|
227
|
+
for (const line of stdout) {
|
|
228
|
+
const ws = JSON.parse(line);
|
|
229
|
+
if (Object.hasOwn(ws, "name")) {
|
|
230
|
+
workspaceNames.push(ws.name);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return workspaceNames;
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
async function extractPackageExtensions() {
|
|
237
|
+
try {
|
|
238
|
+
const yarnrc = await fs.readFile(".yarnrc.yml", "utf-8");
|
|
239
|
+
const parsed = YAML4.parse(yarnrc);
|
|
240
|
+
if (parsed.packageExtensions) {
|
|
241
|
+
return parsed.packageExtensions;
|
|
242
|
+
}
|
|
243
|
+
} catch {
|
|
244
|
+
}
|
|
245
|
+
return void 0;
|
|
246
|
+
}
|
|
173
247
|
async function preparePackageJsonForPnpm() {
|
|
174
248
|
const packageJson2 = await fs.readFile("package.json", "utf-8");
|
|
175
249
|
const manifest = JSON.parse(packageJson2);
|
|
@@ -196,20 +270,20 @@ async function removeFiles(...files) {
|
|
|
196
270
|
)
|
|
197
271
|
);
|
|
198
272
|
}
|
|
199
|
-
async function
|
|
273
|
+
async function replacePMOccurrences() {
|
|
200
274
|
const logger2 = getLogger4(["dx-cli", "codemod"]);
|
|
201
|
-
logger2.info("Replacing yarn occurrences in files...");
|
|
275
|
+
logger2.info("Replacing yarn and npm occurrences in files...");
|
|
202
276
|
const results = await replaceInFile3({
|
|
203
277
|
allowEmptyPaths: true,
|
|
204
278
|
files: ["**/*.json", "**/*.md", "**/Dockerfile", "**/docker-compose.yml"],
|
|
205
279
|
from: [
|
|
206
280
|
"https://yarnpkg.com/",
|
|
207
281
|
"https://classic.yarnpkg.com/",
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
282
|
+
/\b(yarn workspace|npm -(\b-workspace\b|\bw\b)) (\S+)\b/g,
|
|
283
|
+
/\b(yarn workspace|npm -(\b-workspace\b|\bw\b)) /g,
|
|
284
|
+
/\b(yarn install --immutable|npm ci)\b/g,
|
|
285
|
+
/\b(yarn -q dlx|npx)\b/g,
|
|
286
|
+
/\b(Yarn|npm)\b/gi
|
|
213
287
|
],
|
|
214
288
|
ignore: ["**/node_modules/**", "**/dist/**", "**/build/**"],
|
|
215
289
|
to: [
|
|
@@ -232,7 +306,12 @@ async function updateDXWorkflows() {
|
|
|
232
306
|
const logger2 = getLogger4(["dx-cli", "codemod"]);
|
|
233
307
|
logger2.info("Updating Github Workflows workflows...");
|
|
234
308
|
const sha = await getLatestCommitShaOrRef("pagopa", "dx");
|
|
235
|
-
const
|
|
309
|
+
const results = await replaceInFile3({
|
|
310
|
+
allowEmptyPaths: true,
|
|
311
|
+
files: [".github/workflows/*.yaml"],
|
|
312
|
+
processor: updateJSCodeReviewJob(sha)
|
|
313
|
+
});
|
|
314
|
+
const ignore = results.filter((r) => !r.hasChanged).map((r) => r.file);
|
|
236
315
|
await replaceInFile3({
|
|
237
316
|
allowEmptyPaths: true,
|
|
238
317
|
files: [".github/workflows/*.yaml"],
|
|
@@ -240,26 +319,42 @@ async function updateDXWorkflows() {
|
|
|
240
319
|
processor: migrateWorkflow(sha)
|
|
241
320
|
});
|
|
242
321
|
}
|
|
243
|
-
async function writePnpmWorkspaceFile(workspaces) {
|
|
322
|
+
async function writePnpmWorkspaceFile(workspaces, packageExtensions) {
|
|
244
323
|
const pnpmWorkspace = {
|
|
324
|
+
packageExtensions,
|
|
245
325
|
packages: workspaces.length > 0 ? workspaces : ["apps/*", "packages/*"]
|
|
246
326
|
};
|
|
247
|
-
const yamlContent =
|
|
327
|
+
const yamlContent = YAML4.stringify(pnpmWorkspace);
|
|
248
328
|
await fs.writeFile("pnpm-workspace.yaml", yamlContent, "utf-8");
|
|
249
329
|
}
|
|
250
330
|
var apply = async (info) => {
|
|
251
331
|
if (info.packageManager === "pnpm") {
|
|
252
332
|
throw new Error("Project is already using pnpm");
|
|
253
333
|
}
|
|
334
|
+
const pm = info.packageManager === "yarn" ? new Yarn() : new NPM();
|
|
254
335
|
const logger2 = getLogger4(["dx-cli", "codemod"]);
|
|
336
|
+
const localWorkspaces = await pm.listWorkspaces();
|
|
337
|
+
logger2.info("Using the {protocol} protocol for local dependencies", {
|
|
338
|
+
protocol: "workspace:"
|
|
339
|
+
});
|
|
340
|
+
if (localWorkspaces.length > 0) {
|
|
341
|
+
await replaceInFile3({
|
|
342
|
+
allowEmptyPaths: true,
|
|
343
|
+
files: ["**/package.json"],
|
|
344
|
+
from: localWorkspaces.map((ws) => new RegExp(`"${ws}": ".*?"`, "g")),
|
|
345
|
+
to: localWorkspaces.map((ws) => `"${ws}": "workspace:^"`)
|
|
346
|
+
});
|
|
347
|
+
}
|
|
255
348
|
logger2.info("Remove unused fields from {file}", {
|
|
256
349
|
file: "package.json"
|
|
257
350
|
});
|
|
258
351
|
const workspaces = await preparePackageJsonForPnpm();
|
|
352
|
+
const packageExtensions = info.packageManager === "yarn" ? await extractPackageExtensions() : void 0;
|
|
259
353
|
logger2.info("Create {file}", {
|
|
260
354
|
file: "pnpm-workspace.yaml"
|
|
261
355
|
});
|
|
262
|
-
await writePnpmWorkspaceFile(workspaces);
|
|
356
|
+
await writePnpmWorkspaceFile(workspaces, packageExtensions);
|
|
357
|
+
await $`corepack pnpm@latest add --config pnpm-plugin-pagopa`;
|
|
263
358
|
logger2.info("Remove node_modules and yarn files");
|
|
264
359
|
await removeFiles(
|
|
265
360
|
".yarnrc",
|
|
@@ -270,26 +365,29 @@ var apply = async (info) => {
|
|
|
270
365
|
".pnp.loader.cjs",
|
|
271
366
|
"node_modules"
|
|
272
367
|
);
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
target
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
await $`corepack pnpm@latest import
|
|
280
|
-
await removeFiles(
|
|
281
|
-
}
|
|
282
|
-
logger2.info("No
|
|
368
|
+
const stat2 = await fs.stat(pm.lockFileName);
|
|
369
|
+
if (stat2.isFile()) {
|
|
370
|
+
logger2.info("Importing {source} to {target}", {
|
|
371
|
+
source: pm.lockFileName,
|
|
372
|
+
target: "pnpm-lock.yaml"
|
|
373
|
+
});
|
|
374
|
+
await $`corepack pnpm@latest import ${pm.lockFileName}`;
|
|
375
|
+
await removeFiles(pm.lockFileName);
|
|
376
|
+
} else {
|
|
377
|
+
logger2.info("No {source} file found, skipping import.", {
|
|
378
|
+
source: pm.lockFileName
|
|
379
|
+
});
|
|
283
380
|
}
|
|
284
|
-
await
|
|
285
|
-
await replaceYarnOccurrences();
|
|
381
|
+
await replacePMOccurrences();
|
|
286
382
|
await updateDXWorkflows();
|
|
383
|
+
logger2.info("Adding pnpm store to .gitignore...");
|
|
384
|
+
await fs.appendFile(".gitignore", "\n\n# PNPM\n.pnpm-store");
|
|
287
385
|
logger2.info("Setting pnpm as the package manager...");
|
|
288
386
|
await $`corepack use pnpm@latest`;
|
|
289
387
|
};
|
|
290
388
|
var use_pnpm_default = {
|
|
291
389
|
apply,
|
|
292
|
-
description: "
|
|
390
|
+
description: "Migrate the project to use pnpm as the package manager",
|
|
293
391
|
id: "use-pnpm"
|
|
294
392
|
};
|
|
295
393
|
|
|
@@ -665,7 +763,7 @@ import { Command as Command5 } from "commander";
|
|
|
665
763
|
import { getLogger as getLogger7 } from "@logtape/logtape";
|
|
666
764
|
function printVersion() {
|
|
667
765
|
const logger2 = getLogger7(["dx-cli", "version"]);
|
|
668
|
-
logger2.info(`dx CLI version: ${"0.
|
|
766
|
+
logger2.info(`dx CLI version: ${"0.8.1"}`);
|
|
669
767
|
}
|
|
670
768
|
|
|
671
769
|
// src/adapters/commander/commands/version.ts
|
|
@@ -674,11 +772,9 @@ var makeVersionCommand = () => new Command5().name("version").alias("v").action(
|
|
|
674
772
|
// src/adapters/commander/index.ts
|
|
675
773
|
var makeCli = (deps2, config2, cliDeps) => {
|
|
676
774
|
const program2 = new Command6();
|
|
677
|
-
program2.name("dx").description("The CLI for DX-Platform").version("0.
|
|
775
|
+
program2.name("dx").description("The CLI for DX-Platform").version("0.8.1");
|
|
678
776
|
program2.addCommand(makeDoctorCommand(deps2, config2));
|
|
679
|
-
|
|
680
|
-
program2.addCommand(makeCodemodCommand(cliDeps));
|
|
681
|
-
}
|
|
777
|
+
program2.addCommand(makeCodemodCommand(cliDeps));
|
|
682
778
|
if (process.env.ENABLE_INIT_COMMAND) {
|
|
683
779
|
program2.addCommand(makeInitCommand());
|
|
684
780
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pagopa/dx-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A CLI useful to manage DX tools.",
|
|
6
6
|
"repository": {
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"semver": "^7.7.2",
|
|
32
32
|
"yaml": "^2.8.0",
|
|
33
33
|
"zod": "^3.25.28",
|
|
34
|
-
"@pagopa/monorepo-generator": "^0.
|
|
34
|
+
"@pagopa/monorepo-generator": "^0.8.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@tsconfig/node22": "22.0.2",
|