@backstage/repo-tools 0.3.3 → 0.3.4-next.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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @backstage/repo-tools
|
|
2
2
|
|
|
3
|
+
## 0.3.4-next.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 0109d3f11159: The `generate-catalog-info` command now uses the first listed `CODEOWNER` as Component owner when initially
|
|
8
|
+
creating the `catalog-info.yaml` file. It continues to allow any one listed `CODEOWNER` when updating
|
|
9
|
+
entity metadata.
|
|
10
|
+
- ec13d3e86028: Fixed a bug with the `generate-catalog-info` command that could cause the `--dry-run` flag to indicate changes to files when no changes would actually be made if the command were run without the flag.
|
|
11
|
+
- db60a16e0a54: Added a `--ci` flag to the `generate-catalog-info` command. This flag behaves similarly to the same flag on `api-reports`: if `catalog-info.yaml` files would have been added or modified, then the process exits with status code `1`, and instructions are printed.
|
|
12
|
+
- Updated dependencies
|
|
13
|
+
- @backstage/catalog-model@1.4.1
|
|
14
|
+
- @backstage/cli-common@0.1.12
|
|
15
|
+
- @backstage/cli-node@0.1.3
|
|
16
|
+
- @backstage/errors@1.2.1
|
|
17
|
+
|
|
3
18
|
## 0.3.3
|
|
4
19
|
|
|
5
20
|
### Patch Changes
|
package/dist/cjs/{generate-catalog-info-84fe20dd.cjs.js → generate-catalog-info-52b0f2ff.cjs.js}
RENAMED
|
@@ -23,6 +23,8 @@ function isBackstagePackage(packageJson) {
|
|
|
23
23
|
var _a;
|
|
24
24
|
return packageJson && packageJson.hasOwnProperty("backstage") && ((_a = packageJson == null ? void 0 : packageJson.backstage) == null ? void 0 : _a.role) !== "undefined";
|
|
25
25
|
}
|
|
26
|
+
const isRejected = (input) => input.status === "rejected";
|
|
27
|
+
const isFulfilled = (input) => input.status === "fulfilled";
|
|
26
28
|
|
|
27
29
|
async function loadCodeowners() {
|
|
28
30
|
const maybeFiles = await Promise.allSettled(
|
|
@@ -49,7 +51,7 @@ function getPossibleCodeowners(codeowners, relPath) {
|
|
|
49
51
|
function getOwnerFromCodeowners(codeowners, absPath) {
|
|
50
52
|
const relPath = path.relative(".", absPath);
|
|
51
53
|
const possibleOwners = getPossibleCodeowners(codeowners, relPath);
|
|
52
|
-
const owner = possibleOwners
|
|
54
|
+
const owner = possibleOwners[0];
|
|
53
55
|
if (!owner) {
|
|
54
56
|
throw new Error(`${relPath} isn't owned by anyone in CODEOWNERS`);
|
|
55
57
|
}
|
|
@@ -57,15 +59,17 @@ function getOwnerFromCodeowners(codeowners, absPath) {
|
|
|
57
59
|
}
|
|
58
60
|
|
|
59
61
|
var generateCatalogInfo = async (opts) => {
|
|
60
|
-
const { dryRun = false } = opts;
|
|
62
|
+
const { dryRun = false, ci = false } = opts;
|
|
61
63
|
const packages = await cliNode.PackageGraph.listTargetPackages();
|
|
62
64
|
const codeowners = await loadCodeowners();
|
|
63
65
|
const limit = pLimit__default["default"](10);
|
|
66
|
+
const isDryRun = ci ? true : dryRun;
|
|
67
|
+
const checkForChanges = ci;
|
|
64
68
|
const results = await Promise.allSettled(
|
|
65
69
|
packages.map(
|
|
66
70
|
({ packageJson, dir }) => limit(async () => {
|
|
67
71
|
if (!isBackstagePackage(packageJson)) {
|
|
68
|
-
return;
|
|
72
|
+
return "";
|
|
69
73
|
}
|
|
70
74
|
const infoYamlPath = path.resolve(dir, "catalog-info.yaml");
|
|
71
75
|
let yamlString = "";
|
|
@@ -73,29 +77,27 @@ var generateCatalogInfo = async (opts) => {
|
|
|
73
77
|
yamlString = await readFile(infoYamlPath, { encoding: "utf-8" });
|
|
74
78
|
} catch (e) {
|
|
75
79
|
if (e.code === "ENOENT") {
|
|
76
|
-
await createCatalogInfoYaml({
|
|
80
|
+
return await createCatalogInfoYaml({
|
|
77
81
|
yamlPath: infoYamlPath,
|
|
78
82
|
packageJson,
|
|
79
83
|
codeowners,
|
|
80
|
-
dryRun
|
|
84
|
+
dryRun: isDryRun
|
|
81
85
|
});
|
|
82
|
-
return;
|
|
83
86
|
}
|
|
84
87
|
throw e;
|
|
85
88
|
}
|
|
86
|
-
await fixCatalogInfoYaml({
|
|
89
|
+
return await fixCatalogInfoYaml({
|
|
87
90
|
yamlPath: infoYamlPath,
|
|
88
91
|
packageJson,
|
|
89
92
|
codeowners,
|
|
90
93
|
yamlString,
|
|
91
|
-
dryRun
|
|
94
|
+
dryRun: isDryRun,
|
|
95
|
+
ci
|
|
92
96
|
});
|
|
93
97
|
})
|
|
94
98
|
)
|
|
95
99
|
);
|
|
96
|
-
const rejects = results.filter(
|
|
97
|
-
(r) => r.status === "rejected"
|
|
98
|
-
);
|
|
100
|
+
const rejects = results.filter(isRejected);
|
|
99
101
|
if (rejects.length > 0) {
|
|
100
102
|
console.error(
|
|
101
103
|
chalk__default["default"].red("Unable to create or fix catalog-info.yaml files\n")
|
|
@@ -104,16 +106,35 @@ var generateCatalogInfo = async (opts) => {
|
|
|
104
106
|
console.error();
|
|
105
107
|
process.exit(1);
|
|
106
108
|
}
|
|
109
|
+
if (checkForChanges) {
|
|
110
|
+
const instructions = results.filter(isFulfilled).map((r) => r.value).filter((r) => r !== "");
|
|
111
|
+
if (instructions.length > 0) {
|
|
112
|
+
console.error(
|
|
113
|
+
"\ncatalog-info.yaml file(s) out of sync with CODEOWNERS and/or package.json (see instructions above)\n"
|
|
114
|
+
);
|
|
115
|
+
process.exit(1);
|
|
116
|
+
} else {
|
|
117
|
+
console.error(
|
|
118
|
+
"catalog-info.yaml file(s) in sync with CODEOWNERS and package.json"
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
107
122
|
};
|
|
108
|
-
function createCatalogInfoYaml(options) {
|
|
123
|
+
async function createCatalogInfoYaml(options) {
|
|
109
124
|
const { codeowners, dryRun, packageJson, yamlPath } = options;
|
|
125
|
+
const instruction = `Create ${path.relative(".", yamlPath)}`;
|
|
110
126
|
const owner = getOwnerFromCodeowners(codeowners, yamlPath);
|
|
111
127
|
const entity = createOrMergeEntity(packageJson, owner);
|
|
112
|
-
|
|
128
|
+
if (dryRun) {
|
|
129
|
+
console.error(instruction);
|
|
130
|
+
} else {
|
|
131
|
+
await writeFile(yamlPath, YAML__default["default"].dump(entity));
|
|
132
|
+
}
|
|
133
|
+
return instruction;
|
|
113
134
|
}
|
|
114
|
-
function fixCatalogInfoYaml(options) {
|
|
135
|
+
async function fixCatalogInfoYaml(options) {
|
|
115
136
|
var _a, _b, _c;
|
|
116
|
-
const { codeowners, dryRun, packageJson, yamlPath, yamlString } = options;
|
|
137
|
+
const { ci, codeowners, dryRun, packageJson, yamlPath, yamlString } = options;
|
|
117
138
|
const possibleOwners = getPossibleCodeowners(
|
|
118
139
|
codeowners,
|
|
119
140
|
path.relative(".", yamlPath)
|
|
@@ -129,13 +150,42 @@ function fixCatalogInfoYaml(options) {
|
|
|
129
150
|
const badTitle = yamlJson.metadata.title !== packageJson.name;
|
|
130
151
|
const badName = yamlJson.metadata.name !== safeName;
|
|
131
152
|
const badType = ((_b = yamlJson.spec) == null ? void 0 : _b.type) !== `backstage-${packageJson.backstage.role}`;
|
|
132
|
-
|
|
133
|
-
if (badOwner || badTitle || badName || badType || badDesc) {
|
|
153
|
+
if (badOwner || badTitle || badName || badType) {
|
|
134
154
|
const owner = badOwner ? getOwnerFromCodeowners(codeowners, yamlPath) : (_c = yamlJson.spec) == null ? void 0 : _c.owner;
|
|
135
155
|
const newJson = createOrMergeEntity(packageJson, owner, yamlJson);
|
|
136
|
-
|
|
156
|
+
const instructions = [`Update ${path.relative(".", yamlPath)}`];
|
|
157
|
+
if (ci) {
|
|
158
|
+
if (badOwner) {
|
|
159
|
+
instructions.push(
|
|
160
|
+
` spec.owner cannot be "${yamlJson.spec.owner}" because it must be one of (${possibleOwners.join(
|
|
161
|
+
", "
|
|
162
|
+
)}) as listed in CODEOWNERS`
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
if (badTitle) {
|
|
166
|
+
instructions.push(
|
|
167
|
+
` metadata.title cannot be "${yamlJson.metadata.title}" because it must be exactly "${packageJson.name}", the package.json name`
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
if (badName) {
|
|
171
|
+
instructions.push(
|
|
172
|
+
` metadata.name cannot be "${yamlJson.metadata.name}" because it must be exactly "${safeName}", as derived from package.json name`
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
if (badType) {
|
|
176
|
+
instructions.push(
|
|
177
|
+
` spec.type cannot be "${yamlJson.spec.type}" because it must be exactly "backstage-${packageJson.backstage.role}", as derived from package.json backstage.role`
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
if (dryRun) {
|
|
182
|
+
console.error(instructions.join("\n"));
|
|
183
|
+
} else {
|
|
184
|
+
await writeFile(yamlPath, yamlDiffPatch.yamlOverwrite(yamlString, newJson));
|
|
185
|
+
}
|
|
186
|
+
return instructions.join("\n");
|
|
137
187
|
}
|
|
138
|
-
return
|
|
188
|
+
return "";
|
|
139
189
|
}
|
|
140
190
|
function createOrMergeEntity(packageJson, owner, existingEntity = {}) {
|
|
141
191
|
const safeEntityName = packageJson.name.replace(/[^a-z0-9_\-\.]+/g, "-").replace(/^[^a-z0-9]|[^a-z0-9]$/g, "");
|
|
@@ -160,4 +210,4 @@ function createOrMergeEntity(packageJson, owner, existingEntity = {}) {
|
|
|
160
210
|
}
|
|
161
211
|
|
|
162
212
|
exports["default"] = generateCatalogInfo;
|
|
163
|
-
//# sourceMappingURL=generate-catalog-info-
|
|
213
|
+
//# sourceMappingURL=generate-catalog-info-52b0f2ff.cjs.js.map
|
package/dist/index.cjs.js
CHANGED
|
@@ -89,9 +89,12 @@ function registerCommands(program) {
|
|
|
89
89
|
program.command("generate-catalog-info").option(
|
|
90
90
|
"--dry-run",
|
|
91
91
|
"Shows what would happen without actually writing any yaml."
|
|
92
|
+
).option(
|
|
93
|
+
"--ci",
|
|
94
|
+
"CI run checks that there are no changes to catalog-info.yaml files"
|
|
92
95
|
).description("Create or fix info yaml files for all backstage packages").action(
|
|
93
96
|
lazy(
|
|
94
|
-
() => Promise.resolve().then(function () { return require('./cjs/generate-catalog-info-
|
|
97
|
+
() => Promise.resolve().then(function () { return require('./cjs/generate-catalog-info-52b0f2ff.cjs.js'); }).then(
|
|
95
98
|
(m) => m.default
|
|
96
99
|
)
|
|
97
100
|
)
|
|
@@ -111,7 +114,7 @@ function lazy(getActionFunc) {
|
|
|
111
114
|
};
|
|
112
115
|
}
|
|
113
116
|
|
|
114
|
-
var version = "0.3.
|
|
117
|
+
var version = "0.3.4-next.0";
|
|
115
118
|
|
|
116
119
|
const main = (argv) => {
|
|
117
120
|
commander.program.name("backstage-repo-tools").version(version);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/repo-tools",
|
|
3
3
|
"description": "CLI for Backstage repo tooling ",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.4-next.0",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"yaml-diff-patch": "^2.0.0"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
|
-
"@backstage/cli": "^0.22.
|
|
63
|
+
"@backstage/cli": "^0.22.12-next.0",
|
|
64
64
|
"@backstage/types": "^1.1.0",
|
|
65
65
|
"@types/is-glob": "^4.0.2",
|
|
66
66
|
"@types/mock-fs": "^4.13.0",
|