diff --git a/packages/next/cli/next-lint.ts b/packages/next/cli/next-lint.ts index 9f2be2e96abb0bc..a225753a8174f50 100755 --- a/packages/next/cli/next-lint.ts +++ b/packages/next/cli/next-lint.ts @@ -30,6 +30,7 @@ const eslintOptions = (args: arg.Spec, defaultCacheLocation: string) => ({ args['--report-unused-disable-directives'] || null, cache: !Boolean(args['--no-cache']), cacheLocation: args['--cache-location'] || defaultCacheLocation, + cacheStrategy: args['--cache-strategy'] || 'metadata', errorOnUnmatchedPattern: args['--error-on-unmatched-pattern'] ? Boolean(args['--error-on-unmatched-pattern']) : false, @@ -67,6 +68,7 @@ const nextLint: cliCommand = async (argv) => { '--cache': Boolean, // Although cache is enabled by default, this dummy flag still exists to not cause any breaking changes '--no-cache': Boolean, '--cache-location': String, + '--cache-strategy': String, '--error-on-unmatched-pattern': Boolean, '--format': String, @@ -134,6 +136,7 @@ const nextLint: cliCommand = async (argv) => { Caching: --no-cache Disable caching --cache-location path::String Path to the cache file or directory - default: .eslintcache + --cache-strategy String Strategy to use for detecting changed files in the cache, either metadata or content - default: metadata Miscellaneous: --error-on-unmatched-pattern Show errors when any file patterns are unmatched - default: false diff --git a/test/integration/eslint/test/index.test.js b/test/integration/eslint/test/index.test.js index e9b499ab3d19428..ac7a005b48cbea5 100644 --- a/test/integration/eslint/test/index.test.js +++ b/test/integration/eslint/test/index.test.js @@ -536,6 +536,47 @@ describe('ESLint', () => { expect(fs.existsSync(cacheFile)).toBe(true) }) + const getEslintCacheContent = async (cacheDir) => { + const eslintCacheDir = join(cacheDir, 'eslint/') + let files = await fs.readdir(eslintCacheDir) + let cacheFiles = files.filter((f) => /\.cache/.test(f)) + expect(cacheFiles.length).toBe(1) + const cacheFile = join(eslintCacheDir, cacheFiles[0]) + return await fs.readFile(cacheFile, 'utf8') + } + + test('the default eslint caching strategy is metadata', async () => { + const cacheDir = join(dirEslintCache, '.next', 'cache') + + await fs.remove(cacheDir) + await nextLint(dirEslintCache) + + const defaultStrategyCache = await getEslintCacheContent(cacheDir) + + await fs.remove(cacheDir) + await nextLint(dirEslintCache, ['--cache-strategy', 'metadata']) + + const metadataStrategyCache = await getEslintCacheContent(cacheDir) + + expect(metadataStrategyCache).toBe(defaultStrategyCache) + }) + + test('cache with content strategy is different from the one with default strategy', async () => { + const cacheDir = join(dirEslintCache, '.next', 'cache') + + await fs.remove(cacheDir) + await nextLint(dirEslintCache) + + const defaultStrategyCache = await getEslintCacheContent(cacheDir) + + await fs.remove(cacheDir) + await nextLint(dirEslintCache, ['--cache-strategy', 'content']) + + const contentStrategyCache = await getEslintCacheContent(cacheDir) + + expect(contentStrategyCache).not.toBe(defaultStrategyCache) + }) + test('file flag can selectively lint only a single file', async () => { const { stdout, stderr } = await nextLint( dirFileLinting,