@backstage/repo-tools 0.19.2-next.1 → 0.19.2-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 CHANGED
@@ -1,5 +1,22 @@
1
1
  # @backstage/repo-tools
2
2
 
3
+ ## 0.19.2-next.3
4
+
5
+ ### Patch Changes
6
+
7
+ - dec6175: When an API, CLI, SQL, or knip report is out of date in CI, the error output now shows a diff of the changes that need to be committed instead of printing the full expected report.
8
+ - Updated dependencies
9
+ - @backstage/backend-plugin-api@1.11.0-next.2
10
+
11
+ ## 0.19.2-next.2
12
+
13
+ ### Patch Changes
14
+
15
+ - b8c8132: CLI API reports now support help output with separate groups and commands sections, including commands nested within groups.
16
+ - 76ac6ed: Updated dependency `js-yaml` to `^5.0.0`.
17
+ - Updated dependencies
18
+ - @backstage/cli-node@0.3.5-next.1
19
+
3
20
  ## 0.19.2-next.1
4
21
 
5
22
  ### Patch Changes
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var tryRunPrettier = require('../common/tryRunPrettier.cjs.js');
4
+ require('diff');
4
5
  var cliCommon = require('@backstage/cli-common');
5
6
 
6
7
  let applied = false;
@@ -10,13 +10,13 @@ var path = require('node:path');
10
10
  var getPackageExportDetails = require('../../../lib/getPackageExportDetails.cjs.js');
11
11
  var cliCommon = require('@backstage/cli-common');
12
12
  var logApiReportInstructions = require('../common/logApiReportInstructions.cjs.js');
13
+ var logReportDiff = require('../common/logReportDiff.cjs.js');
13
14
  var patchApiReportGeneration = require('./patchApiReportGeneration.cjs.js');
14
15
 
15
16
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
16
17
 
17
18
  var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
18
19
 
19
- const tmpDir = cliCommon.targetPaths.resolveRoot("./node_modules/.cache/api-extractor");
20
20
  async function countApiReportWarnings(reportPath) {
21
21
  try {
22
22
  const content = await fs__default.default.readFile(reportPath, "utf8");
@@ -194,15 +194,12 @@ async function runApiExtraction({
194
194
  showVerboseMessages: false,
195
195
  showDiagnostics: false,
196
196
  messageCallback(message) {
197
- if (message.text.includes("The API report file is missing")) {
198
- shouldLogInstructions = true;
199
- }
200
- if (message.text.includes(
197
+ if (message.text.includes("The API report file is missing") || message.text.includes(
201
198
  "You have changed the API signature for this project."
202
199
  )) {
203
200
  shouldLogInstructions = true;
204
201
  const match = message.text.match(
205
- /Please copy the file "(.*)" to "report\.api\.md"/
202
+ /Please copy the file "(.*)" to "[^"]*\.api\.md"/
206
203
  );
207
204
  if (match) {
208
205
  conflictingFile = match[1];
@@ -237,16 +234,18 @@ async function runApiExtraction({
237
234
  if (shouldLogInstructions) {
238
235
  logApiReportInstructions.logApiReportInstructions();
239
236
  if (conflictingFile) {
240
- console.log("");
241
- console.log(
242
- `The conflicting file is ${path.relative(
243
- tmpDir,
244
- conflictingFile
245
- )}, with the following content:`
237
+ const existing = await fs__default.default.readFile(extractorConfig.reportFilePath, "utf8").catch((error) => {
238
+ if (error.code === "ENOENT") {
239
+ return void 0;
240
+ }
241
+ throw error;
242
+ });
243
+ const expected = await fs__default.default.readFile(conflictingFile, "utf8");
244
+ logReportDiff.logReportDiff(
245
+ path.relative(cliCommon.targetPaths.rootDir, extractorConfig.reportFilePath),
246
+ existing,
247
+ expected
246
248
  );
247
- console.log("");
248
- const content = await fs__default.default.readFile(conflictingFile, "utf8");
249
- console.log(content);
250
249
  logApiReportInstructions.logApiReportInstructions();
251
250
  }
252
251
  }
@@ -8,6 +8,7 @@ var util = require('../../util.cjs.js');
8
8
  var cliCommon = require('@backstage/cli-common');
9
9
  var generateCliReport = require('./generateCliReport.cjs.js');
10
10
  var logApiReportInstructions = require('../common/logApiReportInstructions.cjs.js');
11
+ var logReportDiff = require('../common/logReportDiff.cjs.js');
11
12
 
12
13
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
13
14
 
@@ -23,7 +24,7 @@ function parseHelpPage(helpPageContent) {
23
24
  }
24
25
  const lines = helpPageContent.split(/\r?\n/);
25
26
  let options = new Array();
26
- let commands = new Array();
27
+ const commands = new Array();
27
28
  let commandArguments = new Array();
28
29
  while (lines.length > 0) {
29
30
  while (lines.length > 0 && !lines[0].endsWith(":")) {
@@ -39,8 +40,8 @@ function parseHelpPage(helpPageContent) {
39
40
  const sectionItems = sectionLines.map((line) => line.match(/^\s{1,8}(.*?)\s\s+/)?.[1]).filter(Boolean);
40
41
  if (sectionName === "options:" || sectionName === "flags:") {
41
42
  options = sectionItems;
42
- } else if (sectionName === "commands:") {
43
- commands = sectionItems;
43
+ } else if (sectionName === "commands:" || sectionName === "groups:") {
44
+ commands.push(...sectionItems);
44
45
  } else if (sectionName === "arguments:") {
45
46
  commandArguments = sectionItems;
46
47
  } else if (sectionName === "usage:") {
@@ -130,18 +131,12 @@ async function runCliExtraction({
130
131
  await fs__default.default.writeFile(reportPath, report);
131
132
  } else {
132
133
  logApiReportInstructions.logApiReportInstructions();
133
- if (existingReport) {
134
- console.log("");
135
- console.log(
136
- `The conflicting file is ${path.relative(
137
- cliCommon.targetPaths.rootDir,
138
- reportPath
139
- )}, expecting the following content:`
140
- );
141
- console.log("");
142
- console.log(report);
143
- logApiReportInstructions.logApiReportInstructions();
144
- }
134
+ logReportDiff.logReportDiff(
135
+ path.relative(cliCommon.targetPaths.rootDir, reportPath),
136
+ existingReport,
137
+ report
138
+ );
139
+ logApiReportInstructions.logApiReportInstructions();
145
140
  throw new Error(`CLI report changed for ${packageDir}`);
146
141
  }
147
142
  }
@@ -150,5 +145,6 @@ async function runCliExtraction({
150
145
  );
151
146
  }
152
147
 
148
+ exports.parseHelpPage = parseHelpPage;
153
149
  exports.runCliExtraction = runCliExtraction;
154
150
  //# sourceMappingURL=runCliExtraction.cjs.js.map
@@ -0,0 +1,29 @@
1
+ 'use strict';
2
+
3
+ var diff = require('diff');
4
+
5
+ function formatReportDiff(path, existing, expected) {
6
+ const patch = diff.createTwoFilesPatch(
7
+ existing === void 0 ? "/dev/null" : `a/${path}`,
8
+ `b/${path}`,
9
+ existing ?? "",
10
+ expected,
11
+ void 0,
12
+ void 0,
13
+ { context: 3 }
14
+ );
15
+ return patch.split("\n").filter((line) => !line.startsWith("Index: ") && !line.startsWith("=====")).join("\n").trimEnd();
16
+ }
17
+ function logReportDiff(path, existing, expected) {
18
+ console.log("");
19
+ console.log(
20
+ `The report ${path} is out of date. These are the changes that need to be committed:`
21
+ );
22
+ console.log("");
23
+ console.log(formatReportDiff(path, existing, expected));
24
+ console.log("");
25
+ }
26
+
27
+ exports.formatReportDiff = formatReportDiff;
28
+ exports.logReportDiff = logReportDiff;
29
+ //# sourceMappingURL=logReportDiff.cjs.js.map
@@ -8,6 +8,7 @@ var getPgSchemaInfo = require('./getPgSchemaInfo.cjs.js');
8
8
  var generateSqlReport = require('./generateSqlReport.cjs.js');
9
9
  var tryRunPrettier = require('../common/tryRunPrettier.cjs.js');
10
10
  var logApiReportInstructions = require('../common/logApiReportInstructions.cjs.js');
11
+ var logReportDiff = require('../common/logReportDiff.cjs.js');
11
12
 
12
13
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
13
14
 
@@ -130,18 +131,12 @@ async function runSingleSqlExtraction(targetDir, migrationTarget, pkgName, knex,
130
131
  await fs__default.default.writeFile(reportPath, report);
131
132
  } else {
132
133
  logApiReportInstructions.logApiReportInstructions();
133
- if (existingReport) {
134
- console.log("");
135
- console.log(
136
- `The conflicting file is ${path.relative(
137
- cliCommon.targetPaths.rootDir,
138
- reportPath
139
- )}, expecting the following content:`
140
- );
141
- console.log("");
142
- console.log(report);
143
- logApiReportInstructions.logApiReportInstructions();
144
- }
134
+ logReportDiff.logReportDiff(
135
+ path.relative(cliCommon.targetPaths.rootDir, reportPath),
136
+ existingReport,
137
+ report
138
+ );
139
+ logApiReportInstructions.logApiReportInstructions();
145
140
  throw new Error(`Report ${reportPath} is out of date`);
146
141
  }
147
142
  }
@@ -3,6 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var YAML = require('js-yaml');
6
+ var yaml = require('../../lib/yaml.cjs.js');
6
7
  var pLimit = require('p-limit');
7
8
  var path = require('node:path');
8
9
  var yamlDiffPatch = require('yaml-diff-patch');
@@ -13,7 +14,25 @@ var utils = require('./utils.cjs.js');
13
14
 
14
15
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
15
16
 
16
- var YAML__default = /*#__PURE__*/_interopDefaultCompat(YAML);
17
+ function _interopNamespaceCompat(e) {
18
+ if (e && typeof e === 'object' && 'default' in e) return e;
19
+ var n = Object.create(null);
20
+ if (e) {
21
+ Object.keys(e).forEach(function (k) {
22
+ if (k !== 'default') {
23
+ var d = Object.getOwnPropertyDescriptor(e, k);
24
+ Object.defineProperty(n, k, d.get ? d : {
25
+ enumerable: true,
26
+ get: function () { return e[k]; }
27
+ });
28
+ }
29
+ });
30
+ }
31
+ n.default = e;
32
+ return Object.freeze(n);
33
+ }
34
+
35
+ var YAML__namespace = /*#__PURE__*/_interopNamespaceCompat(YAML);
17
36
  var pLimit__default = /*#__PURE__*/_interopDefaultCompat(pLimit);
18
37
  var chalk__default = /*#__PURE__*/_interopDefaultCompat(chalk);
19
38
 
@@ -87,7 +106,7 @@ async function createCatalogInfoYaml(options) {
87
106
  if (dryRun) {
88
107
  console.error(instruction);
89
108
  } else {
90
- await utils.writeFile(yamlPath, YAML__default.default.dump(entity));
109
+ await utils.writeFile(yamlPath, YAML__namespace.dump(entity));
91
110
  }
92
111
  return instruction;
93
112
  }
@@ -100,7 +119,7 @@ async function fixCatalogInfoYaml(options) {
100
119
  const safeName = utils.safeEntityName(packageJson.name);
101
120
  let yamlJson;
102
121
  try {
103
- yamlJson = YAML__default.default.load(yamlString);
122
+ yamlJson = yaml.loadYaml(yamlString);
104
123
  } catch (e) {
105
124
  throw new Error(`Unable to parse ${path.relative(".", yamlPath)}: ${e}`);
106
125
  }
@@ -6,6 +6,7 @@ var os = require('node:os');
6
6
  var path = require('node:path');
7
7
  var fs = require('fs-extra');
8
8
  var util = require('../util.cjs.js');
9
+ var logReportDiff = require('../api-reports/common/logReportDiff.cjs.js');
9
10
 
10
11
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
11
12
 
@@ -118,18 +119,12 @@ async function handlePackage({
118
119
  await fs__default.default.writeFile(reportPath, report);
119
120
  } else {
120
121
  logKnipReportInstructions();
121
- if (existingReport) {
122
- console.log("");
123
- console.log(
124
- `The conflicting file is ${path.relative(
125
- cliCommon.targetPaths.rootDir,
126
- reportPath
127
- )}, expecting the following content:`
128
- );
129
- console.log("");
130
- console.log(report);
131
- logKnipReportInstructions();
132
- }
122
+ logReportDiff.logReportDiff(
123
+ path.relative(cliCommon.targetPaths.rootDir, reportPath),
124
+ existingReport,
125
+ report
126
+ );
127
+ logKnipReportInstructions();
133
128
  throw new Error(`Knip report changed for ${packageDir}, `);
134
129
  }
135
130
  }
@@ -6,7 +6,7 @@ var chalk = require('chalk');
6
6
  var exec = require('../../../../lib/exec.cjs.js');
7
7
  var helpers = require('../../../../lib/openapi/helpers.cjs.js');
8
8
  var configLoader = require('@backstage/config-loader');
9
- var YAML = require('js-yaml');
9
+ var yaml = require('../../../../lib/yaml.cjs.js');
10
10
  var path = require('node:path');
11
11
  var commandExists = require('command-exists');
12
12
 
@@ -14,7 +14,6 @@ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'defau
14
14
 
15
15
  var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
16
16
  var chalk__default = /*#__PURE__*/_interopDefaultCompat(chalk);
17
- var YAML__default = /*#__PURE__*/_interopDefaultCompat(YAML);
18
17
 
19
18
  async function fuzz(opts) {
20
19
  const resolvedOpenapiPath = await helpers.getPathToCurrentOpenApiSpec();
@@ -26,7 +25,7 @@ async function fuzz(opts) {
26
25
  );
27
26
  process.exit(1);
28
27
  }
29
- const openapiSpec = YAML__default.default.load(
28
+ const openapiSpec = yaml.loadYaml(
30
29
  await fs__default.default.readFile(resolvedOpenapiPath, "utf8")
31
30
  );
32
31
  const configSource = configLoader.ConfigSources.default({
@@ -3,7 +3,7 @@
3
3
  var backendPluginApi = require('@backstage/backend-plugin-api');
4
4
  var chalk = require('chalk');
5
5
  var fs = require('fs-extra');
6
- var YAML = require('js-yaml');
6
+ var yaml = require('../../../../../lib/yaml.cjs.js');
7
7
  var path = require('node:path');
8
8
  var exec = require('../../../../../lib/exec.cjs.js');
9
9
  var constants = require('../../../../../lib/openapi/constants.cjs.js');
@@ -15,11 +15,10 @@ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'defau
15
15
 
16
16
  var chalk__default = /*#__PURE__*/_interopDefaultCompat(chalk);
17
17
  var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
18
- var YAML__default = /*#__PURE__*/_interopDefaultCompat(YAML);
19
18
 
20
19
  async function generateSpecFile() {
21
20
  const openapiPath = await helpers.getPathToCurrentOpenApiSpec();
22
- const yaml = YAML__default.default.load(await fs__default.default.readFile(openapiPath, "utf8"));
21
+ const yaml$1 = yaml.loadYaml(await fs__default.default.readFile(openapiPath, "utf8"));
23
22
  const tsPath = cliCommon.targetPaths.resolve(constants.TS_SCHEMA_PATH);
24
23
  const schemaDir = path.dirname(tsPath);
25
24
  await fs__default.default.mkdirp(schemaDir);
@@ -37,7 +36,7 @@ async function generateSpecFile() {
37
36
  // ******************************************************************
38
37
  import {createValidatedOpenApiRouterFromGeneratedEndpointMap} from '@backstage/backend-openapi-utils';
39
38
  import {EndpointMap} from './apis';
40
- export const spec = ${JSON.stringify(yaml, null, 2)} as const;
39
+ export const spec = ${JSON.stringify(yaml$1, null, 2)} as const;
41
40
  export const createOpenApiRouter = async (
42
41
  options?: Parameters<typeof createValidatedOpenApiRouterFromGeneratedEndpointMap>['1'],
43
42
  ) => createValidatedOpenApiRouterFromGeneratedEndpointMap<EndpointMap>(spec, options);
@@ -2,7 +2,7 @@
2
2
 
3
3
  var Parser = require('@apidevtools/swagger-parser');
4
4
  var fs = require('fs-extra');
5
- var YAML = require('js-yaml');
5
+ var yaml = require('../yaml.cjs.js');
6
6
  var lodash = require('lodash');
7
7
  var cliCommon = require('@backstage/cli-common');
8
8
  var path = require('node:path');
@@ -12,7 +12,6 @@ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'defau
12
12
 
13
13
  var Parser__default = /*#__PURE__*/_interopDefaultCompat(Parser);
14
14
  var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
15
- var YAML__default = /*#__PURE__*/_interopDefaultCompat(YAML);
16
15
 
17
16
  const getPathToFile = async (directory, filename) => {
18
17
  return path.resolve(directory, filename);
@@ -33,9 +32,9 @@ const getPathToCurrentOpenApiSpec = async () => {
33
32
  return await assertExists(await getRelativePathToFile(constants.YAML_SCHEMA_PATH));
34
33
  };
35
34
  async function loadAndValidateOpenApiYaml(path) {
36
- const yaml = YAML__default.default.load(await fs__default.default.readFile(path, "utf8"));
37
- await Parser__default.default.validate(lodash.cloneDeep(yaml));
38
- return yaml;
35
+ const yaml$1 = yaml.loadYaml(await fs__default.default.readFile(path, "utf8"));
36
+ await Parser__default.default.validate(lodash.cloneDeep(yaml$1));
37
+ return yaml$1;
39
38
  }
40
39
  function toGeneratorAdditionalProperties({
41
40
  initialValue,
@@ -0,0 +1,11 @@
1
+ 'use strict';
2
+
3
+ var YAML = require('js-yaml');
4
+
5
+ const YAML_SCHEMA = YAML.CORE_SCHEMA.withTags(YAML.mergeTag);
6
+ function loadYaml(source) {
7
+ return YAML.load(source, { schema: YAML_SCHEMA });
8
+ }
9
+
10
+ exports.loadYaml = loadYaml;
11
+ //# sourceMappingURL=yaml.cjs.js.map
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var version = "0.19.2-next.1";
3
+ var version = "0.19.2-next.3";
4
4
 
5
5
  exports.version = version;
6
6
  //# sourceMappingURL=package.json.cjs.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/repo-tools",
3
- "version": "0.19.2-next.1",
3
+ "version": "0.19.2-next.3",
4
4
  "description": "CLI for Backstage repo tooling ",
5
5
  "backstage": {
6
6
  "role": "cli"
@@ -43,10 +43,10 @@
43
43
  "dependencies": {
44
44
  "@apidevtools/swagger-parser": "^10.1.0",
45
45
  "@apisyouwonthate/style-guide": "^1.4.0",
46
- "@backstage/backend-plugin-api": "1.11.0-next.1",
46
+ "@backstage/backend-plugin-api": "1.11.0-next.2",
47
47
  "@backstage/catalog-model": "1.10.2-next.0",
48
48
  "@backstage/cli-common": "0.3.2-next.0",
49
- "@backstage/cli-node": "0.3.5-next.0",
49
+ "@backstage/cli-node": "0.3.5-next.1",
50
50
  "@backstage/config-loader": "1.11.4-next.0",
51
51
  "@backstage/errors": "1.3.2-next.0",
52
52
  "@electric-sql/pglite": "^0.5.8",
@@ -67,11 +67,12 @@
67
67
  "codeowners-utils": "^1.0.2",
68
68
  "command-exists": "^1.2.9",
69
69
  "commander": "^14.0.3",
70
+ "diff": "^9.0.0",
70
71
  "fs-extra": "^11.2.0",
71
72
  "glob": "^13.0.0",
72
73
  "globby": "^11.0.0",
73
74
  "is-glob": "^4.0.3",
74
- "js-yaml": "^4.3.2",
75
+ "js-yaml": "^5.0.0",
75
76
  "just-diff": "^6.0.2",
76
77
  "knex": "^3.0.0",
77
78
  "knex-pglite": "^0.14.0",
@@ -86,7 +87,7 @@
86
87
  "zod": "^3.25.76 || ^4.0.0"
87
88
  },
88
89
  "devDependencies": {
89
- "@backstage/backend-test-utils": "1.11.8-next.1",
90
+ "@backstage/backend-test-utils": "1.11.8-next.2",
90
91
  "@backstage/cli": "0.36.7-next.0",
91
92
  "@backstage/types": "1.2.2",
92
93
  "@types/is-glob": "^4.0.2",