@backstage/cli 0.29.0-next.0 → 0.29.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 +29 -0
- package/config/jest.js +8 -4
- package/dist/commands/repo/lint.cjs.js +9 -5
- package/dist/commands/repo/test.cjs.js +47 -16
- package/dist/lib/cache/SuccessCache.cjs.js +9 -0
- 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 -3
- package/dist/packages/core-components/package.json.cjs.js +1 -1
- package/dist/packages/dev-utils/package.json.cjs.js +1 -1
- package/dist/packages/test-utils/package.json.cjs.js +1 -1
- package/dist/packages/theme/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 +17 -17
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# @backstage/cli
|
|
2
2
|
|
|
3
|
+
## 0.29.0-next.1
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 6819f8c: Added a new optimization to the `repo test` command that will filter out unused packages in watch mode if all provide filters are paths that point from the repo root. This significantly speeds up running individual tests from the repo root in a large workspace, for example:
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
yarn test packages/app/src/App.test.tsx
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- 4046d53: Fixed an issue where the `--successCache` option for the `repo test` and `repo lint` commands would be include the workspace path in generated cache keys. This previously broke caching in environments where the workspace path varies across builds.
|
|
16
|
+
- 6b2888c: Fixed an issue with the `--successCache` flag for `repo test` where the tree hash for the wrong package directory would sometimes be used to generate the cache key.
|
|
17
|
+
- 6266ed3: Updated dependency `del` to `^8.0.0`.
|
|
18
|
+
- 4046d53: Fixed an issue with the `repo lint` command where the cache key for the `--successCache` option would not properly ignore files that should be ignored according to `.eslintignore`s.
|
|
19
|
+
- 702f41d: Bumped dev dependencies `@types/node`
|
|
20
|
+
- Updated dependencies
|
|
21
|
+
- @backstage/cli-common@0.1.15-next.0
|
|
22
|
+
- @backstage/catalog-model@1.7.0
|
|
23
|
+
- @backstage/cli-node@0.2.10-next.0
|
|
24
|
+
- @backstage/config@1.2.0
|
|
25
|
+
- @backstage/config-loader@1.9.2-next.0
|
|
26
|
+
- @backstage/errors@1.2.4
|
|
27
|
+
- @backstage/eslint-plugin@0.1.10
|
|
28
|
+
- @backstage/integration@1.15.1
|
|
29
|
+
- @backstage/release-manifests@0.0.11
|
|
30
|
+
- @backstage/types@1.1.1
|
|
31
|
+
|
|
3
32
|
## 0.29.0-next.0
|
|
4
33
|
|
|
5
34
|
### Minor Changes
|
package/config/jest.js
CHANGED
|
@@ -264,7 +264,7 @@ async function getProjectConfig(targetPath, extraConfig, extraOptions) {
|
|
|
264
264
|
.createHash('sha256')
|
|
265
265
|
.update(version)
|
|
266
266
|
.update(Buffer.alloc(1))
|
|
267
|
-
.update(JSON.stringify(config.transform))
|
|
267
|
+
.update(JSON.stringify(config.transform).replaceAll(paths.targetRoot, ''))
|
|
268
268
|
.digest('hex');
|
|
269
269
|
config.id = `backstage_cli_${configHash}`;
|
|
270
270
|
}
|
|
@@ -326,7 +326,7 @@ async function getRootConfig() {
|
|
|
326
326
|
),
|
|
327
327
|
).then(_ => _.flat());
|
|
328
328
|
|
|
329
|
-
let
|
|
329
|
+
let projects = await Promise.all(
|
|
330
330
|
projectPaths.flat().map(async projectPath => {
|
|
331
331
|
const packagePath = path.resolve(projectPath, 'package.json');
|
|
332
332
|
if (!(await fs.pathExists(packagePath))) {
|
|
@@ -357,12 +357,16 @@ async function getRootConfig() {
|
|
|
357
357
|
|
|
358
358
|
const cache = global.__backstageCli_jestSuccessCache;
|
|
359
359
|
if (cache) {
|
|
360
|
-
|
|
360
|
+
projects = await cache.filterConfigs(projects, globalRootConfig);
|
|
361
|
+
}
|
|
362
|
+
const watchProjectFilter = global.__backstageCli_watchProjectFilter;
|
|
363
|
+
if (watchProjectFilter) {
|
|
364
|
+
projects = await watchProjectFilter.filter(projects);
|
|
361
365
|
}
|
|
362
366
|
|
|
363
367
|
return {
|
|
364
368
|
rootDir: paths.targetRoot,
|
|
365
|
-
projects
|
|
369
|
+
projects,
|
|
366
370
|
testResultsProcessor: cache
|
|
367
371
|
? require.resolve('./jestCacheResultProcessor.cjs')
|
|
368
372
|
: undefined,
|
|
@@ -89,7 +89,7 @@ async function command(opts, cmd) {
|
|
|
89
89
|
const crypto = require("crypto");
|
|
90
90
|
const globby = require("globby");
|
|
91
91
|
const { readFile } = require("fs/promises");
|
|
92
|
-
const
|
|
92
|
+
const workerPath = require("path");
|
|
93
93
|
return async ({
|
|
94
94
|
fullDir,
|
|
95
95
|
relativeDir,
|
|
@@ -114,15 +114,19 @@ async function command(opts, cmd) {
|
|
|
114
114
|
hash.update(parentHash);
|
|
115
115
|
hash.update("\0");
|
|
116
116
|
for (const path of result.sort()) {
|
|
117
|
-
|
|
117
|
+
const absPath = workerPath.resolve(rootDir, path);
|
|
118
|
+
const pathInPackage = workerPath.relative(fullDir, absPath);
|
|
119
|
+
if (await eslint.isPathIgnored(pathInPackage)) {
|
|
118
120
|
continue;
|
|
119
121
|
}
|
|
120
|
-
hash.update(
|
|
122
|
+
hash.update(pathInPackage);
|
|
121
123
|
hash.update("\0");
|
|
122
|
-
hash.update(await readFile(
|
|
124
|
+
hash.update(await readFile(absPath));
|
|
123
125
|
hash.update("\0");
|
|
124
126
|
hash.update(
|
|
125
|
-
JSON.stringify(
|
|
127
|
+
JSON.stringify(
|
|
128
|
+
await eslint.calculateConfigForFile(pathInPackage)
|
|
129
|
+
).replaceAll(rootDir, "")
|
|
126
130
|
);
|
|
127
131
|
hash.update("\0");
|
|
128
132
|
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
var os = require('os');
|
|
4
4
|
var crypto = require('node:crypto');
|
|
5
5
|
var yargs = require('yargs');
|
|
6
|
+
var jestCli = require('jest-cli');
|
|
6
7
|
var path = require('path');
|
|
7
8
|
var cliNode = require('@backstage/cli-node');
|
|
8
9
|
var paths = require('../../lib/paths.cjs.js');
|
|
@@ -17,23 +18,30 @@ var crypto__default = /*#__PURE__*/_interopDefaultCompat(crypto);
|
|
|
17
18
|
var yargs__default = /*#__PURE__*/_interopDefaultCompat(yargs);
|
|
18
19
|
|
|
19
20
|
async function readPackageTreeHashes(graph) {
|
|
20
|
-
const pkgs = Array.from(graph.values())
|
|
21
|
+
const pkgs = Array.from(graph.values()).map((pkg) => ({
|
|
22
|
+
...pkg,
|
|
23
|
+
path: path.relative(paths.paths.targetRoot, pkg.dir)
|
|
24
|
+
}));
|
|
21
25
|
const output = await run.runPlain(
|
|
22
26
|
"git",
|
|
23
27
|
"ls-tree",
|
|
24
|
-
|
|
28
|
+
'--format="%(objectname)=%(path)"',
|
|
25
29
|
"HEAD",
|
|
26
30
|
"--",
|
|
27
|
-
...pkgs.map((pkg) =>
|
|
31
|
+
...pkgs.map((pkg) => pkg.path)
|
|
28
32
|
);
|
|
29
|
-
const treeShaList = output.trim().split(/\r?\n/);
|
|
30
|
-
if (treeShaList.length !== pkgs.length) {
|
|
31
|
-
throw new Error(
|
|
32
|
-
`Error listing project git tree hashes, output length does not equal input length`
|
|
33
|
-
);
|
|
34
|
-
}
|
|
35
33
|
const map = new Map(
|
|
36
|
-
|
|
34
|
+
output.trim().split(/\r?\n/).map((line) => {
|
|
35
|
+
const [itemSha, ...itemPathParts] = line.split("=");
|
|
36
|
+
const itemPath = itemPathParts.join("=");
|
|
37
|
+
const pkg = pkgs.find((p) => p.path === itemPath);
|
|
38
|
+
if (!pkg) {
|
|
39
|
+
throw new Error(
|
|
40
|
+
`Unexpectedly missing tree sha entry for path ${itemPath}`
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
return [pkg.packageJson.name, itemSha];
|
|
44
|
+
})
|
|
37
45
|
);
|
|
38
46
|
return (pkgName) => {
|
|
39
47
|
const sha = map.get(pkgName);
|
|
@@ -83,6 +91,7 @@ function removeOptionArg(args, option, size = 2) {
|
|
|
83
91
|
} while (changed);
|
|
84
92
|
}
|
|
85
93
|
async function command(opts, cmd) {
|
|
94
|
+
const testGlobal = global;
|
|
86
95
|
let parent = cmd;
|
|
87
96
|
while (parent.parent) {
|
|
88
97
|
parent = parent.parent;
|
|
@@ -90,21 +99,44 @@ async function command(opts, cmd) {
|
|
|
90
99
|
const allArgs = parent.args;
|
|
91
100
|
const args = allArgs.slice(allArgs.indexOf("test") + 1);
|
|
92
101
|
const hasFlags = createFlagFinder(args);
|
|
102
|
+
const { _: parsedArgs } = await yargs__default.default(args).options(jestCli.yargsOptions).argv;
|
|
93
103
|
if (!hasFlags("-c", "--config")) {
|
|
94
104
|
args.push("--config", paths.paths.resolveOwn("config/jest.js"));
|
|
95
105
|
}
|
|
96
106
|
if (!hasFlags("--passWithNoTests")) {
|
|
97
107
|
args.push("--passWithNoTests");
|
|
98
108
|
}
|
|
109
|
+
let isSingleWatchMode = args.includes("--watch");
|
|
99
110
|
if (!opts.since && !process.env.CI && !hasFlags("--coverage", "--watch", "--watchAll")) {
|
|
100
111
|
const isGitRepo = () => run.runCheck("git", "rev-parse", "--is-inside-work-tree");
|
|
101
112
|
const isMercurialRepo = () => run.runCheck("hg", "--cwd", ".", "root");
|
|
102
113
|
if (await isGitRepo() || await isMercurialRepo()) {
|
|
114
|
+
isSingleWatchMode = true;
|
|
103
115
|
args.push("--watch");
|
|
104
116
|
} else {
|
|
105
117
|
args.push("--watchAll");
|
|
106
118
|
}
|
|
107
119
|
}
|
|
120
|
+
if (isSingleWatchMode && parsedArgs.length > 0) {
|
|
121
|
+
testGlobal.__backstageCli_watchProjectFilter = {
|
|
122
|
+
async filter(projectConfigs) {
|
|
123
|
+
const selectedProjects2 = [];
|
|
124
|
+
const usedArgs = /* @__PURE__ */ new Set();
|
|
125
|
+
for (const project of projectConfigs) {
|
|
126
|
+
for (const arg of parsedArgs) {
|
|
127
|
+
if (cliCommon.isChildPath(project.rootDir, String(arg))) {
|
|
128
|
+
selectedProjects2.push(project);
|
|
129
|
+
usedArgs.add(arg);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (usedArgs.size !== parsedArgs.length) {
|
|
134
|
+
return projectConfigs;
|
|
135
|
+
}
|
|
136
|
+
return selectedProjects2;
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
}
|
|
108
140
|
if (!hasFlags("--workerIdleMemoryLimit")) {
|
|
109
141
|
args.push("--workerIdleMemoryLimit=1000M");
|
|
110
142
|
}
|
|
@@ -153,11 +185,9 @@ async function command(opts, cmd) {
|
|
|
153
185
|
args.push("--help");
|
|
154
186
|
process.stdout._handle.setBlocking(true);
|
|
155
187
|
}
|
|
156
|
-
const jestCli = require("jest-cli");
|
|
157
188
|
if (opts.successCache) {
|
|
158
189
|
removeOptionArg(args, "--successCache", 1);
|
|
159
190
|
removeOptionArg(args, "--successCacheDir");
|
|
160
|
-
const { _: parsedArgs } = await yargs__default.default(args).options(jestCli.yargsOptions).argv;
|
|
161
191
|
if (parsedArgs.length > 0) {
|
|
162
192
|
throw new Error(
|
|
163
193
|
`The --successCache flag can not be combined with the following arguments: ${parsedArgs.join(
|
|
@@ -174,8 +204,7 @@ async function command(opts, cmd) {
|
|
|
174
204
|
const graph = await getPackageGraph();
|
|
175
205
|
const projectHashes = /* @__PURE__ */ new Map();
|
|
176
206
|
const outputSuccessCache = new Array();
|
|
177
|
-
|
|
178
|
-
globalWithCache.__backstageCli_jestSuccessCache = {
|
|
207
|
+
testGlobal.__backstageCli_jestSuccessCache = {
|
|
179
208
|
// This is called by `config/jest.js` after the project configs have been gathered
|
|
180
209
|
async filterConfigs(projectConfigs, globalRootConfig) {
|
|
181
210
|
const cacheEntries = await cache.read();
|
|
@@ -188,7 +217,9 @@ async function command(opts, cmd) {
|
|
|
188
217
|
baseHash.update("\0");
|
|
189
218
|
baseHash.update(process.version);
|
|
190
219
|
baseHash.update("\0");
|
|
191
|
-
baseHash.update(
|
|
220
|
+
baseHash.update(
|
|
221
|
+
SuccessCache.SuccessCache.trimPaths(JSON.stringify(globalRootConfig))
|
|
222
|
+
);
|
|
192
223
|
const baseSha = baseHash.digest("hex");
|
|
193
224
|
return projectConfigs.filter((project) => {
|
|
194
225
|
const packageName = project.displayName;
|
|
@@ -206,7 +237,7 @@ async function command(opts, cmd) {
|
|
|
206
237
|
const depHash = getPackageTreeHash(depPkg.name);
|
|
207
238
|
hash.update(`${depName}:${depHash}`);
|
|
208
239
|
}
|
|
209
|
-
hash.update(JSON.stringify(project));
|
|
240
|
+
hash.update(SuccessCache.SuccessCache.trimPaths(JSON.stringify(project)));
|
|
210
241
|
hash.update(lockfile.getDependencyTreeHash(packageName));
|
|
211
242
|
const sha = hash.digest("hex");
|
|
212
243
|
projectHashes.set(packageName, sha);
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var fs = require('fs-extra');
|
|
4
4
|
var node_path = require('node:path');
|
|
5
|
+
var paths = require('../paths.cjs.js');
|
|
5
6
|
|
|
6
7
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
7
8
|
|
|
@@ -11,6 +12,14 @@ const DEFAULT_CACHE_BASE_PATH = "node_modules/.cache/backstage-cli";
|
|
|
11
12
|
const CACHE_MAX_AGE_MS = 7 * 24 * 36e5;
|
|
12
13
|
class SuccessCache {
|
|
13
14
|
#path;
|
|
15
|
+
/**
|
|
16
|
+
* Trim any occurrences of the workspace root path from the input string. This
|
|
17
|
+
* is useful to ensure stable hashes that don't vary based on the workspace
|
|
18
|
+
* location.
|
|
19
|
+
*/
|
|
20
|
+
static trimPaths(input) {
|
|
21
|
+
return input.replaceAll(paths.paths.targetRoot, "");
|
|
22
|
+
}
|
|
14
23
|
constructor(name, basePath) {
|
|
15
24
|
this.#path = node_path.resolve(basePath ?? DEFAULT_CACHE_BASE_PATH, name);
|
|
16
25
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var version = "0.29.0-next.
|
|
3
|
+
var version = "0.29.0-next.1";
|
|
4
4
|
var dependencies = {
|
|
5
5
|
"@backstage/catalog-model": "workspace:^",
|
|
6
6
|
"@backstage/cli-common": "workspace:^",
|
|
@@ -144,7 +144,7 @@ var devDependencies = {
|
|
|
144
144
|
"@types/fs-extra": "^11.0.0",
|
|
145
145
|
"@types/http-proxy": "^1.17.4",
|
|
146
146
|
"@types/inquirer": "^8.1.3",
|
|
147
|
-
"@types/node": "^
|
|
147
|
+
"@types/node": "^20.16.0",
|
|
148
148
|
"@types/npm-packlist": "^3.0.0",
|
|
149
149
|
"@types/recursive-readdir": "^2.2.0",
|
|
150
150
|
"@types/rollup-plugin-peer-deps-external": "^2.2.0",
|
|
@@ -155,7 +155,7 @@ var devDependencies = {
|
|
|
155
155
|
"@types/webpack-sources": "^3.2.3",
|
|
156
156
|
"@types/yarnpkg__lockfile": "^1.1.4",
|
|
157
157
|
"@vitejs/plugin-react": "^4.3.1",
|
|
158
|
-
del: "^
|
|
158
|
+
del: "^8.0.0",
|
|
159
159
|
msw: "^1.0.0",
|
|
160
160
|
nodemon: "^3.0.1",
|
|
161
161
|
vite: "^5.0.0",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/cli",
|
|
3
|
-
"version": "0.29.0-next.
|
|
3
|
+
"version": "0.29.0-next.1",
|
|
4
4
|
"description": "CLI for developing Backstage plugins and apps",
|
|
5
5
|
"backstage": {
|
|
6
6
|
"role": "cli"
|
|
@@ -43,10 +43,10 @@
|
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"@backstage/catalog-model": "1.7.0",
|
|
46
|
-
"@backstage/cli-common": "0.1.
|
|
47
|
-
"@backstage/cli-node": "0.2.
|
|
46
|
+
"@backstage/cli-common": "0.1.15-next.0",
|
|
47
|
+
"@backstage/cli-node": "0.2.10-next.0",
|
|
48
48
|
"@backstage/config": "1.2.0",
|
|
49
|
-
"@backstage/config-loader": "1.9.
|
|
49
|
+
"@backstage/config-loader": "1.9.2-next.0",
|
|
50
50
|
"@backstage/errors": "1.2.4",
|
|
51
51
|
"@backstage/eslint-plugin": "0.1.10",
|
|
52
52
|
"@backstage/integration": "1.15.1",
|
|
@@ -159,22 +159,22 @@
|
|
|
159
159
|
},
|
|
160
160
|
"devDependencies": {
|
|
161
161
|
"@backstage/backend-common": "^0.25.0",
|
|
162
|
-
"@backstage/backend-plugin-api": "1.0.2-next.
|
|
163
|
-
"@backstage/backend-test-utils": "1.0.3-next.
|
|
162
|
+
"@backstage/backend-plugin-api": "1.0.2-next.1",
|
|
163
|
+
"@backstage/backend-test-utils": "1.0.3-next.1",
|
|
164
164
|
"@backstage/catalog-client": "1.8.0-next.0",
|
|
165
165
|
"@backstage/config": "1.2.0",
|
|
166
166
|
"@backstage/core-app-api": "1.15.1",
|
|
167
|
-
"@backstage/core-components": "0.16.0-next.
|
|
167
|
+
"@backstage/core-components": "0.16.0-next.1",
|
|
168
168
|
"@backstage/core-plugin-api": "1.10.0",
|
|
169
|
-
"@backstage/dev-utils": "1.1.3-next.
|
|
169
|
+
"@backstage/dev-utils": "1.1.3-next.1",
|
|
170
170
|
"@backstage/errors": "1.2.4",
|
|
171
|
-
"@backstage/plugin-auth-backend": "0.24.0-next.
|
|
172
|
-
"@backstage/plugin-auth-backend-module-guest-provider": "0.2.2-next.
|
|
173
|
-
"@backstage/plugin-catalog-node": "1.14.0-next.
|
|
174
|
-
"@backstage/plugin-scaffolder-node": "0.5.1-next.
|
|
175
|
-
"@backstage/plugin-scaffolder-node-test-utils": "0.1.15-next.
|
|
176
|
-
"@backstage/test-utils": "1.7.0",
|
|
177
|
-
"@backstage/theme": "0.6.0",
|
|
171
|
+
"@backstage/plugin-auth-backend": "0.24.0-next.1",
|
|
172
|
+
"@backstage/plugin-auth-backend-module-guest-provider": "0.2.2-next.1",
|
|
173
|
+
"@backstage/plugin-catalog-node": "1.14.0-next.1",
|
|
174
|
+
"@backstage/plugin-scaffolder-node": "0.5.1-next.1",
|
|
175
|
+
"@backstage/plugin-scaffolder-node-test-utils": "0.1.15-next.1",
|
|
176
|
+
"@backstage/test-utils": "1.7.1-next.0",
|
|
177
|
+
"@backstage/theme": "0.6.1-next.0",
|
|
178
178
|
"@rspack/core": "^1.0.10",
|
|
179
179
|
"@rspack/dev-server": "^1.0.9",
|
|
180
180
|
"@rspack/plugin-react-refresh": "^1.0.0",
|
|
@@ -184,7 +184,7 @@
|
|
|
184
184
|
"@types/fs-extra": "^11.0.0",
|
|
185
185
|
"@types/http-proxy": "^1.17.4",
|
|
186
186
|
"@types/inquirer": "^8.1.3",
|
|
187
|
-
"@types/node": "^
|
|
187
|
+
"@types/node": "^20.16.0",
|
|
188
188
|
"@types/npm-packlist": "^3.0.0",
|
|
189
189
|
"@types/recursive-readdir": "^2.2.0",
|
|
190
190
|
"@types/rollup-plugin-peer-deps-external": "^2.2.0",
|
|
@@ -195,7 +195,7 @@
|
|
|
195
195
|
"@types/webpack-sources": "^3.2.3",
|
|
196
196
|
"@types/yarnpkg__lockfile": "^1.1.4",
|
|
197
197
|
"@vitejs/plugin-react": "^4.3.1",
|
|
198
|
-
"del": "^
|
|
198
|
+
"del": "^8.0.0",
|
|
199
199
|
"msw": "^1.0.0",
|
|
200
200
|
"nodemon": "^3.0.1",
|
|
201
201
|
"vite": "^5.0.0",
|