@backstage/cli 0.28.0 → 0.29.0-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/config/jest.js +49 -25
  3. package/config/jestRejectNetworkRequests.js +59 -0
  4. package/config/nodeTransform.cjs +33 -0
  5. package/dist/commands/build/buildFrontend.cjs.js +8 -11
  6. package/dist/commands/buildWorkspace.cjs.js +1 -1
  7. package/dist/commands/index.cjs.js +9 -3
  8. package/dist/commands/repo/lint.cjs.js +6 -28
  9. package/dist/commands/repo/test.cjs.js +5 -27
  10. package/dist/commands/start/command.cjs.js +1 -0
  11. package/dist/commands/start/startBackend.cjs.js +23 -92
  12. package/dist/commands/start/startFrontend.cjs.js +6 -8
  13. package/dist/commands/versions/bump.cjs.js +9 -3
  14. package/dist/lib/bundler/config.cjs.js +20 -138
  15. package/dist/lib/bundler/linkWorkspaces.cjs.js +31 -0
  16. package/dist/lib/cache/SuccessCache.cjs.js +70 -0
  17. package/dist/lib/packager/createDistWorkspace.cjs.js +3 -3
  18. package/dist/lib/{experimental/startBackendExperimental.cjs.js → runner/runBackend.cjs.js} +6 -5
  19. package/dist/packages/backend-defaults/package.json.cjs.js +1 -1
  20. package/dist/packages/backend-plugin-api/package.json.cjs.js +1 -1
  21. package/dist/packages/backend-test-utils/package.json.cjs.js +1 -1
  22. package/dist/packages/catalog-client/package.json.cjs.js +1 -1
  23. package/dist/packages/cli/package.json.cjs.js +2 -4
  24. package/dist/packages/core-components/package.json.cjs.js +1 -1
  25. package/dist/packages/dev-utils/package.json.cjs.js +1 -1
  26. package/dist/plugins/auth-backend/package.json.cjs.js +1 -1
  27. package/dist/plugins/auth-backend-module-guest-provider/package.json.cjs.js +1 -1
  28. package/dist/plugins/catalog-node/package.json.cjs.js +1 -1
  29. package/dist/plugins/scaffolder-node/package.json.cjs.js +1 -1
  30. package/dist/plugins/scaffolder-node-test-utils/package.json.cjs.js +1 -1
  31. package/package.json +28 -30
  32. package/dist/lib/bundler/LinkedPackageResolvePlugin.cjs.js +0 -47
  33. package/dist/lib/bundler/backend.cjs.js +0 -36
  34. /package/dist/lib/{experimental → ipc}/IpcServer.cjs.js +0 -0
  35. /package/dist/lib/{experimental → ipc}/ServerDataStore.cjs.js +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,47 @@
1
1
  # @backstage/cli
2
2
 
3
+ ## 0.29.0-next.0
4
+
5
+ ### Minor Changes
6
+
7
+ - bc71665: **BREAKING**: The `LEGACY_BACKEND_START` flag has been removed, along with support for `src/run.ts` as the development entry point.
8
+
9
+ ### Patch Changes
10
+
11
+ - 28b60ad: The check for `react-dom/client` in the Jest configuration will now properly always run from the target directory.
12
+ - e30b65d: Added `--alwaysPack` as a replacement for the now hidden `--alwaysYarnPack` flag for the `build-workspace` command.
13
+ - a7f97e4: Added a new `"rejectFrontendNetworkRequests"` configuration flag that can be set in the `"jest"` field in the root `package.json`:
14
+
15
+ ```json
16
+ {
17
+ "jest": {
18
+ "rejectFrontendNetworkRequests": true
19
+ }
20
+ }
21
+ ```
22
+
23
+ This flag causes rejection of any form of network requests that are attempted to be made in frontend or common package tests. This flag can only be set in the root `package.json` and can not be overridden in individual package configurations.
24
+
25
+ - 04297a0: The `--successCache` option for the `repo test` and `repo lint` commands now use an additive store that keeps old entries around for a week before they are cleaned up automatically.
26
+ - b4627f2: Fixed an issue where the `raw-loader` for loading HTML templates was not resolved from the context of the CLI package.
27
+ - 17850a5: Update upgrade-helper link in `versions:bump` command to include `yarnPlugin` parameter when the yarn plugin is installed
28
+ - b084f5a: Bump the Webpack dependency range to `^5.94.0`, as our current configuration is not compatible with some older versions.
29
+ - 946fa34: Added a new `--link <workspace-path>` option for frontend builds that allow you to override module resolution to link in an external workspace at runtime.
30
+
31
+ As part of this change the Webpack linked workspace resolution plugin for frontend builds has been removed. It was in place to support the old workspace linking where it was done by Yarn, which is no longer a working option.
32
+
33
+ - Updated dependencies
34
+ - @backstage/catalog-model@1.7.0
35
+ - @backstage/cli-common@0.1.14
36
+ - @backstage/cli-node@0.2.9
37
+ - @backstage/config@1.2.0
38
+ - @backstage/config-loader@1.9.1
39
+ - @backstage/errors@1.2.4
40
+ - @backstage/eslint-plugin@0.1.10
41
+ - @backstage/integration@1.15.1
42
+ - @backstage/release-manifests@0.0.11
43
+ - @backstage/types@1.1.1
44
+
3
45
  ## 0.28.0
4
46
 
5
47
  ### Minor Changes
package/config/jest.js CHANGED
@@ -23,12 +23,22 @@ const paths = require('@backstage/cli-common').findPaths(process.cwd());
23
23
 
24
24
  const SRC_EXTS = ['ts', 'js', 'tsx', 'jsx', 'mts', 'cts', 'mjs', 'cjs'];
25
25
 
26
+ const FRONTEND_ROLES = [
27
+ 'frontend',
28
+ 'web-library',
29
+ 'common-library',
30
+ 'frontend-plugin',
31
+ 'frontend-plugin-module',
32
+ ];
33
+
26
34
  const envOptions = {
27
35
  oldTests: Boolean(process.env.BACKSTAGE_OLD_TESTS),
28
36
  };
29
37
 
30
38
  try {
31
- require.resolve('react-dom/client');
39
+ require.resolve('react-dom/client', {
40
+ paths: [paths.targetRoot],
41
+ });
32
42
  process.env.HAS_REACT_DOM_CLIENT = true;
33
43
  } catch {
34
44
  /* ignored */
@@ -121,24 +131,13 @@ const transformIgnorePattern = [
121
131
 
122
132
  // Provides additional config that's based on the role of the target package
123
133
  function getRoleConfig(role) {
124
- switch (role) {
125
- case 'frontend':
126
- case 'web-library':
127
- case 'common-library':
128
- case 'frontend-plugin':
129
- case 'frontend-plugin-module':
130
- return { testEnvironment: require.resolve('jest-environment-jsdom') };
131
- case 'cli':
132
- case 'backend':
133
- case 'node-library':
134
- case 'backend-plugin':
135
- case 'backend-plugin-module':
136
- default:
137
- return { testEnvironment: require.resolve('jest-environment-node') };
134
+ if (FRONTEND_ROLES.includes(role)) {
135
+ return { testEnvironment: require.resolve('jest-environment-jsdom') };
138
136
  }
137
+ return { testEnvironment: require.resolve('jest-environment-node') };
139
138
  }
140
139
 
141
- async function getProjectConfig(targetPath, extraConfig) {
140
+ async function getProjectConfig(targetPath, extraConfig, extraOptions) {
142
141
  const configJsPath = path.resolve(targetPath, 'jest.config.js');
143
142
  const configTsPath = path.resolve(targetPath, 'jest.config.ts');
144
143
  // If the package has it's own jest config, we use that instead.
@@ -232,6 +231,17 @@ async function getProjectConfig(targetPath, extraConfig) {
232
231
 
233
232
  options.setupFilesAfterEnv = options.setupFilesAfterEnv || [];
234
233
 
234
+ if (
235
+ extraOptions.rejectFrontendNetworkRequests &&
236
+ FRONTEND_ROLES.includes(pkgJson.backstage?.role)
237
+ ) {
238
+ // By adding this first we ensure that it's possible to for example override
239
+ // fetch with a mock in a custom setup file
240
+ options.setupFilesAfterEnv.unshift(
241
+ require.resolve('./jestRejectNetworkRequests.js'),
242
+ );
243
+ }
244
+
235
245
  if (options.testEnvironment === require.resolve('jest-environment-jsdom')) {
236
246
  // FIXME https://github.com/jsdom/jsdom/issues/1724
237
247
  options.setupFilesAfterEnv.unshift(require.resolve('cross-fetch/polyfill'));
@@ -276,21 +286,31 @@ async function getRootConfig() {
276
286
  collectCoverageFrom: ['**/*.{js,jsx,ts,tsx,mjs,cjs}', '!**/*.d.ts'],
277
287
  };
278
288
 
289
+ const { rejectFrontendNetworkRequests, ...rootOptions } =
290
+ rootPkgJson.jest ?? {};
291
+ const extraRootOptions = {
292
+ rejectFrontendNetworkRequests,
293
+ };
294
+
279
295
  const workspacePatterns =
280
296
  rootPkgJson.workspaces && rootPkgJson.workspaces.packages;
281
297
 
282
298
  // Check if we're running within a specific monorepo package. In that case just get the single project config.
283
299
  if (!workspacePatterns || paths.targetRoot !== paths.targetDir) {
284
- return getProjectConfig(paths.targetDir, {
285
- ...baseCoverageConfig,
286
- ...(rootPkgJson.jest ?? {}),
287
- });
300
+ return getProjectConfig(
301
+ paths.targetDir,
302
+ {
303
+ ...baseCoverageConfig,
304
+ ...rootOptions,
305
+ },
306
+ extraRootOptions,
307
+ );
288
308
  }
289
309
 
290
310
  const globalRootConfig = { ...baseCoverageConfig };
291
311
  const globalProjectConfig = {};
292
312
 
293
- for (const [key, value] of Object.entries(rootPkgJson.jest ?? {})) {
313
+ for (const [key, value] of Object.entries(rootOptions)) {
294
314
  if (projectConfigKeys.includes(key)) {
295
315
  globalProjectConfig[key] = value;
296
316
  } else {
@@ -321,10 +341,14 @@ async function getRootConfig() {
321
341
  testScript?.includes('backstage-cli test') ||
322
342
  testScript?.includes('backstage-cli package test');
323
343
  if (testScript && isSupportedTestScript) {
324
- return await getProjectConfig(projectPath, {
325
- ...globalProjectConfig,
326
- displayName: packageData.name,
327
- });
344
+ return await getProjectConfig(
345
+ projectPath,
346
+ {
347
+ ...globalProjectConfig,
348
+ displayName: packageData.name,
349
+ },
350
+ extraRootOptions,
351
+ );
328
352
  }
329
353
 
330
354
  return undefined;
@@ -0,0 +1,59 @@
1
+ /*
2
+ * Copyright 2024 The Backstage Authors
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ const http = require('http');
18
+ const https = require('https');
19
+
20
+ const errorMessage = 'Network requests are not allowed in tests';
21
+
22
+ const origHttpAgent = http.globalAgent;
23
+ const origHttpsAgent = https.globalAgent;
24
+ const origFetch = global.fetch;
25
+ const origXMLHttpRequest = global.fetch;
26
+
27
+ http.globalAgent = new http.Agent({
28
+ lookup() {
29
+ throw new Error(errorMessage);
30
+ },
31
+ });
32
+
33
+ https.globalAgent = new https.Agent({
34
+ lookup() {
35
+ throw new Error(errorMessage);
36
+ },
37
+ });
38
+
39
+ if (global.fetch) {
40
+ global.fetch = async () => {
41
+ throw new Error(errorMessage);
42
+ };
43
+ }
44
+
45
+ if (global.XMLHttpRequest) {
46
+ global.XMLHttpRequest = class {
47
+ constructor() {
48
+ throw new Error(errorMessage);
49
+ }
50
+ };
51
+ }
52
+
53
+ // Reset overrides after each suite to make sure we don't pollute the test environment
54
+ afterAll(() => {
55
+ http.globalAgent = origHttpAgent;
56
+ https.globalAgent = origHttpsAgent;
57
+ global.fetch = origFetch;
58
+ global.XMLHttpRequest = origXMLHttpRequest;
59
+ });
@@ -16,6 +16,39 @@
16
16
 
17
17
  const { transformSync } = require('@swc/core');
18
18
  const { addHook } = require('pirates');
19
+ const { Module } = require('module');
20
+
21
+ // This hooks into module resolution and overrides imports of packages that
22
+ // exist in the linked workspace to instead be resolved from the linked workspace.
23
+ if (process.env.BACKSTAGE_CLI_LINKED_WORKSPACE) {
24
+ const { join: joinPath } = require('path');
25
+ const { getPackagesSync } = require('@manypkg/get-packages');
26
+ const { packages: linkedPackages, root: linkedRoot } = getPackagesSync(
27
+ process.env.BACKSTAGE_CLI_LINKED_WORKSPACE,
28
+ );
29
+
30
+ // Matches all packages in the linked workspaces, as well as sub-path exports from them
31
+ const replacementRegex = new RegExp(
32
+ `^(?:${linkedPackages
33
+ .map(pkg => pkg.packageJson.name)
34
+ .join('|')})(?:/.*)?$`,
35
+ );
36
+
37
+ const origLoad = Module._load;
38
+ Module._load = function requireHook(request, parent) {
39
+ if (!replacementRegex.test(request)) {
40
+ return origLoad.call(this, request, parent);
41
+ }
42
+
43
+ // The package import that we're overriding will always existing in the root
44
+ // node_modules of the linked workspace, so it's enough to override the the
45
+ // parent paths with that single entry
46
+ return origLoad.call(this, request, {
47
+ ...parent,
48
+ paths: [joinPath(linkedRoot.dir, 'node_modules')],
49
+ });
50
+ };
51
+ }
19
52
 
20
53
  addHook(
21
54
  (code, filename) => {
@@ -2,30 +2,27 @@
2
2
 
3
3
  var fs = require('fs-extra');
4
4
  var path = require('path');
5
- require('webpack');
5
+ var bundle = require('../../lib/bundler/bundle.cjs.js');
6
+ var moduleFederation = require('../../lib/bundler/moduleFederation.cjs.js');
6
7
  require('chalk');
8
+ require('react-dev-utils/openBrowser');
9
+ require('webpack');
10
+ require('webpack-dev-server');
11
+ require('../../lib/paths.cjs.js');
12
+ var config = require('../../lib/config.cjs.js');
7
13
  require('eslint-webpack-plugin');
8
14
  require('fork-ts-checker-webpack-plugin');
9
15
  require('html-webpack-plugin');
10
16
  require('@module-federation/enhanced/webpack');
11
- require('@backstage/cli-common');
12
17
  require('react-dev-utils/ModuleScopePlugin');
13
- require('run-script-webpack-plugin');
14
18
  require('@pmmmwh/react-refresh-webpack-plugin');
15
- require('../../lib/paths.cjs.js');
16
- require('@manypkg/get-packages');
17
- require('webpack-node-externals');
18
19
  require('../../lib/bundler/optimization.cjs.js');
19
20
  require('lodash/pickBy');
20
21
  require('../../lib/run.cjs.js');
21
22
  require('mini-css-extract-plugin');
22
23
  require('../../lib/version.cjs.js');
23
24
  require('yn');
24
- var bundle = require('../../lib/bundler/bundle.cjs.js');
25
- var moduleFederation = require('../../lib/bundler/moduleFederation.cjs.js');
26
- require('react-dev-utils/openBrowser');
27
- require('webpack-dev-server');
28
- var config = require('../../lib/config.cjs.js');
25
+ require('@manypkg/get-packages');
29
26
  require('../../lib/bundler/packageDetection.cjs.js');
30
27
  var parallel = require('../../lib/parallel.cjs.js');
31
28
 
@@ -15,7 +15,7 @@ var buildWorkspace = async (dir, packages, options) => {
15
15
  }
16
16
  await createDistWorkspace.createDistWorkspace(packages, {
17
17
  targetDir: dir,
18
- alwaysYarnPack: options.alwaysYarnPack,
18
+ alwaysPack: options.alwaysPack,
19
19
  enableFeatureDetection: true
20
20
  });
21
21
  };
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ var commander = require('commander');
3
4
  var errors = require('@backstage/errors');
4
5
  var errors$1 = require('../lib/errors.cjs.js');
5
6
 
@@ -67,7 +68,7 @@ function registerScriptCommand(program) {
67
68
  command.command("start").description("Start a package for local development").option(...configOption).option("--role <name>", "Run the command with an explicit package role").option("--check", "Enable type checking and linting if available").option("--inspect [host]", "Enable debugger in Node.js environments").option(
68
69
  "--inspect-brk [host]",
69
70
  "Enable debugger in Node.js environments, breaking before code starts"
70
- ).option("--require <path>", "Add a --require argument to the node process").action(lazy(() => Promise.resolve().then(function () { return require('./start/index.cjs.js'); }).then((m) => m.command)));
71
+ ).option("--require <path>", "Add a --require argument to the node process").option("--link <path>", "Link an external workspace for module resolution").action(lazy(() => Promise.resolve().then(function () { return require('./start/index.cjs.js'); }).then((m) => m.command)));
71
72
  command.command("build").description("Build a package for production deployment or publishing").option("--role <name>", "Run the command with an explicit package role").option(
72
73
  "--minify",
73
74
  "Minify the generated code. Does not apply to app package (app is minified by default)."
@@ -184,8 +185,13 @@ function registerCommands(program) {
184
185
  ).description(
185
186
  "Migrate any plugins that have been moved to the @backstage-community namespace automatically"
186
187
  ).action(lazy(() => Promise.resolve().then(function () { return require('./versions/migrate.cjs.js'); }).then((m) => m.default)));
187
- program.command("build-workspace <workspace-dir> [packages...]").option(
188
- "--alwaysYarnPack",
188
+ program.command("build-workspace <workspace-dir> [packages...]").addOption(
189
+ new commander.Option(
190
+ "--alwaysYarnPack",
191
+ "Alias for --alwaysPack for backwards compatibility."
192
+ ).implies({ alwaysPack: true }).hideHelp(true)
193
+ ).option(
194
+ "--alwaysPack",
189
195
  "Force workspace output to be a result of running `yarn pack` on each package (warning: very slow)"
190
196
  ).description("Builds a temporary dist workspace from the provided packages").action(lazy(() => Promise.resolve().then(function () { return require('./buildWorkspace.cjs.js'); }).then((m) => m.default)));
191
197
  program.command("create-github-app <github-org>").description("Create new GitHub App in your organization.").action(lazy(() => Promise.resolve().then(function () { return require('./create-github-app/index.cjs.js'); }).then((m) => m.default)));
@@ -1,50 +1,28 @@
1
1
  'use strict';
2
2
 
3
3
  var chalk = require('chalk');
4
- var fs = require('fs-extra');
5
4
  var crypto = require('crypto');
6
5
  var path = require('path');
7
6
  var cliNode = require('@backstage/cli-node');
8
7
  var paths = require('../../lib/paths.cjs.js');
9
8
  var parallel = require('../../lib/parallel.cjs.js');
10
9
  var optionsParser = require('./optionsParser.cjs.js');
10
+ var SuccessCache = require('../../lib/cache/SuccessCache.cjs.js');
11
11
 
12
12
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
13
13
 
14
14
  var chalk__default = /*#__PURE__*/_interopDefaultCompat(chalk);
15
- var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
16
15
 
17
16
  function depCount(pkg) {
18
17
  const deps = pkg.dependencies ? Object.keys(pkg.dependencies).length : 0;
19
18
  const devDeps = pkg.devDependencies ? Object.keys(pkg.devDependencies).length : 0;
20
19
  return deps + devDeps;
21
20
  }
22
- const CACHE_FILE_NAME = "lint-cache.json";
23
- async function readCache(dir) {
24
- try {
25
- const data = await fs__default.default.readJson(path.resolve(dir, CACHE_FILE_NAME));
26
- if (!Array.isArray(data)) {
27
- return void 0;
28
- }
29
- if (data.some((x) => typeof x !== "string")) {
30
- return void 0;
31
- }
32
- return data;
33
- } catch {
34
- return void 0;
35
- }
36
- }
37
- async function writeCache(dir, cache) {
38
- await fs__default.default.mkdirp(dir);
39
- await fs__default.default.writeJson(path.resolve(dir, CACHE_FILE_NAME), cache, { spaces: 2 });
40
- }
41
21
  async function command(opts, cmd) {
42
22
  let packages = await cliNode.PackageGraph.listTargetPackages();
43
- const cacheDir = path.resolve(
44
- opts.successCacheDir ?? "node_modules/.cache/backstage-cli"
45
- );
23
+ const cache = new SuccessCache.SuccessCache("lint", opts.successCacheDir);
46
24
  const cacheContext = opts.successCache ? {
47
- cache: await readCache(cacheDir),
25
+ entries: await cache.read(),
48
26
  lockfile: await cliNode.Lockfile.load(paths.paths.resolveTargetRoot("yarn.lock"))
49
27
  } : void 0;
50
28
  if (opts.since) {
@@ -97,7 +75,7 @@ async function command(opts, cmd) {
97
75
  fix: Boolean(opts.fix),
98
76
  format: opts.format,
99
77
  shouldCache: Boolean(cacheContext),
100
- successCache: cacheContext?.cache,
78
+ successCache: cacheContext?.entries,
101
79
  rootDir: paths.paths.targetRoot
102
80
  },
103
81
  workerFactory: async ({
@@ -149,7 +127,7 @@ async function command(opts, cmd) {
149
127
  hash.update("\0");
150
128
  }
151
129
  sha = await hash.digest("hex");
152
- if (successCache?.includes(sha)) {
130
+ if (successCache?.has(sha)) {
153
131
  console.log(`Skipped ${relativeDir} due to cache hit`);
154
132
  return { relativeDir, sha, failed: false };
155
133
  }
@@ -194,7 +172,7 @@ async function command(opts, cmd) {
194
172
  }
195
173
  }
196
174
  if (cacheContext) {
197
- await writeCache(cacheDir, outputSuccessCache);
175
+ await cache.write(outputSuccessCache);
198
176
  }
199
177
  if (failed) {
200
178
  process.exit(1);
@@ -2,40 +2,20 @@
2
2
 
3
3
  var os = require('os');
4
4
  var crypto = require('node:crypto');
5
- var fs = require('fs-extra');
6
5
  var yargs = require('yargs');
7
6
  var path = require('path');
8
7
  var cliNode = require('@backstage/cli-node');
9
8
  var paths = require('../../lib/paths.cjs.js');
10
9
  var run = require('../../lib/run.cjs.js');
11
10
  var cliCommon = require('@backstage/cli-common');
11
+ var SuccessCache = require('../../lib/cache/SuccessCache.cjs.js');
12
12
 
13
13
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
14
14
 
15
15
  var os__default = /*#__PURE__*/_interopDefaultCompat(os);
16
16
  var crypto__default = /*#__PURE__*/_interopDefaultCompat(crypto);
17
- var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
18
17
  var yargs__default = /*#__PURE__*/_interopDefaultCompat(yargs);
19
18
 
20
- const CACHE_FILE_NAME = "test-cache.json";
21
- async function readCache(dir) {
22
- try {
23
- const data = await fs__default.default.readJson(path.resolve(dir, CACHE_FILE_NAME));
24
- if (!Array.isArray(data)) {
25
- return void 0;
26
- }
27
- if (data.some((x) => typeof x !== "string")) {
28
- return void 0;
29
- }
30
- return data;
31
- } catch {
32
- return void 0;
33
- }
34
- }
35
- function writeCache(dir, cache) {
36
- fs__default.default.mkdirpSync(dir);
37
- fs__default.default.writeJsonSync(path.resolve(dir, CACHE_FILE_NAME), cache, { spaces: 2 });
38
- }
39
19
  async function readPackageTreeHashes(graph) {
40
20
  const pkgs = Array.from(graph.values());
41
21
  const output = await run.runPlain(
@@ -177,9 +157,6 @@ async function command(opts, cmd) {
177
157
  if (opts.successCache) {
178
158
  removeOptionArg(args, "--successCache", 1);
179
159
  removeOptionArg(args, "--successCacheDir");
180
- const cacheDir = path.resolve(
181
- opts.successCacheDir ?? "node_modules/.cache/backstage-cli"
182
- );
183
160
  const { _: parsedArgs } = await yargs__default.default(args).options(jestCli.yargsOptions).argv;
184
161
  if (parsedArgs.length > 0) {
185
162
  throw new Error(
@@ -193,6 +170,7 @@ async function command(opts, cmd) {
193
170
  `The --successCache flag can not be combined with the --shard flag`
194
171
  );
195
172
  }
173
+ const cache = new SuccessCache.SuccessCache("test", opts.successCacheDir);
196
174
  const graph = await getPackageGraph();
197
175
  const projectHashes = /* @__PURE__ */ new Map();
198
176
  const outputSuccessCache = new Array();
@@ -200,7 +178,7 @@ async function command(opts, cmd) {
200
178
  globalWithCache.__backstageCli_jestSuccessCache = {
201
179
  // This is called by `config/jest.js` after the project configs have been gathered
202
180
  async filterConfigs(projectConfigs, globalRootConfig) {
203
- const cache = await readCache(cacheDir);
181
+ const cacheEntries = await cache.read();
204
182
  const lockfile = await cliNode.Lockfile.load(
205
183
  paths.paths.resolveTargetRoot("yarn.lock")
206
184
  );
@@ -232,7 +210,7 @@ async function command(opts, cmd) {
232
210
  hash.update(lockfile.getDependencyTreeHash(packageName));
233
211
  const sha = hash.digest("hex");
234
212
  projectHashes.set(packageName, sha);
235
- if (cache?.includes(sha)) {
213
+ if (cacheEntries.has(sha)) {
236
214
  if (!selectedProjects || selectedProjects.includes(packageName)) {
237
215
  console.log(`Skipped ${packageName} due to cache hit`);
238
216
  }
@@ -265,7 +243,7 @@ async function command(opts, cmd) {
265
243
  outputSuccessCache.push(sha);
266
244
  }
267
245
  }
268
- await writeCache(cacheDir, outputSuccessCache);
246
+ await cache.write(outputSuccessCache);
269
247
  }
270
248
  };
271
249
  }
@@ -9,6 +9,7 @@ async function command(opts) {
9
9
  const options = {
10
10
  configPaths: opts.config,
11
11
  checksEnabled: Boolean(opts.check),
12
+ linkedWorkspace: opts.link,
12
13
  inspectEnabled: opts.inspect,
13
14
  inspectBrkEnabled: opts.inspectBrk,
14
15
  require: opts.require
@@ -2,109 +2,40 @@
2
2
 
3
3
  var fs = require('fs-extra');
4
4
  var paths = require('../../lib/paths.cjs.js');
5
- var backend = require('../../lib/bundler/backend.cjs.js');
6
- require('yn');
7
- require('path');
8
- require('webpack');
9
- require('react-dev-utils/FileSizeReporter');
10
- require('react-dev-utils/formatWebpackMessages');
11
- require('chalk');
12
- require('eslint-webpack-plugin');
13
- require('fork-ts-checker-webpack-plugin');
14
- require('html-webpack-plugin');
15
- require('@module-federation/enhanced/webpack');
16
- require('@backstage/cli-common');
17
- require('react-dev-utils/ModuleScopePlugin');
18
- require('run-script-webpack-plugin');
19
- require('@pmmmwh/react-refresh-webpack-plugin');
20
- require('@manypkg/get-packages');
21
- require('webpack-node-externals');
22
- require('../../lib/bundler/optimization.cjs.js');
23
- require('lodash/pickBy');
24
- require('../../lib/run.cjs.js');
25
- require('mini-css-extract-plugin');
26
- require('../../lib/version.cjs.js');
27
- require('../../lib/bundler/packageDetection.cjs.js');
28
- require('react-dev-utils/openBrowser');
29
- require('webpack-dev-server');
30
- require('@backstage/config-loader');
31
- require('@backstage/config');
32
- require('@backstage/cli-node');
33
- var startBackendExperimental = require('../../lib/experimental/startBackendExperimental.cjs.js');
5
+ var runBackend = require('../../lib/runner/runBackend.cjs.js');
34
6
 
35
7
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
36
8
 
37
9
  var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
38
10
 
39
11
  async function startBackend(options) {
40
- if (!process.env.LEGACY_BACKEND_START) {
41
- const waitForExit = await startBackendExperimental.startBackendExperimental({
42
- entry: "src/index",
43
- checksEnabled: false,
44
- // not supported
45
- inspectEnabled: options.inspectEnabled,
46
- inspectBrkEnabled: options.inspectBrkEnabled,
47
- require: options.require
48
- });
49
- await waitForExit();
50
- } else {
51
- console.warn(
52
- "LEGACY_BACKEND_START is deprecated and will be removed in a future release"
53
- );
54
- const waitForExit = await cleanDistAndServeBackend({
55
- entry: "src/index",
56
- checksEnabled: options.checksEnabled,
57
- inspectEnabled: options.inspectEnabled,
58
- inspectBrkEnabled: options.inspectBrkEnabled,
59
- require: options.require
60
- });
61
- await waitForExit();
62
- }
12
+ const waitForExit = await runBackend.runBackend({
13
+ entry: "src/index",
14
+ inspectEnabled: options.inspectEnabled,
15
+ inspectBrkEnabled: options.inspectBrkEnabled,
16
+ linkedWorkspace: options.linkedWorkspace,
17
+ require: options.require
18
+ });
19
+ await waitForExit();
63
20
  }
64
21
  async function startBackendPlugin(options) {
65
- if (!process.env.LEGACY_BACKEND_START) {
66
- const hasDevIndexEntry = await fs__default.default.pathExists(
67
- paths.paths.resolveTarget("dev", "index.ts")
68
- );
69
- if (!hasDevIndexEntry) {
70
- console.warn(
71
- `The 'dev' directory is missing. Please create a proper dev/index.ts in order to start the plugin.`
72
- );
73
- return;
74
- }
75
- const waitForExit = await startBackendExperimental.startBackendExperimental({
76
- entry: "dev/index",
77
- checksEnabled: false,
78
- // not supported
79
- inspectEnabled: options.inspectEnabled,
80
- inspectBrkEnabled: options.inspectBrkEnabled,
81
- require: options.require
82
- });
83
- await waitForExit();
84
- } else {
85
- const hasEntry = await fs__default.default.pathExists(paths.paths.resolveTarget("src", "run.ts"));
86
- if (!hasEntry) {
87
- console.warn(
88
- `src/run.ts is missing. Please create the file or run the command without LEGACY_BACKEND_START`
89
- );
90
- return;
91
- }
22
+ const hasDevIndexEntry = await fs__default.default.pathExists(
23
+ paths.paths.resolveTarget("dev", "index.ts")
24
+ );
25
+ if (!hasDevIndexEntry) {
92
26
  console.warn(
93
- "LEGACY_BACKEND_START is deprecated and will be removed in a future release"
27
+ `The 'dev' directory is missing. Please create a proper dev/index.ts in order to start the plugin.`
94
28
  );
95
- const waitForExit = await cleanDistAndServeBackend({
96
- entry: "src/run",
97
- checksEnabled: options.checksEnabled,
98
- inspectEnabled: options.inspectEnabled,
99
- inspectBrkEnabled: options.inspectBrkEnabled,
100
- require: options.require
101
- });
102
- await waitForExit();
29
+ return;
103
30
  }
104
- }
105
- async function cleanDistAndServeBackend(options) {
106
- await fs__default.default.remove(paths.paths.resolveTarget("dist"));
107
- return backend.serveBackend(options);
31
+ const waitForExit = await runBackend.runBackend({
32
+ entry: "dev/index",
33
+ inspectEnabled: options.inspectEnabled,
34
+ inspectBrkEnabled: options.inspectBrkEnabled,
35
+ require: options.require,
36
+ linkedWorkspace: options.linkedWorkspace
37
+ });
38
+ await waitForExit();
108
39
  }
109
40
 
110
41
  exports.startBackend = startBackend;