@backstage/repo-tools 0.9.7 → 0.10.0-next.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/CHANGELOG.md +34 -0
- package/dist/cjs/{api-reports-_IpmreNR.cjs.js → api-reports-BqwD6i_J.cjs.js} +12 -6
- package/dist/cjs/peer-deps-wmxV4fVq.cjs.js +173 -0
- package/dist/cjs/{type-deps-DgJcEpV_.cjs.js → type-deps-CYUUkOZo.cjs.js} +4 -1
- package/dist/index.cjs.js +6 -3
- package/package.json +15 -15
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,39 @@
|
|
|
1
1
|
# @backstage/repo-tools
|
|
2
2
|
|
|
3
|
+
## 0.10.0-next.1
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 8eb3033: Adds a new command `backstage-repo-tools peer-deps` for validating your usage of peer dependencies in your plugins. It currently supports react related peer dependencies. It also has a `--fix` mode for quickly fixing any issues that it finds.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 1f6706f: Properly log instructions when APIs do not match
|
|
12
|
+
- Updated dependencies
|
|
13
|
+
- @backstage/backend-plugin-api@1.0.1-next.0
|
|
14
|
+
- @backstage/catalog-model@1.7.0
|
|
15
|
+
- @backstage/cli-common@0.1.14
|
|
16
|
+
- @backstage/cli-node@0.2.8
|
|
17
|
+
- @backstage/config-loader@1.9.1
|
|
18
|
+
- @backstage/errors@1.2.4
|
|
19
|
+
|
|
20
|
+
## 0.10.0-next.0
|
|
21
|
+
|
|
22
|
+
### Minor Changes
|
|
23
|
+
|
|
24
|
+
- 30c2be9: Update @microsoft/api-extractor and use their api report resolution.
|
|
25
|
+
Change api report format from `api-report.md` to `report.api.md`
|
|
26
|
+
|
|
27
|
+
### Patch Changes
|
|
28
|
+
|
|
29
|
+
- Updated dependencies
|
|
30
|
+
- @backstage/backend-plugin-api@1.0.1-next.0
|
|
31
|
+
- @backstage/catalog-model@1.7.0
|
|
32
|
+
- @backstage/cli-common@0.1.14
|
|
33
|
+
- @backstage/cli-node@0.2.8
|
|
34
|
+
- @backstage/config-loader@1.9.1
|
|
35
|
+
- @backstage/errors@1.2.4
|
|
36
|
+
|
|
3
37
|
## 0.9.7
|
|
4
38
|
|
|
5
39
|
### Patch Changes
|
|
@@ -245,14 +245,17 @@ async function runApiExtraction({
|
|
|
245
245
|
);
|
|
246
246
|
const remainingReportFiles = new Set(
|
|
247
247
|
fs__default.default.readdirSync(projectFolder).filter(
|
|
248
|
-
(filename) =>
|
|
248
|
+
(filename) => (
|
|
249
|
+
// https://regex101.com/r/QDZIV0/2
|
|
250
|
+
filename !== "knip-report.md" && // this has to temporarily match all old api report formats
|
|
251
|
+
filename.match(/^.*?(api-)?report(-[^.-]+)?(.*?)\.md$/)
|
|
252
|
+
)
|
|
249
253
|
)
|
|
250
254
|
);
|
|
251
255
|
for (const packageEntryPoint of packageEntryPoints) {
|
|
252
256
|
const suffix = packageEntryPoint.name === "index" ? "" : `-${packageEntryPoint.name}`;
|
|
253
|
-
const reportFileName = `
|
|
257
|
+
const reportFileName = `report${suffix}`;
|
|
254
258
|
const reportPath = path.resolve(projectFolder, reportFileName);
|
|
255
|
-
remainingReportFiles.delete(reportFileName);
|
|
256
259
|
const warningCountBefore = await countApiReportWarnings(reportPath);
|
|
257
260
|
const extractorConfig = apiExtractor.ExtractorConfig.prepare({
|
|
258
261
|
configObject: {
|
|
@@ -319,6 +322,9 @@ async function runApiExtraction({
|
|
|
319
322
|
tsdocConfigFile: await getTsDocConfig(),
|
|
320
323
|
ignoreMissingEntryPoint: true
|
|
321
324
|
});
|
|
325
|
+
for (const reportConfig of extractorConfig.reportConfigs) {
|
|
326
|
+
remainingReportFiles.delete(reportConfig.fileName);
|
|
327
|
+
}
|
|
322
328
|
extractorConfig.packageFolder = packageFolder;
|
|
323
329
|
if (!compilerState) {
|
|
324
330
|
compilerState = apiExtractor.CompilerState.create(extractorConfig, {
|
|
@@ -338,11 +344,11 @@ async function runApiExtraction({
|
|
|
338
344
|
shouldLogInstructions = true;
|
|
339
345
|
}
|
|
340
346
|
if (message.text.includes(
|
|
341
|
-
"You have changed the
|
|
347
|
+
"You have changed the API signature for this project."
|
|
342
348
|
)) {
|
|
343
349
|
shouldLogInstructions = true;
|
|
344
350
|
const match = message.text.match(
|
|
345
|
-
/Please copy the file "(.*)" to "
|
|
351
|
+
/Please copy the file "(.*)" to "report\.api\.md"/
|
|
346
352
|
);
|
|
347
353
|
if (match) {
|
|
348
354
|
conflictingFile = match[1];
|
|
@@ -1122,4 +1128,4 @@ function parseArrayOption(value) {
|
|
|
1122
1128
|
}
|
|
1123
1129
|
|
|
1124
1130
|
exports.buildApiReports = buildApiReports;
|
|
1125
|
-
//# sourceMappingURL=api-reports-
|
|
1131
|
+
//# sourceMappingURL=api-reports-BqwD6i_J.cjs.js.map
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var path = require('path');
|
|
4
|
+
var getPackages = require('@manypkg/get-packages');
|
|
5
|
+
var fs = require('fs');
|
|
6
|
+
|
|
7
|
+
const desiredLocalVersionsOfDependencies = {
|
|
8
|
+
"@types/react": "^18.0.0",
|
|
9
|
+
react: "^18.0.2",
|
|
10
|
+
"react-dom": "^18.0.2",
|
|
11
|
+
"react-router-dom": "^6.3.0"
|
|
12
|
+
};
|
|
13
|
+
const peerDependencies = {
|
|
14
|
+
"@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0",
|
|
15
|
+
react: "^16.13.1 || ^17.0.0 || ^18.0.0",
|
|
16
|
+
"react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0",
|
|
17
|
+
"react-router-dom": "6.0.0-beta.0 || ^6.3.0"
|
|
18
|
+
};
|
|
19
|
+
const groupsOfPeerDependencies = [["@types/react", "react", "react-dom"]];
|
|
20
|
+
const optionalPeerDependencies = /* @__PURE__ */ new Set(["@types/react"]);
|
|
21
|
+
const isOptional = (dep) => {
|
|
22
|
+
return optionalPeerDependencies.has(dep);
|
|
23
|
+
};
|
|
24
|
+
const isMarkedAsOptional = (dep, packageJson) => {
|
|
25
|
+
return packageJson.peerDependenciesMeta?.[dep]?.optional;
|
|
26
|
+
};
|
|
27
|
+
const isDevDependency = (dep, packageJson) => {
|
|
28
|
+
return !!packageJson.devDependencies?.[dep];
|
|
29
|
+
};
|
|
30
|
+
const isProdDependency = (dep, packageJson) => {
|
|
31
|
+
return !!packageJson.dependencies?.[dep];
|
|
32
|
+
};
|
|
33
|
+
const isPeerDependency = (dep, packageJson) => {
|
|
34
|
+
return !!packageJson.peerDependencies?.[dep];
|
|
35
|
+
};
|
|
36
|
+
const isStandaloneApplication = (packageJson) => {
|
|
37
|
+
return ["cli", "frontend", "backend"].includes(
|
|
38
|
+
packageJson.backstage?.role || ""
|
|
39
|
+
);
|
|
40
|
+
};
|
|
41
|
+
const matchesDependency = (dep, packageJson) => {
|
|
42
|
+
return packageJson.devDependencies && packageJson.devDependencies[dep] === desiredLocalVersionsOfDependencies[dep];
|
|
43
|
+
};
|
|
44
|
+
const matchesPeerDependency = (dep, packageJson) => {
|
|
45
|
+
return packageJson.peerDependencies && packageJson.peerDependencies[dep] === peerDependencies[dep];
|
|
46
|
+
};
|
|
47
|
+
var peerDeps = async ({ fix }) => {
|
|
48
|
+
let failed = false;
|
|
49
|
+
const attemptToApplyFix = (fn) => {
|
|
50
|
+
if (fix) {
|
|
51
|
+
fn();
|
|
52
|
+
} else {
|
|
53
|
+
failed = true;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
const { packages } = await getPackages.getPackages(path.resolve("."));
|
|
57
|
+
const packagesWithRelevantDependencies = [];
|
|
58
|
+
for (const pkg of packages) {
|
|
59
|
+
if (isStandaloneApplication(pkg.packageJson)) {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
const dependencies = {
|
|
63
|
+
...pkg.packageJson.dependencies,
|
|
64
|
+
...pkg.packageJson.devDependencies,
|
|
65
|
+
...pkg.packageJson.peerDependencies
|
|
66
|
+
};
|
|
67
|
+
for (const dep in peerDependencies) {
|
|
68
|
+
if (dependencies?.[dep]) {
|
|
69
|
+
packagesWithRelevantDependencies.push(pkg);
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
for (const pkg of packagesWithRelevantDependencies) {
|
|
75
|
+
const packageJson = pkg.packageJson;
|
|
76
|
+
for (const dep of Object.keys(peerDependencies)) {
|
|
77
|
+
if (isPeerDependency(dep, packageJson)) {
|
|
78
|
+
if (isOptional(dep) && !isMarkedAsOptional(dep, packageJson)) {
|
|
79
|
+
console.error(
|
|
80
|
+
`Optional peer dependency ${dep} in ${pkg.packageJson.name} is not marked as optional`
|
|
81
|
+
);
|
|
82
|
+
attemptToApplyFix(() => {
|
|
83
|
+
packageJson.peerDependenciesMeta = packageJson.peerDependenciesMeta || {};
|
|
84
|
+
packageJson.peerDependenciesMeta[dep] = { optional: true };
|
|
85
|
+
});
|
|
86
|
+
} else if (!isOptional(dep) && isMarkedAsOptional(dep, packageJson)) {
|
|
87
|
+
console.error(
|
|
88
|
+
`Peer dependency ${dep} in ${pkg.packageJson.name} is marked as optional but should not be`
|
|
89
|
+
);
|
|
90
|
+
attemptToApplyFix(() => {
|
|
91
|
+
packageJson.peerDependenciesMeta = packageJson.peerDependenciesMeta || {};
|
|
92
|
+
delete packageJson.peerDependenciesMeta[dep];
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
if (!isDevDependency(dep, packageJson)) {
|
|
96
|
+
console.error(
|
|
97
|
+
`Peer dependency ${dep} in ${pkg.packageJson.name} is not listed as a devDependency`
|
|
98
|
+
);
|
|
99
|
+
attemptToApplyFix(() => {
|
|
100
|
+
delete packageJson.dependencies?.[dep];
|
|
101
|
+
packageJson.devDependencies = packageJson.devDependencies || {};
|
|
102
|
+
packageJson.devDependencies[dep] = desiredLocalVersionsOfDependencies[dep];
|
|
103
|
+
});
|
|
104
|
+
} else if (isProdDependency(dep, packageJson)) {
|
|
105
|
+
console.error(
|
|
106
|
+
`Peer dependency ${dep} in ${pkg.packageJson.name} is listed as a dependency`
|
|
107
|
+
);
|
|
108
|
+
attemptToApplyFix(() => {
|
|
109
|
+
delete packageJson.dependencies?.[dep];
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
const groups = groupsOfPeerDependencies.filter(
|
|
113
|
+
(group) => group.includes(dep)
|
|
114
|
+
);
|
|
115
|
+
if (groups.length) {
|
|
116
|
+
for (const group of groups) {
|
|
117
|
+
for (const groupDep of group) {
|
|
118
|
+
if (!isPeerDependency(groupDep, packageJson)) {
|
|
119
|
+
console.error(
|
|
120
|
+
`Peer dependency ${groupDep} in ${pkg.packageJson.name} is missing`
|
|
121
|
+
);
|
|
122
|
+
attemptToApplyFix(() => {
|
|
123
|
+
packageJson.peerDependencies = packageJson.peerDependencies || {};
|
|
124
|
+
packageJson.peerDependencies[groupDep] = peerDependencies[groupDep];
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (!matchesDependency(dep, packageJson)) {
|
|
131
|
+
console.error(
|
|
132
|
+
`Incorrect dependency ${dep} in ${pkg.packageJson.name}`
|
|
133
|
+
);
|
|
134
|
+
attemptToApplyFix(() => {
|
|
135
|
+
packageJson.devDependencies = packageJson.devDependencies || {};
|
|
136
|
+
packageJson.devDependencies[dep] = desiredLocalVersionsOfDependencies[dep];
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
if (!matchesPeerDependency(dep, packageJson)) {
|
|
140
|
+
console.error(
|
|
141
|
+
`Incorrect peer dependency ${dep} in ${pkg.packageJson.name}`
|
|
142
|
+
);
|
|
143
|
+
attemptToApplyFix(() => {
|
|
144
|
+
packageJson.peerDependencies = packageJson.peerDependencies || {};
|
|
145
|
+
packageJson.peerDependencies[dep] = peerDependencies[dep];
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
} else {
|
|
149
|
+
console.error(
|
|
150
|
+
`Missing peer dependency ${dep} in ${pkg.packageJson.name}`
|
|
151
|
+
);
|
|
152
|
+
attemptToApplyFix(() => {
|
|
153
|
+
packageJson.peerDependencies = packageJson.peerDependencies || {};
|
|
154
|
+
packageJson.peerDependencies[dep] = peerDependencies[dep];
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
if (fix) {
|
|
159
|
+
fs.writeFileSync(
|
|
160
|
+
path.resolve(pkg.dir, "package.json"),
|
|
161
|
+
`${JSON.stringify(packageJson, null, 2)}
|
|
162
|
+
`
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (failed) {
|
|
167
|
+
console.error("Some packages have incorrect peer dependencies");
|
|
168
|
+
process.exit(1);
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
exports.default = peerDeps;
|
|
173
|
+
//# sourceMappingURL=peer-deps-wmxV4fVq.cjs.js.map
|
|
@@ -144,6 +144,9 @@ function findTypeDepErrors(typeDeps, pkg) {
|
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
146
|
for (const dep of deps) {
|
|
147
|
+
if (["@types/react"].includes(dep)) {
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
147
150
|
errors.push(
|
|
148
151
|
mkErr("WrongDepError", `Should be dev dep ${dep}`, {
|
|
149
152
|
dep,
|
|
@@ -166,4 +169,4 @@ function mkErr(name, msg, extra) {
|
|
|
166
169
|
}
|
|
167
170
|
|
|
168
171
|
exports.default = typeDeps;
|
|
169
|
-
//# sourceMappingURL=type-deps-
|
|
172
|
+
//# sourceMappingURL=type-deps-CYUUkOZo.cjs.js.map
|
package/dist/index.cjs.js
CHANGED
|
@@ -148,10 +148,13 @@ function registerCommands(program) {
|
|
|
148
148
|
"Turn on release tag validation for the public, beta, and alpha APIs"
|
|
149
149
|
).description("Generate an API report for selected packages").action(
|
|
150
150
|
lazy(
|
|
151
|
-
() => Promise.resolve().then(function () { return require('./cjs/api-reports-
|
|
151
|
+
() => Promise.resolve().then(function () { return require('./cjs/api-reports-BqwD6i_J.cjs.js'); }).then((m) => m.buildApiReports)
|
|
152
152
|
)
|
|
153
153
|
);
|
|
154
|
-
program.command("type-deps").description("Find inconsistencies in types of all packages and plugins").action(lazy(() => Promise.resolve().then(function () { return require('./cjs/type-deps-
|
|
154
|
+
program.command("type-deps").description("Find inconsistencies in types of all packages and plugins").action(lazy(() => Promise.resolve().then(function () { return require('./cjs/type-deps-CYUUkOZo.cjs.js'); }).then((m) => m.default)));
|
|
155
|
+
program.command("peer-deps").description(
|
|
156
|
+
"Ensure your packages are using the correct peer dependency format."
|
|
157
|
+
).option("--fix", "Fix the issues found").action(lazy(() => Promise.resolve().then(function () { return require('./cjs/peer-deps-wmxV4fVq.cjs.js'); }).then((m) => m.default)));
|
|
155
158
|
program.command("generate-catalog-info").option(
|
|
156
159
|
"--dry-run",
|
|
157
160
|
"Shows what would happen without actually writing any yaml."
|
|
@@ -187,7 +190,7 @@ function lazy(getActionFunc) {
|
|
|
187
190
|
};
|
|
188
191
|
}
|
|
189
192
|
|
|
190
|
-
var version = "0.
|
|
193
|
+
var version = "0.10.0-next.1";
|
|
191
194
|
|
|
192
195
|
const main = (argv) => {
|
|
193
196
|
commander.program.name("backstage-repo-tools").version(version);
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/repo-tools",
|
|
3
|
+
"version": "0.10.0-next.1",
|
|
3
4
|
"description": "CLI for Backstage repo tooling ",
|
|
4
|
-
"version": "0.9.7",
|
|
5
|
-
"publishConfig": {
|
|
6
|
-
"access": "public"
|
|
7
|
-
},
|
|
8
5
|
"backstage": {
|
|
9
6
|
"role": "cli"
|
|
10
7
|
},
|
|
8
|
+
"publishConfig": {
|
|
9
|
+
"access": "public"
|
|
10
|
+
},
|
|
11
11
|
"keywords": [
|
|
12
12
|
"backstage"
|
|
13
13
|
],
|
|
@@ -43,15 +43,15 @@
|
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@apidevtools/swagger-parser": "^10.1.0",
|
|
45
45
|
"@apisyouwonthate/style-guide": "^1.4.0",
|
|
46
|
-
"@backstage/backend-plugin-api": "
|
|
47
|
-
"@backstage/catalog-model": "
|
|
48
|
-
"@backstage/cli-common": "
|
|
49
|
-
"@backstage/cli-node": "
|
|
50
|
-
"@backstage/config-loader": "
|
|
51
|
-
"@backstage/errors": "
|
|
46
|
+
"@backstage/backend-plugin-api": "1.0.1-next.0",
|
|
47
|
+
"@backstage/catalog-model": "1.7.0",
|
|
48
|
+
"@backstage/cli-common": "0.1.14",
|
|
49
|
+
"@backstage/cli-node": "0.2.8",
|
|
50
|
+
"@backstage/config-loader": "1.9.1",
|
|
51
|
+
"@backstage/errors": "1.2.4",
|
|
52
52
|
"@manypkg/get-packages": "^1.1.3",
|
|
53
|
-
"@microsoft/api-documenter": "^7.
|
|
54
|
-
"@microsoft/api-extractor": "^7.
|
|
53
|
+
"@microsoft/api-documenter": "^7.25.7",
|
|
54
|
+
"@microsoft/api-extractor": "^7.47.2",
|
|
55
55
|
"@openapitools/openapi-generator-cli": "^2.7.0",
|
|
56
56
|
"@stoplight/spectral-core": "^1.18.0",
|
|
57
57
|
"@stoplight/spectral-formatters": "^1.1.0",
|
|
@@ -77,9 +77,9 @@
|
|
|
77
77
|
"yaml-diff-patch": "^2.0.0"
|
|
78
78
|
},
|
|
79
79
|
"devDependencies": {
|
|
80
|
-
"@backstage/backend-test-utils": "
|
|
81
|
-
"@backstage/cli": "
|
|
82
|
-
"@backstage/types": "
|
|
80
|
+
"@backstage/backend-test-utils": "1.0.1-next.1",
|
|
81
|
+
"@backstage/cli": "0.28.0-next.1",
|
|
82
|
+
"@backstage/types": "1.1.1",
|
|
83
83
|
"@types/is-glob": "^4.0.2",
|
|
84
84
|
"@types/node": "^18.17.8",
|
|
85
85
|
"@types/prettier": "^2.0.0"
|