diff --git a/CHANGELOG.md b/CHANGELOG.md index a1b750e27d4f..67f6ac0a17c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ symlinked paths ([#5085](https://github.com/facebook/jest/pull/5085)) * `[jest-editor-support]` Update `Settings` to use spawn in shell option ([#5658](https://github.com/facebook/jest/pull/5658)) +* `[jest-cli]` Improve the error message when 2 projects resolve to the same + config ([#5674](https://github.com/facebook/jest/pull/5674)) ## 22.4.2 diff --git a/integration-tests/__tests__/multi_project_runner.test.js b/integration-tests/__tests__/multi_project_runner.test.js index 6d2d6e369cd1..7ea2773a57be 100644 --- a/integration-tests/__tests__/multi_project_runner.test.js +++ b/integration-tests/__tests__/multi_project_runner.test.js @@ -12,6 +12,7 @@ import runJest from '../runJest'; import os from 'os'; import path from 'path'; +import stripAnsi from 'strip-ansi'; const {cleanup, extractSummary, writeFiles} = require('../Utils'); const SkipOnWindows = require('../../scripts/SkipOnWindows'); @@ -303,12 +304,15 @@ test('resolves projects and their properly', () => { }), }); - ({stderr} = runJest(DIR)); + ({stderr} = stripAnsi(runJest(DIR))); expect(stderr).toMatch( - /One or more specified projects share the same config file/, + /Whoops! Two projects resolved to the same config path/, ); + expect(stderr).toMatch(`${path.join(DIR, 'package.json')}`); + expect(stderr).toMatch(/Project 1|2: dir1/); + expect(stderr).toMatch(/Project 1|2: dir2/); - // praject with a directory/file that does not exist + // project with a directory/file that does not exist writeFiles(DIR, { 'package.json': JSON.stringify({ jest: { diff --git a/packages/jest-cli/src/cli/index.js b/packages/jest-cli/src/cli/index.js index 99ae6384555e..116a07d5989d 100644 --- a/packages/jest-cli/src/cli/index.js +++ b/packages/jest-cli/src/cli/index.js @@ -173,27 +173,30 @@ const printVersionAndExit = outputStream => { exit(0); }; -const ensureNoDuplicateConfigs = (parsedConfigs, projects) => { - const configPathSet = new Set(); - - for (const {configPath} of parsedConfigs) { - if (configPathSet.has(configPath)) { - let message = - 'One or more specified projects share the same config file\n'; - - parsedConfigs.forEach(({configPath}, index) => { - message = - message + - '\nProject: "' + - projects[index] + - '"\nConfig: "' + - String(configPath) + - '"'; - }); +const ensureNoDuplicateConfigs = (parsedConfigs, projects, rootConfigPath) => { + const configPathMap = new Map(); + + for (const config of parsedConfigs) { + const {configPath} = config; + if (configPathMap.has(configPath)) { + const message = `Whoops! Two projects resolved to the same config path: ${chalk.bold( + String(configPath), + )}: + + Project 1: ${chalk.bold(projects[parsedConfigs.findIndex(x => x === config)])} + Project 2: ${chalk.bold( + projects[parsedConfigs.findIndex(x => x === configPathMap.get(configPath))], + )} + +This usually means that your ${chalk.bold( + '"projects"', + )} config includes a directory that doesn't have any configuration recognizable by Jest. Please fix it. +`; + throw new Error(message); } if (configPath !== null) { - configPathSet.add(configPath); + configPathMap.set(configPath, config); } } }; @@ -259,7 +262,7 @@ const getConfigs = ( }) .map(root => readConfig(argv, root, true, configPath)); - ensureNoDuplicateConfigs(parsedConfigs, projects); + ensureNoDuplicateConfigs(parsedConfigs, projects, configPath); configs = parsedConfigs.map(({projectConfig}) => projectConfig); if (!hasDeprecationWarnings) { hasDeprecationWarnings = parsedConfigs.some(