Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature] [may break .yarnrc for older versions] Ability to pass command CLI arguments via configuration in .yarnrc #3033

Merged
merged 8 commits into from
Apr 6, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--cache-folder foobar/hello/world
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{
}
1 change: 1 addition & 0 deletions __tests__/fixtures/lifecycle-scripts/yarnrc-cli/.yarnrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--cache-folder /tmp/foobar
2 changes: 2 additions & 0 deletions __tests__/fixtures/lifecycle-scripts/yarnrc-cli/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{
}
16 changes: 16 additions & 0 deletions __tests__/lifecycle-scripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,22 @@ async function execCommand(cmd: string, packageName: string, env = process.env):
});
}

test('should add the yarnrc values to the command line', async () => {
const stdout = await execCommand('cache dir', 'yarnrc-cli');
expect(stdout.replace(/\\/g, '/')).toMatch(/^\/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$/);
});

// Test disabled for now, cf rc.js
test.skip('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$/);
});

test('should expose `npm_config_argv` environment variable to lifecycle scripts for back compatibility with npm (#684)',
async () => {
const env = Object.assign({}, process.env);
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"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",
Expand Down
6 changes: 3 additions & 3 deletions src/cli/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import * as network from '../util/network.js';
import {MessageError} from '../errors.js';
import aliases from './aliases.js';
import Config from '../config.js';
import {getRcArgs} from '../rc.js';
import {camelCase} from '../util/misc.js';

const chalk = require('chalk');
Expand Down Expand Up @@ -166,8 +167,7 @@ if (args.indexOf('--help') >= 0 || args.indexOf('-h') >= 0) {
process.exit(1);
}

// parse flags
args.unshift(commandName);
args = [commandName].concat(getRcArgs(commandName), args);

if (ARGS_THAT_SHARE_NAMES_WITH_OPTIONS.indexOf(commandName) >= 0 && args[0] === commandName) {
args.shift();
Expand Down Expand Up @@ -369,7 +369,7 @@ config.init({
binLinks: commander.binLinks,
modulesFolder: commander.modulesFolder,
globalFolder: commander.globalFolder,
cacheRootFolder: commander.cacheFolder,
cacheFolder: commander.cacheFolder,
preferOffline: commander.preferOffline,
captureHar: commander.har,
ignorePlatform: commander.ignorePlatform,
Expand Down
2 changes: 1 addition & 1 deletion src/lockfile/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ export function* tokenise(input: string): Iterator<Token> {
} else if (input[0] === ',') {
yield buildToken(TOKEN_TYPES.comma);
chop++;
} else if (/^[a-zA-Z]/g.test(input)) {
} else if (/^[a-zA-Z\/-]/g.test(input)) {
let name = "";
for (let i = 0; i < input.length; i++) {
const char = input[i];
Expand Down
87 changes: 87 additions & 0 deletions src/rc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/* @flow */

import parse from './lockfile/parse.js';

const rc = require('rc');

// Keys that will get resolved relative to the path of the rc file they belong to
const PATH_KEYS = [
'cache-folder',
'global-folder',
'modules-folder',
];

let rcConfCache;
let rcArgsCache;

const buildRcConf = () => rc('yarn', {}, [], (fileText) => {
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];
}
}
}
}

return values;
});

export function getRcConf(): { [string]: Array<string> } {
if (!rcConfCache) {
rcConfCache = buildRcConf();
}

return rcConfCache;
}

const buildRcArgs = () => Object.keys(getRcConf()).reduce((argLists, key) => {
const miniparse = key.match(/^--(?:([^.]+)\.)?(.*)$/);

if (!miniparse) {
return argLists;
}

const namespace = miniparse[1] || '*';
const arg = miniparse[2];
const value = getRcConf()[key];

if (!argLists[namespace]) {
argLists[namespace] = [];
}

if (typeof value === 'string') {
argLists[namespace] = argLists[namespace].concat([`--${arg}`, value]);
} else {
argLists[namespace] = argLists[namespace].concat([`--${arg}`]);
}

return argLists;
}, {});

export function getRcArgs(command: string): Array<string> {
if (!rcArgsCache) {
rcArgsCache = buildRcArgs();
}

let result = rcArgsCache['*'] || [];

if (command !== '*') {
result = result.concat(rcArgsCache[command] || []);
}

return result;
}

export function clearRcCache() {
rcConfCache = null;
rcArgsCache = null;
}
9 changes: 9 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3719,6 +3719,15 @@ 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"
Expand Down