@red-hat-developer-hub/extensions-cli 0.14.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 +255 -0
- package/bin/extensions-cli +29 -0
- package/dist/commands/export-csv/index.cjs.js +165 -0
- package/dist/commands/generate/index.cjs.js +212 -0
- package/dist/commands/index.cjs.js +39 -0
- package/dist/commands/init/index.cjs.js +143 -0
- package/dist/commands/verify/index.cjs.js +99 -0
- package/dist/index.cjs.js +32 -0
- package/dist/lib/errors.cjs.js +42 -0
- package/dist/lib/lazy.cjs.js +22 -0
- package/package.json +52 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
# @red-hat-developer-hub/extensions-cli
|
|
2
|
+
|
|
3
|
+
## 0.14.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 4fafdf3: Renamed plugins from marketplace to extensions
|
|
8
|
+
|
|
9
|
+
- Renamed all packages from `backstage-plugin-marketplace-*` to `backstage-plugin-extensions-*`
|
|
10
|
+
- Updated all internal references, exports, and API endpoints
|
|
11
|
+
- lazy load codeEditor to reduce the frontend plugin bundle size
|
|
12
|
+
- Made catalog entities directory path configurable via `extensions.directory` in app-config.yaml with fallback to `extensions` and `marketplace` directories
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- Updated dependencies [4fafdf3]
|
|
17
|
+
- @red-hat-developer-hub/backstage-plugin-extensions-common@0.14.0
|
|
18
|
+
|
|
19
|
+
## 0.13.2
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- @red-hat-developer-hub/backstage-plugin-marketplace-common@0.13.2
|
|
24
|
+
|
|
25
|
+
## 0.13.1
|
|
26
|
+
|
|
27
|
+
### Patch Changes
|
|
28
|
+
|
|
29
|
+
- @red-hat-developer-hub/backstage-plugin-marketplace-common@0.13.1
|
|
30
|
+
|
|
31
|
+
## 0.13.0
|
|
32
|
+
|
|
33
|
+
### Minor Changes
|
|
34
|
+
|
|
35
|
+
- bee615a: Backstage version bump to v1.45.2
|
|
36
|
+
|
|
37
|
+
### Patch Changes
|
|
38
|
+
|
|
39
|
+
- Updated dependencies [bee615a]
|
|
40
|
+
- @red-hat-developer-hub/backstage-plugin-marketplace-common@0.13.0
|
|
41
|
+
|
|
42
|
+
## 0.12.2
|
|
43
|
+
|
|
44
|
+
### Patch Changes
|
|
45
|
+
|
|
46
|
+
- @red-hat-developer-hub/backstage-plugin-marketplace-common@0.12.2
|
|
47
|
+
|
|
48
|
+
## 0.12.1
|
|
49
|
+
|
|
50
|
+
### Patch Changes
|
|
51
|
+
|
|
52
|
+
- @red-hat-developer-hub/backstage-plugin-marketplace-common@0.12.1
|
|
53
|
+
|
|
54
|
+
## 0.12.0
|
|
55
|
+
|
|
56
|
+
### Minor Changes
|
|
57
|
+
|
|
58
|
+
- f8e6f04: Backstage version bump to v1.44.1
|
|
59
|
+
|
|
60
|
+
### Patch Changes
|
|
61
|
+
|
|
62
|
+
- Updated dependencies [f8e6f04]
|
|
63
|
+
- @red-hat-developer-hub/backstage-plugin-marketplace-common@0.12.0
|
|
64
|
+
|
|
65
|
+
## 0.6.1
|
|
66
|
+
|
|
67
|
+
### Patch Changes
|
|
68
|
+
|
|
69
|
+
- Updated dependencies [4d79286]
|
|
70
|
+
- @red-hat-developer-hub/backstage-plugin-marketplace-common@0.10.1
|
|
71
|
+
|
|
72
|
+
## 0.6.0
|
|
73
|
+
|
|
74
|
+
### Minor Changes
|
|
75
|
+
|
|
76
|
+
- b33db25: Backstage version bump to v1.42.5
|
|
77
|
+
|
|
78
|
+
### Patch Changes
|
|
79
|
+
|
|
80
|
+
- Updated dependencies [b33db25]
|
|
81
|
+
- @red-hat-developer-hub/backstage-plugin-marketplace-common@0.10.0
|
|
82
|
+
|
|
83
|
+
## 0.5.1
|
|
84
|
+
|
|
85
|
+
### Patch Changes
|
|
86
|
+
|
|
87
|
+
- Updated dependencies [fdda9a1]
|
|
88
|
+
- Updated dependencies [cbe1174]
|
|
89
|
+
- @red-hat-developer-hub/backstage-plugin-marketplace-common@0.9.0
|
|
90
|
+
|
|
91
|
+
## 0.5.0
|
|
92
|
+
|
|
93
|
+
### Minor Changes
|
|
94
|
+
|
|
95
|
+
- 8887468: Backstage version bump to v1.41.1
|
|
96
|
+
|
|
97
|
+
### Patch Changes
|
|
98
|
+
|
|
99
|
+
- Updated dependencies [8887468]
|
|
100
|
+
- @red-hat-developer-hub/backstage-plugin-marketplace-common@0.8.0
|
|
101
|
+
|
|
102
|
+
## 0.4.10
|
|
103
|
+
|
|
104
|
+
### Patch Changes
|
|
105
|
+
|
|
106
|
+
- Updated dependencies [171b7fd]
|
|
107
|
+
- @red-hat-developer-hub/backstage-plugin-marketplace-common@0.7.2
|
|
108
|
+
|
|
109
|
+
## 0.4.9
|
|
110
|
+
|
|
111
|
+
### Patch Changes
|
|
112
|
+
|
|
113
|
+
- Updated dependencies [fb23720]
|
|
114
|
+
- @red-hat-developer-hub/backstage-plugin-marketplace-common@0.7.1
|
|
115
|
+
|
|
116
|
+
## 0.4.8
|
|
117
|
+
|
|
118
|
+
### Patch Changes
|
|
119
|
+
|
|
120
|
+
- Updated dependencies [f70ccb1]
|
|
121
|
+
- Updated dependencies [7aac60c]
|
|
122
|
+
- @red-hat-developer-hub/backstage-plugin-marketplace-common@0.7.0
|
|
123
|
+
|
|
124
|
+
## 0.4.7
|
|
125
|
+
|
|
126
|
+
### Patch Changes
|
|
127
|
+
|
|
128
|
+
- ca2e330: Bump to backstage version 1.39.1
|
|
129
|
+
- 58ae1fe: Added an alert for production environment
|
|
130
|
+
Integrated the fetch configuration and install API calls
|
|
131
|
+
Fixed an import error
|
|
132
|
+
- Updated dependencies [ca2e330]
|
|
133
|
+
- Updated dependencies [3973839]
|
|
134
|
+
- Updated dependencies [58ae1fe]
|
|
135
|
+
- @red-hat-developer-hub/backstage-plugin-marketplace-common@0.6.0
|
|
136
|
+
|
|
137
|
+
## 0.4.6
|
|
138
|
+
|
|
139
|
+
### Patch Changes
|
|
140
|
+
|
|
141
|
+
- Updated dependencies [7ae0ca0]
|
|
142
|
+
- @red-hat-developer-hub/backstage-plugin-marketplace-common@0.5.0
|
|
143
|
+
|
|
144
|
+
## 0.4.5
|
|
145
|
+
|
|
146
|
+
### Patch Changes
|
|
147
|
+
|
|
148
|
+
- Updated dependencies [4413eef]
|
|
149
|
+
- Updated dependencies [7d138e5]
|
|
150
|
+
- Updated dependencies [f56908a]
|
|
151
|
+
- @red-hat-developer-hub/backstage-plugin-marketplace-common@0.4.0
|
|
152
|
+
|
|
153
|
+
## 0.4.4
|
|
154
|
+
|
|
155
|
+
### Patch Changes
|
|
156
|
+
|
|
157
|
+
- dd94b9d: use namespace parameter also for packages location
|
|
158
|
+
|
|
159
|
+
## 0.4.3
|
|
160
|
+
|
|
161
|
+
### Patch Changes
|
|
162
|
+
|
|
163
|
+
- e5e4655: use new Backstage `lazy` loading function
|
|
164
|
+
|
|
165
|
+
## 0.4.2
|
|
166
|
+
|
|
167
|
+
### Patch Changes
|
|
168
|
+
|
|
169
|
+
- 7517e3b: (export-csv) Always escape newlines in each CSV cell and add more columns
|
|
170
|
+
|
|
171
|
+
## 0.4.1
|
|
172
|
+
|
|
173
|
+
### Patch Changes
|
|
174
|
+
|
|
175
|
+
- 5a99fdd: use CJS imports instead of ESM to fix double-encapsulation import issue
|
|
176
|
+
|
|
177
|
+
## 0.4.0
|
|
178
|
+
|
|
179
|
+
### Minor Changes
|
|
180
|
+
|
|
181
|
+
- 6501387: Backstage version bump to v1.36.1
|
|
182
|
+
|
|
183
|
+
### Patch Changes
|
|
184
|
+
|
|
185
|
+
- Updated dependencies [6501387]
|
|
186
|
+
- @red-hat-developer-hub/backstage-plugin-marketplace-common@0.3.0
|
|
187
|
+
|
|
188
|
+
## 0.3.0
|
|
189
|
+
|
|
190
|
+
### Minor Changes
|
|
191
|
+
|
|
192
|
+
- efc1592: add new marketplace-cli init command
|
|
193
|
+
- a4b60fd: Added a new command: `export-csv`, which generates a CSV file given a folder of plugin YAML files
|
|
194
|
+
|
|
195
|
+
## 0.2.0
|
|
196
|
+
|
|
197
|
+
### Minor Changes
|
|
198
|
+
|
|
199
|
+
- d3bcc76: rename apiVersion and annotations to extensions.backstage.io
|
|
200
|
+
|
|
201
|
+
### Patch Changes
|
|
202
|
+
|
|
203
|
+
- Updated dependencies [d3bcc76]
|
|
204
|
+
- @red-hat-developer-hub/backstage-plugin-marketplace-common@0.2.0
|
|
205
|
+
|
|
206
|
+
## 0.1.2
|
|
207
|
+
|
|
208
|
+
### Patch Changes
|
|
209
|
+
|
|
210
|
+
- a7e38a9: remove core-plugin-api dependency from common
|
|
211
|
+
- Updated dependencies [a7e38a9]
|
|
212
|
+
- @red-hat-developer-hub/backstage-plugin-marketplace-common@0.1.2
|
|
213
|
+
|
|
214
|
+
## 0.1.1
|
|
215
|
+
|
|
216
|
+
### Patch Changes
|
|
217
|
+
|
|
218
|
+
- fa70a22: remove unused knex and zod dependency from common package
|
|
219
|
+
- Updated dependencies [fa70a22]
|
|
220
|
+
- @red-hat-developer-hub/backstage-plugin-marketplace-common@0.1.1
|
|
221
|
+
|
|
222
|
+
## 0.1.0
|
|
223
|
+
|
|
224
|
+
### Minor Changes
|
|
225
|
+
|
|
226
|
+
- d39d4e3: Initial tech-preview of the marketplace
|
|
227
|
+
|
|
228
|
+
### Patch Changes
|
|
229
|
+
|
|
230
|
+
- f16dd69: Refactore and update API, UI, and catalog types
|
|
231
|
+
- Updated dependencies [d39d4e3]
|
|
232
|
+
- Updated dependencies [f16dd69]
|
|
233
|
+
- @red-hat-developer-hub/backstage-plugin-marketplace-common@0.1.0
|
|
234
|
+
|
|
235
|
+
## 0.0.3
|
|
236
|
+
|
|
237
|
+
### Patch Changes
|
|
238
|
+
|
|
239
|
+
- Updated dependencies [f310add]
|
|
240
|
+
- @red-hat-developer-hub/backstage-plugin-marketplace-common@0.0.9
|
|
241
|
+
|
|
242
|
+
## 0.0.2
|
|
243
|
+
|
|
244
|
+
### Patch Changes
|
|
245
|
+
|
|
246
|
+
- Updated dependencies [4e0ec06]
|
|
247
|
+
- @red-hat-developer-hub/backstage-plugin-marketplace-common@0.0.8
|
|
248
|
+
|
|
249
|
+
## 0.0.1
|
|
250
|
+
|
|
251
|
+
### Patch Changes
|
|
252
|
+
|
|
253
|
+
- 3c12103: Added new `marketplace-cli` and implement `generate` command.
|
|
254
|
+
|
|
255
|
+
This command generates Plugin entities based on the information from the [dynamic-plugins.default.yaml](https://github.com/redhat-developer/rhdh/blob/main/dynamic-plugins.default.yaml) and wrapper's `package.json`. It assumes that all `packages` in the config files are wrappers.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/*
|
|
3
|
+
* Copyright The Backstage Authors
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
const path = require('path');
|
|
19
|
+
|
|
20
|
+
// Figure out whether we're running inside the backstage repo or as an installed dependency
|
|
21
|
+
/* eslint-disable-next-line no-restricted-syntax */
|
|
22
|
+
const isLocal = require('fs').existsSync(path.resolve(__dirname, '../src'));
|
|
23
|
+
|
|
24
|
+
if (!isLocal) {
|
|
25
|
+
require('..');
|
|
26
|
+
} else {
|
|
27
|
+
require('@backstage/cli/config/nodeTransform.cjs');
|
|
28
|
+
require('../src');
|
|
29
|
+
}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var chalk = require('chalk');
|
|
6
|
+
var backstagePluginExtensionsCommon = require('@red-hat-developer-hub/backstage-plugin-extensions-common');
|
|
7
|
+
var fs = require('fs-extra');
|
|
8
|
+
var path = require('path');
|
|
9
|
+
var yaml = require('yaml');
|
|
10
|
+
var glob = require('glob');
|
|
11
|
+
|
|
12
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
13
|
+
|
|
14
|
+
var chalk__default = /*#__PURE__*/_interopDefaultCompat(chalk);
|
|
15
|
+
var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
|
|
16
|
+
var path__default = /*#__PURE__*/_interopDefaultCompat(path);
|
|
17
|
+
var yaml__default = /*#__PURE__*/_interopDefaultCompat(yaml);
|
|
18
|
+
var glob__default = /*#__PURE__*/_interopDefaultCompat(glob);
|
|
19
|
+
|
|
20
|
+
class CSVGenerator {
|
|
21
|
+
/** The columns to be included in the CSV. */
|
|
22
|
+
columns;
|
|
23
|
+
/** The rows to be included in the CSV */
|
|
24
|
+
rows;
|
|
25
|
+
constructor(columns, rows = []) {
|
|
26
|
+
this.columns = columns;
|
|
27
|
+
this.rows = rows;
|
|
28
|
+
}
|
|
29
|
+
/** Escape problematic characters in a CSV cell */
|
|
30
|
+
static escapeCSVCell = (cell) => {
|
|
31
|
+
const removedNewLines = cell.replace(/\n/g, "\\n");
|
|
32
|
+
const regex = /[\s,"]/;
|
|
33
|
+
if (regex.exec(removedNewLines.replace(/ /g, ""))) {
|
|
34
|
+
return `"${removedNewLines.replace(/"/g, '""')}"`;
|
|
35
|
+
}
|
|
36
|
+
return removedNewLines;
|
|
37
|
+
};
|
|
38
|
+
/** Add a row to the CSV */
|
|
39
|
+
addRow(row) {
|
|
40
|
+
this.rows.push(row);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* @param includeHeader Whether to include the header row in the CSV
|
|
44
|
+
* @returns A CSV generated from the rows and columns provided
|
|
45
|
+
*/
|
|
46
|
+
generate(includeHeader = true) {
|
|
47
|
+
const header = Object.keys(this.columns).map((key) => CSVGenerator.escapeCSVCell(key)).join(",");
|
|
48
|
+
const rows = this.rows.map(
|
|
49
|
+
(row) => Object.values(this.columns).map((column) => CSVGenerator.escapeCSVCell(String(column(row) || ""))).join(",")
|
|
50
|
+
).join("\n");
|
|
51
|
+
return includeHeader ? `${header}
|
|
52
|
+
${rows}` : rows;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
const isEntity = (entity) => {
|
|
56
|
+
return !!entity && typeof entity === "object" && "apiVersion" in entity && "kind" in entity;
|
|
57
|
+
};
|
|
58
|
+
const parseYamls = async (yamls, recurse = false) => {
|
|
59
|
+
return await Promise.all(
|
|
60
|
+
(yamls || []).flatMap((basePath) => {
|
|
61
|
+
return glob__default.default.sync(recurse ? "**/*.yaml" : "*.yaml", { cwd: basePath }).map(async (file) => {
|
|
62
|
+
const fileContent = await fs__default.default.readFile(
|
|
63
|
+
path__default.default.join(basePath, file),
|
|
64
|
+
"utf-8"
|
|
65
|
+
);
|
|
66
|
+
const plugins = yaml__default.default.parseAllDocuments(fileContent).map((doc) => doc.toJS()).filter(isEntity);
|
|
67
|
+
return plugins;
|
|
68
|
+
});
|
|
69
|
+
})
|
|
70
|
+
).then((plugins) => plugins.flat());
|
|
71
|
+
};
|
|
72
|
+
const getPackagesOfType = (packages, allPackages, types) => {
|
|
73
|
+
return packages.map((name) => {
|
|
74
|
+
const pkg = allPackages[name];
|
|
75
|
+
if (!pkg) {
|
|
76
|
+
console.error(
|
|
77
|
+
chalk__default.default.red(`Package ${name} not found in the list of packages`)
|
|
78
|
+
);
|
|
79
|
+
return "";
|
|
80
|
+
}
|
|
81
|
+
const version = pkg.spec?.version ? `(${pkg.spec?.version})` : "(no version)";
|
|
82
|
+
if (types.includes(pkg?.spec?.backstage?.role || "")) {
|
|
83
|
+
return `${pkg.spec?.packageName} ${version}`;
|
|
84
|
+
}
|
|
85
|
+
return "";
|
|
86
|
+
}).filter(Boolean).join(", ");
|
|
87
|
+
};
|
|
88
|
+
var index = async ({
|
|
89
|
+
outputFile,
|
|
90
|
+
pluginsYamlPath,
|
|
91
|
+
recursive,
|
|
92
|
+
type
|
|
93
|
+
}) => {
|
|
94
|
+
if (!pluginsYamlPath) {
|
|
95
|
+
console.error(
|
|
96
|
+
"No plugins path provided! Provide one using --plugins-yaml-path"
|
|
97
|
+
);
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
const yamls = parseYamls(pluginsYamlPath.split(","), recursive);
|
|
101
|
+
const packages = {};
|
|
102
|
+
const packageCSV = new CSVGenerator({
|
|
103
|
+
name: (yaml) => yaml?.metadata?.name,
|
|
104
|
+
title: (yaml) => yaml?.metadata?.title,
|
|
105
|
+
version: (yaml) => yaml?.spec?.version,
|
|
106
|
+
author: (yaml) => yaml?.spec?.developer || yaml?.spec?.author || yaml?.spec?.owner || (yaml?.spec?.authors || []).join(","),
|
|
107
|
+
lifecycle: (yaml) => yaml?.spec?.lifecycle,
|
|
108
|
+
packages: (yaml) => (yaml?.spec?.partOf || []).join(", "),
|
|
109
|
+
role: (yaml) => yaml?.spec?.role || yaml?.spec?.backstage?.role
|
|
110
|
+
});
|
|
111
|
+
const pluginCSV = new CSVGenerator({
|
|
112
|
+
name: (p) => p?.metadata?.name,
|
|
113
|
+
title: (p) => p?.metadata?.title,
|
|
114
|
+
author: (p) => p?.spec?.developer || p?.spec?.author || p?.spec?.owner || (p?.spec?.authors || [])?.map((a) => a.name).join(", "),
|
|
115
|
+
categories: (p) => (p?.spec?.categories || []).join(", "),
|
|
116
|
+
lifecycle: (p) => p?.spec?.lifecycle,
|
|
117
|
+
metadataDescription: (p) => p?.metadata?.description,
|
|
118
|
+
specDescription: (p) => p?.spec?.description,
|
|
119
|
+
support: (p) => p?.spec?.support,
|
|
120
|
+
publisher: (p) => p?.spec?.publisher,
|
|
121
|
+
highlights: (p) => (p?.spec?.highlights || []).join(", "),
|
|
122
|
+
"certified-by": (p) => p?.metadata?.annotations?.["extensions.backstage.io/certified-by"],
|
|
123
|
+
"verified-by": (p) => p?.metadata?.annotations?.["extensions.backstage.io/verified-by"],
|
|
124
|
+
"pre-installed": (p) => p?.metadata?.annotations?.["extensions.backstage.io/pre-installed"],
|
|
125
|
+
packages: (p) => (p?.spec?.packages || []).join(", "),
|
|
126
|
+
"backend packages": (p) => getPackagesOfType(p?.spec?.packages || [], packages, [
|
|
127
|
+
"backend-plugin",
|
|
128
|
+
"backend-plugin-module"
|
|
129
|
+
]),
|
|
130
|
+
"frontend packages": (p) => getPackagesOfType(p?.spec?.packages || [], packages, ["frontend-plugin"])
|
|
131
|
+
});
|
|
132
|
+
for (const yaml of await yamls) {
|
|
133
|
+
if (backstagePluginExtensionsCommon.isExtensionsPackage(yaml)) {
|
|
134
|
+
packages[yaml.metadata.name] = yaml;
|
|
135
|
+
packageCSV.addRow(yaml);
|
|
136
|
+
} else if (backstagePluginExtensionsCommon.isExtensionsPlugin(yaml)) {
|
|
137
|
+
pluginCSV.addRow(yaml);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
const csvs = {};
|
|
141
|
+
switch (type) {
|
|
142
|
+
case "plugin":
|
|
143
|
+
csvs["-plugins.csv"] = pluginCSV.generate();
|
|
144
|
+
break;
|
|
145
|
+
case "package":
|
|
146
|
+
csvs["-packages.csv"] = packageCSV.generate();
|
|
147
|
+
break;
|
|
148
|
+
case "all":
|
|
149
|
+
default:
|
|
150
|
+
csvs["-plugins.csv"] = pluginCSV.generate();
|
|
151
|
+
csvs["-packages.csv"] = packageCSV.generate();
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
for (const [suffix, csv] of Object.entries(csvs)) {
|
|
155
|
+
if (!outputFile) {
|
|
156
|
+
console.log(csv);
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
await fs__default.default.writeFile(`${outputFile}${suffix}`, csv);
|
|
160
|
+
}
|
|
161
|
+
process.exit(0);
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
exports.default = index;
|
|
165
|
+
//# sourceMappingURL=index.cjs.js.map
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var fs = require('fs-extra');
|
|
6
|
+
var path = require('path');
|
|
7
|
+
var yaml = require('yaml');
|
|
8
|
+
var backstagePluginExtensionsCommon = require('@red-hat-developer-hub/backstage-plugin-extensions-common');
|
|
9
|
+
|
|
10
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
11
|
+
|
|
12
|
+
var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
|
|
13
|
+
var path__default = /*#__PURE__*/_interopDefaultCompat(path);
|
|
14
|
+
var yaml__default = /*#__PURE__*/_interopDefaultCompat(yaml);
|
|
15
|
+
|
|
16
|
+
const DEFAULT_LIFECYCLE = "unknown";
|
|
17
|
+
var index = async (opts) => {
|
|
18
|
+
const { defaultDynamicPluginsConfig, outputDir, namespace, owner } = opts;
|
|
19
|
+
const entities = [];
|
|
20
|
+
if (defaultDynamicPluginsConfig) {
|
|
21
|
+
const defaultDynamicPluginsPath = path__default.default.resolve(defaultDynamicPluginsConfig);
|
|
22
|
+
const defaultDynamicPluginsContent = fs__default.default.readFileSync(
|
|
23
|
+
defaultDynamicPluginsPath,
|
|
24
|
+
"utf8"
|
|
25
|
+
);
|
|
26
|
+
const defaultPluginsConfig = yaml__default.default.parse(
|
|
27
|
+
defaultDynamicPluginsContent
|
|
28
|
+
);
|
|
29
|
+
for (const plugin of defaultPluginsConfig.plugins) {
|
|
30
|
+
const wrapperDir = plugin.package.replace("/dist/", "/wrappers/");
|
|
31
|
+
const wrapperPath = path__default.default.join(
|
|
32
|
+
path__default.default.dirname(defaultDynamicPluginsConfig),
|
|
33
|
+
wrapperDir
|
|
34
|
+
);
|
|
35
|
+
const packageJSONPath = path__default.default.join(wrapperPath, "package.json");
|
|
36
|
+
const packageJSON = fs__default.default.readJsonSync(packageJSONPath);
|
|
37
|
+
const packageName = guessPackageFromDependencies(
|
|
38
|
+
packageJSON.name,
|
|
39
|
+
packageJSON.dependencies
|
|
40
|
+
) || packageJSON.name;
|
|
41
|
+
const links = [];
|
|
42
|
+
if (packageJSON.homepage) {
|
|
43
|
+
links.push({ url: packageJSON.homepage, title: "Homepage" });
|
|
44
|
+
}
|
|
45
|
+
if (packageJSON.bugs) {
|
|
46
|
+
const bugs = packageJSON.bugs;
|
|
47
|
+
if (bugs.url) {
|
|
48
|
+
links.push({ url: bugs.url, title: "Bugs" });
|
|
49
|
+
} else {
|
|
50
|
+
links.push({ url: packageJSON.bugs, title: "Bugs" });
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
let sourceLocation = "";
|
|
54
|
+
if (packageJSON.repository) {
|
|
55
|
+
const repo = packageJSON.repository;
|
|
56
|
+
const url = { title: "Source Code", url: "" };
|
|
57
|
+
if (repo.url) {
|
|
58
|
+
if (repo.url.startsWith("https://github.com")) {
|
|
59
|
+
url.url = `${repo.url}/tree/main/${repo.directory}`;
|
|
60
|
+
} else {
|
|
61
|
+
url.url = `${repo.url}/${repo.directory}`;
|
|
62
|
+
}
|
|
63
|
+
} else {
|
|
64
|
+
url.url = packageJSON.repository;
|
|
65
|
+
}
|
|
66
|
+
links.push(url);
|
|
67
|
+
sourceLocation = `url ${url.url}`;
|
|
68
|
+
}
|
|
69
|
+
let author = "";
|
|
70
|
+
if (packageJSON.author) {
|
|
71
|
+
const a = packageJSON.author;
|
|
72
|
+
if (a.name) {
|
|
73
|
+
author = a.name;
|
|
74
|
+
author += a.email ? ` <${a.email}>` : "";
|
|
75
|
+
author += a.url ? ` (${a.url})` : "";
|
|
76
|
+
} else {
|
|
77
|
+
author = packageJSON.author;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const partOf = [];
|
|
81
|
+
if (packageJSON.backstage?.pluginId) {
|
|
82
|
+
if (packageJSON.backstage?.role === "backend-plugin-module") {
|
|
83
|
+
const scope = getScope(packageName);
|
|
84
|
+
const module = getModuleName(packageName);
|
|
85
|
+
let pof = "";
|
|
86
|
+
if (scope) {
|
|
87
|
+
pof = `${scope}-`;
|
|
88
|
+
}
|
|
89
|
+
if (module) {
|
|
90
|
+
pof += `${module}-`;
|
|
91
|
+
}
|
|
92
|
+
pof += `${packageJSON.backstage.pluginId}-module`;
|
|
93
|
+
partOf.push(pof);
|
|
94
|
+
} else {
|
|
95
|
+
partOf.push(packageJSON.backstage.pluginId);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
const appConfigExamples = [];
|
|
99
|
+
if (plugin.pluginConfig) {
|
|
100
|
+
appConfigExamples.push({
|
|
101
|
+
title: "Default configuration",
|
|
102
|
+
content: plugin.pluginConfig
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
const entity = {
|
|
106
|
+
apiVersion: backstagePluginExtensionsCommon.EXTENSIONS_API_VERSION,
|
|
107
|
+
kind: backstagePluginExtensionsCommon.ExtensionsKind.Package,
|
|
108
|
+
metadata: {
|
|
109
|
+
name: entityName(packageJSON.name),
|
|
110
|
+
namespace: namespace ?? undefined,
|
|
111
|
+
title: packageName,
|
|
112
|
+
links,
|
|
113
|
+
annotations: {
|
|
114
|
+
"backstage.io/source-location": sourceLocation
|
|
115
|
+
},
|
|
116
|
+
tags: packageJSON.keywords?.filter(
|
|
117
|
+
(k) => !k.startsWith("support:") && !k.startsWith("lifecycle:")
|
|
118
|
+
)
|
|
119
|
+
},
|
|
120
|
+
spec: {
|
|
121
|
+
owner,
|
|
122
|
+
packageName,
|
|
123
|
+
dynamicArtifact: plugin.package,
|
|
124
|
+
version: packageJSON.version,
|
|
125
|
+
backstage: {
|
|
126
|
+
role: packageJSON.backstage?.role,
|
|
127
|
+
supportedVersions: packageJSON.backstage?.["supported-versions"]
|
|
128
|
+
},
|
|
129
|
+
author,
|
|
130
|
+
lifecycle: packageJSON.keywords?.find((k) => k.startsWith("lifecycle:"))?.split(":")[1] ?? DEFAULT_LIFECYCLE,
|
|
131
|
+
partOf,
|
|
132
|
+
appConfigExamples
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
entities.push(entity);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (outputDir) {
|
|
139
|
+
const outputDirPath = path__default.default.resolve(outputDir);
|
|
140
|
+
await fs__default.default.ensureDir(outputDirPath);
|
|
141
|
+
const location = {
|
|
142
|
+
apiVersion: "backstage.io/v1alpha1",
|
|
143
|
+
kind: "Location",
|
|
144
|
+
metadata: {
|
|
145
|
+
namespace,
|
|
146
|
+
name: "packages"
|
|
147
|
+
},
|
|
148
|
+
spec: {
|
|
149
|
+
targets: []
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
for (const entity of entities) {
|
|
153
|
+
const filename = `${entity.metadata.name}.yaml`;
|
|
154
|
+
const entityPath = path__default.default.join(outputDirPath, filename);
|
|
155
|
+
await fs__default.default.writeFile(entityPath, yaml__default.default.stringify(entity));
|
|
156
|
+
location.spec.targets?.push(`./${filename}`);
|
|
157
|
+
}
|
|
158
|
+
await fs__default.default.writeFile(
|
|
159
|
+
path__default.default.join(outputDirPath, "all.yaml"),
|
|
160
|
+
yaml__default.default.stringify(location)
|
|
161
|
+
);
|
|
162
|
+
} else {
|
|
163
|
+
for (const entity of entities) {
|
|
164
|
+
console.log(yaml__default.default.stringify(entity));
|
|
165
|
+
console.log("---");
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
function entityName(str) {
|
|
170
|
+
let name = str.toLowerCase().replace(/[^a-z0-9-_.]/g, "-").replace(/-+/g, "-");
|
|
171
|
+
if (name.startsWith("-")) {
|
|
172
|
+
name = name.substring(1);
|
|
173
|
+
}
|
|
174
|
+
if (name.endsWith("-")) {
|
|
175
|
+
name = name.slice(0, -1);
|
|
176
|
+
}
|
|
177
|
+
if (name.length > 63) {
|
|
178
|
+
name = name.substring(0, 63);
|
|
179
|
+
}
|
|
180
|
+
return name;
|
|
181
|
+
}
|
|
182
|
+
function guessPackageFromDependencies(pkgname, dependencies) {
|
|
183
|
+
if (!dependencies) {
|
|
184
|
+
return undefined;
|
|
185
|
+
}
|
|
186
|
+
if (Object.keys(dependencies).length === 1) {
|
|
187
|
+
return Object.keys(dependencies)[0];
|
|
188
|
+
}
|
|
189
|
+
for (const dep of Object.keys(dependencies)) {
|
|
190
|
+
const convertedName = dep.replaceAll("/", "-").replaceAll("@", "");
|
|
191
|
+
if (convertedName === pkgname) {
|
|
192
|
+
return dep;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return undefined;
|
|
196
|
+
}
|
|
197
|
+
function getScope(pkgname) {
|
|
198
|
+
if (pkgname.startsWith("@")) {
|
|
199
|
+
return pkgname.split("/")[0].substring(1);
|
|
200
|
+
}
|
|
201
|
+
return undefined;
|
|
202
|
+
}
|
|
203
|
+
function getModuleName(pkgname) {
|
|
204
|
+
const parts = pkgname.split("-module-");
|
|
205
|
+
if (parts.length > 1) {
|
|
206
|
+
return parts[1];
|
|
207
|
+
}
|
|
208
|
+
return undefined;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
exports.default = index;
|
|
212
|
+
//# sourceMappingURL=index.cjs.js.map
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var lazy = require('../lib/lazy.cjs.js');
|
|
4
|
+
|
|
5
|
+
const registerCommands = (program) => {
|
|
6
|
+
program.command("init").description("init").action(lazy.lazy(() => import('./init/index.cjs.js'), "default"));
|
|
7
|
+
program.command("generate").description(
|
|
8
|
+
"Generate a Plugin entities for the extensions. By default, it will output entities to the standard output"
|
|
9
|
+
).option(
|
|
10
|
+
"-p, --default-dynamic-plugins-config [path]",
|
|
11
|
+
"Path to the default dynamic plugins file (usually dynamic-plugins.default.yaml in rhdh source code)"
|
|
12
|
+
).option(
|
|
13
|
+
"-o, --output-dir [path]",
|
|
14
|
+
"Path to the output directory. Each entity will be written to a separate file"
|
|
15
|
+
).option(
|
|
16
|
+
"--namespace [namespace]",
|
|
17
|
+
"metadata.namespace for the generated Package entities"
|
|
18
|
+
).option("--owner [owner]", "spec.owner for the generated Package entities").action(lazy.lazy(() => import('./generate/index.cjs.js'), "default"));
|
|
19
|
+
program.command("verify").description(
|
|
20
|
+
"Verify a set of extensions entities. By default, it will read entities from the standard input"
|
|
21
|
+
).action(lazy.lazy(() => import('./verify/index.cjs.js'), "default"));
|
|
22
|
+
program.command("export-csv").description("Export a folder of extensions plugin YAMLs to a CSV file").option(
|
|
23
|
+
"-o, --output-file [path]",
|
|
24
|
+
'Path to the output CSV file. By default, it will output to the standard output. When a file is specified, the "csv" file extension will be added automatically'
|
|
25
|
+
).option(
|
|
26
|
+
"-p, --plugins-yaml-path [path]",
|
|
27
|
+
"Path to the default plugins folder, containing extensions plugin YAML files. Multiple paths can be provided, separated by commas"
|
|
28
|
+
).option(
|
|
29
|
+
"-r, --recursive",
|
|
30
|
+
"Recursively search for YAML files in each directory provided in plugins-yaml-path"
|
|
31
|
+
).option(
|
|
32
|
+
"-t, --type [type]",
|
|
33
|
+
'The type of CSV to export. Can be one of: "plugin", "package", or "all". "all" will generate two files.',
|
|
34
|
+
"all"
|
|
35
|
+
).action(lazy.lazy(() => import('./export-csv/index.cjs.js'), "default"));
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
exports.registerCommands = registerCommands;
|
|
39
|
+
//# sourceMappingURL=index.cjs.js.map
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var fs = require('fs');
|
|
6
|
+
var inquirer = require('inquirer');
|
|
7
|
+
var glob = require('glob');
|
|
8
|
+
var yaml = require('yaml');
|
|
9
|
+
var backstagePluginExtensionsCommon = require('@red-hat-developer-hub/backstage-plugin-extensions-common');
|
|
10
|
+
|
|
11
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
12
|
+
|
|
13
|
+
var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
|
|
14
|
+
var inquirer__default = /*#__PURE__*/_interopDefaultCompat(inquirer);
|
|
15
|
+
var glob__default = /*#__PURE__*/_interopDefaultCompat(glob);
|
|
16
|
+
var yaml__default = /*#__PURE__*/_interopDefaultCompat(yaml);
|
|
17
|
+
|
|
18
|
+
async function init() {
|
|
19
|
+
const pluginFolders = await glob__default.default.glob("plugins/*/package.json/../");
|
|
20
|
+
const autoGeneratePackages = pluginFolders.length === 0;
|
|
21
|
+
const cwd = process.cwd().split("/").pop() ?? "";
|
|
22
|
+
const defaultTitle = cwd.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
23
|
+
const questions = [
|
|
24
|
+
{
|
|
25
|
+
type: "input",
|
|
26
|
+
name: "title",
|
|
27
|
+
message: "Plugin name (display name)",
|
|
28
|
+
default: defaultTitle
|
|
29
|
+
}
|
|
30
|
+
];
|
|
31
|
+
if (autoGeneratePackages) {
|
|
32
|
+
questions.push({
|
|
33
|
+
type: "input",
|
|
34
|
+
name: "packageName",
|
|
35
|
+
message: "NPM package name incl. org (e.g. @my-org/my-plugin)"
|
|
36
|
+
});
|
|
37
|
+
questions.push({
|
|
38
|
+
type: "checkbox",
|
|
39
|
+
name: "packages",
|
|
40
|
+
message: "Packages",
|
|
41
|
+
choices: [
|
|
42
|
+
{ name: "Frontend", value: "frontend", checked: true },
|
|
43
|
+
{ name: "Backend", value: "backend", checked: true }
|
|
44
|
+
]
|
|
45
|
+
});
|
|
46
|
+
} else {
|
|
47
|
+
questions.push({
|
|
48
|
+
type: "checkbox",
|
|
49
|
+
name: "packages",
|
|
50
|
+
message: "Packages",
|
|
51
|
+
choices: pluginFolders.map((pluginFolder) => ({
|
|
52
|
+
name: pluginFolder,
|
|
53
|
+
value: pluginFolder,
|
|
54
|
+
checked: true
|
|
55
|
+
}))
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
const answers = await inquirer__default.default.prompt(questions);
|
|
59
|
+
console.log("answers", answers);
|
|
60
|
+
const { title, packageName, namespace, author } = answers;
|
|
61
|
+
let name = (packageName || title).toLowerCase().replace(/^@/, "");
|
|
62
|
+
if (name.includes("/")) {
|
|
63
|
+
name = name.substring(name.lastIndexOf("/") + 1);
|
|
64
|
+
}
|
|
65
|
+
const plugin = {
|
|
66
|
+
apiVersion: backstagePluginExtensionsCommon.EXTENSIONS_API_VERSION,
|
|
67
|
+
kind: backstagePluginExtensionsCommon.ExtensionsKind.Plugin,
|
|
68
|
+
metadata: {
|
|
69
|
+
namespace,
|
|
70
|
+
name,
|
|
71
|
+
title,
|
|
72
|
+
description: "Plugin summary"
|
|
73
|
+
},
|
|
74
|
+
spec: {
|
|
75
|
+
author,
|
|
76
|
+
description: "# Plugin name\n\nFull plugin description..."
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
console.log(yaml__default.default.stringify(plugin).trim());
|
|
80
|
+
if (autoGeneratePackages) {
|
|
81
|
+
if (answers.packages.includes("frontend")) {
|
|
82
|
+
const frontendPackage = {
|
|
83
|
+
apiVersion: backstagePluginExtensionsCommon.EXTENSIONS_API_VERSION,
|
|
84
|
+
kind: backstagePluginExtensionsCommon.ExtensionsKind.Package,
|
|
85
|
+
metadata: {
|
|
86
|
+
namespace,
|
|
87
|
+
name: packageName.toLowerCase().replace(/^@/, "").replaceAll(/[^a-z0-9]/g, "-"),
|
|
88
|
+
title: packageName
|
|
89
|
+
},
|
|
90
|
+
spec: {
|
|
91
|
+
packageName,
|
|
92
|
+
version: "0.1.0",
|
|
93
|
+
partOf: [plugin.metadata.name]
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
console.log("---");
|
|
97
|
+
console.log(yaml__default.default.stringify(frontendPackage).trim());
|
|
98
|
+
}
|
|
99
|
+
if (answers.packages.includes("backend")) {
|
|
100
|
+
const backendPackage = {
|
|
101
|
+
apiVersion: backstagePluginExtensionsCommon.EXTENSIONS_API_VERSION,
|
|
102
|
+
kind: backstagePluginExtensionsCommon.ExtensionsKind.Package,
|
|
103
|
+
metadata: {
|
|
104
|
+
namespace,
|
|
105
|
+
name: `${packageName.toLowerCase().replace(/^@/, "").replaceAll(/[^a-z0-9]/g, "-")}-backend`,
|
|
106
|
+
title: `${packageName}-backend`
|
|
107
|
+
},
|
|
108
|
+
spec: {
|
|
109
|
+
packageName: `${packageName}-backend`,
|
|
110
|
+
version: "0.1.0",
|
|
111
|
+
partOf: [plugin.metadata.name]
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
console.log("---");
|
|
115
|
+
console.log(yaml__default.default.stringify(backendPackage).trim());
|
|
116
|
+
}
|
|
117
|
+
} else {
|
|
118
|
+
answers.packages.forEach((pluginFolder) => {
|
|
119
|
+
const packageJsonPath = `${pluginFolder}/package.json`;
|
|
120
|
+
const packageJson = JSON.parse(
|
|
121
|
+
fs__default.default.readFileSync(packageJsonPath, { encoding: "utf8" })
|
|
122
|
+
);
|
|
123
|
+
const pkg = {
|
|
124
|
+
apiVersion: backstagePluginExtensionsCommon.EXTENSIONS_API_VERSION,
|
|
125
|
+
kind: backstagePluginExtensionsCommon.ExtensionsKind.Package,
|
|
126
|
+
metadata: {
|
|
127
|
+
namespace,
|
|
128
|
+
name: packageJson.name.toLowerCase().replace(/^@/, "").replaceAll(/[^a-z0-9]/g, "-")
|
|
129
|
+
},
|
|
130
|
+
spec: {
|
|
131
|
+
packageName: packageJson.name,
|
|
132
|
+
version: packageJson.version,
|
|
133
|
+
partOf: [plugin.metadata.name]
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
console.log("---");
|
|
137
|
+
console.log(yaml__default.default.stringify(pkg).trim());
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
exports.default = init;
|
|
143
|
+
//# sourceMappingURL=index.cjs.js.map
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var chalk = require('chalk');
|
|
6
|
+
var fs = require('fs-extra');
|
|
7
|
+
var glob = require('glob');
|
|
8
|
+
var yaml = require('yaml');
|
|
9
|
+
var backstagePluginExtensionsCommon = require('@red-hat-developer-hub/backstage-plugin-extensions-common');
|
|
10
|
+
|
|
11
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
12
|
+
|
|
13
|
+
var chalk__default = /*#__PURE__*/_interopDefaultCompat(chalk);
|
|
14
|
+
var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
|
|
15
|
+
var yaml__default = /*#__PURE__*/_interopDefaultCompat(yaml);
|
|
16
|
+
|
|
17
|
+
const packages = {};
|
|
18
|
+
const plugins = {};
|
|
19
|
+
var index = async () => {
|
|
20
|
+
const filenames = await glob.glob("**/*.yaml", { ignore: "node_modules/**" });
|
|
21
|
+
filenames.sort();
|
|
22
|
+
for (const filename of filenames) {
|
|
23
|
+
const content = await fs__default.default.readFile(filename, "utf8");
|
|
24
|
+
const parsed = await yaml__default.default.parse(content);
|
|
25
|
+
if (Array.isArray(content)) {
|
|
26
|
+
for (const chunk of content) {
|
|
27
|
+
await load(filename, chunk);
|
|
28
|
+
}
|
|
29
|
+
} else {
|
|
30
|
+
await load(filename, parsed);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
verifyPackages();
|
|
34
|
+
verifyPlugins();
|
|
35
|
+
};
|
|
36
|
+
function stringifyEntityRef(entity) {
|
|
37
|
+
return `${entity.metadata.namespace ?? "default"}/${entity.metadata.name}`;
|
|
38
|
+
}
|
|
39
|
+
function isEntity(maybe) {
|
|
40
|
+
return "apiVersion" in maybe && "kind" in maybe;
|
|
41
|
+
}
|
|
42
|
+
async function load(filename, content) {
|
|
43
|
+
if (typeof content !== "object") {
|
|
44
|
+
throw new Error(`Expected object, got ${typeof content}`);
|
|
45
|
+
}
|
|
46
|
+
if (backstagePluginExtensionsCommon.isExtensionsPackage(content)) {
|
|
47
|
+
packages[stringifyEntityRef(content)] = content;
|
|
48
|
+
} else if (backstagePluginExtensionsCommon.isExtensionsPlugin(content)) {
|
|
49
|
+
plugins[stringifyEntityRef(content)] = content;
|
|
50
|
+
} else if (isEntity(content)) {
|
|
51
|
+
console.log(
|
|
52
|
+
`Ignore file ${chalk__default.default.blue(filename)} with apiVersion ${content.apiVersion} and kind ${content.kind}`
|
|
53
|
+
);
|
|
54
|
+
} else {
|
|
55
|
+
console.log(
|
|
56
|
+
`Ignore file ${chalk__default.default.blue(filename)} without apiVersion or kind`
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
async function verifyPackages() {
|
|
61
|
+
for (const pkg of Object.values(packages)) {
|
|
62
|
+
const displayName = pkg.metadata.title ?? pkg.metadata.name ?? "unknown";
|
|
63
|
+
console.log(`Verifying package ${chalk__default.default.blue(displayName)}...`);
|
|
64
|
+
if (!pkg.metadata.title) {
|
|
65
|
+
console.log(` - missing title`);
|
|
66
|
+
}
|
|
67
|
+
if (pkg.spec?.partOf?.length) {
|
|
68
|
+
for (const partOf of pkg.spec.partOf) {
|
|
69
|
+
if (!plugins[partOf]) {
|
|
70
|
+
console.log(` - missing plugin ${partOf}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async function verifyPlugins() {
|
|
77
|
+
for (const plugin of Object.values(plugins)) {
|
|
78
|
+
const displayName = plugin.metadata.title ?? plugin.metadata.name ?? "unknown";
|
|
79
|
+
console.log(`Verifying plugin ${chalk__default.default.blue(displayName)}`);
|
|
80
|
+
if (!plugin.metadata.title) {
|
|
81
|
+
console.log(` - missing title`);
|
|
82
|
+
}
|
|
83
|
+
if (plugin.spec?.packages?.length) {
|
|
84
|
+
for (const pkg of plugin.spec.packages) {
|
|
85
|
+
if (typeof pkg === "string") {
|
|
86
|
+
if (!packages[pkg]) {
|
|
87
|
+
console.log(` - missing package ${pkg}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (!plugin.spec?.documentation?.length) {
|
|
93
|
+
console.log(` - missing documentation`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
exports.default = index;
|
|
99
|
+
//# sourceMappingURL=index.cjs.js.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var commander = require('commander');
|
|
4
|
+
var chalk = require('chalk');
|
|
5
|
+
var errors = require('./lib/errors.cjs.js');
|
|
6
|
+
var index = require('./commands/index.cjs.js');
|
|
7
|
+
|
|
8
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
9
|
+
|
|
10
|
+
var chalk__default = /*#__PURE__*/_interopDefaultCompat(chalk);
|
|
11
|
+
|
|
12
|
+
const main = (argv) => {
|
|
13
|
+
commander.program.name("extensions-cli");
|
|
14
|
+
index.registerCommands(commander.program);
|
|
15
|
+
commander.program.on("command:*", () => {
|
|
16
|
+
console.log();
|
|
17
|
+
console.log(chalk__default.default.red(`Invalid command: ${commander.program.args.join(" ")}`));
|
|
18
|
+
console.log();
|
|
19
|
+
commander.program.outputHelp();
|
|
20
|
+
process.exit(1);
|
|
21
|
+
});
|
|
22
|
+
commander.program.parse(argv);
|
|
23
|
+
};
|
|
24
|
+
process.on("unhandledRejection", (rejection) => {
|
|
25
|
+
if (rejection instanceof Error) {
|
|
26
|
+
errors.exitWithError(rejection);
|
|
27
|
+
} else {
|
|
28
|
+
errors.exitWithError(new Error(`Unknown rejection: '${rejection}'`));
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
main(process.argv);
|
|
32
|
+
//# sourceMappingURL=index.cjs.js.map
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chalk = require('chalk');
|
|
4
|
+
|
|
5
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
6
|
+
|
|
7
|
+
var chalk__default = /*#__PURE__*/_interopDefaultCompat(chalk);
|
|
8
|
+
|
|
9
|
+
class CustomError extends Error {
|
|
10
|
+
get name() {
|
|
11
|
+
return this.constructor.name;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
class ExitCodeError extends CustomError {
|
|
15
|
+
code;
|
|
16
|
+
constructor(code, command) {
|
|
17
|
+
super(
|
|
18
|
+
command ? `Command '${command}' exited with code ${code}` : `Child exited with code ${code}`
|
|
19
|
+
);
|
|
20
|
+
this.code = code;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function exitWithError(error) {
|
|
24
|
+
if (error instanceof ExitCodeError) {
|
|
25
|
+
process.stderr.write(`
|
|
26
|
+
${chalk__default.default.red(error.message)}
|
|
27
|
+
|
|
28
|
+
`);
|
|
29
|
+
process.exit(error.code);
|
|
30
|
+
} else {
|
|
31
|
+
process.stderr.write(`
|
|
32
|
+
${chalk__default.default.red(`${error.stack}`)}
|
|
33
|
+
|
|
34
|
+
`);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
exports.CustomError = CustomError;
|
|
40
|
+
exports.ExitCodeError = ExitCodeError;
|
|
41
|
+
exports.exitWithError = exitWithError;
|
|
42
|
+
//# sourceMappingURL=errors.cjs.js.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var errors = require('@backstage/errors');
|
|
4
|
+
var errors$1 = require('./errors.cjs.js');
|
|
5
|
+
|
|
6
|
+
function lazy(moduleLoader, exportName) {
|
|
7
|
+
return async (...args) => {
|
|
8
|
+
try {
|
|
9
|
+
const mod = await moduleLoader();
|
|
10
|
+
const actualModule = mod.default;
|
|
11
|
+
const actionFunc = actualModule[exportName];
|
|
12
|
+
await actionFunc(...args);
|
|
13
|
+
process.exit(0);
|
|
14
|
+
} catch (error) {
|
|
15
|
+
errors.assertError(error);
|
|
16
|
+
errors$1.exitWithError(error);
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
exports.lazy = lazy;
|
|
22
|
+
//# sourceMappingURL=lazy.cjs.js.map
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@red-hat-developer-hub/extensions-cli",
|
|
3
|
+
"description": "CLI for the Extensions",
|
|
4
|
+
"version": "0.14.0",
|
|
5
|
+
"backstage": {
|
|
6
|
+
"role": "cli"
|
|
7
|
+
},
|
|
8
|
+
"homepage": "https://red.ht/rhdh",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "https://github.com/redhat-developer/rhdh-plugins",
|
|
12
|
+
"directory": "workspaces/extensions/packages/cli"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"backstage"
|
|
16
|
+
],
|
|
17
|
+
"license": "Apache-2.0",
|
|
18
|
+
"main": "dist/index.cjs.js",
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "backstage-cli package build",
|
|
21
|
+
"lint": "backstage-cli package lint",
|
|
22
|
+
"test": "backstage-cli package test",
|
|
23
|
+
"clean": "backstage-cli package clean",
|
|
24
|
+
"start": "nodemon --"
|
|
25
|
+
},
|
|
26
|
+
"bin": "bin/extensions-cli",
|
|
27
|
+
"files": [
|
|
28
|
+
"bin",
|
|
29
|
+
"dist/**/*.js"
|
|
30
|
+
],
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@backstage/catalog-model": "^1.7.6",
|
|
33
|
+
"@backstage/cli": "^0.34.5",
|
|
34
|
+
"@backstage/errors": "^1.2.7",
|
|
35
|
+
"@backstage/types": "^1.2.2",
|
|
36
|
+
"@red-hat-developer-hub/backstage-plugin-extensions-common": "^0.14.0",
|
|
37
|
+
"chalk": "^4.1.2",
|
|
38
|
+
"commander": "^12.0.0",
|
|
39
|
+
"fs-extra": "^11.2.0",
|
|
40
|
+
"glob": "^9.3.5",
|
|
41
|
+
"inquirer": "^12.4.3",
|
|
42
|
+
"yaml": "^2.7.0"
|
|
43
|
+
},
|
|
44
|
+
"nodemonConfig": {
|
|
45
|
+
"watch": "./src",
|
|
46
|
+
"exec": "bin/extensions-cli",
|
|
47
|
+
"ext": "ts"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@types/fs-extra": "^11.0.4"
|
|
51
|
+
}
|
|
52
|
+
}
|