From bea0cdfccb2f6b0b739f9afbdf1e17fc3833285c Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Tue, 21 Nov 2023 12:33:09 -0800 Subject: [PATCH] Properly escape the configuration string printed by eslint-patch; add a minimum version check --- eslint/eslint-bulk/src/start.ts | 62 +++++++++++++++++-- .../src/eslint-bulk-suppressions/index.ts | 2 +- .../eslint-bulk-suppressions/path-utils.ts | 21 +++++-- 3 files changed, 73 insertions(+), 12 deletions(-) diff --git a/eslint/eslint-bulk/src/start.ts b/eslint/eslint-bulk/src/start.ts index 56111c58cf5..bb87fbb2f1d 100644 --- a/eslint/eslint-bulk/src/start.ts +++ b/eslint/eslint-bulk/src/start.ts @@ -6,6 +6,17 @@ import * as process from 'process'; import * as fs from 'fs'; import * as path from 'path'; +interface IEslintBulkConfigurationJson { + /** + * `@rushtack/eslint`-bulk should report an error if its package.json is older than this number + */ + minCliVersion: string; + /** + * `@rushtack/eslint-bulk` will invoke this entry point + */ + cliEntryPoint: string; +} + function findPatchPath(): string { let eslintrcPath: string; if (fs.existsSync(path.join(process.cwd(), '.eslintrc.js'))) { @@ -19,7 +30,7 @@ function findPatchPath(): string { process.exit(1); } - const env: { [key: string]: string } = { ...process.env, ESLINT_BULK_FIND: 'true' }; + const env: { [key: string]: string } = { ...process.env, _RUSHSTACK_ESLINT_BULK_DETECT: 'true' }; let stdout: Buffer; try { @@ -29,15 +40,56 @@ function findPatchPath(): string { process.exit(1); } - const startDelimiter: string = 'ESLINT_BULK_STDOUT_START'; - const endDelimiter: string = 'ESLINT_BULK_STDOUT_END'; + const startDelimiter: string = 'RUSHSTACK_ESLINT_BULK_START'; + const endDelimiter: string = 'RUSHSTACK_ESLINT_BULK_END'; const regex: RegExp = new RegExp(`${startDelimiter}(.*?)${endDelimiter}`); const match: RegExpMatchArray | null = stdout.toString().match(regex); if (match) { - const filePath: string = match[1].trim(); - return filePath; + // The configuration data will look something like this: + // + // RUSHSTACK_ESLINT_BULK_START{"minCliVersion":"0.0.0","cliEntryPoint":"path/to/eslint-bulk.js"}RUSHSTACK_ESLINT_BULK_END + const configurationJson: string = match[1].trim(); + let configuration: IEslintBulkConfigurationJson; + try { + configuration = JSON.parse(configurationJson); + if (!configuration.minCliVersion || !configuration.cliEntryPoint) { + throw new Error('Required field is missing'); + } + } catch (e) { + console.error('@rushstack/eslint-bulk: Error parsing patch configuration object:' + e.message); + process.exit(1); + } + + const myVersion: string = require('../package.json').version; + const myVersionParts: number[] = myVersion.split('.').map((x) => parseInt(x, 10)); + const minVersion: string = configuration.minCliVersion; + const minVersionParts: number[] = minVersion.split('.').map((x) => parseInt(x, 10)); + if ( + myVersionParts.length !== 3 || + minVersionParts.length !== 3 || + myVersionParts.some((x) => isNaN(x)) || + minVersionParts.some((x) => isNaN(x)) + ) { + console.error(`@rushstack/eslint-bulk: Unable to compare versions "${myVersion}" and "${minVersion}"`); + process.exit(1); + } + + for (let i: number = 0; i < 3; ++i) { + if (myVersionParts[i] > minVersionParts[i]) { + break; + } + if (myVersionParts[i] < minVersionParts[i]) { + console.error( + `@rushstack/eslint-bulk: The @rushstack/eslint-bulk version ${myVersion} is too old;` + + ` please upgrade to ${minVersion} or newer.` + ); + process.exit(1); + } + } + + return configuration.cliEntryPoint; } console.error( diff --git a/eslint/eslint-patch/src/eslint-bulk-suppressions/index.ts b/eslint/eslint-patch/src/eslint-bulk-suppressions/index.ts index 36df419dcc2..db8a937e076 100644 --- a/eslint/eslint-patch/src/eslint-bulk-suppressions/index.ts +++ b/eslint/eslint-patch/src/eslint-bulk-suppressions/index.ts @@ -18,7 +18,7 @@ if (!eslintFolder) { process.exit(1); } -if (process.env.ESLINT_BULK_FIND === 'true') { +if (process.env._RUSHSTACK_ESLINT_BULK_DETECT === 'true') { findAndConsoleLogPatchPathCli(__dirname); process.exit(0); } diff --git a/eslint/eslint-patch/src/eslint-bulk-suppressions/path-utils.ts b/eslint/eslint-patch/src/eslint-bulk-suppressions/path-utils.ts index 6d69a441850..1ca26050547 100644 --- a/eslint/eslint-patch/src/eslint-bulk-suppressions/path-utils.ts +++ b/eslint/eslint-patch/src/eslint-bulk-suppressions/path-utils.ts @@ -6,16 +6,25 @@ import path from 'path'; import { eslintFolder } from '../_patch-base'; export function findAndConsoleLogPatchPathCli(patchPath: string): void { - if (process.env.ESLINT_BULK_FIND !== 'true') { + if (process.env._RUSHSTACK_ESLINT_BULK_DETECT !== 'true') { return; } - const startDelimiter = 'ESLINT_BULK_STDOUT_START'; - const endDelimiter = 'ESLINT_BULK_STDOUT_END'; + const startDelimiter = 'RUSHSTACK_ESLINT_BULK_START'; + const endDelimiter = 'RUSHSTACK_ESLINT_BULK_END'; - console.log( - `${startDelimiter}${path.resolve(patchPath, '..', 'exports', 'eslint-bulk.js')}${endDelimiter}` - ); + const configuration = { + /** + * `@rushtack/eslint`-bulk should report an error if its package.json is older than this number + */ + minCliVersion: '0.0.0', + /** + * `@rushtack/eslint-bulk` will invoke this entry point + */ + cliEntryPoint: path.resolve(patchPath, '..', 'exports', 'eslint-bulk.js') + }; + + console.log(startDelimiter + JSON.stringify(configuration) + endDelimiter); } export function getPathToLinterJS(): string {