diff --git a/packages/next/cli/next-lint.ts b/packages/next/cli/next-lint.ts index b4e9d38343803..57bae548524ef 100755 --- a/packages/next/cli/next-lint.ts +++ b/packages/next/cli/next-lint.ts @@ -55,6 +55,7 @@ const nextLint: cliCommand = (argv) => { '--ignore-path': String, '--no-ignore': Boolean, '--quiet': Boolean, + '--max-warnings': Number, '--no-inline-config': Boolean, '--report-unused-disable-directives': String, '--cache': Boolean, @@ -108,6 +109,7 @@ const nextLint: cliCommand = (argv) => { Handling warnings: --quiet Report errors only - default: false + --max-warnings Int Number of warnings to trigger nonzero exit code - default: -1 Inline configuration comments: --no-inline-config Prevent comments from changing config or rules @@ -143,8 +145,16 @@ const nextLint: cliCommand = (argv) => { ) const reportErrorsOnly = Boolean(args['--quiet']) - - runLintCheck(baseDir, lintDirs, false, eslintOptions(args), reportErrorsOnly) + const maxWarnings = args['--max-warnings'] ?? -1 + + runLintCheck( + baseDir, + lintDirs, + false, + eslintOptions(args), + reportErrorsOnly, + maxWarnings + ) .then(async (lintResults) => { const lintOutput = typeof lintResults === 'string' ? lintResults : lintResults?.output diff --git a/packages/next/lib/eslint/runLintCheck.ts b/packages/next/lib/eslint/runLintCheck.ts index 9787e98652c56..8ba90b17a7141 100644 --- a/packages/next/lib/eslint/runLintCheck.ts +++ b/packages/next/lib/eslint/runLintCheck.ts @@ -6,7 +6,7 @@ import findUp from 'next/dist/compiled/find-up' import semver from 'next/dist/compiled/semver' import * as CommentJson from 'next/dist/compiled/comment-json' -import { formatResults } from './customFormatter' +import { LintResult, formatResults } from './customFormatter' import { writeDefaultConfig } from './writeDefaultConfig' import { existsSync, findPagesDir } from '../find-pages-dir' import { @@ -29,7 +29,8 @@ async function lint( eslintrcFile: string | null, pkgJsonPath: string | null, eslintOptions: any = null, - reportErrorsOnly: boolean = false + reportErrorsOnly: boolean = false, + maxWarnings: number = -1 ): Promise< | string | null @@ -116,10 +117,16 @@ async function lint( const formattedResult = formatResults(baseDir, results) const lintEnd = process.hrtime(lintStart) + const totalWarnings = results.reduce( + (sum: number, file: LintResult) => sum + file.warningCount, + 0 + ) return { output: formattedResult.output, - isError: ESLint.getErrorResults(results)?.length > 0, + isError: + ESLint.getErrorResults(results)?.length > 0 || + (maxWarnings >= 0 && totalWarnings > maxWarnings), eventInfo: { durationInSeconds: lintEnd[0], eslintVersion: eslintVersion, @@ -143,7 +150,8 @@ export async function runLintCheck( lintDirs: string[], lintDuringBuild: boolean = false, eslintOptions: any = null, - reportErrorsOnly: boolean = false + reportErrorsOnly: boolean = false, + maxWarnings: number = -1 ): ReturnType { try { // Find user's .eslintrc file @@ -205,7 +213,8 @@ export async function runLintCheck( eslintrcFile, pkgJsonPath, eslintOptions, - reportErrorsOnly + reportErrorsOnly, + maxWarnings ) } catch (err) { throw err diff --git a/test/integration/eslint/max-warnings/.eslintrc b/test/integration/eslint/max-warnings/.eslintrc new file mode 100644 index 0000000000000..1940c0953ab0a --- /dev/null +++ b/test/integration/eslint/max-warnings/.eslintrc @@ -0,0 +1,8 @@ +{ + "extends": "next", + "root": true, + "rules": { + "@next/next/no-html-link-for-pages": 0, + "@next/next/no-sync-scripts": 1 + } +} diff --git a/test/integration/eslint/max-warnings/pages/about.js b/test/integration/eslint/max-warnings/pages/about.js new file mode 100644 index 0000000000000..0738ed04c40c7 --- /dev/null +++ b/test/integration/eslint/max-warnings/pages/about.js @@ -0,0 +1,8 @@ +const About = () => ( +
+

About

+