From 2ac0ac99a2c38177d601e1bb1ab63c64b4a6d42a Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Thu, 23 May 2024 14:42:35 -0600 Subject: [PATCH] fix: disable linting on builds without a eslint configuration present --- test/lib/next-modes/next-start.ts | 1 + test/lib/next-test-utils.ts | 62 +++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/test/lib/next-modes/next-start.ts b/test/lib/next-modes/next-start.ts index 6366c7a114438..571879924d424 100644 --- a/test/lib/next-modes/next-start.ts +++ b/test/lib/next-modes/next-start.ts @@ -68,6 +68,7 @@ export class NextStartInstance extends NextInstance { if (this.buildCommand) { buildArgs = this.buildCommand.split(' ') } + if (this.startCommand) { startArgs = this.startCommand.split(' ') } diff --git a/test/lib/next-test-utils.ts b/test/lib/next-test-utils.ts index 0179ecd530ecf..5b42399d8a922 100644 --- a/test/lib/next-test-utils.ts +++ b/test/lib/next-test-utils.ts @@ -18,6 +18,7 @@ import fetch from 'node-fetch' import qs from 'querystring' import treeKill from 'tree-kill' import { once } from 'events' +import vm from 'vm' import server from 'next/dist/server/next' import _pkg from 'next/package.json' @@ -437,11 +438,72 @@ export function launchApp( ) } +/** + * Read a JavaScript file and return the exports. + * + * @param path The path to the JavaScript file. + * @returns The exports of the JavaScript file. + */ +function readJS(path: string) { + const data = readFileSync(path, 'utf8') + const script = new vm.Script(data, { filename: path }) + const context = { module: { exports: {} } } + script.runInNewContext(context) + return context.module.exports +} + +/** + * Check if the directory provides an ESLint configuration. + * + * @param dir The directory to check. + * @returns Whether the directory provides an ESLint configuration. + */ +export function shouldDisableLinting(dir: string) { + try { + // If the project already has a `next.config.js` file that includes an eslint + // config, then don't disable linting. + if ( + existsSync(path.join(dir, 'next.config.js')) && + 'eslint' in readJS(path.join(dir, 'next.config.js')) + ) { + return false + } + + // If some of these files exist, we should not disable linting. + if ( + ['.eslintrc.json', '.eslintrc.js', '.eslintrc'].some((file) => + existsSync(path.join(dir, file)) + ) + ) { + return false + } + + // If the `eslintConfig` field is present in the `package.json` file, we + // should not disable linting. + if ( + existsSync(path.join(dir, 'package.json')) && + readJson(path.join(dir, 'package.json')).eslintConfig + ) { + return false + } + + return true + } catch { + // An error ocurred while checking the directory, so we should not disable + // linting. + return false + } +} + export function nextBuild( dir: string, args: string[] = [], opts: NextOptions = {} ) { + // Disable linting if the directory provides an ESLint configuration. This + // prevents the project's eslint configuration from affecting the test. + if (shouldDisableLinting(dir)) args.push('--no-lint') + return runNextCommand(['build', dir, ...args], opts) }