diff --git a/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.js.snap b/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.js.snap index d695d85b0..02aeb3db5 100644 --- a/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.js.snap +++ b/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.js.snap @@ -175,3 +175,7 @@ Object { }, } `; + +exports[`should skip packages that have invalid configuration: dependencies config 1`] = `Object {}`; + +exports[`should skip packages that have invalid configuration: logged warning 1`] = `"Package react-native has been ignored because it contains invalid configuration. Reason: Unknown option invalidProperty with value \\"5\\" was found. This is either a typing error or a user mistake. Fixing it will remove this message."`; diff --git a/packages/cli/src/tools/config/__tests__/index-test.js b/packages/cli/src/tools/config/__tests__/index-test.js index cba33e1a2..8a58dd9b7 100644 --- a/packages/cli/src/tools/config/__tests__/index-test.js +++ b/packages/cli/src/tools/config/__tests__/index-test.js @@ -10,6 +10,8 @@ import { getTempDirectory, } from '../../../../../../jest/helpers'; +import {logger} from '@react-native-community/cli-tools'; + const DIR = getTempDirectory('resolve_config_path_test'); // Removes string from all key/values within an object @@ -236,3 +238,21 @@ test('should not add default React Native config when one present', () => { const {commands} = loadConfig(DIR); expect(commands).toMatchSnapshot(); }); + +test('should skip packages that have invalid configuration', () => { + writeFiles(DIR, { + 'node_modules/react-native/package.json': '{}', + 'node_modules/react-native/react-native.config.js': `module.exports = { + invalidProperty: 5 + }`, + 'package.json': `{ + "dependencies": { + "react-native": "0.0.1" + } + }`, + }); + const spy = jest.spyOn(logger, 'warn'); + const {dependencies} = loadConfig(DIR); + expect(dependencies).toMatchSnapshot('dependencies config'); + expect(spy.mock.calls[0][0]).toMatchSnapshot('logged warning'); +}); diff --git a/packages/cli/src/tools/config/index.js b/packages/cli/src/tools/config/index.js index d1e31efde..640d4d13b 100644 --- a/packages/cli/src/tools/config/index.js +++ b/packages/cli/src/tools/config/index.js @@ -3,6 +3,7 @@ */ import path from 'path'; import {mapValues} from 'lodash'; +import chalk from 'chalk'; import findDependencies from './findDependencies'; import resolveReactNativePath from './resolveReactNativePath'; @@ -23,6 +24,7 @@ import merge from '../merge'; */ import * as ios from '@react-native-community/cli-platform-ios'; import * as android from '@react-native-community/cli-platform-android'; +import {logger, inlineString} from '@react-native-community/cli-tools'; /** * Loads CLI configuration @@ -34,9 +36,23 @@ function loadConfig(projectRoot: string = process.cwd()): ConfigT { (acc: ConfigT, dependencyName) => { const root = path.join(projectRoot, 'node_modules', dependencyName); - const config = - readLegacyDependencyConfigFromDisk(root) || - readDependencyConfigFromDisk(root); + let config; + try { + config = + readLegacyDependencyConfigFromDisk(root) || + readDependencyConfigFromDisk(root); + } catch (error) { + logger.warn( + inlineString(` + Package ${chalk.bold( + dependencyName, + )} has been ignored because it contains invalid configuration. + + Reason: ${chalk.dim(error.message)} + `), + ); + return acc; + } /** * This workaround is neccessary for development only before diff --git a/packages/cli/src/tools/config/readConfigFromDisk.js b/packages/cli/src/tools/config/readConfigFromDisk.js index c4723afdf..121937e2b 100644 --- a/packages/cli/src/tools/config/readConfigFromDisk.js +++ b/packages/cli/src/tools/config/readConfigFromDisk.js @@ -6,6 +6,7 @@ import Joi from 'joi'; import cosmiconfig from 'cosmiconfig'; import path from 'path'; +import chalk from 'chalk'; import { type UserDependencyConfigT, @@ -116,9 +117,9 @@ export function readLegacyDependencyConfigFromDisk( // @todo: paste a link to documentation that explains the migration steps logger.warn( - `Package '${path.basename( - name, - )}' is using deprecated "rnpm" config that will stop working from next release. Consider upgrading to the new config format.`, + `Package ${chalk.bold( + path.basename(name), + )} is using deprecated "rnpm" config that will stop working from next release. Consider upgrading to the new config format.`, ); const result = Joi.validate(transformedConfig, schema.dependencyConfig); diff --git a/packages/tools/src/errors.js b/packages/tools/src/errors.js index 0fdfbe82e..6cb5de299 100644 --- a/packages/tools/src/errors.js +++ b/packages/tools/src/errors.js @@ -11,7 +11,7 @@ */ export class CLIError extends Error { constructor(msg: string, originError?: Error | string) { - super(msg.replace(/(\s{2,})/gm, ' ').trim()); + super(inlineString(msg)); if (originError) { this.stack = typeof originError === 'string' @@ -25,3 +25,6 @@ export class CLIError extends Error { } } } + +export const inlineString = (str: string) => + str.replace(/(\s{2,})/gm, ' ').trim();