UNPKG

@neo-one/simulation-utils

Version:

NEO•ONE Simulation utils.

75 lines (68 loc) 2.01 kB
/* @flow */ import execa from 'execa'; const shouldUseYarn = async () => { try { await execa('yarn', ['--version'], { stdio: 'ignore' }); return true; } catch (e) { return false; } }; const checkThatNpmCanReadCwd = () => { const cwd = process.cwd(); let childOutput = null; try { // Note: intentionally using spawn over exec since // the problem doesn't reproduce otherwise. // `npm config list` is the only reliable way I could find // to reproduce the wrong path. Just printing process.cwd() // in a Node process was not enough. childOutput = execa.sync('npm', ['config', 'list']).output.join(''); } catch (err) { // Something went wrong spawning node. // Not great, but it means we can't do this check. // We might fail later on, but let's continue. return true; } if (typeof childOutput !== 'string') { return true; } const lines = childOutput.split('\n'); // `npm config list` output includes the following line: // "; cwd = C:\path\to\current\dir" (unquoted) // I couldn't find an easier way to get it. const prefix = '; cwd = '; const line = lines.find((l) => l.indexOf(prefix) === 0); if (typeof line !== 'string') { // Fail gracefully. They could remove it. return true; } const npmCWD = line.substring(prefix.length); if (npmCWD === cwd) { return true; } return false; }; const install = async () => { const useYarn = await shouldUseYarn(); let command = 'npm'; const args = ['install']; if (useYarn) { command = 'yarn'; args.push('--cwd'); args.push(process.cwd()); } else if (!checkThatNpmCanReadCwd()) { throw new Error( 'npm could not read cwd. This is probably caused by a misconfigured ' + 'system terminal shell.', ); } await execa(command, args, { stdio: 'inherit' }).catch((error) => { throw new Error( `${command} ${args.join(' ')} exited with code ${error.code}`, ); }); }; export default { install, };