@backstage/cli-module-lint 0.0.0-nightly-20260317031259

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 ADDED
@@ -0,0 +1,13 @@
1
+ # @backstage/cli-module-lint
2
+
3
+ ## 0.0.0-nightly-20260317031259
4
+
5
+ ### Minor Changes
6
+
7
+ - 329f394: Initial release of the CLI module packages. Each module provides a set of commands that can be discovered automatically by `@backstage/cli` or executed standalone.
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies
12
+ - @backstage/cli-node@0.0.0-nightly-20260317031259
13
+ - @backstage/cli-common@0.0.0-nightly-20260317031259
package/README.md ADDED
@@ -0,0 +1,15 @@
1
+ # @backstage/cli-module-lint
2
+
3
+ CLI module that provides linting commands for the Backstage CLI.
4
+
5
+ ## Commands
6
+
7
+ | Command | Description |
8
+ | :------------- | :---------------- |
9
+ | `package lint` | Lint a package |
10
+ | `repo lint` | Lint a repository |
11
+
12
+ ## Documentation
13
+
14
+ - [Backstage Readme](https://github.com/backstage/backstage/blob/master/README.md)
15
+ - [Backstage Documentation](https://backstage.io/docs)
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env node
2
+ /*
3
+ * Copyright 2024 The Backstage Authors
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ const path = require('node:path');
19
+
20
+ /* eslint-disable-next-line no-restricted-syntax */
21
+ const isLocal = require('node:fs').existsSync(
22
+ path.resolve(__dirname, '../src'),
23
+ );
24
+
25
+ if (isLocal) {
26
+ require('@backstage/cli-node/config/nodeTransform.cjs');
27
+ }
28
+
29
+ const { runCliModule } = require('@backstage/cli-node');
30
+ const cliModule = require(isLocal ? '../src/index' : '..').default;
31
+ const pkg = require('../package.json');
32
+ runCliModule({ module: cliModule, name: pkg.name, version: pkg.version });
@@ -0,0 +1,78 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var fs = require('fs-extra');
6
+ var cleye = require('cleye');
7
+ var cliCommon = require('@backstage/cli-common');
8
+ var eslint = require('eslint');
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
+ var lint = async ({ args, info }) => {
15
+ const {
16
+ flags: { fix, format, outputFile, maxWarnings },
17
+ _: directories
18
+ } = cleye.cli(
19
+ {
20
+ help: { ...info, usage: `${info.usage} [directories...]` },
21
+ booleanFlagNegation: true,
22
+ parameters: ["[directories...]"],
23
+ flags: {
24
+ fix: {
25
+ type: Boolean,
26
+ description: "Attempt to automatically fix violations"
27
+ },
28
+ format: {
29
+ type: String,
30
+ description: "Lint report output format",
31
+ default: "eslint-formatter-friendly"
32
+ },
33
+ outputFile: {
34
+ type: String,
35
+ description: "Write the lint report to a file instead of stdout"
36
+ },
37
+ maxWarnings: {
38
+ type: String,
39
+ description: "Fail if more than this number of warnings. -1 allows warnings. (default: -1)"
40
+ }
41
+ }
42
+ },
43
+ void 0,
44
+ args
45
+ );
46
+ const eslint$1 = new eslint.ESLint({
47
+ cwd: cliCommon.targetPaths.dir,
48
+ fix,
49
+ extensions: ["js", "jsx", "ts", "tsx", "mjs", "cjs"]
50
+ });
51
+ const results = await eslint$1.lintFiles(
52
+ directories.length ? directories : ["."]
53
+ );
54
+ const maxWarningsNum = maxWarnings ? +maxWarnings : -1;
55
+ const ignoreWarnings = maxWarningsNum === -1;
56
+ const failed = results.some((r) => r.errorCount > 0) || !ignoreWarnings && results.reduce((current, next) => current + next.warningCount, 0) > maxWarningsNum;
57
+ if (fix) {
58
+ await eslint.ESLint.outputFixes(results);
59
+ }
60
+ const formatter = await eslint$1.loadFormatter(format);
61
+ if (format === "eslint-formatter-friendly") {
62
+ process.chdir(cliCommon.targetPaths.rootDir);
63
+ }
64
+ const resultText = await formatter.format(results);
65
+ if (resultText) {
66
+ if (outputFile) {
67
+ await fs__default.default.writeFile(cliCommon.targetPaths.resolve(outputFile), resultText);
68
+ } else {
69
+ console.log(resultText);
70
+ }
71
+ }
72
+ if (failed) {
73
+ process.exit(1);
74
+ }
75
+ };
76
+
77
+ exports.default = lint;
78
+ //# sourceMappingURL=lint.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lint.cjs.js","sources":["../../../src/commands/package/lint.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport fs from 'fs-extra';\nimport { cli } from 'cleye';\nimport { targetPaths } from '@backstage/cli-common';\nimport { ESLint } from 'eslint';\nimport type { CliCommandContext } from '@backstage/cli-node';\n\nexport default async ({ args, info }: CliCommandContext) => {\n const {\n flags: { fix, format, outputFile, maxWarnings },\n _: directories,\n } = cli(\n {\n help: { ...info, usage: `${info.usage} [directories...]` },\n booleanFlagNegation: true,\n parameters: ['[directories...]'],\n flags: {\n fix: {\n type: Boolean,\n description: 'Attempt to automatically fix violations',\n },\n format: {\n type: String,\n description: 'Lint report output format',\n default: 'eslint-formatter-friendly',\n },\n outputFile: {\n type: String,\n description: 'Write the lint report to a file instead of stdout',\n },\n maxWarnings: {\n type: String,\n description:\n 'Fail if more than this number of warnings. -1 allows warnings. (default: -1)',\n },\n },\n },\n undefined,\n args,\n );\n\n const eslint = new ESLint({\n cwd: targetPaths.dir,\n fix,\n extensions: ['js', 'jsx', 'ts', 'tsx', 'mjs', 'cjs'],\n });\n\n const results = await eslint.lintFiles(\n directories.length ? directories : ['.'],\n );\n\n const maxWarningsNum = maxWarnings ? +maxWarnings : -1;\n const ignoreWarnings = maxWarningsNum === -1;\n\n const failed =\n results.some(r => r.errorCount > 0) ||\n (!ignoreWarnings &&\n results.reduce((current, next) => current + next.warningCount, 0) >\n maxWarningsNum);\n\n if (fix) {\n await ESLint.outputFixes(results);\n }\n\n const formatter = await eslint.loadFormatter(format);\n\n // This formatter uses the cwd to format file paths, so let's have that happen from the root instead\n if (format === 'eslint-formatter-friendly') {\n process.chdir(targetPaths.rootDir);\n }\n\n const resultText = await formatter.format(results);\n\n if (resultText) {\n if (outputFile) {\n await fs.writeFile(targetPaths.resolve(outputFile), resultText);\n } else {\n console.log(resultText);\n }\n }\n\n if (failed) {\n process.exit(1);\n }\n};\n"],"names":["cli","eslint","ESLint","targetPaths","fs"],"mappings":";;;;;;;;;;;;;AAsBA,WAAe,OAAO,EAAE,IAAA,EAAM,IAAA,EAAK,KAAyB;AAC1D,EAAA,MAAM;AAAA,IACJ,KAAA,EAAO,EAAE,GAAA,EAAK,MAAA,EAAQ,YAAY,WAAA,EAAY;AAAA,IAC9C,CAAA,EAAG;AAAA,GACL,GAAIA,SAAA;AAAA,IACF;AAAA,MACE,IAAA,EAAM,EAAE,GAAG,IAAA,EAAM,OAAO,CAAA,EAAG,IAAA,CAAK,KAAK,CAAA,iBAAA,CAAA,EAAoB;AAAA,MACzD,mBAAA,EAAqB,IAAA;AAAA,MACrB,UAAA,EAAY,CAAC,kBAAkB,CAAA;AAAA,MAC/B,KAAA,EAAO;AAAA,QACL,GAAA,EAAK;AAAA,UACH,IAAA,EAAM,OAAA;AAAA,UACN,WAAA,EAAa;AAAA,SACf;AAAA,QACA,MAAA,EAAQ;AAAA,UACN,IAAA,EAAM,MAAA;AAAA,UACN,WAAA,EAAa,2BAAA;AAAA,UACb,OAAA,EAAS;AAAA,SACX;AAAA,QACA,UAAA,EAAY;AAAA,UACV,IAAA,EAAM,MAAA;AAAA,UACN,WAAA,EAAa;AAAA,SACf;AAAA,QACA,WAAA,EAAa;AAAA,UACX,IAAA,EAAM,MAAA;AAAA,UACN,WAAA,EACE;AAAA;AACJ;AACF,KACF;AAAA,IACA,MAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,MAAMC,QAAA,GAAS,IAAIC,aAAA,CAAO;AAAA,IACxB,KAAKC,qBAAA,CAAY,GAAA;AAAA,IACjB,GAAA;AAAA,IACA,YAAY,CAAC,IAAA,EAAM,OAAO,IAAA,EAAM,KAAA,EAAO,OAAO,KAAK;AAAA,GACpD,CAAA;AAED,EAAA,MAAM,OAAA,GAAU,MAAMF,QAAA,CAAO,SAAA;AAAA,IAC3B,WAAA,CAAY,MAAA,GAAS,WAAA,GAAc,CAAC,GAAG;AAAA,GACzC;AAEA,EAAA,MAAM,cAAA,GAAiB,WAAA,GAAc,CAAC,WAAA,GAAc,EAAA;AACpD,EAAA,MAAM,iBAAiB,cAAA,KAAmB,EAAA;AAE1C,EAAA,MAAM,SACJ,OAAA,CAAQ,IAAA,CAAK,OAAK,CAAA,CAAE,UAAA,GAAa,CAAC,CAAA,IACjC,CAAC,kBACA,OAAA,CAAQ,MAAA,CAAO,CAAC,OAAA,EAAS,IAAA,KAAS,UAAU,IAAA,CAAK,YAAA,EAAc,CAAC,CAAA,GAC9D,cAAA;AAEN,EAAA,IAAI,GAAA,EAAK;AACP,IAAA,MAAMC,aAAA,CAAO,YAAY,OAAO,CAAA;AAAA,EAClC;AAEA,EAAA,MAAM,SAAA,GAAY,MAAMD,QAAA,CAAO,aAAA,CAAc,MAAM,CAAA;AAGnD,EAAA,IAAI,WAAW,2BAAA,EAA6B;AAC1C,IAAA,OAAA,CAAQ,KAAA,CAAME,sBAAY,OAAO,CAAA;AAAA,EACnC;AAEA,EAAA,MAAM,UAAA,GAAa,MAAM,SAAA,CAAU,MAAA,CAAO,OAAO,CAAA;AAEjD,EAAA,IAAI,UAAA,EAAY;AACd,IAAA,IAAI,UAAA,EAAY;AACd,MAAA,MAAMC,oBAAG,SAAA,CAAUD,qBAAA,CAAY,OAAA,CAAQ,UAAU,GAAG,UAAU,CAAA;AAAA,IAChE,CAAA,MAAO;AACL,MAAA,OAAA,CAAQ,IAAI,UAAU,CAAA;AAAA,IACxB;AAAA,EACF;AAEA,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AACF,CAAA;;;;"}
@@ -0,0 +1,282 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var chalk = require('chalk');
6
+ var fs = require('fs-extra');
7
+ var cleye = require('cleye');
8
+ var node_crypto = require('node:crypto');
9
+ var node_path = require('node:path');
10
+ var cliNode = require('@backstage/cli-node');
11
+ var cliCommon = require('@backstage/cli-common');
12
+ var optionsParser = require('../../lib/optionsParser.cjs.js');
13
+
14
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
15
+
16
+ var chalk__default = /*#__PURE__*/_interopDefaultCompat(chalk);
17
+ var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
18
+
19
+ function depCount(pkg) {
20
+ const deps = pkg.dependencies ? Object.keys(pkg.dependencies).length : 0;
21
+ const devDeps = pkg.devDependencies ? Object.keys(pkg.devDependencies).length : 0;
22
+ return deps + devDeps;
23
+ }
24
+ var lint = async ({ args, info }) => {
25
+ for (const flag of [
26
+ "outputFile",
27
+ "successCache",
28
+ "successCacheDir",
29
+ "maxWarnings"
30
+ ]) {
31
+ if (args.some((a) => a === `--${flag}` || a.startsWith(`--${flag}=`))) {
32
+ process.stderr.write(
33
+ `DEPRECATION WARNING: --${flag} is deprecated, use the kebab-case form instead
34
+ `
35
+ );
36
+ }
37
+ }
38
+ const {
39
+ flags: {
40
+ fix,
41
+ format,
42
+ outputFile,
43
+ successCache: useSuccessCache,
44
+ successCacheDir,
45
+ since,
46
+ maxWarnings
47
+ }
48
+ } = cleye.cli(
49
+ {
50
+ help: info,
51
+ booleanFlagNegation: true,
52
+ flags: {
53
+ fix: {
54
+ type: Boolean,
55
+ description: "Attempt to automatically fix violations"
56
+ },
57
+ format: {
58
+ type: String,
59
+ description: "Lint report output format",
60
+ default: "eslint-formatter-friendly"
61
+ },
62
+ outputFile: {
63
+ type: String,
64
+ description: "Write the lint report to a file instead of stdout"
65
+ },
66
+ successCache: {
67
+ type: Boolean,
68
+ description: "Enable success caching, which skips running tests for unchanged packages that were successful in the previous run"
69
+ },
70
+ successCacheDir: {
71
+ type: String,
72
+ description: "Set the success cache location, (default: node_modules/.cache/backstage-cli)"
73
+ },
74
+ since: {
75
+ type: String,
76
+ description: "Only lint packages that changed since the specified ref"
77
+ },
78
+ maxWarnings: {
79
+ type: String,
80
+ description: "Fail if more than this number of warnings. -1 allows warnings. (default: -1)"
81
+ }
82
+ }
83
+ },
84
+ void 0,
85
+ args
86
+ );
87
+ let packages = await cliNode.PackageGraph.listTargetPackages();
88
+ const cache = cliNode.SuccessCache.create({
89
+ name: "lint",
90
+ basePath: successCacheDir
91
+ });
92
+ const cacheContext = useSuccessCache ? {
93
+ entries: await cache.read(),
94
+ lockfile: await cliNode.Lockfile.load(cliCommon.targetPaths.resolveRoot("yarn.lock"))
95
+ } : void 0;
96
+ if (since) {
97
+ const graph = cliNode.PackageGraph.fromPackages(packages);
98
+ packages = await graph.listChangedPackages({
99
+ ref: since,
100
+ analyzeLockfile: true
101
+ });
102
+ }
103
+ packages.sort((a, b) => depCount(b.packageJson) - depCount(a.packageJson));
104
+ if (format === "eslint-formatter-friendly") {
105
+ process.chdir(cliCommon.targetPaths.rootDir);
106
+ }
107
+ if (!process.env.FORCE_COLOR) {
108
+ process.env.FORCE_COLOR = "1";
109
+ }
110
+ const parseLintScript = optionsParser.createScriptOptionsParser(["package", "lint"], {
111
+ fix: { type: "boolean" },
112
+ format: { type: "string" },
113
+ "output-file": { type: "string" },
114
+ "max-warnings": { type: "string" }
115
+ });
116
+ const items = await Promise.all(
117
+ packages.map(async (pkg) => {
118
+ const lintOptions = parseLintScript(pkg.packageJson.scripts?.lint);
119
+ const base = {
120
+ fullDir: pkg.dir,
121
+ relativeDir: node_path.relative(cliCommon.targetPaths.rootDir, pkg.dir),
122
+ lintOptions,
123
+ parentHash: void 0
124
+ };
125
+ if (!cacheContext) {
126
+ return base;
127
+ }
128
+ const hash = node_crypto.createHash("sha1");
129
+ hash.update(
130
+ cacheContext.lockfile.getDependencyTreeHash(pkg.packageJson.name)
131
+ );
132
+ hash.update("\0");
133
+ hash.update(JSON.stringify(lintOptions ?? {}));
134
+ hash.update("\0");
135
+ hash.update(process.version);
136
+ hash.update("\0");
137
+ hash.update("v1");
138
+ return {
139
+ ...base,
140
+ parentHash: hash.digest("hex")
141
+ };
142
+ })
143
+ );
144
+ const { results: resultsList } = await cliNode.runWorkerQueueThreads({
145
+ items: items.filter((item) => item.lintOptions),
146
+ // Filter out packages without lint script
147
+ context: {
148
+ fix: Boolean(fix),
149
+ format,
150
+ shouldCache: Boolean(cacheContext),
151
+ maxWarnings: maxWarnings ?? "-1",
152
+ successCache: cacheContext?.entries,
153
+ rootDir: cliCommon.targetPaths.rootDir
154
+ },
155
+ workerFactory: async ({
156
+ fix: workerFix,
157
+ format: workerFormat,
158
+ shouldCache,
159
+ successCache,
160
+ rootDir,
161
+ maxWarnings: workerMaxWarnings
162
+ }) => {
163
+ const { ESLint } = require("eslint");
164
+ const crypto = require("node:crypto");
165
+ const globby = require("globby");
166
+ const { readFile } = require("node:fs/promises");
167
+ const workerPath = require("node:path");
168
+ return async ({
169
+ fullDir,
170
+ relativeDir,
171
+ parentHash
172
+ }) => {
173
+ process.cwd = () => fullDir;
174
+ const start = Date.now();
175
+ const eslint = new ESLint({
176
+ cwd: fullDir,
177
+ fix: workerFix,
178
+ extensions: ["js", "jsx", "ts", "tsx", "mjs", "cjs"]
179
+ });
180
+ let sha = void 0;
181
+ if (shouldCache) {
182
+ const result = await globby(relativeDir, {
183
+ gitignore: true,
184
+ onlyFiles: true,
185
+ cwd: rootDir
186
+ });
187
+ const hash = crypto.createHash("sha1");
188
+ hash.update(parentHash);
189
+ hash.update("\0");
190
+ for (const path of result.sort()) {
191
+ const absPath = workerPath.resolve(rootDir, path);
192
+ const pathInPackage = workerPath.relative(fullDir, absPath);
193
+ if (await eslint.isPathIgnored(pathInPackage)) {
194
+ continue;
195
+ }
196
+ hash.update(pathInPackage);
197
+ hash.update("\0");
198
+ hash.update(await readFile(absPath));
199
+ hash.update("\0");
200
+ hash.update(
201
+ JSON.stringify(
202
+ await eslint.calculateConfigForFile(pathInPackage)
203
+ ).replaceAll(rootDir, "")
204
+ );
205
+ hash.update("\0");
206
+ }
207
+ sha = await hash.digest("hex");
208
+ if (successCache?.has(sha)) {
209
+ console.log(`Skipped ${relativeDir} due to cache hit`);
210
+ return { relativeDir, sha, failed: false };
211
+ }
212
+ }
213
+ const formatter = await eslint.loadFormatter(workerFormat);
214
+ const results = await eslint.lintFiles(["."]);
215
+ const count = String(results.length).padStart(3);
216
+ const time = ((Date.now() - start) / 1e3).toFixed(2);
217
+ console.log(`Checked ${count} files in ${relativeDir} ${time}s`);
218
+ if (workerFix) {
219
+ await ESLint.outputFixes(results);
220
+ }
221
+ const ignoreWarnings = +workerMaxWarnings === -1;
222
+ const resultText = formatter.format(results);
223
+ const failed2 = results.some((r) => r.errorCount > 0) || !ignoreWarnings && results.reduce((current, next) => current + next.warningCount, 0) > +workerMaxWarnings;
224
+ return {
225
+ relativeDir,
226
+ resultText,
227
+ failed: failed2,
228
+ sha
229
+ };
230
+ };
231
+ }
232
+ });
233
+ const outputSuccessCache = [];
234
+ const jsonResults = [];
235
+ let errorOutput = "";
236
+ let failed = false;
237
+ for (const {
238
+ relativeDir,
239
+ resultText,
240
+ failed: runFailed,
241
+ sha
242
+ } of resultsList) {
243
+ if (runFailed) {
244
+ console.log(chalk__default.default.red(`Lint failed in ${relativeDir}`));
245
+ failed = true;
246
+ if (resultText) {
247
+ if (outputFile) {
248
+ if (format === "json") {
249
+ jsonResults.push(resultText);
250
+ } else {
251
+ errorOutput += `${resultText}
252
+ `;
253
+ }
254
+ } else {
255
+ console.log();
256
+ console.log(resultText.trimStart());
257
+ }
258
+ }
259
+ } else if (sha) {
260
+ outputSuccessCache.push(sha);
261
+ }
262
+ }
263
+ if (format === "json") {
264
+ let mergedJsonResults = [];
265
+ for (const jsonResult of jsonResults) {
266
+ mergedJsonResults = mergedJsonResults.concat(JSON.parse(jsonResult));
267
+ }
268
+ errorOutput = JSON.stringify(mergedJsonResults, null, 2);
269
+ }
270
+ if (outputFile && errorOutput) {
271
+ await fs__default.default.writeFile(cliCommon.targetPaths.resolveRoot(outputFile), errorOutput);
272
+ }
273
+ if (cacheContext) {
274
+ await cache.write(outputSuccessCache);
275
+ }
276
+ if (failed) {
277
+ process.exit(1);
278
+ }
279
+ };
280
+
281
+ exports.default = lint;
282
+ //# sourceMappingURL=lint.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lint.cjs.js","sources":["../../../src/commands/repo/lint.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport chalk from 'chalk';\nimport fs from 'fs-extra';\nimport { cli } from 'cleye';\nimport { createHash } from 'node:crypto';\nimport { relative as relativePath } from 'node:path';\nimport {\n PackageGraph,\n BackstagePackageJson,\n Lockfile,\n runWorkerQueueThreads,\n SuccessCache,\n} from '@backstage/cli-node';\nimport { targetPaths } from '@backstage/cli-common';\n\nimport { createScriptOptionsParser } from '../../lib/optionsParser';\nimport type { CliCommandContext } from '@backstage/cli-node';\n\nfunction depCount(pkg: BackstagePackageJson) {\n const deps = pkg.dependencies ? Object.keys(pkg.dependencies).length : 0;\n const devDeps = pkg.devDependencies\n ? Object.keys(pkg.devDependencies).length\n : 0;\n return deps + devDeps;\n}\n\nexport default async ({ args, info }: CliCommandContext) => {\n for (const flag of [\n 'outputFile',\n 'successCache',\n 'successCacheDir',\n 'maxWarnings',\n ]) {\n if (args.some(a => a === `--${flag}` || a.startsWith(`--${flag}=`))) {\n process.stderr.write(\n `DEPRECATION WARNING: --${flag} is deprecated, use the kebab-case form instead\\n`,\n );\n }\n }\n\n const {\n flags: {\n fix,\n format,\n outputFile,\n successCache: useSuccessCache,\n successCacheDir,\n since,\n maxWarnings,\n },\n } = cli(\n {\n help: info,\n booleanFlagNegation: true,\n flags: {\n fix: {\n type: Boolean,\n description: 'Attempt to automatically fix violations',\n },\n format: {\n type: String,\n description: 'Lint report output format',\n default: 'eslint-formatter-friendly',\n },\n outputFile: {\n type: String,\n description: 'Write the lint report to a file instead of stdout',\n },\n successCache: {\n type: Boolean,\n description:\n 'Enable success caching, which skips running tests for unchanged packages that were successful in the previous run',\n },\n successCacheDir: {\n type: String,\n description:\n 'Set the success cache location, (default: node_modules/.cache/backstage-cli)',\n },\n since: {\n type: String,\n description:\n 'Only lint packages that changed since the specified ref',\n },\n maxWarnings: {\n type: String,\n description:\n 'Fail if more than this number of warnings. -1 allows warnings. (default: -1)',\n },\n },\n },\n undefined,\n args,\n );\n\n let packages = await PackageGraph.listTargetPackages();\n\n const cache = SuccessCache.create({\n name: 'lint',\n basePath: successCacheDir,\n });\n const cacheContext = useSuccessCache\n ? {\n entries: await cache.read(),\n lockfile: await Lockfile.load(targetPaths.resolveRoot('yarn.lock')),\n }\n : undefined;\n\n if (since) {\n const graph = PackageGraph.fromPackages(packages);\n packages = await graph.listChangedPackages({\n ref: since,\n analyzeLockfile: true,\n });\n }\n\n // Packages are ordered from most to least number of dependencies, as a\n // very cheap way of guessing which packages are more likely to be larger.\n packages.sort((a, b) => depCount(b.packageJson) - depCount(a.packageJson));\n\n // This formatter uses the cwd to format file paths, so let's have that happen from the root instead\n if (format === 'eslint-formatter-friendly') {\n process.chdir(targetPaths.rootDir);\n }\n\n // Make sure lint output is colored unless the user explicitly disabled it\n if (!process.env.FORCE_COLOR) {\n process.env.FORCE_COLOR = '1';\n }\n\n const parseLintScript = createScriptOptionsParser(['package', 'lint'], {\n fix: { type: 'boolean' },\n format: { type: 'string' },\n 'output-file': { type: 'string' },\n 'max-warnings': { type: 'string' },\n });\n\n const items = await Promise.all(\n packages.map(async pkg => {\n const lintOptions = parseLintScript(pkg.packageJson.scripts?.lint);\n const base = {\n fullDir: pkg.dir,\n relativeDir: relativePath(targetPaths.rootDir, pkg.dir),\n lintOptions,\n parentHash: undefined,\n };\n\n if (!cacheContext) {\n return base;\n }\n\n const hash = createHash('sha1');\n\n hash.update(\n cacheContext.lockfile.getDependencyTreeHash(pkg.packageJson.name),\n );\n hash.update('\\0');\n hash.update(JSON.stringify(lintOptions ?? {}));\n hash.update('\\0');\n hash.update(process.version); // Node.js version\n hash.update('\\0');\n hash.update('v1'); // The version of this implementation\n\n return {\n ...base,\n parentHash: hash.digest('hex'),\n };\n }),\n );\n\n const { results: resultsList } = await runWorkerQueueThreads({\n items: items.filter(item => item.lintOptions), // Filter out packages without lint script\n context: {\n fix: Boolean(fix),\n format: format as string | undefined,\n shouldCache: Boolean(cacheContext),\n maxWarnings: maxWarnings ?? '-1',\n successCache: cacheContext?.entries,\n rootDir: targetPaths.rootDir,\n },\n workerFactory: async ({\n fix: workerFix,\n format: workerFormat,\n shouldCache,\n successCache,\n rootDir,\n maxWarnings: workerMaxWarnings,\n }) => {\n const { ESLint } = require('eslint') as typeof import('eslint');\n const crypto = require('node:crypto') as typeof import('crypto');\n const globby = require('globby') as typeof import('globby');\n const { readFile } =\n require('node:fs/promises') as typeof import('fs/promises');\n const workerPath = require('node:path') as typeof import('path');\n\n return async ({\n fullDir,\n relativeDir,\n parentHash,\n }): Promise<{\n relativeDir: string;\n sha?: string;\n resultText?: string;\n failed: boolean;\n }> => {\n // Bit of a hack to make file resolutions happen from the correct directory\n // since some lint rules don't respect the cwd of ESLint\n process.cwd = () => fullDir;\n\n const start = Date.now();\n const eslint = new ESLint({\n cwd: fullDir,\n fix: workerFix,\n extensions: ['js', 'jsx', 'ts', 'tsx', 'mjs', 'cjs'],\n });\n\n let sha: string | undefined = undefined;\n if (shouldCache) {\n const result = await globby(relativeDir, {\n gitignore: true,\n onlyFiles: true,\n cwd: rootDir,\n });\n\n const hash = crypto.createHash('sha1');\n hash.update(parentHash!);\n hash.update('\\0');\n\n for (const path of result.sort()) {\n const absPath = workerPath.resolve(rootDir, path);\n const pathInPackage = workerPath.relative(fullDir, absPath);\n\n if (await eslint.isPathIgnored(pathInPackage)) {\n continue;\n }\n hash.update(pathInPackage);\n hash.update('\\0');\n hash.update(await readFile(absPath));\n hash.update('\\0');\n hash.update(\n JSON.stringify(\n await eslint.calculateConfigForFile(pathInPackage),\n ).replaceAll(rootDir, ''),\n );\n hash.update('\\0');\n }\n sha = await hash.digest('hex');\n if (successCache?.has(sha)) {\n console.log(`Skipped ${relativeDir} due to cache hit`);\n return { relativeDir, sha, failed: false };\n }\n }\n\n const formatter = await eslint.loadFormatter(workerFormat);\n\n const results = await eslint.lintFiles(['.']);\n\n const count = String(results.length).padStart(3);\n const time = ((Date.now() - start) / 1000).toFixed(2);\n console.log(`Checked ${count} files in ${relativeDir} ${time}s`);\n\n if (workerFix) {\n await ESLint.outputFixes(results);\n }\n\n const ignoreWarnings = +workerMaxWarnings === -1;\n\n const resultText = formatter.format(results) as string;\n const failed =\n results.some(r => r.errorCount > 0) ||\n (!ignoreWarnings &&\n results.reduce((current, next) => current + next.warningCount, 0) >\n +workerMaxWarnings);\n\n return {\n relativeDir,\n resultText,\n failed,\n sha,\n };\n };\n },\n });\n\n const outputSuccessCache = [];\n const jsonResults = [];\n\n let errorOutput = '';\n\n let failed = false;\n for (const {\n relativeDir,\n resultText,\n failed: runFailed,\n sha,\n } of resultsList) {\n if (runFailed) {\n console.log(chalk.red(`Lint failed in ${relativeDir}`));\n failed = true;\n\n // When doing repo lint, only list the results if the lint failed to avoid a log\n // dump of all warnings that might be irrelevant\n if (resultText) {\n if (outputFile) {\n if (format === 'json') {\n jsonResults.push(resultText);\n } else {\n errorOutput += `${resultText}\\n`;\n }\n } else {\n console.log();\n console.log(resultText.trimStart());\n }\n }\n } else if (sha) {\n outputSuccessCache.push(sha);\n }\n }\n\n if (format === 'json') {\n let mergedJsonResults: any[] = [];\n for (const jsonResult of jsonResults) {\n mergedJsonResults = mergedJsonResults.concat(JSON.parse(jsonResult));\n }\n errorOutput = JSON.stringify(mergedJsonResults, null, 2);\n }\n\n if (outputFile && errorOutput) {\n await fs.writeFile(targetPaths.resolveRoot(outputFile), errorOutput);\n }\n\n if (cacheContext) {\n await cache.write(outputSuccessCache);\n }\n\n if (failed) {\n process.exit(1);\n }\n};\n"],"names":["cli","PackageGraph","SuccessCache","Lockfile","targetPaths","createScriptOptionsParser","relativePath","createHash","runWorkerQueueThreads","failed","chalk","fs"],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var cliNode = require('@backstage/cli-node');
6
+ var _package = require('./package.json.cjs.js');
7
+
8
+ var index = cliNode.createCliModule({
9
+ packageJson: _package.default,
10
+ init: async (reg) => {
11
+ reg.addCommand({
12
+ path: ["package", "lint"],
13
+ description: "Lint a package",
14
+ execute: { loader: () => import('./commands/package/lint.cjs.js') }
15
+ });
16
+ reg.addCommand({
17
+ path: ["repo", "lint"],
18
+ description: "Lint a repository",
19
+ execute: { loader: () => import('./commands/repo/lint.cjs.js') }
20
+ });
21
+ }
22
+ });
23
+
24
+ exports.default = index;
25
+ //# sourceMappingURL=index.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs.js","sources":["../src/index.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { createCliModule } from '@backstage/cli-node';\nimport packageJson from '../package.json';\n\nexport default createCliModule({\n packageJson,\n init: async reg => {\n reg.addCommand({\n path: ['package', 'lint'],\n description: 'Lint a package',\n execute: { loader: () => import('./commands/package/lint') },\n });\n\n reg.addCommand({\n path: ['repo', 'lint'],\n description: 'Lint a repository',\n execute: { loader: () => import('./commands/repo/lint') },\n });\n },\n});\n"],"names":["createCliModule","packageJson"],"mappings":";;;;;;;AAkBA,YAAeA,uBAAA,CAAgB;AAAA,eAC7BC,gBAAA;AAAA,EACA,IAAA,EAAM,OAAM,GAAA,KAAO;AACjB,IAAA,GAAA,CAAI,UAAA,CAAW;AAAA,MACb,IAAA,EAAM,CAAC,SAAA,EAAW,MAAM,CAAA;AAAA,MACxB,WAAA,EAAa,gBAAA;AAAA,MACb,SAAS,EAAE,MAAA,EAAQ,MAAM,OAAO,gCAAyB,CAAA;AAAE,KAC5D,CAAA;AAED,IAAA,GAAA,CAAI,UAAA,CAAW;AAAA,MACb,IAAA,EAAM,CAAC,MAAA,EAAQ,MAAM,CAAA;AAAA,MACrB,WAAA,EAAa,mBAAA;AAAA,MACb,SAAS,EAAE,MAAA,EAAQ,MAAM,OAAO,6BAAsB,CAAA;AAAE,KACzD,CAAA;AAAA,EACH;AACF,CAAC,CAAA;;;;"}
@@ -0,0 +1,5 @@
1
+ import * as _backstage_cli_node from '@backstage/cli-node';
2
+
3
+ declare const _default: _backstage_cli_node.CliModule;
4
+
5
+ export { _default as default };
@@ -0,0 +1,22 @@
1
+ 'use strict';
2
+
3
+ var node_util = require('node:util');
4
+ var shellQuote = require('shell-quote');
5
+
6
+ function createScriptOptionsParser(commandPath, options) {
7
+ const expectedScript = `backstage-cli ${commandPath.join(" ")}`;
8
+ return (scriptStr) => {
9
+ if (!scriptStr || !scriptStr.startsWith(expectedScript)) {
10
+ return void 0;
11
+ }
12
+ const argsStr = scriptStr.slice(expectedScript.length).trim();
13
+ const args = argsStr ? shellQuote.parse(argsStr).filter(
14
+ (e) => typeof e === "string"
15
+ ) : [];
16
+ const { values } = node_util.parseArgs({ args, strict: false, options });
17
+ return values;
18
+ };
19
+ }
20
+
21
+ exports.createScriptOptionsParser = createScriptOptionsParser;
22
+ //# sourceMappingURL=optionsParser.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"optionsParser.cjs.js","sources":["../../src/lib/optionsParser.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { parseArgs, type ParseArgsConfig } from 'node:util';\nimport { parse as parseShellArgs } from 'shell-quote';\n\nexport function createScriptOptionsParser(\n commandPath: string[],\n options: ParseArgsConfig['options'],\n) {\n const expectedScript = `backstage-cli ${commandPath.join(' ')}`;\n\n return (scriptStr?: string) => {\n if (!scriptStr || !scriptStr.startsWith(expectedScript)) {\n return undefined;\n }\n\n const argsStr = scriptStr.slice(expectedScript.length).trim();\n const args = argsStr\n ? parseShellArgs(argsStr).filter(\n (e): e is string => typeof e === 'string',\n )\n : [];\n\n const { values } = parseArgs({ args, strict: false, options });\n return values;\n };\n}\n"],"names":["parseShellArgs","parseArgs"],"mappings":";;;;;AAkBO,SAAS,yBAAA,CACd,aACA,OAAA,EACA;AACA,EAAA,MAAM,cAAA,GAAiB,CAAA,cAAA,EAAiB,WAAA,CAAY,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA;AAE7D,EAAA,OAAO,CAAC,SAAA,KAAuB;AAC7B,IAAA,IAAI,CAAC,SAAA,IAAa,CAAC,SAAA,CAAU,UAAA,CAAW,cAAc,CAAA,EAAG;AACvD,MAAA,OAAO,MAAA;AAAA,IACT;AAEA,IAAA,MAAM,UAAU,SAAA,CAAU,KAAA,CAAM,cAAA,CAAe,MAAM,EAAE,IAAA,EAAK;AAC5D,IAAA,MAAM,IAAA,GAAO,OAAA,GACTA,gBAAA,CAAe,OAAO,CAAA,CAAE,MAAA;AAAA,MACtB,CAAC,CAAA,KAAmB,OAAO,CAAA,KAAM;AAAA,QAEnC,EAAC;AAEL,IAAA,MAAM,EAAE,QAAO,GAAIC,mBAAA,CAAU,EAAE,IAAA,EAAM,MAAA,EAAQ,KAAA,EAAO,OAAA,EAAS,CAAA;AAC7D,IAAA,OAAO,MAAA;AAAA,EACT,CAAA;AACF;;;;"}
@@ -0,0 +1,88 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var name = "@backstage/cli-module-lint";
6
+ var version = "0.0.0-nightly-20260317031259";
7
+ var description = "CLI module for Backstage CLI";
8
+ var backstage = {
9
+ role: "cli-module"
10
+ };
11
+ var publishConfig = {
12
+ access: "public",
13
+ main: "dist/index.cjs.js",
14
+ types: "dist/index.d.ts"
15
+ };
16
+ var homepage = "https://backstage.io";
17
+ var repository = {
18
+ type: "git",
19
+ url: "https://github.com/backstage/backstage",
20
+ directory: "packages/cli-module-lint"
21
+ };
22
+ var license = "Apache-2.0";
23
+ var main = "src/index.ts";
24
+ var types = "src/index.ts";
25
+ var files = [
26
+ "dist",
27
+ "bin"
28
+ ];
29
+ var scripts = {
30
+ build: "backstage-cli package build",
31
+ clean: "backstage-cli package clean",
32
+ lint: "backstage-cli package lint",
33
+ prepack: "backstage-cli package prepack",
34
+ postpack: "backstage-cli package postpack",
35
+ test: "backstage-cli package test"
36
+ };
37
+ var dependencies = {
38
+ "@backstage/cli-common": "workspace:*",
39
+ "@backstage/cli-node": "workspace:*",
40
+ chalk: "^4.0.0",
41
+ cleye: "^2.3.0",
42
+ eslint: "^8.6.0",
43
+ "eslint-formatter-friendly": "^7.0.0",
44
+ "fs-extra": "^11.2.0",
45
+ globby: "^11.1.0",
46
+ "shell-quote": "^1.8.1"
47
+ };
48
+ var devDependencies = {
49
+ "@backstage/cli": "workspace:*",
50
+ "@types/fs-extra": "^11.0.0",
51
+ "@types/shell-quote": "^1.7.5"
52
+ };
53
+ var bin = "bin/backstage-cli-module-lint";
54
+ var packageJson = {
55
+ name: name,
56
+ version: version,
57
+ description: description,
58
+ backstage: backstage,
59
+ publishConfig: publishConfig,
60
+ homepage: homepage,
61
+ repository: repository,
62
+ license: license,
63
+ main: main,
64
+ types: types,
65
+ files: files,
66
+ scripts: scripts,
67
+ dependencies: dependencies,
68
+ devDependencies: devDependencies,
69
+ bin: bin
70
+ };
71
+
72
+ exports.backstage = backstage;
73
+ exports.bin = bin;
74
+ exports.default = packageJson;
75
+ exports.dependencies = dependencies;
76
+ exports.description = description;
77
+ exports.devDependencies = devDependencies;
78
+ exports.files = files;
79
+ exports.homepage = homepage;
80
+ exports.license = license;
81
+ exports.main = main;
82
+ exports.name = name;
83
+ exports.publishConfig = publishConfig;
84
+ exports.repository = repository;
85
+ exports.scripts = scripts;
86
+ exports.types = types;
87
+ exports.version = version;
88
+ //# sourceMappingURL=package.json.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package.json.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@backstage/cli-module-lint",
3
+ "version": "0.0.0-nightly-20260317031259",
4
+ "description": "CLI module for Backstage CLI",
5
+ "backstage": {
6
+ "role": "cli-module"
7
+ },
8
+ "publishConfig": {
9
+ "access": "public",
10
+ "main": "dist/index.cjs.js",
11
+ "types": "dist/index.d.ts"
12
+ },
13
+ "homepage": "https://backstage.io",
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "https://github.com/backstage/backstage",
17
+ "directory": "packages/cli-module-lint"
18
+ },
19
+ "license": "Apache-2.0",
20
+ "main": "dist/index.cjs.js",
21
+ "types": "dist/index.d.ts",
22
+ "files": [
23
+ "dist",
24
+ "bin"
25
+ ],
26
+ "scripts": {
27
+ "build": "backstage-cli package build",
28
+ "clean": "backstage-cli package clean",
29
+ "lint": "backstage-cli package lint",
30
+ "prepack": "backstage-cli package prepack",
31
+ "postpack": "backstage-cli package postpack",
32
+ "test": "backstage-cli package test"
33
+ },
34
+ "dependencies": {
35
+ "@backstage/cli-common": "0.0.0-nightly-20260317031259",
36
+ "@backstage/cli-node": "0.0.0-nightly-20260317031259",
37
+ "chalk": "^4.0.0",
38
+ "cleye": "^2.3.0",
39
+ "eslint": "^8.6.0",
40
+ "eslint-formatter-friendly": "^7.0.0",
41
+ "fs-extra": "^11.2.0",
42
+ "globby": "^11.1.0",
43
+ "shell-quote": "^1.8.1"
44
+ },
45
+ "devDependencies": {
46
+ "@backstage/cli": "0.0.0-nightly-20260317031259",
47
+ "@types/fs-extra": "^11.0.0",
48
+ "@types/shell-quote": "^1.7.5"
49
+ },
50
+ "bin": "bin/backstage-cli-module-lint",
51
+ "typesVersions": {
52
+ "*": {
53
+ "package.json": [
54
+ "package.json"
55
+ ]
56
+ }
57
+ }
58
+ }