From 757ab0b936bb46a59a1fd4099a2ea5ca711427af Mon Sep 17 00:00:00 2001 From: Adam Miskiewicz Date: Fri, 12 Aug 2016 11:46:04 -0700 Subject: [PATCH] Add `--config` option to CLI to allow passing a path to an `rn-cli.config.js` Summary: Currently we just try to resolve a rn-cli.config.js file by walking up the tree from node_modules/react-native. In non-standard uses of RN, when your copy of RN may not live within node_modules, it's impossible to use rn-cli.config.js. This PR adds a "config" flag to the cli that let's you pass in a path to rn-cli.config.js. cc ide Closes https://github.com/facebook/react-native/pull/7883 Differential Revision: D3382823 Pulled By: bestander fbshipit-source-id: b946f3bb355050fc2fe99273d0e99e441dbed111 --- local-cli/cliEntry.js | 25 ++++++++++++++++++++- local-cli/util/Config.js | 47 +++++++++++++++++++++++++--------------- package.json | 9 ++++---- 3 files changed, 58 insertions(+), 23 deletions(-) diff --git a/local-cli/cliEntry.js b/local-cli/cliEntry.js index 22c0d8fa0..7a6653ce0 100644 --- a/local-cli/cliEntry.js +++ b/local-cli/cliEntry.js @@ -16,6 +16,7 @@ const Config = require('./util/Config'); const childProcess = require('child_process'); const Promise = require('promise'); const chalk = require('chalk'); +const minimist = require('minimist'); const path = require('path'); const fs = require('fs'); const gracefulFs = require('graceful-fs'); @@ -121,16 +122,38 @@ const addCommand = (command: Command, config: Config) => { opt.parse || defaultOptParser, typeof opt.default === 'function' ? opt.default(config) : opt.default, )); + + // Placeholder option for --config, which is parsed before any other option, + // but needs to be here to avoid "unknown option" errors when specified + cmd.option('--config [string]', 'Path to the CLI configuration file'); }; +function getCliConfig() { + // Use a lightweight option parser to look up the CLI configuration file, + // which we need to set up the parser for the other args and options + let cliArgs = minimist(process.argv.slice(2)); + + let cwd; + let configPath; + if (cliArgs.config != null) { + cwd = process.cwd(); + configPath = cliArgs.config; + } else { + cwd = __dirname; + configPath = Config.findConfigPath(cwd); + } + + return Config.get(cwd, defaultConfig, configPath); +} + function run() { - const config = Config.get(__dirname, defaultConfig); const setupEnvScript = /^win/.test(process.platform) ? 'setup_env.bat' : 'setup_env.sh'; childProcess.execFileSync(path.join(__dirname, setupEnvScript)); + const config = getCliConfig(); commands.forEach(cmd => addCommand(cmd, config)); commander.parse(process.argv); diff --git a/local-cli/util/Config.js b/local-cli/util/Config.js index bc555733d..f92d9ba0c 100644 --- a/local-cli/util/Config.js +++ b/local-cli/util/Config.js @@ -8,11 +8,11 @@ */ 'use strict'; +const assert = require('assert'); const fs = require('fs'); const path = require('path'); const RN_CLI_CONFIG = 'rn-cli.config.js'; -let cachedConfig = null; /** * Module capable of getting the configuration that should be used for @@ -25,26 +25,37 @@ let cachedConfig = null; * error will be thrown. */ const Config = { - get(cwd, defaultConfig) { - if (cachedConfig) { - return cachedConfig; + get(cwd, defaultConfig, pathToConfig) { + let baseConfig; + + // Handle the legacy code path where pathToConfig is unspecified + if (pathToConfig === undefined) { + const configPath = Config.findConfigPath(cwd); + if (!configPath && !defaultConfig) { + throw new Error( + `Can't find "${RN_CLI_CONFIG}" file in any parent folder of "${cwd}"` + ); + } + baseConfig = require(configPath); + } else if (pathToConfig == null) { + assert(defaultConfig, 'Must have a default config if config is missing'); + } else { + baseConfig = path.isAbsolute(pathToConfig) ? + require(pathToConfig) : + require(path.join(cwd, pathToConfig)); } + return { + ...defaultConfig, + ...baseConfig, + cwd, + }; + }, + + findConfigPath(cwd) { const parentDir = findParentDirectory(cwd, RN_CLI_CONFIG); - if (!parentDir && !defaultConfig) { - throw new Error( - `Can't find "rn-cli.config.js" file in any parent folder of "${cwd}"` - ); - } - - const config = parentDir - ? require(path.join(parentDir, RN_CLI_CONFIG)) - : {}; - - cachedConfig = Object.assign({}, defaultConfig, config); - cachedConfig.cwd = cwd; - return cachedConfig; - } + return parentDir ? path.join(parentDir, RN_CLI_CONFIG) : null; + }, }; // Finds the most near ancestor starting at `currentFullPath` that has diff --git a/package.json b/package.json index e6e18805f..2cb89a626 100644 --- a/package.json +++ b/package.json @@ -148,6 +148,7 @@ "connect": "^2.8.3", "core-js": "^2.2.2", "debug": "^2.2.0", + "denodeify": "^1.2.1", "event-target-shim": "^1.0.5", "fbjs": "^0.8.3", "fbjs-scripts": "^0.7.0", @@ -163,6 +164,8 @@ "jstransform": "^11.0.3", "lodash": "^3.10.1", "mime": "^1.3.4", + "mime-types": "2.1.11", + "minimist": "^1.2.0", "mkdirp": "^0.5.1", "module-deps": "^3.9.1", "node-fetch": "^1.3.3", @@ -183,6 +186,7 @@ "stacktrace-parser": "^0.1.3", "temp": "0.8.3", "uglify-js": "^2.6.2", + "whatwg-fetch": "^1.0.0", "wordwrap": "^1.0.0", "worker-farm": "^1.3.1", "ws": "^1.1.0", @@ -190,10 +194,7 @@ "xmldoc": "^0.4.0", "yargs": "^3.24.0", "yeoman-environment": "1.5.3", - "yeoman-generator": "0.21.2", - "mime-types": "2.1.11", - "whatwg-fetch": "^1.0.0", - "denodeify": "^1.2.1" + "yeoman-generator": "0.21.2" }, "devDependencies": { "babel-eslint": "^6.0.0",