@tapjs/run
Version:
Command-line interface for the node-tap runner
83 lines • 2.42 kB
JavaScript
/**
* some utilities for interfacing with npm in the `tap plugin` command
*/
import { foregroundChild } from 'foreground-child';
import { mkdirp } from 'mkdirp';
import { spawnSync } from 'node:child_process';
import { resolve } from 'node:path';
const npmFreeEnv = Object.fromEntries(Object.entries(process.env).filter(([k]) => !/^npm_/i.test(k)));
let npmCwd = undefined;
export const npmFindCwd = async (projectRoot) => {
if (!npmCwd) {
npmCwd = resolve(projectRoot, '.tap/plugins');
await mkdirp(npmCwd + '/node_modules');
}
return npmCwd;
};
// exported for testing
export const npmExe = process.platform === 'win32' ? 'npm.cmd' : 'npm';
/**
* Run an npm command in the background, returning the result
*/
export const npmBg = (args, npmCwd) => {
return spawnSync(npmExe, args, {
env: {
...npmFreeEnv,
npm_config_prefix: npmCwd,
},
encoding: 'utf8',
cwd: npmCwd,
shell: false,
});
};
/**
* Run an npm command in the foreground
*/
const npmFg = (args, npmCwd, cb) => {
return foregroundChild(npmExe, args, {
env: {
...npmFreeEnv,
npm_config_prefix: npmCwd,
},
cwd: npmCwd,
shell: false,
}, cb);
};
// suppress all non-essential npm output
const quiet = [
'--silent',
'--log-level=silent',
'--no-audit',
'--loglevel=error',
'--no-progress',
'--no-fund',
];
export const install = async (pkgs, config) => {
const npmCwd = await npmFindCwd(config.projectRoot);
const args = ['install', ...quiet, '--save', ...pkgs];
await new Promise((res, rej) => {
npmFg(args, npmCwd, (code, signal) => {
// allow error exit to proceed
if (code || signal) {
rej(Object.assign(new Error('install failed'), {
code,
signal,
}));
return;
}
res();
// do not exit
return false;
});
});
};
export const uninstall = async (pkgs, config) => {
const args = ['rm', ...quiet, ...pkgs];
const npmCwd = await npmFindCwd(config.projectRoot);
await new Promise(res => npmFg(args, npmCwd, (code, signal) => {
// allow error exit to proceed
res();
return code || signal ? undefined : false;
}));
};
//# sourceMappingURL=npm.js.map