@backstage/cli 0.30.0-next.2 → 0.30.0-next.3
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 +33 -0
- package/dist/commands/index.cjs.js +3 -0
- package/dist/commands/new/new.cjs.js +39 -80
- package/dist/lib/new/createNewPackage.cjs.js +32 -0
- package/dist/lib/new/defaultTemplates.cjs.js +16 -0
- package/dist/lib/new/execution/PortableTemplater.cjs.js +91 -0
- package/dist/lib/new/execution/executePortableTemplate.cjs.js +54 -0
- package/dist/lib/new/execution/installNewPackage.cjs.js +127 -0
- package/dist/lib/new/execution/writeTemplateContents.cjs.js +111 -0
- package/dist/lib/new/preparation/collectPortableTemplateInput.cjs.js +157 -0
- package/dist/lib/new/preparation/loadPortableTemplate.cjs.js +82 -0
- package/dist/lib/new/preparation/loadPortableTemplateConfig.cjs.js +121 -0
- package/dist/lib/new/preparation/resolvePackageParams.cjs.js +40 -0
- package/dist/lib/new/preparation/selectTemplateInteractively.cjs.js +38 -0
- package/dist/lib/new/types.cjs.js +15 -4
- package/dist/lib/tasks.cjs.js +0 -111
- package/dist/packages/backend-defaults/package.json.cjs.js +1 -1
- package/dist/packages/backend-plugin-api/package.json.cjs.js +1 -1
- package/dist/packages/backend-test-utils/package.json.cjs.js +1 -1
- package/dist/packages/cli/package.json.cjs.js +3 -2
- package/dist/packages/dev-utils/package.json.cjs.js +1 -1
- package/dist/plugins/auth-backend/package.json.cjs.js +1 -1
- package/dist/plugins/auth-backend-module-guest-provider/package.json.cjs.js +1 -1
- package/dist/plugins/catalog-node/package.json.cjs.js +1 -1
- package/dist/plugins/scaffolder-node/package.json.cjs.js +1 -1
- package/dist/plugins/scaffolder-node-test-utils/package.json.cjs.js +1 -1
- package/package.json +11 -10
- package/templates/{default-backend-plugin → backend-plugin}/README.md.hbs +4 -4
- package/templates/{default-backend-plugin → backend-plugin}/dev/index.ts.hbs +5 -5
- package/templates/{default-backend-plugin → backend-plugin}/package.json.hbs +1 -9
- package/templates/backend-plugin/portable-template.yaml +5 -0
- package/templates/{default-backend-plugin → backend-plugin}/src/plugin.test.ts.hbs +5 -5
- package/templates/{default-backend-plugin → backend-plugin}/src/plugin.ts.hbs +1 -1
- package/templates/{default-backend-module → backend-plugin-module}/README.md.hbs +1 -1
- package/templates/{default-backend-module → backend-plugin-module}/package.json.hbs +1 -9
- package/templates/backend-plugin-module/portable-template.yaml +5 -0
- package/templates/{default-plugin → frontend-plugin}/README.md.hbs +3 -3
- package/templates/{default-plugin → frontend-plugin}/dev/index.tsx.hbs +1 -1
- package/templates/{default-plugin → frontend-plugin}/package.json.hbs +1 -9
- package/templates/frontend-plugin/portable-template.yaml +6 -0
- package/templates/{default-plugin → frontend-plugin}/src/components/ExampleComponent/ExampleComponent.test.tsx.hbs +1 -1
- package/templates/{default-plugin → frontend-plugin}/src/components/ExampleComponent/ExampleComponent.tsx.hbs +1 -1
- package/templates/{default-plugin → frontend-plugin}/src/plugin.test.ts.hbs +1 -1
- package/templates/{default-plugin → frontend-plugin}/src/plugin.ts.hbs +1 -1
- package/templates/{default-plugin → frontend-plugin}/src/routes.ts.hbs +1 -1
- package/templates/{node-library-package → node-library}/README.md.hbs +2 -2
- package/templates/{node-library-package → node-library}/package.json.hbs +1 -9
- package/templates/node-library/portable-template.yaml +3 -0
- package/templates/plugin-common-library/README.md.hbs +5 -0
- package/templates/{default-common-plugin-package → plugin-common-library}/package.json.hbs +2 -10
- package/templates/plugin-common-library/portable-template.yaml +3 -0
- package/templates/{default-common-plugin-package → plugin-common-library}/src/index.ts.hbs +1 -1
- package/templates/plugin-node-library/README.md.hbs +5 -0
- package/templates/{default-node-plugin-package → plugin-node-library}/package.json.hbs +2 -10
- package/templates/plugin-node-library/portable-template.yaml +3 -0
- package/templates/{default-node-plugin-package → plugin-node-library}/src/index.ts.hbs +1 -1
- package/templates/plugin-web-library/README.md.hbs +5 -0
- package/templates/{default-react-plugin-package → plugin-web-library}/package.json.hbs +2 -10
- package/templates/plugin-web-library/portable-template.yaml +3 -0
- package/templates/{default-react-plugin-package → plugin-web-library}/src/index.ts.hbs +1 -1
- package/templates/scaffolder-backend-module/README.md.hbs +5 -0
- package/templates/{scaffolder-module → scaffolder-backend-module}/package.json.hbs +2 -10
- package/templates/scaffolder-backend-module/portable-template.yaml +6 -0
- package/templates/{scaffolder-module → scaffolder-backend-module}/src/index.ts.hbs +1 -1
- package/templates/{web-library-package → web-library}/README.md.hbs +2 -2
- package/templates/{web-library-package → web-library}/package.json.hbs +1 -9
- package/templates/web-library/portable-template.yaml +3 -0
- package/dist/lib/new/FactoryRegistry.cjs.js +0 -96
- package/dist/lib/new/factories/backendModule.cjs.js +0 -82
- package/dist/lib/new/factories/backendPlugin.cjs.js +0 -78
- package/dist/lib/new/factories/common/prompts.cjs.js +0 -57
- package/dist/lib/new/factories/common/tasks.cjs.js +0 -66
- package/dist/lib/new/factories/common/util.cjs.js +0 -16
- package/dist/lib/new/factories/frontendPlugin.cjs.js +0 -107
- package/dist/lib/new/factories/index.cjs.js +0 -24
- package/dist/lib/new/factories/nodeLibraryPackage.cjs.js +0 -57
- package/dist/lib/new/factories/pluginCommon.cjs.js +0 -58
- package/dist/lib/new/factories/pluginNode.cjs.js +0 -58
- package/dist/lib/new/factories/pluginWeb.cjs.js +0 -58
- package/dist/lib/new/factories/scaffolderModule.cjs.js +0 -90
- package/dist/lib/new/factories/webLibraryPackage.cjs.js +0 -57
- package/templates/default-backend-module/tsconfig.json +0 -9
- package/templates/default-backend-plugin/tsconfig.json +0 -13
- package/templates/default-common-plugin-package/README.md.hbs +0 -5
- package/templates/default-common-plugin-package/tsconfig.json +0 -9
- package/templates/default-node-plugin-package/README.md.hbs +0 -5
- package/templates/default-node-plugin-package/tsconfig.json +0 -9
- package/templates/default-plugin/tsconfig.json +0 -12
- package/templates/default-react-plugin-package/README.md.hbs +0 -5
- package/templates/default-react-plugin-package/tsconfig.json +0 -11
- package/templates/node-library-package/tsconfig.json +0 -11
- package/templates/scaffolder-module/README.md.hbs +0 -5
- package/templates/scaffolder-module/tsconfig.json +0 -9
- package/templates/web-library-package/tsconfig.json +0 -11
- /package/templates/{default-backend-plugin → backend-plugin}/.eslintrc.js.hbs +0 -0
- /package/templates/{default-backend-plugin → backend-plugin}/src/index.ts.hbs +0 -0
- /package/templates/{default-backend-plugin → backend-plugin}/src/router.test.ts +0 -0
- /package/templates/{default-backend-plugin → backend-plugin}/src/router.ts +0 -0
- /package/templates/{default-backend-plugin → backend-plugin}/src/services/TodoListService/createTodoListService.ts +0 -0
- /package/templates/{default-backend-plugin → backend-plugin}/src/services/TodoListService/index.ts +0 -0
- /package/templates/{default-backend-plugin → backend-plugin}/src/services/TodoListService/types.ts +0 -0
- /package/templates/{default-backend-plugin → backend-plugin}/src/setupTests.ts +0 -0
- /package/templates/{default-backend-module → backend-plugin-module}/.eslintrc.js.hbs +0 -0
- /package/templates/{default-backend-module → backend-plugin-module}/src/index.ts.hbs +0 -0
- /package/templates/{default-backend-module → backend-plugin-module}/src/module.ts.hbs +0 -0
- /package/templates/{default-common-plugin-package → frontend-plugin}/.eslintrc.js.hbs +0 -0
- /package/templates/{default-plugin → frontend-plugin}/src/components/ExampleComponent/index.ts +0 -0
- /package/templates/{default-plugin → frontend-plugin}/src/components/ExampleFetchComponent/ExampleFetchComponent.test.tsx.hbs +0 -0
- /package/templates/{default-plugin → frontend-plugin}/src/components/ExampleFetchComponent/ExampleFetchComponent.tsx.hbs +0 -0
- /package/templates/{default-plugin → frontend-plugin}/src/components/ExampleFetchComponent/index.ts +0 -0
- /package/templates/{default-plugin → frontend-plugin}/src/index.ts.hbs +0 -0
- /package/templates/{default-plugin → frontend-plugin}/src/setupTests.ts +0 -0
- /package/templates/{default-node-plugin-package → node-library}/.eslintrc.js.hbs +0 -0
- /package/templates/{node-library-package → node-library}/src/index.ts.hbs +0 -0
- /package/templates/{default-common-plugin-package → node-library}/src/setupTests.ts +0 -0
- /package/templates/{default-plugin → plugin-common-library}/.eslintrc.js.hbs +0 -0
- /package/templates/{default-node-plugin-package → plugin-common-library}/src/setupTests.ts +0 -0
- /package/templates/{default-react-plugin-package → plugin-node-library}/.eslintrc.js.hbs +0 -0
- /package/templates/{node-library-package → plugin-node-library}/src/setupTests.ts +0 -0
- /package/templates/{node-library-package → plugin-web-library}/.eslintrc.js.hbs +0 -0
- /package/templates/{default-react-plugin-package → plugin-web-library}/src/components/ExampleComponent/ExampleComponent.test.tsx +0 -0
- /package/templates/{default-react-plugin-package → plugin-web-library}/src/components/ExampleComponent/ExampleComponent.tsx +0 -0
- /package/templates/{default-react-plugin-package → plugin-web-library}/src/components/ExampleComponent/index.ts +0 -0
- /package/templates/{default-react-plugin-package → plugin-web-library}/src/components/index.ts +0 -0
- /package/templates/{default-react-plugin-package → plugin-web-library}/src/hooks/index.ts +0 -0
- /package/templates/{default-react-plugin-package → plugin-web-library}/src/hooks/useExample/index.ts +0 -0
- /package/templates/{default-react-plugin-package → plugin-web-library}/src/hooks/useExample/useExample.ts +0 -0
- /package/templates/{default-react-plugin-package → plugin-web-library}/src/setupTests.ts +0 -0
- /package/templates/{scaffolder-module → scaffolder-backend-module}/.eslintrc.js.hbs +0 -0
- /package/templates/{scaffolder-module → scaffolder-backend-module}/src/actions/example.test.ts +0 -0
- /package/templates/{scaffolder-module → scaffolder-backend-module}/src/actions/example.ts +0 -0
- /package/templates/{scaffolder-module → scaffolder-backend-module}/src/module.ts +0 -0
- /package/templates/{web-library-package → web-library}/.eslintrc.js.hbs +0 -0
- /package/templates/{web-library-package → web-library}/src/index.ts.hbs +0 -0
- /package/templates/{web-library-package → web-library}/src/setupTests.ts +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
# @backstage/cli
|
|
2
2
|
|
|
3
|
+
## 0.30.0-next.3
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- b30e788: The `new` command is now powered by a new template system that allows you to define your own templates in a declarative way, as well as import existing templates from external sources. See the [CLI templates documentation](https://backstage.io/docs/tooling/cli/templates) for more information.
|
|
8
|
+
|
|
9
|
+
The following flags for the `new` command have been deprecated and will be removed in a future release:
|
|
10
|
+
|
|
11
|
+
- `--license=<license>`: Configure the global `license` instead.
|
|
12
|
+
- `--no-private`: Configure the global `private` instead.
|
|
13
|
+
- `--baseVersion=<version>`: Configure the global `version` instead.
|
|
14
|
+
- `--npmRegistry=<url>`: Configure the global `publishRegistry` instead.
|
|
15
|
+
- `--scope=<scope>`: Configure the global `namePrefix` and/or `namePluginInfix` instead.
|
|
16
|
+
|
|
17
|
+
As part of this change the template IDs and their options have changed. The following backwards compatibility mappings for the `--select` and `--option` flags are enabled when using the default set of templates, but they will also be removed in the future:
|
|
18
|
+
|
|
19
|
+
- `--select=plugin` is mapped to `--select=frontend-plugin` instead.
|
|
20
|
+
- `--option=id=<id>` is mapped to `--option=pluginId=<id>` instead.
|
|
21
|
+
|
|
22
|
+
### Patch Changes
|
|
23
|
+
|
|
24
|
+
- Updated dependencies
|
|
25
|
+
- @backstage/cli-node@0.2.13-next.1
|
|
26
|
+
- @backstage/config-loader@1.9.6-next.0
|
|
27
|
+
- @backstage/catalog-model@1.7.3
|
|
28
|
+
- @backstage/cli-common@0.1.15
|
|
29
|
+
- @backstage/config@1.3.2
|
|
30
|
+
- @backstage/errors@1.2.7
|
|
31
|
+
- @backstage/eslint-plugin@0.1.10
|
|
32
|
+
- @backstage/integration@1.16.1
|
|
33
|
+
- @backstage/release-manifests@0.0.12
|
|
34
|
+
- @backstage/types@1.2.1
|
|
35
|
+
|
|
3
36
|
## 0.30.0-next.2
|
|
4
37
|
|
|
5
38
|
### Patch Changes
|
|
@@ -118,6 +118,9 @@ function registerCommands(program) {
|
|
|
118
118
|
"Pre-fill options for the creation process",
|
|
119
119
|
(opt, arr) => [...arr, opt],
|
|
120
120
|
[]
|
|
121
|
+
).option(
|
|
122
|
+
"--skip-install",
|
|
123
|
+
`Skips running 'yarn install' and 'yarn lint --fix'`
|
|
121
124
|
).option("--scope <scope>", "The scope to use for new packages").option(
|
|
122
125
|
"--npm-registry <URL>",
|
|
123
126
|
"The package registry to use for new packages"
|
|
@@ -2,21 +2,46 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var
|
|
6
|
-
var fs = require('fs-extra');
|
|
7
|
-
var path = require('path');
|
|
8
|
-
var FactoryRegistry = require('../../lib/new/FactoryRegistry.cjs.js');
|
|
9
|
-
var cliNode = require('@backstage/cli-node');
|
|
10
|
-
var paths = require('../../lib/paths.cjs.js');
|
|
11
|
-
var errors = require('@backstage/errors');
|
|
12
|
-
var tasks = require('../../lib/tasks.cjs.js');
|
|
5
|
+
var createNewPackage = require('../../lib/new/createNewPackage.cjs.js');
|
|
13
6
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
7
|
+
var _new = async (opts) => {
|
|
8
|
+
const {
|
|
9
|
+
option: rawArgOptions,
|
|
10
|
+
select: preselectedTemplateId,
|
|
11
|
+
skipInstall,
|
|
12
|
+
scope,
|
|
13
|
+
private: isPrivate,
|
|
14
|
+
...otherGlobals
|
|
15
|
+
} = opts;
|
|
16
|
+
const prefilledParams = parseParams(rawArgOptions);
|
|
17
|
+
let pluginInfix = void 0;
|
|
18
|
+
let packagePrefix = void 0;
|
|
19
|
+
if (scope) {
|
|
20
|
+
const backstagePrefix = scope.startsWith("backstage") ? "" : "backstage-";
|
|
21
|
+
packagePrefix = scope.includes("/") ? `@${scope}${backstagePrefix}` : `@${scope}/${backstagePrefix}`;
|
|
22
|
+
pluginInfix = scope.includes("backstage") ? "plugin-" : "backstage-plugin-";
|
|
23
|
+
}
|
|
24
|
+
if (isPrivate === false || // set to false with --no-private flag
|
|
25
|
+
Object.values(otherGlobals).filter(Boolean).length !== 0) {
|
|
26
|
+
console.warn(
|
|
27
|
+
`Global template configuration via CLI flags is deprecated, see https://backstage.io/docs/cli/new for information on how to configure package templating`
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
await createNewPackage.createNewPackage({
|
|
31
|
+
prefilledParams,
|
|
32
|
+
preselectedTemplateId,
|
|
33
|
+
configOverrides: {
|
|
34
|
+
license: otherGlobals.license,
|
|
35
|
+
version: otherGlobals.baseVersion,
|
|
36
|
+
private: isPrivate,
|
|
37
|
+
publishRegistry: otherGlobals.npmRegistry,
|
|
38
|
+
packageNamePrefix: packagePrefix,
|
|
39
|
+
packageNamePluginInfix: pluginInfix
|
|
40
|
+
},
|
|
41
|
+
skipInstall
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
function parseParams(optionStrings) {
|
|
20
45
|
const options = {};
|
|
21
46
|
for (const str of optionStrings) {
|
|
22
47
|
const [key] = str.split("=", 1);
|
|
@@ -30,72 +55,6 @@ function parseOptions(optionStrings) {
|
|
|
30
55
|
}
|
|
31
56
|
return options;
|
|
32
57
|
}
|
|
33
|
-
var _new = async (opts) => {
|
|
34
|
-
const factory = await FactoryRegistry.FactoryRegistry.interactiveSelect(opts.select);
|
|
35
|
-
const providedOptions = parseOptions(opts.option);
|
|
36
|
-
const options = await FactoryRegistry.FactoryRegistry.populateOptions(
|
|
37
|
-
factory,
|
|
38
|
-
providedOptions
|
|
39
|
-
);
|
|
40
|
-
let defaultVersion = "0.1.0";
|
|
41
|
-
if (opts.baseVersion) {
|
|
42
|
-
defaultVersion = opts.baseVersion;
|
|
43
|
-
} else {
|
|
44
|
-
const lernaVersion = await fs__default.default.readJson(paths.paths.resolveTargetRoot("lerna.json")).then((pkg) => pkg.version).catch(() => void 0);
|
|
45
|
-
if (lernaVersion) {
|
|
46
|
-
defaultVersion = lernaVersion;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
const tempDirs = new Array();
|
|
50
|
-
async function createTemporaryDirectory(name) {
|
|
51
|
-
const dir = await fs__default.default.mkdtemp(path.join(os__default.default.tmpdir(), name));
|
|
52
|
-
tempDirs.push(dir);
|
|
53
|
-
return dir;
|
|
54
|
-
}
|
|
55
|
-
const license = opts.license ?? "Apache-2.0";
|
|
56
|
-
let modified = false;
|
|
57
|
-
try {
|
|
58
|
-
await factory.create(options, {
|
|
59
|
-
isMonoRepo: await cliNode.isMonoRepo(),
|
|
60
|
-
defaultVersion,
|
|
61
|
-
license,
|
|
62
|
-
scope: opts.scope?.replace(/^@/, ""),
|
|
63
|
-
npmRegistry: opts.npmRegistry,
|
|
64
|
-
private: Boolean(opts.private),
|
|
65
|
-
createTemporaryDirectory,
|
|
66
|
-
markAsModified() {
|
|
67
|
-
modified = true;
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
tasks.Task.log();
|
|
71
|
-
tasks.Task.log(`\u{1F389} Successfully created ${factory.name}`);
|
|
72
|
-
tasks.Task.log();
|
|
73
|
-
} catch (error) {
|
|
74
|
-
errors.assertError(error);
|
|
75
|
-
tasks.Task.error(error.message);
|
|
76
|
-
if (modified) {
|
|
77
|
-
tasks.Task.log("It seems that something went wrong in the creation process \u{1F914}");
|
|
78
|
-
tasks.Task.log();
|
|
79
|
-
tasks.Task.log(
|
|
80
|
-
"We have left the changes that were made intact in case you want to"
|
|
81
|
-
);
|
|
82
|
-
tasks.Task.log(
|
|
83
|
-
"continue manually, but you can also revert the changes and try again."
|
|
84
|
-
);
|
|
85
|
-
tasks.Task.error(`\u{1F525} Failed to create ${factory.name}!`);
|
|
86
|
-
}
|
|
87
|
-
} finally {
|
|
88
|
-
for (const dir of tempDirs) {
|
|
89
|
-
try {
|
|
90
|
-
await fs__default.default.remove(dir);
|
|
91
|
-
} catch (error) {
|
|
92
|
-
console.error(
|
|
93
|
-
`Failed to remove temporary directory '${dir}', ${error}`
|
|
94
|
-
);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
};
|
|
99
58
|
|
|
100
59
|
exports.default = _new;
|
|
101
60
|
//# sourceMappingURL=new.cjs.js.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var collectPortableTemplateInput = require('./preparation/collectPortableTemplateInput.cjs.js');
|
|
4
|
+
var loadPortableTemplateConfig = require('./preparation/loadPortableTemplateConfig.cjs.js');
|
|
5
|
+
var selectTemplateInteractively = require('./preparation/selectTemplateInteractively.cjs.js');
|
|
6
|
+
var loadPortableTemplate = require('./preparation/loadPortableTemplate.cjs.js');
|
|
7
|
+
var executePortableTemplate = require('./execution/executePortableTemplate.cjs.js');
|
|
8
|
+
|
|
9
|
+
async function createNewPackage(options) {
|
|
10
|
+
const config = await loadPortableTemplateConfig.loadPortableTemplateConfig({
|
|
11
|
+
overrides: options.configOverrides
|
|
12
|
+
});
|
|
13
|
+
const selectedTemplate = await selectTemplateInteractively.selectTemplateInteractively(
|
|
14
|
+
config,
|
|
15
|
+
options.preselectedTemplateId
|
|
16
|
+
);
|
|
17
|
+
const template = await loadPortableTemplate.loadPortableTemplate(selectedTemplate);
|
|
18
|
+
const input = await collectPortableTemplateInput.collectPortableTemplateInput({
|
|
19
|
+
config,
|
|
20
|
+
template,
|
|
21
|
+
prefilledParams: options.prefilledParams
|
|
22
|
+
});
|
|
23
|
+
await executePortableTemplate.executePortableTemplate({
|
|
24
|
+
config,
|
|
25
|
+
template,
|
|
26
|
+
input,
|
|
27
|
+
skipInstall: options.skipInstall
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
exports.createNewPackage = createNewPackage;
|
|
32
|
+
//# sourceMappingURL=createNewPackage.cjs.js.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const defaultTemplates = [
|
|
4
|
+
"@backstage/cli/templates/frontend-plugin",
|
|
5
|
+
"@backstage/cli/templates/backend-plugin",
|
|
6
|
+
"@backstage/cli/templates/backend-plugin-module",
|
|
7
|
+
"@backstage/cli/templates/plugin-web-library",
|
|
8
|
+
"@backstage/cli/templates/plugin-node-library",
|
|
9
|
+
"@backstage/cli/templates/plugin-common-library",
|
|
10
|
+
"@backstage/cli/templates/web-library",
|
|
11
|
+
"@backstage/cli/templates/node-library",
|
|
12
|
+
"@backstage/cli/templates/scaffolder-backend-module"
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
exports.defaultTemplates = defaultTemplates;
|
|
16
|
+
//# sourceMappingURL=defaultTemplates.cjs.js.map
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var handlebars = require('handlebars');
|
|
4
|
+
var camelCase = require('lodash/camelCase');
|
|
5
|
+
var kebabCase = require('lodash/kebabCase');
|
|
6
|
+
var lowerCase = require('lodash/lowerCase');
|
|
7
|
+
var snakeCase = require('lodash/snakeCase');
|
|
8
|
+
var startCase = require('lodash/startCase');
|
|
9
|
+
var upperCase = require('lodash/upperCase');
|
|
10
|
+
var upperFirst = require('lodash/upperFirst');
|
|
11
|
+
var lowerFirst = require('lodash/lowerFirst');
|
|
12
|
+
var Lockfile = require('../../versioning/Lockfile.cjs.js');
|
|
13
|
+
require('minimatch');
|
|
14
|
+
require('@manypkg/get-packages');
|
|
15
|
+
require('chalk');
|
|
16
|
+
require('../../yarn.cjs.js');
|
|
17
|
+
require('../../run.cjs.js');
|
|
18
|
+
var paths = require('../../paths.cjs.js');
|
|
19
|
+
var version = require('../../version.cjs.js');
|
|
20
|
+
|
|
21
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
22
|
+
|
|
23
|
+
var handlebars__default = /*#__PURE__*/_interopDefaultCompat(handlebars);
|
|
24
|
+
var camelCase__default = /*#__PURE__*/_interopDefaultCompat(camelCase);
|
|
25
|
+
var kebabCase__default = /*#__PURE__*/_interopDefaultCompat(kebabCase);
|
|
26
|
+
var lowerCase__default = /*#__PURE__*/_interopDefaultCompat(lowerCase);
|
|
27
|
+
var snakeCase__default = /*#__PURE__*/_interopDefaultCompat(snakeCase);
|
|
28
|
+
var startCase__default = /*#__PURE__*/_interopDefaultCompat(startCase);
|
|
29
|
+
var upperCase__default = /*#__PURE__*/_interopDefaultCompat(upperCase);
|
|
30
|
+
var upperFirst__default = /*#__PURE__*/_interopDefaultCompat(upperFirst);
|
|
31
|
+
var lowerFirst__default = /*#__PURE__*/_interopDefaultCompat(lowerFirst);
|
|
32
|
+
|
|
33
|
+
const builtInHelpers = {
|
|
34
|
+
camelCase: camelCase__default.default,
|
|
35
|
+
kebabCase: kebabCase__default.default,
|
|
36
|
+
lowerCase: lowerCase__default.default,
|
|
37
|
+
snakeCase: snakeCase__default.default,
|
|
38
|
+
startCase: startCase__default.default,
|
|
39
|
+
upperCase: upperCase__default.default,
|
|
40
|
+
upperFirst: upperFirst__default.default,
|
|
41
|
+
lowerFirst: lowerFirst__default.default
|
|
42
|
+
};
|
|
43
|
+
class PortableTemplater {
|
|
44
|
+
static async create(options = {}) {
|
|
45
|
+
let lockfile;
|
|
46
|
+
try {
|
|
47
|
+
lockfile = await Lockfile.Lockfile.load(paths.paths.resolveTargetRoot("yarn.lock"));
|
|
48
|
+
} catch {
|
|
49
|
+
}
|
|
50
|
+
const versionProvider = version.createPackageVersionProvider(lockfile);
|
|
51
|
+
const templater = new PortableTemplater(
|
|
52
|
+
{
|
|
53
|
+
versionQuery(name, versionHint) {
|
|
54
|
+
return versionProvider(
|
|
55
|
+
name,
|
|
56
|
+
typeof versionHint === "string" ? versionHint : void 0
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
options.values ?? {}
|
|
61
|
+
);
|
|
62
|
+
if (options.templatedValues) {
|
|
63
|
+
templater.appendTemplatedValues(options.templatedValues);
|
|
64
|
+
}
|
|
65
|
+
return templater;
|
|
66
|
+
}
|
|
67
|
+
#templater;
|
|
68
|
+
#values;
|
|
69
|
+
constructor(helpers, values) {
|
|
70
|
+
this.#templater = handlebars__default.default.create();
|
|
71
|
+
this.#templater.registerHelper(builtInHelpers);
|
|
72
|
+
if (helpers) {
|
|
73
|
+
this.#templater.registerHelper(helpers);
|
|
74
|
+
}
|
|
75
|
+
this.#values = values;
|
|
76
|
+
}
|
|
77
|
+
template(content) {
|
|
78
|
+
return this.#templater.compile(content, {
|
|
79
|
+
strict: true
|
|
80
|
+
})(this.#values);
|
|
81
|
+
}
|
|
82
|
+
appendTemplatedValues(record) {
|
|
83
|
+
const newValues = Object.fromEntries(
|
|
84
|
+
Object.entries(record).map(([key, value]) => [key, this.template(value)])
|
|
85
|
+
);
|
|
86
|
+
this.#values = { ...this.#values, ...newValues };
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
exports.PortableTemplater = PortableTemplater;
|
|
91
|
+
//# sourceMappingURL=PortableTemplater.cjs.js.map
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var errors = require('@backstage/errors');
|
|
4
|
+
var codeowners = require('../../codeowners/codeowners.cjs.js');
|
|
5
|
+
var tasks = require('../../tasks.cjs.js');
|
|
6
|
+
var installNewPackage = require('./installNewPackage.cjs.js');
|
|
7
|
+
var writeTemplateContents = require('./writeTemplateContents.cjs.js');
|
|
8
|
+
|
|
9
|
+
async function executePortableTemplate(options) {
|
|
10
|
+
const { template, input } = options;
|
|
11
|
+
let modified = false;
|
|
12
|
+
try {
|
|
13
|
+
const { targetDir } = await tasks.Task.forItem(
|
|
14
|
+
"templating",
|
|
15
|
+
input.packagePath,
|
|
16
|
+
() => writeTemplateContents.writeTemplateContents(template, input)
|
|
17
|
+
);
|
|
18
|
+
modified = true;
|
|
19
|
+
await installNewPackage.installNewPackage(input);
|
|
20
|
+
if (input.owner) {
|
|
21
|
+
await codeowners.addCodeownersEntry(targetDir, input.owner);
|
|
22
|
+
}
|
|
23
|
+
if (!options.skipInstall) {
|
|
24
|
+
await tasks.Task.forCommand("yarn install", {
|
|
25
|
+
cwd: targetDir,
|
|
26
|
+
optional: true
|
|
27
|
+
});
|
|
28
|
+
await tasks.Task.forCommand("yarn lint --fix", {
|
|
29
|
+
cwd: targetDir,
|
|
30
|
+
optional: true
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
tasks.Task.log();
|
|
34
|
+
tasks.Task.log(`\u{1F389} Successfully created ${template.name}`);
|
|
35
|
+
tasks.Task.log();
|
|
36
|
+
} catch (error) {
|
|
37
|
+
errors.assertError(error);
|
|
38
|
+
tasks.Task.error(error.message);
|
|
39
|
+
if (modified) {
|
|
40
|
+
tasks.Task.log("It seems that something went wrong in the creation process \u{1F914}");
|
|
41
|
+
tasks.Task.log();
|
|
42
|
+
tasks.Task.log(
|
|
43
|
+
"We have left the changes that were made intact in case you want to"
|
|
44
|
+
);
|
|
45
|
+
tasks.Task.log(
|
|
46
|
+
"continue manually, but you can also revert the changes and try again."
|
|
47
|
+
);
|
|
48
|
+
tasks.Task.error(`\u{1F525} Failed to create ${template.name}!`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
exports.executePortableTemplate = executePortableTemplate;
|
|
54
|
+
//# sourceMappingURL=executePortableTemplate.cjs.js.map
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var fs = require('fs-extra');
|
|
4
|
+
var upperFirst = require('lodash/upperFirst');
|
|
5
|
+
var camelCase = require('lodash/camelCase');
|
|
6
|
+
var paths = require('../../paths.cjs.js');
|
|
7
|
+
var tasks = require('../../tasks.cjs.js');
|
|
8
|
+
|
|
9
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
10
|
+
|
|
11
|
+
var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
|
|
12
|
+
var upperFirst__default = /*#__PURE__*/_interopDefaultCompat(upperFirst);
|
|
13
|
+
var camelCase__default = /*#__PURE__*/_interopDefaultCompat(camelCase);
|
|
14
|
+
|
|
15
|
+
async function installNewPackage(input) {
|
|
16
|
+
switch (input.roleParams.role) {
|
|
17
|
+
case "web-library":
|
|
18
|
+
case "node-library":
|
|
19
|
+
case "common-library":
|
|
20
|
+
case "plugin-web-library":
|
|
21
|
+
case "plugin-node-library":
|
|
22
|
+
case "plugin-common-library":
|
|
23
|
+
return;
|
|
24
|
+
// No installation action needed for library packages
|
|
25
|
+
case "frontend-plugin":
|
|
26
|
+
await addDependency(input, "package/app/package.json");
|
|
27
|
+
await tryAddFrontendLegacy(input);
|
|
28
|
+
return;
|
|
29
|
+
case "frontend-plugin-module":
|
|
30
|
+
await addDependency(input, "package/app/package.json");
|
|
31
|
+
return;
|
|
32
|
+
case "backend-plugin":
|
|
33
|
+
await addDependency(input, "package/backend/package.json");
|
|
34
|
+
await tryAddBackend(input);
|
|
35
|
+
return;
|
|
36
|
+
case "backend-plugin-module":
|
|
37
|
+
await addDependency(input, "package/backend/package.json");
|
|
38
|
+
await tryAddBackend(input);
|
|
39
|
+
return;
|
|
40
|
+
default:
|
|
41
|
+
throw new Error(
|
|
42
|
+
`Unsupported role ${input.roleParams.role}`
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
async function addDependency(input, path) {
|
|
47
|
+
const pkgJsonPath = paths.paths.resolveTargetRoot(path);
|
|
48
|
+
const pkgJson = await fs__default.default.readJson(pkgJsonPath).catch((error) => {
|
|
49
|
+
if (error.code === "ENOENT") {
|
|
50
|
+
return void 0;
|
|
51
|
+
}
|
|
52
|
+
throw error;
|
|
53
|
+
});
|
|
54
|
+
if (!pkgJson) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
pkgJson.dependencies = {
|
|
59
|
+
...pkgJson.dependencies,
|
|
60
|
+
[input.packageName]: `workspace:^`
|
|
61
|
+
};
|
|
62
|
+
await fs__default.default.writeJson(path, pkgJson, { spaces: 2 });
|
|
63
|
+
} catch (error) {
|
|
64
|
+
throw new Error(`Failed to add package dependencies, ${error}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
async function tryAddFrontendLegacy(input) {
|
|
68
|
+
const { roleParams } = input;
|
|
69
|
+
if (roleParams.role !== "frontend-plugin") {
|
|
70
|
+
throw new Error(
|
|
71
|
+
"add-frontend-legacy can only be used for frontend plugins"
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
const appDefinitionPath = paths.paths.resolveTargetRoot("packages/app/src/App.tsx");
|
|
75
|
+
if (!await fs__default.default.pathExists(appDefinitionPath)) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
await tasks.Task.forItem("app", "adding import", async () => {
|
|
79
|
+
const content = await fs__default.default.readFile(appDefinitionPath, "utf8");
|
|
80
|
+
const revLines = content.split("\n").reverse();
|
|
81
|
+
const lastImportIndex = revLines.findIndex(
|
|
82
|
+
(line) => line.match(/ from ("|').*("|')/)
|
|
83
|
+
);
|
|
84
|
+
const lastRouteIndex = revLines.findIndex(
|
|
85
|
+
(line) => line.match(/<\/FlatRoutes/)
|
|
86
|
+
);
|
|
87
|
+
if (lastImportIndex !== -1 && lastRouteIndex !== -1) {
|
|
88
|
+
const extensionName = upperFirst__default.default(`${camelCase__default.default(roleParams.pluginId)}Page`);
|
|
89
|
+
const importLine = `import { ${extensionName} } from '${input.packageName}';`;
|
|
90
|
+
if (!content.includes(importLine)) {
|
|
91
|
+
revLines.splice(lastImportIndex, 0, importLine);
|
|
92
|
+
}
|
|
93
|
+
const componentLine = `<Route path="/${roleParams.pluginId}" element={<${extensionName} />} />`;
|
|
94
|
+
if (!content.includes(componentLine)) {
|
|
95
|
+
const [indentation] = revLines[lastRouteIndex + 1].match(/^\s*/) ?? [];
|
|
96
|
+
revLines.splice(lastRouteIndex + 1, 0, indentation + componentLine);
|
|
97
|
+
}
|
|
98
|
+
const newContent = revLines.reverse().join("\n");
|
|
99
|
+
await fs__default.default.writeFile(appDefinitionPath, newContent, "utf8");
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
async function tryAddBackend(input) {
|
|
104
|
+
const backendIndexPath = paths.paths.resolveTargetRoot(
|
|
105
|
+
"packages/backend/src/index.ts"
|
|
106
|
+
);
|
|
107
|
+
if (!await fs__default.default.pathExists(backendIndexPath)) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
await tasks.Task.forItem("backend", `adding ${input.packageName}`, async () => {
|
|
111
|
+
const content = await fs__default.default.readFile(backendIndexPath, "utf8");
|
|
112
|
+
const lines = content.split("\n");
|
|
113
|
+
const backendAddLine = `backend.add(import('${input.packageName}'));`;
|
|
114
|
+
const backendStartIndex = lines.findIndex(
|
|
115
|
+
(line) => line.match(/backend.start/)
|
|
116
|
+
);
|
|
117
|
+
if (backendStartIndex !== -1) {
|
|
118
|
+
const [indentation] = lines[backendStartIndex].match(/^\s*/);
|
|
119
|
+
lines.splice(backendStartIndex, 0, `${indentation}${backendAddLine}`);
|
|
120
|
+
const newContent = lines.join("\n");
|
|
121
|
+
await fs__default.default.writeFile(backendIndexPath, newContent, "utf8");
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
exports.installNewPackage = installNewPackage;
|
|
127
|
+
//# sourceMappingURL=installNewPackage.cjs.js.map
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var fs = require('fs-extra');
|
|
4
|
+
var path = require('path');
|
|
5
|
+
var paths = require('../../paths.cjs.js');
|
|
6
|
+
var errors = require('@backstage/errors');
|
|
7
|
+
var cliNode = require('@backstage/cli-node');
|
|
8
|
+
var PortableTemplater = require('./PortableTemplater.cjs.js');
|
|
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
|
+
|
|
14
|
+
async function writeTemplateContents(template, input) {
|
|
15
|
+
const targetDir = paths.paths.resolveTargetRoot(input.packagePath);
|
|
16
|
+
if (await fs__default.default.pathExists(targetDir)) {
|
|
17
|
+
throw new errors.InputError(`Package '${input.packagePath}' already exists`);
|
|
18
|
+
}
|
|
19
|
+
try {
|
|
20
|
+
const isMonoRepo = await cliNode.isMonoRepo();
|
|
21
|
+
const { role, ...roleValues } = input.roleParams;
|
|
22
|
+
const templater = await PortableTemplater.PortableTemplater.create({
|
|
23
|
+
values: {
|
|
24
|
+
...roleValues,
|
|
25
|
+
packageName: input.packageName
|
|
26
|
+
},
|
|
27
|
+
templatedValues: template.values
|
|
28
|
+
});
|
|
29
|
+
if (!isMonoRepo) {
|
|
30
|
+
await fs__default.default.writeJson(
|
|
31
|
+
path.resolve(targetDir, "tsconfig.json"),
|
|
32
|
+
{
|
|
33
|
+
extends: "@backstage/cli/config/tsconfig.json",
|
|
34
|
+
include: ["src", "dev", "migrations"],
|
|
35
|
+
exclude: ["node_modules"],
|
|
36
|
+
compilerOptions: {
|
|
37
|
+
outDir: "dist-types",
|
|
38
|
+
rootDir: "."
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
{ spaces: 2 }
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
for (const file of template.files) {
|
|
45
|
+
const destPath = path.resolve(targetDir, file.path);
|
|
46
|
+
await fs__default.default.ensureDir(path.dirname(destPath));
|
|
47
|
+
let content = file.syntax === "handlebars" ? templater.template(file.content) : file.content;
|
|
48
|
+
if (file.path === "package.json") {
|
|
49
|
+
try {
|
|
50
|
+
content = injectPackageJsonInput(input, content);
|
|
51
|
+
} catch (error) {
|
|
52
|
+
throw new errors.ForwardedError(
|
|
53
|
+
"Failed to transform templated package.json",
|
|
54
|
+
error
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
await fs__default.default.writeFile(destPath, content).catch((error) => {
|
|
59
|
+
throw new errors.ForwardedError(`Failed to copy file to ${destPath}`, error);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
return { targetDir };
|
|
63
|
+
} catch (error) {
|
|
64
|
+
await fs__default.default.rm(targetDir, { recursive: true, force: true, maxRetries: 10 });
|
|
65
|
+
throw error;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function injectPackageJsonInput(input, content) {
|
|
69
|
+
const pkgJson = JSON.parse(content);
|
|
70
|
+
const toAdd = new Array();
|
|
71
|
+
if (pkgJson.version) {
|
|
72
|
+
pkgJson.version = input.version;
|
|
73
|
+
} else {
|
|
74
|
+
toAdd.push(["version", input.version]);
|
|
75
|
+
}
|
|
76
|
+
if (pkgJson.license) {
|
|
77
|
+
pkgJson.license = input.license;
|
|
78
|
+
} else {
|
|
79
|
+
toAdd.push(["license", input.license]);
|
|
80
|
+
}
|
|
81
|
+
if (input.private) {
|
|
82
|
+
if (pkgJson.private === false) {
|
|
83
|
+
pkgJson.private = true;
|
|
84
|
+
} else if (!pkgJson.private) {
|
|
85
|
+
toAdd.push(["private", true]);
|
|
86
|
+
}
|
|
87
|
+
} else {
|
|
88
|
+
delete pkgJson.private;
|
|
89
|
+
}
|
|
90
|
+
if (input.publishRegistry) {
|
|
91
|
+
if (pkgJson.publishConfig) {
|
|
92
|
+
pkgJson.publishConfig = {
|
|
93
|
+
...pkgJson.publishConfig,
|
|
94
|
+
registry: input.publishRegistry
|
|
95
|
+
};
|
|
96
|
+
} else {
|
|
97
|
+
toAdd.push(["publishConfig", { registry: input.publishRegistry }]);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
const entries = Object.entries(pkgJson);
|
|
101
|
+
const nameIndex = entries.findIndex(([name]) => name === "name");
|
|
102
|
+
if (nameIndex === -1) {
|
|
103
|
+
throw new Error("templated package.json does not contain a name field");
|
|
104
|
+
}
|
|
105
|
+
entries.splice(nameIndex + 1, 0, ...toAdd);
|
|
106
|
+
return JSON.stringify(Object.fromEntries(entries), null, 2);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
exports.injectPackageJsonInput = injectPackageJsonInput;
|
|
110
|
+
exports.writeTemplateContents = writeTemplateContents;
|
|
111
|
+
//# sourceMappingURL=writeTemplateContents.cjs.js.map
|