Skip to content

Commit

Permalink
Emulate npm_config_argv environment variable for lifecycle scripts (c…
Browse files Browse the repository at this point in the history
…loses #684)
  • Loading branch information
inikulin committed Oct 16, 2016
1 parent 8f4f01e commit 9f50043
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
try {
const argv = JSON.parse(process.env['npm_config_argv']);

console.log(`##${argv.cooked[0]}##`);
} catch (err) {
console.log(`##${err.toString()}##`);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "npm_config_argv_env_vars",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"prepublish" : "node log-command.js",
"pretest" : "node log-command.js"
}
}
45 changes: 45 additions & 0 deletions __tests__/lifecycle-scripts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/* @flow */

import makeTemp from './_temp';
import * as fs from '../src/util/fs.js';

const path = require('path');
const exec = require('child_process').exec;

const fixturesLoc = path.join(__dirname, './fixtures/lifecycle-scripts');
const yarnBin = path.join(__dirname, '../bin/yarn.js');

jasmine.DEFAULT_TIMEOUT_INTERVAL = 60000;

async function execCommand(cmd: string, packageName: string): Promise<string> {
const srcPackageDir = path.join(fixturesLoc, packageName);
const packageDir = await makeTemp(packageName);

await fs.copy(srcPackageDir, packageDir);

return new Promise((resolve, reject) => {
const env = Object.assign({}, process.env);

delete env.npm_config_argv;

exec(`node ${yarnBin} ${cmd}`, {cwd:packageDir, env}, (err, stdout) => {
if (err) {
reject(err);
} else {
resolve(stdout.toString());
}
});
});
}

test('should expose `npm_config_argv` environment variable to lifecycle scripts for back compatibility with npm (#684)',
async () => {
let stdout = await execCommand('install', 'npm_config_argv_env_vars');
expect(stdout).toContain('##install##');

stdout = await execCommand('', 'npm_config_argv_env_vars');
expect(stdout).toContain('##install##');

stdout = await execCommand('test', 'npm_config_argv_env_vars');
expect(stdout).toContain('##test##');
});
1 change: 1 addition & 0 deletions src/cli/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ config.init({
ignoreEngines: commander.ignoreEngines,
offline: commander.preferOffline || commander.offline,
looseSemver: !commander.strictSemver,
commandName,
}).then(() => {
const exit = () => {
process.exit(0);
Expand Down
6 changes: 6 additions & 0 deletions src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export type ConfigOptions = {

// Loosely compare semver for invalid cases like "0.01.0"
looseSemver?: ?boolean,
commandName?: ?string
};

type PackageMetadata = {
Expand Down Expand Up @@ -115,6 +116,9 @@ export default class Config {
[key: string]: ?Promise<any>
};

//
commandName: string;

/**
* Execute a promise produced by factory if it doesn't exist in our cache with
* the associated key.
Expand Down Expand Up @@ -194,6 +198,8 @@ export default class Config {

this.looseSemver = opts.looseSemver == undefined ? true : opts.looseSemver;

this.commandName = opts.commandName || '';

this.preferOffline = !!opts.preferOffline;
this.modulesFolder = opts.modulesFolder;
this.globalFolder = opts.globalFolder || constants.GLOBAL_MODULE_DIRECTORY;
Expand Down
4 changes: 4 additions & 0 deletions src/util/execute-lifecycle-script.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ async function makeEnv(stage: string, cwd: string, config: Config): {
env.npm_node_execpath = env.NODE || process.execPath;
env.npm_execpath = path.join(__dirname, '..', '..', 'bin', 'yarn.js');

// Note: npm_config_argv environment variable contains output of nopt - command-line
// parser used by npm. Since we use other parser, we just roughly emulate it's output. (See: #684)
env.npm_config_argv = JSON.stringify({remain:[], cooked: [config.commandName], original: [config.commandName]});

// add npm_package_*
const manifest = await config.readManifest(cwd);
const queue = [['', manifest]];
Expand Down

0 comments on commit 9f50043

Please sign in to comment.