@backstage/repo-tools 0.17.1-next.0 → 0.17.1-next.2
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/CHANGELOG.md +22 -0
- package/dist/commands/api-reports/cli-reports/runCliExtraction.cjs.js +62 -55
- package/dist/commands/index.cjs.js +3 -4
- package/dist/commands/package-docs/command.cjs.js +2 -1
- package/dist/commands/util.cjs.js +40 -29
- package/dist/package.json.cjs.js +1 -1
- package/package.json +10 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# @backstage/repo-tools
|
|
2
2
|
|
|
3
|
+
## 0.17.1-next.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 482ceed: Migrated from `assertError` to `toError` for error handling.
|
|
8
|
+
- Updated dependencies
|
|
9
|
+
- @backstage/errors@1.3.0-next.0
|
|
10
|
+
- @backstage/cli-common@0.2.1-next.1
|
|
11
|
+
- @backstage/cli-node@0.3.1-next.1
|
|
12
|
+
- @backstage/config-loader@1.10.10-next.1
|
|
13
|
+
- @backstage/backend-plugin-api@1.9.0-next.2
|
|
14
|
+
- @backstage/catalog-model@1.7.8-next.0
|
|
15
|
+
|
|
16
|
+
## 0.17.1-next.1
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- 2e5c5f8: Bumped `glob` dependency from v7/v8/v11 to v13 to address security vulnerabilities in older versions. Bumped `rollup` from v4.27 to v4.59+ to fix a high severity path traversal vulnerability (GHSA-mw96-cpmx-2vgc).
|
|
21
|
+
- 8e9679b: Parallelized CLI report generation, reducing wall-clock time by ~4x.
|
|
22
|
+
- Updated dependencies
|
|
23
|
+
- @backstage/backend-plugin-api@1.9.0-next.1
|
|
24
|
+
|
|
3
25
|
## 0.17.1-next.0
|
|
4
26
|
|
|
5
27
|
### Patch Changes
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var path = require('node:path');
|
|
4
|
+
var os = require('node:os');
|
|
4
5
|
var fs = require('fs-extra');
|
|
6
|
+
var pLimit = require('p-limit');
|
|
5
7
|
var util = require('../../util.cjs.js');
|
|
6
8
|
var cliCommon = require('@backstage/cli-common');
|
|
7
9
|
var generateCliReport = require('./generateCliReport.cjs.js');
|
|
@@ -9,7 +11,9 @@ var logApiReportInstructions = require('../common/logApiReportInstructions.cjs.j
|
|
|
9
11
|
|
|
10
12
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
11
13
|
|
|
14
|
+
var os__default = /*#__PURE__*/_interopDefaultCompat(os);
|
|
12
15
|
var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
|
|
16
|
+
var pLimit__default = /*#__PURE__*/_interopDefaultCompat(pLimit);
|
|
13
17
|
|
|
14
18
|
function parseHelpPage(helpPageContent) {
|
|
15
19
|
let usage;
|
|
@@ -59,10 +63,10 @@ function parseHelpPage(helpPageContent) {
|
|
|
59
63
|
commandArguments
|
|
60
64
|
};
|
|
61
65
|
}
|
|
62
|
-
async function exploreCliHelpPages(run) {
|
|
66
|
+
async function exploreCliHelpPages(run, limit) {
|
|
63
67
|
const helpPages = new Array();
|
|
64
68
|
async function exploreHelpPage(...path) {
|
|
65
|
-
const content = await run(...path, "--help");
|
|
69
|
+
const content = await limit(() => run(...path, "--help"));
|
|
66
70
|
const parsed = parseHelpPage(content);
|
|
67
71
|
helpPages.push({ path, ...parsed });
|
|
68
72
|
await Promise.all(
|
|
@@ -82,65 +86,68 @@ async function runCliExtraction({
|
|
|
82
86
|
packageDirs,
|
|
83
87
|
isLocalBuild
|
|
84
88
|
}) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
if (typeof pkgJson.bin === "string") {
|
|
99
|
-
const run = util.createBinRunner(fullDir, pkgJson.bin);
|
|
100
|
-
const helpPages = await exploreCliHelpPages(run);
|
|
101
|
-
models.push({ name: path.basename(pkgJson.bin), helpPages });
|
|
102
|
-
} else {
|
|
103
|
-
for (const [name, path] of Object.entries(pkgJson.bin)) {
|
|
104
|
-
const run = util.createBinRunner(fullDir, path);
|
|
105
|
-
const helpPages = await exploreCliHelpPages(run);
|
|
106
|
-
models.push({ name, helpPages });
|
|
89
|
+
const limit = pLimit__default.default(os__default.default.cpus().length);
|
|
90
|
+
await Promise.all(
|
|
91
|
+
packageDirs.map(async (packageDir) => {
|
|
92
|
+
console.log(`## Processing ${packageDir}`);
|
|
93
|
+
const fullDir = cliCommon.targetPaths.resolveRoot(packageDir);
|
|
94
|
+
const pkgJson = await fs__default.default.readJson(path.resolve(fullDir, "package.json"));
|
|
95
|
+
if (!pkgJson.bin) {
|
|
96
|
+
if (pkgJson.backstage?.role === "cli") {
|
|
97
|
+
throw new Error(
|
|
98
|
+
`CLI package ${pkgJson.name} is missing a "bin" field in its package.json`
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
return;
|
|
107
102
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
103
|
+
const models = new Array();
|
|
104
|
+
if (typeof pkgJson.bin === "string") {
|
|
105
|
+
const run = util.createBinRunner(fullDir, pkgJson.bin);
|
|
106
|
+
const helpPages = await exploreCliHelpPages(run, limit);
|
|
107
|
+
models.push({ name: path.basename(pkgJson.bin), helpPages });
|
|
108
|
+
} else {
|
|
109
|
+
for (const [name, path] of Object.entries(pkgJson.bin)) {
|
|
110
|
+
const run = util.createBinRunner(fullDir, path);
|
|
111
|
+
const helpPages = await exploreCliHelpPages(run, limit);
|
|
112
|
+
models.push({ name, helpPages });
|
|
118
113
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
if (
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
);
|
|
135
|
-
|
|
136
|
-
|
|
114
|
+
}
|
|
115
|
+
for (const model of models) {
|
|
116
|
+
const report = generateCliReport.generateCliReport({ packageName: pkgJson.name, model });
|
|
117
|
+
const reportPath = path.resolve(
|
|
118
|
+
fullDir,
|
|
119
|
+
`cli-report.${models.length === 1 ? "" : `${model.name}.`}md`
|
|
120
|
+
);
|
|
121
|
+
const existingReport = await fs__default.default.readFile(reportPath, "utf8").catch((error) => {
|
|
122
|
+
if (error.code === "ENOENT") {
|
|
123
|
+
return void 0;
|
|
124
|
+
}
|
|
125
|
+
throw error;
|
|
126
|
+
});
|
|
127
|
+
if (existingReport !== report) {
|
|
128
|
+
if (isLocalBuild) {
|
|
129
|
+
console.warn(`CLI report changed for ${packageDir}`);
|
|
130
|
+
await fs__default.default.writeFile(reportPath, report);
|
|
131
|
+
} else {
|
|
137
132
|
logApiReportInstructions.logApiReportInstructions();
|
|
133
|
+
if (existingReport) {
|
|
134
|
+
console.log("");
|
|
135
|
+
console.log(
|
|
136
|
+
`The conflicting file is ${path.relative(
|
|
137
|
+
cliCommon.targetPaths.rootDir,
|
|
138
|
+
reportPath
|
|
139
|
+
)}, expecting the following content:`
|
|
140
|
+
);
|
|
141
|
+
console.log("");
|
|
142
|
+
console.log(report);
|
|
143
|
+
logApiReportInstructions.logApiReportInstructions();
|
|
144
|
+
}
|
|
145
|
+
throw new Error(`CLI report changed for ${packageDir}`);
|
|
138
146
|
}
|
|
139
|
-
throw new Error(`CLI report changed for ${packageDir}, `);
|
|
140
147
|
}
|
|
141
148
|
}
|
|
142
|
-
}
|
|
143
|
-
|
|
149
|
+
})
|
|
150
|
+
);
|
|
144
151
|
}
|
|
145
152
|
|
|
146
153
|
exports.runCliExtraction = runCliExtraction;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var errors = require('@backstage/errors');
|
|
4
|
-
var errors
|
|
3
|
+
var errors$1 = require('@backstage/errors');
|
|
4
|
+
var errors = require('../lib/errors.cjs.js');
|
|
5
5
|
|
|
6
6
|
function registerPackageCommand(program) {
|
|
7
7
|
const command = program.command("package [command]").description("Various tools for working with specific packages.");
|
|
@@ -149,8 +149,7 @@ function lazy(moduleLoader, exportName) {
|
|
|
149
149
|
await actionFunc(...args);
|
|
150
150
|
process.exit(0);
|
|
151
151
|
} catch (error) {
|
|
152
|
-
errors.
|
|
153
|
-
errors$1.exitWithError(error);
|
|
152
|
+
errors.exitWithError(errors$1.toError(error));
|
|
154
153
|
}
|
|
155
154
|
};
|
|
156
155
|
}
|
|
@@ -97,7 +97,8 @@ async function generateDocJson(pkg) {
|
|
|
97
97
|
async function packageDocs(paths$1 = [], opts) {
|
|
98
98
|
console.warn("!!! This is an experimental command !!!");
|
|
99
99
|
const existingDocsJsonPaths = glob.glob.sync(
|
|
100
|
-
cliCommon.targetPaths.resolveRoot("dist-types/**/docs.json")
|
|
100
|
+
cliCommon.targetPaths.resolveRoot("dist-types/**/docs.json"),
|
|
101
|
+
{ windowsPathsNoEscape: true }
|
|
101
102
|
);
|
|
102
103
|
if (existingDocsJsonPaths.length > 0) {
|
|
103
104
|
console.warn(
|
|
@@ -8,40 +8,51 @@ var path = require('node:path');
|
|
|
8
8
|
|
|
9
9
|
const ansiPattern = new RegExp(`${String.fromCharCode(27)}\\[[0-9;]*m`, "g");
|
|
10
10
|
function createBinRunner(cwd, path$1) {
|
|
11
|
-
return
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const
|
|
11
|
+
return (...command) => {
|
|
12
|
+
return new Promise((resolve, reject) => {
|
|
13
|
+
const args = path$1 ? [path$1, ...command] : command;
|
|
14
|
+
const outPath = path.join(os.tmpdir(), `backstage-cli-out-${crypto.randomUUID()}.txt`);
|
|
15
|
+
const outFd = fs.openSync(outPath, "w");
|
|
16
|
+
const child = node_child_process.spawn("node", args, {
|
|
17
17
|
cwd,
|
|
18
18
|
env: { ...process.env, NO_COLOR: "1" },
|
|
19
19
|
stdio: ["ignore", outFd, "pipe"]
|
|
20
20
|
});
|
|
21
21
|
fs.closeSync(outFd);
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
22
|
+
const stderrChunks = [];
|
|
23
|
+
child.stderr?.on("data", (chunk) => stderrChunks.push(chunk));
|
|
24
|
+
child.on("error", (err) => {
|
|
25
|
+
try {
|
|
26
|
+
fs.unlinkSync(outPath);
|
|
27
|
+
} catch {
|
|
28
|
+
}
|
|
29
|
+
reject(new Error(`Process error: ${err.message}`));
|
|
30
|
+
});
|
|
31
|
+
child.on("close", (code, signal) => {
|
|
32
|
+
try {
|
|
33
|
+
const stdout = fs.readFileSync(outPath, "utf8").replace(ansiPattern, "");
|
|
34
|
+
const stderr = Buffer.concat(stderrChunks).toString();
|
|
35
|
+
if (signal) {
|
|
36
|
+
reject(
|
|
37
|
+
new Error(`Process was killed with signal ${signal}
|
|
38
|
+
${stderr}`)
|
|
39
|
+
);
|
|
40
|
+
} else if (code !== 0) {
|
|
41
|
+
reject(new Error(`Process exited with code ${code}
|
|
42
|
+
${stderr}`));
|
|
43
|
+
} else if (stderr.trim()) {
|
|
44
|
+
reject(new Error(`Command printed error output: ${stderr}`));
|
|
45
|
+
} else {
|
|
46
|
+
resolve(stdout);
|
|
47
|
+
}
|
|
48
|
+
} finally {
|
|
49
|
+
try {
|
|
50
|
+
fs.unlinkSync(outPath);
|
|
51
|
+
} catch {
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
});
|
|
45
56
|
};
|
|
46
57
|
}
|
|
47
58
|
|
package/dist/package.json.cjs.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/repo-tools",
|
|
3
|
-
"version": "0.17.1-next.
|
|
3
|
+
"version": "0.17.1-next.2",
|
|
4
4
|
"description": "CLI for Backstage repo tooling ",
|
|
5
5
|
"backstage": {
|
|
6
6
|
"role": "cli"
|
|
@@ -43,12 +43,12 @@
|
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@apidevtools/swagger-parser": "^10.1.0",
|
|
45
45
|
"@apisyouwonthate/style-guide": "^1.4.0",
|
|
46
|
-
"@backstage/backend-plugin-api": "1.
|
|
47
|
-
"@backstage/catalog-model": "1.7.
|
|
48
|
-
"@backstage/cli-common": "0.2.1-next.
|
|
49
|
-
"@backstage/cli-node": "0.3.1-next.
|
|
50
|
-
"@backstage/config-loader": "1.10.10-next.
|
|
51
|
-
"@backstage/errors": "1.
|
|
46
|
+
"@backstage/backend-plugin-api": "1.9.0-next.2",
|
|
47
|
+
"@backstage/catalog-model": "1.7.8-next.0",
|
|
48
|
+
"@backstage/cli-common": "0.2.1-next.1",
|
|
49
|
+
"@backstage/cli-node": "0.3.1-next.1",
|
|
50
|
+
"@backstage/config-loader": "1.10.10-next.1",
|
|
51
|
+
"@backstage/errors": "1.3.0-next.0",
|
|
52
52
|
"@electric-sql/pglite": "^0.3.0",
|
|
53
53
|
"@manypkg/get-packages": "^1.1.3",
|
|
54
54
|
"@microsoft/api-documenter": "^7.28.1",
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"command-exists": "^1.2.9",
|
|
70
70
|
"commander": "^14.0.3",
|
|
71
71
|
"fs-extra": "^11.2.0",
|
|
72
|
-
"glob": "^
|
|
72
|
+
"glob": "^13.0.0",
|
|
73
73
|
"globby": "^11.0.0",
|
|
74
74
|
"is-glob": "^4.0.3",
|
|
75
75
|
"js-yaml": "^4.1.0",
|
|
@@ -87,8 +87,8 @@
|
|
|
87
87
|
"zod": "^3.25.76 || ^4.0.0"
|
|
88
88
|
},
|
|
89
89
|
"devDependencies": {
|
|
90
|
-
"@backstage/backend-test-utils": "1.11.2-next.
|
|
91
|
-
"@backstage/cli": "0.36.1-next.
|
|
90
|
+
"@backstage/backend-test-utils": "1.11.2-next.2",
|
|
91
|
+
"@backstage/cli": "0.36.1-next.2",
|
|
92
92
|
"@backstage/types": "1.2.2",
|
|
93
93
|
"@types/is-glob": "^4.0.2",
|
|
94
94
|
"@types/node": "^22.13.14",
|