diff --git a/__tests__/lifecycle-scripts.js b/__tests__/lifecycle-scripts.js index 178ace9cdc..51e77633f1 100644 --- a/__tests__/lifecycle-scripts.js +++ b/__tests__/lifecycle-scripts.js @@ -32,28 +32,28 @@ async function execCommand(cmd: string, packageName: string, env = process.env): test('should add the global yarnrc arguments to the command line', async () => { const stdout = await execCommand('cache dir', 'yarnrc-cli'); - expect(stdout.replace(/\\/g, '/')).toMatch(/^\/tmp\/foobar\/v[0-9]+\n$/); + expect(stdout.replace(/\\/g, '/')).toMatch(/^(C:)?\/tmp\/foobar\/v[0-9]+\n$/); }); test('should add the command-specific yarnrc arguments to the command line if the command name matches', async () => { const stdout = await execCommand('cache dir', 'yarnrc-cli-command-specific-ok'); - expect(stdout.replace(/\\/g, '/')).toMatch(/^\/tmp\/foobar\/v[0-9]+\n$/); + expect(stdout.replace(/\\/g, '/')).toMatch(/^(C:)?\/tmp\/foobar\/v[0-9]+\n$/); }); test('should not add the command-specific yarnrc arguments if the command name doesn\'t match', async () => { const stdout = await execCommand('cache dir', 'yarnrc-cli-command-specific-ko'); - expect(stdout.replace(/\\/g, '/')).not.toMatch(/^\/tmp\/foobar\/v[0-9]+\n$/); + expect(stdout.replace(/\\/g, '/')).not.toMatch(/^(C:)?\/tmp\/foobar\/v[0-9]+\n$/); }); test('should allow overriding the yarnrc values from the command line', async () => { const stdout = await execCommand('cache dir --cache-folder /tmp/toto', 'yarnrc-cli'); - expect(stdout.replace(/\\/g, '/')).toMatch(/^\/tmp\/toto\/v[0-9]+\n$/); + expect(stdout.replace(/\\/g, '/')).toMatch(/^(C:)?\/tmp\/toto\/v[0-9]+\n$/); }); // Test disabled for now, cf rc.js -test.skip('should resolve the yarnrc values relative to where the file lives', async () => { +test('should resolve the yarnrc values relative to where the file lives', async () => { const stdout = await execCommand('cache dir', 'yarnrc-cli-relative'); - expect(stdout.replace(/\\/g, '/')).toMatch(/^(\/[^\/]+)+\/foobar\/hello\/world\/v[0-9]+\n$/); + expect(stdout.replace(/\\/g, '/')).toMatch(/^(C:)?(\/[^\/]+)+\/foobar\/hello\/world\/v[0-9]+\n$/); }); test('should expose `npm_config_argv` environment variable to lifecycle scripts for back compatibility with npm (#684)', diff --git a/package.json b/package.json index c54db16133..6241b27590 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,6 @@ "node-gyp": "^3.2.1", "object-path": "^0.11.2", "proper-lockfile": "^2.0.0", - "rc": "^1.2.1", "read": "^1.0.7", "request": "^2.81.0", "request-capture-har": "^1.2.2", diff --git a/scripts/build-webpack.js b/scripts/build-webpack.js index 0aede020c7..b94d2aa7e2 100755 --- a/scripts/build-webpack.js +++ b/scripts/build-webpack.js @@ -56,7 +56,7 @@ const compilerLegacy = webpack({ exclude: /node_modules/, loader: 'babel-loader', query: babelRc.env['pre-node5'], - }], + }] }, plugins: [ new webpack.BannerPlugin({ diff --git a/src/rc.js b/src/rc.js index 9624537dee..29ae25f4b3 100644 --- a/src/rc.js +++ b/src/rc.js @@ -1,8 +1,8 @@ /* @flow */ +import {dirname, resolve} from 'path'; import parse from './lockfile/parse.js'; - -const rc = require('rc'); +import * as rcUtil from './util/rc.js'; // Keys that will get resolved relative to the path of the rc file they belong to const PATH_KEYS = [ @@ -14,20 +14,14 @@ const PATH_KEYS = [ let rcConfCache; let rcArgsCache; -const buildRcConf = () => rc('yarn', {}, [], (fileText) => { +const buildRcConf = () => rcUtil.findRc('yarn', (fileText, filePath) => { const values = parse(fileText, 'yarnrc'); const keys = Object.keys(values); - // Unfortunately, the "rc" module we use doesn't tell us the file path :( - // cf https://github.com/dominictarr/rc/issues/61 - for (const key of keys) { for (const pathKey of PATH_KEYS) { - if (key.replace(/^(--)?([^.]+\.)+/, '') === pathKey) { - // values[key] = resolve(dirname(filePath), values[key]); - if (!values[key].startsWith('/')) { - delete values[keys]; - } + if (key.replace(/^(--)?([^.]+\.)*/, '') === pathKey) { + values[key] = resolve(dirname(filePath), values[key]); } } } diff --git a/src/util/rc.js b/src/util/rc.js new file mode 100644 index 0000000000..3692a910de --- /dev/null +++ b/src/util/rc.js @@ -0,0 +1,64 @@ +/* @flow */ + +import {readFileSync} from 'fs'; +import {basename, dirname, join} from 'path'; + +const etc = '/etc'; +const isWin = process.platform === 'win32'; +const home = isWin ? process.env.USERPROFILE : process.env.HOME; + +export function findRc(name: string, parser: Function): Object { + let configPaths = []; + + function addConfigPath(... segments) { + configPaths.push(join(... segments)); + } + + function addRecursiveConfigPath(... segments) { + const queue = []; + + let oldPath; + let path = join(... segments); + + do { + queue.unshift(path); + + oldPath = path; + path = join(dirname(dirname(path)), basename(path)); + } while (path !== oldPath); + + configPaths = configPaths.concat(queue); + } + + function fetchConfigs(): Object { + return Object.assign({}, ... configPaths.map((path) => { + try { + return parser(readFileSync(path).toString(), path); + } catch (error) { + return {}; + } + })); + } + + if (!isWin) { + addConfigPath(etc, name, 'config'); + addConfigPath(etc, `${name}rc`); + } + + if (home) { + addConfigPath(home, '.config', name, 'config'); + addConfigPath(home, '.config', name); + addConfigPath(home, `.${name}`, 'config'); + addConfigPath(home, `.${name}rc`); + } + + addRecursiveConfigPath(process.cwd(), `.${name}rc`); + + const envVariable = `${name}_config`.toUpperCase(); + + if (process.env[envVariable]) { + addConfigPath(process.env[envVariable]); + } + + return fetchConfigs(); +} diff --git a/yarn.lock b/yarn.lock index fc9498fde2..23fbc50120 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3719,15 +3719,6 @@ randombytes@^2.0.0, randombytes@^2.0.1: version "2.0.3" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.3.tgz#674c99760901c3c4112771a31e521dc349cc09ec" -rc@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.1.tgz#2e03e8e42ee450b8cb3dce65be1bf8974e1dfd95" - dependencies: - deep-extend "~0.4.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - rc@~1.1.6: version "1.1.7" resolved "https://registry.yarnpkg.com/rc/-/rc-1.1.7.tgz#c5ea564bb07aff9fd3a5b32e906c1d3a65940fea"