@backstage/repo-tools 0.7.1 → 0.8.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,32 @@
1
1
  # @backstage/repo-tools
2
2
 
3
+ ## 0.8.0-next.0
4
+
5
+ ### Minor Changes
6
+
7
+ - cfdc5e7: Adds two new commands, `repo schema openapi fuzz` and `package schema openapi fuzz` for fuzzing your plugins documented with OpenAPI. This can help find bugs in your application code through the use of auto-generated schema-compliant inputs. For more information on the underlying library this leverages, take a look at [the docs](https://schemathesis.readthedocs.io/en/stable/index.html).
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies
12
+ - @backstage/backend-common@0.21.7-next.0
13
+ - @backstage/config-loader@1.8.0-next.0
14
+ - @backstage/catalog-model@1.4.5
15
+ - @backstage/cli-common@0.1.13
16
+ - @backstage/cli-node@0.2.4
17
+ - @backstage/errors@1.2.4
18
+
19
+ ## 0.7.2
20
+
21
+ ### Patch Changes
22
+
23
+ - Updated dependencies
24
+ - @backstage/backend-common@0.21.6
25
+ - @backstage/catalog-model@1.4.5
26
+ - @backstage/cli-common@0.1.13
27
+ - @backstage/cli-node@0.2.4
28
+ - @backstage/errors@1.2.4
29
+
3
30
  ## 0.7.1
4
31
 
5
32
  ### Patch Changes
@@ -0,0 +1,39 @@
1
+ 'use strict';
2
+
3
+ var util = require('util');
4
+ var child_process = require('child_process');
5
+
6
+ const execPromise = util.promisify(child_process.exec);
7
+ const exec = (command, args = [], options) => {
8
+ return execPromise(
9
+ [
10
+ command,
11
+ ...args.filter((e) => e).map((e) => e.startsWith("-") ? e : `"${e}"`)
12
+ ].join(" "),
13
+ options
14
+ );
15
+ };
16
+ const spawn = (command, args, options) => {
17
+ return new Promise((resolve, reject) => {
18
+ var _a;
19
+ const cp = child_process.spawn(command, args, options != null ? options : {});
20
+ const error = [];
21
+ const stdout = [];
22
+ (_a = cp.stdout) == null ? void 0 : _a.on("data", (data) => {
23
+ stdout.push(data.toString());
24
+ });
25
+ cp.on("error", (e) => {
26
+ error.push(e.toString());
27
+ });
28
+ cp.on("close", (exitCode) => {
29
+ if (exitCode)
30
+ reject(error.join(""));
31
+ else
32
+ resolve(stdout.join(""));
33
+ });
34
+ });
35
+ };
36
+
37
+ exports.exec = exec;
38
+ exports.spawn = spawn;
39
+ //# sourceMappingURL=exec-B_ZXslMw.cjs.js.map
@@ -0,0 +1,45 @@
1
+ 'use strict';
2
+
3
+ var cliNode = require('@backstage/cli-node');
4
+ var exec = require('./exec-B_ZXslMw.cjs.js');
5
+ var chalk = require('chalk');
6
+ require('util');
7
+ require('child_process');
8
+
9
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
10
+
11
+ var chalk__default = /*#__PURE__*/_interopDefaultCompat(chalk);
12
+
13
+ async function command(opts) {
14
+ let packages = await cliNode.PackageGraph.listTargetPackages();
15
+ if (opts.since) {
16
+ const graph = cliNode.PackageGraph.fromPackages(packages);
17
+ const changedPackages = await graph.listChangedPackages({
18
+ ref: opts.since,
19
+ analyzeLockfile: true
20
+ });
21
+ const withDevDependents = graph.collectPackageNames(
22
+ changedPackages.map((pkg) => pkg.name),
23
+ (pkg) => pkg.localDevDependents.keys()
24
+ );
25
+ packages = Array.from(withDevDependents).map((name) => graph.get(name));
26
+ }
27
+ const fuzzablePackages = packages.filter((e) => {
28
+ var _a;
29
+ return (_a = e.packageJson.scripts) == null ? void 0 : _a.fuzz;
30
+ });
31
+ try {
32
+ for (const pkg of fuzzablePackages) {
33
+ await exec.exec("yarn", ["fuzz"], {
34
+ cwd: pkg.dir
35
+ });
36
+ }
37
+ console.log(chalk__default.default.green(`Successfully fuzzed.`));
38
+ } catch (err) {
39
+ console.error(err.stdout);
40
+ process.exit(1);
41
+ }
42
+ }
43
+
44
+ exports.command = command;
45
+ //# sourceMappingURL=fuzz-B61zys1g.cjs.js.map
@@ -0,0 +1,87 @@
1
+ 'use strict';
2
+
3
+ var fs = require('fs-extra');
4
+ var paths = require('./paths-BvbxdT_S.cjs.js');
5
+ var chalk = require('chalk');
6
+ var exec = require('./exec-B_ZXslMw.cjs.js');
7
+ var helpers = require('./helpers-Dd7PBM8s.cjs.js');
8
+ var configLoader = require('@backstage/config-loader');
9
+ var YAML = require('js-yaml');
10
+ var path = require('path');
11
+ var commandExists = require('command-exists');
12
+ require('@backstage/cli-common');
13
+ require('@backstage/cli-node');
14
+ require('minimatch');
15
+ require('util');
16
+ require('child_process');
17
+
18
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
19
+
20
+ var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
21
+ var chalk__default = /*#__PURE__*/_interopDefaultCompat(chalk);
22
+ var YAML__default = /*#__PURE__*/_interopDefaultCompat(YAML);
23
+
24
+ async function fuzz(opts) {
25
+ const resolvedOpenapiPath = await helpers.getPathToCurrentOpenApiSpec();
26
+ if (!commandExists.sync("st")) {
27
+ console.log(
28
+ chalk__default.default.red(
29
+ `Please install schemathesis globally with 'python -m pip install schemathesis'. Then run this command again.`
30
+ )
31
+ );
32
+ process.exit(1);
33
+ }
34
+ const openapiSpec = YAML__default.default.load(
35
+ await fs__default.default.readFile(resolvedOpenapiPath, "utf8")
36
+ );
37
+ const configSource = configLoader.ConfigSources.default({
38
+ rootDir: paths.paths.targetRoot
39
+ });
40
+ const config = await configLoader.ConfigSources.toConfig(configSource);
41
+ const pluginId = openapiSpec.info.title;
42
+ const args = [];
43
+ if (opts.debug) {
44
+ args.push(
45
+ "--cassette-path",
46
+ paths.paths.resolveTargetRoot(path.join(".cassettes", `${pluginId}.yml`))
47
+ );
48
+ }
49
+ if (opts.limit) {
50
+ args.push("--hypothesis-max-examples", opts.limit);
51
+ }
52
+ args.push("--workers", opts.workers);
53
+ if (opts.useGuest) {
54
+ args.push("--header", `Authorization: Basic guest`);
55
+ } else {
56
+ args.push("--header", `Authorization: Basic test`);
57
+ }
58
+ if (opts.excludeChecks) {
59
+ args.push("--exclude-checks", opts.excludeChecks);
60
+ }
61
+ await exec.spawn(
62
+ "st",
63
+ [
64
+ "run",
65
+ "--checks",
66
+ "all",
67
+ ...args,
68
+ `${config.getString("backend.baseUrl")}/api/${pluginId}/openapi.json`
69
+ ],
70
+ {
71
+ stdio: ["ignore", "inherit", "ignore"]
72
+ }
73
+ );
74
+ }
75
+ async function command(opts) {
76
+ try {
77
+ await fuzz(opts);
78
+ console.log(chalk__default.default.green(`Successfully fuzzed.`));
79
+ } catch (err) {
80
+ console.log(chalk__default.default.red(`OpenAPI fuzzing failed.`));
81
+ console.error(err);
82
+ process.exit(1);
83
+ }
84
+ }
85
+
86
+ exports.command = command;
87
+ //# sourceMappingURL=fuzz-BQh7xgC3.cjs.js.map
@@ -5,7 +5,7 @@ var path = require('path');
5
5
  var helpers = require('./helpers-Dd7PBM8s.cjs.js');
6
6
  var paths = require('./paths-BvbxdT_S.cjs.js');
7
7
  var fs = require('fs-extra');
8
- var exec$1 = require('./exec-d7-AweRf.cjs.js');
8
+ var exec$1 = require('./exec-B_ZXslMw.cjs.js');
9
9
  var backendCommon = require('@backstage/backend-common');
10
10
  var YAML = require('js-yaml');
11
11
  var util = require('util');
@@ -139,4 +139,4 @@ async function command(opts) {
139
139
  }
140
140
 
141
141
  exports.command = command;
142
- //# sourceMappingURL=index-CM0bJMpv.cjs.js.map
142
+ //# sourceMappingURL=index-CWbHgAsr.cjs.js.map
@@ -4,7 +4,7 @@ var fs = require('fs-extra');
4
4
  var helpers = require('./helpers-Dd7PBM8s.cjs.js');
5
5
  var paths = require('./paths-BvbxdT_S.cjs.js');
6
6
  var chalk = require('chalk');
7
- var exec = require('./exec-d7-AweRf.cjs.js');
7
+ var exec = require('./exec-B_ZXslMw.cjs.js');
8
8
  require('path');
9
9
  require('@backstage/cli-common');
10
10
  require('@backstage/cli-node');
@@ -70,4 +70,4 @@ async function singleCommand() {
70
70
  }
71
71
 
72
72
  exports.singleCommand = singleCommand;
73
- //# sourceMappingURL=init-q37Rum6N.cjs.js.map
73
+ //# sourceMappingURL=init-Canxj28t.cjs.js.map
@@ -6,7 +6,7 @@ var chalk = require('chalk');
6
6
  var runner = require('./runner-CRAhuK8A.cjs.js');
7
7
  var helpers = require('./helpers-Dd7PBM8s.cjs.js');
8
8
  var paths = require('./paths-BvbxdT_S.cjs.js');
9
- var exec = require('./exec-d7-AweRf.cjs.js');
9
+ var exec = require('./exec-B_ZXslMw.cjs.js');
10
10
  require('p-limit');
11
11
  require('portfinder');
12
12
  require('@backstage/cli-common');
@@ -95,4 +95,4 @@ async function bulkCommand(paths = [], options) {
95
95
  }
96
96
 
97
97
  exports.bulkCommand = bulkCommand;
98
- //# sourceMappingURL=test-Bjep-DJ3.cjs.js.map
98
+ //# sourceMappingURL=test-B-zlD07F.cjs.js.map
package/dist/index.cjs.js CHANGED
@@ -54,7 +54,7 @@ function registerPackageCommand(program) {
54
54
  "Initialize any required files to use the OpenAPI tooling for this package."
55
55
  ).action(
56
56
  lazy(
57
- () => Promise.resolve().then(function () { return require('./cjs/init-q37Rum6N.cjs.js'); }).then((m) => m.singleCommand)
57
+ () => Promise.resolve().then(function () { return require('./cjs/init-Canxj28t.cjs.js'); }).then((m) => m.singleCommand)
58
58
  )
59
59
  );
60
60
  openApiCommand.command("generate").option(
@@ -64,9 +64,20 @@ function registerPackageCommand(program) {
64
64
  "Command to generate a client and/or a server stub from an OpenAPI spec."
65
65
  ).action(
66
66
  lazy(
67
- () => Promise.resolve().then(function () { return require('./cjs/index-CM0bJMpv.cjs.js'); }).then((m) => m.command)
67
+ () => Promise.resolve().then(function () { return require('./cjs/index-CWbHgAsr.cjs.js'); }).then((m) => m.command)
68
68
  )
69
69
  );
70
+ openApiCommand.command("fuzz").description(
71
+ "Fuzz an OpenAPI schema by generating random data and sending it to the server."
72
+ ).option("--limit <limit>", "Maximum number of requests to send.").option("--workers <workers>", "Number of workers to use", "2").option(
73
+ "--debug",
74
+ `Enable debug mode, which will save cassettes to '.cassettes/{pluginId}.yml'`
75
+ ).option(
76
+ "--exclude-checks <excludeChecks>",
77
+ "Exclude checks from schemathesis run"
78
+ ).action(
79
+ lazy(() => Promise.resolve().then(function () { return require('./cjs/fuzz-BQh7xgC3.cjs.js'); }).then((m) => m.command))
80
+ );
70
81
  }
71
82
  function registerRepoCommand(program) {
72
83
  const command = program.command("repo [command]").description("Tools for working across your entire repository.");
@@ -86,7 +97,13 @@ function registerRepoCommand(program) {
86
97
  lazy(() => Promise.resolve().then(function () { return require('./cjs/lint-BNE-BGv5.cjs.js'); }).then((m) => m.bulkCommand))
87
98
  );
88
99
  openApiCommand.command("test [paths...]").description("Test OpenAPI schemas against written tests").option("--update", "Update the spec on failure.").action(
89
- lazy(() => Promise.resolve().then(function () { return require('./cjs/test-Bjep-DJ3.cjs.js'); }).then((m) => m.bulkCommand))
100
+ lazy(() => Promise.resolve().then(function () { return require('./cjs/test-B-zlD07F.cjs.js'); }).then((m) => m.bulkCommand))
101
+ );
102
+ openApiCommand.command("fuzz").description("Fuzz all packages").option(
103
+ "--since <ref>",
104
+ "Only fuzz packages that have changed since the given ref"
105
+ ).action(
106
+ lazy(() => Promise.resolve().then(function () { return require('./cjs/fuzz-B61zys1g.cjs.js'); }).then((m) => m.command))
90
107
  );
91
108
  }
92
109
  function registerCommands(program) {
@@ -151,7 +168,7 @@ function lazy(getActionFunc) {
151
168
  };
152
169
  }
153
170
 
154
- var version = "0.7.1";
171
+ var version = "0.8.0-next.0";
155
172
 
156
173
  const main = (argv) => {
157
174
  commander.program.name("backstage-repo-tools").version(version);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@backstage/repo-tools",
3
3
  "description": "CLI for Backstage repo tooling ",
4
- "version": "0.7.1",
4
+ "version": "0.8.0-next.0",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -32,10 +32,11 @@
32
32
  "dependencies": {
33
33
  "@apidevtools/swagger-parser": "^10.1.0",
34
34
  "@apisyouwonthate/style-guide": "^1.4.0",
35
- "@backstage/backend-common": "^0.21.5",
35
+ "@backstage/backend-common": "^0.21.7-next.0",
36
36
  "@backstage/catalog-model": "^1.4.5",
37
37
  "@backstage/cli-common": "^0.1.13",
38
38
  "@backstage/cli-node": "^0.2.4",
39
+ "@backstage/config-loader": "^1.8.0-next.0",
39
40
  "@backstage/errors": "^1.2.4",
40
41
  "@manypkg/get-packages": "^1.1.3",
41
42
  "@microsoft/api-documenter": "^7.22.33",
@@ -50,6 +51,7 @@
50
51
  "@stoplight/types": "^14.0.0",
51
52
  "chalk": "^4.0.0",
52
53
  "codeowners-utils": "^1.0.2",
54
+ "command-exists": "^1.2.9",
53
55
  "commander": "^12.0.0",
54
56
  "fs-extra": "^11.2.0",
55
57
  "glob": "^8.0.3",
@@ -62,8 +64,8 @@
62
64
  "yaml-diff-patch": "^2.0.0"
63
65
  },
64
66
  "devDependencies": {
65
- "@backstage/backend-test-utils": "^0.3.5",
66
- "@backstage/cli": "^0.26.1",
67
+ "@backstage/backend-test-utils": "^0.3.7-next.0",
68
+ "@backstage/cli": "^0.26.3-next.0",
67
69
  "@backstage/types": "^1.1.1",
68
70
  "@types/is-glob": "^4.0.2",
69
71
  "@types/node": "^18.17.8",
@@ -1,18 +0,0 @@
1
- 'use strict';
2
-
3
- var util = require('util');
4
- var child_process = require('child_process');
5
-
6
- const execPromise = util.promisify(child_process.exec);
7
- const exec = (command, options = [], execOptions) => {
8
- return execPromise(
9
- [
10
- command,
11
- ...options.filter((e) => e).map((e) => e.startsWith("-") ? e : `"${e}"`)
12
- ].join(" "),
13
- execOptions
14
- );
15
- };
16
-
17
- exports.exec = exec;
18
- //# sourceMappingURL=exec-d7-AweRf.cjs.js.map