1const ciInfo = require('ci-info') 2const runScript = require('@npmcli/run-script') 3const readPackageJson = require('read-package-json-fast') 4const npmlog = require('npmlog') 5const log = require('proc-log') 6const noTTY = require('./no-tty.js') 7 8const run = async ({ 9 args, 10 call, 11 flatOptions, 12 locationMsg, 13 output = () => {}, 14 path, 15 binPaths, 16 runPath, 17 scriptShell, 18}) => { 19 // turn list of args into command string 20 const script = call || args.shift() || scriptShell 21 22 // do the fakey runScript dance 23 // still should work if no package.json in cwd 24 const realPkg = await readPackageJson(`${path}/package.json`) 25 .catch(() => ({})) 26 const pkg = { 27 ...realPkg, 28 scripts: { 29 ...(realPkg.scripts || {}), 30 npx: script, 31 }, 32 } 33 34 npmlog.disableProgress() 35 36 try { 37 if (script === scriptShell) { 38 if (!noTTY()) { 39 if (ciInfo.isCI) { 40 return log.warn('exec', 'Interactive mode disabled in CI environment') 41 } 42 43 locationMsg = locationMsg || ` at location:\n${flatOptions.chalk.dim(runPath)}` 44 45 output(`${ 46 flatOptions.chalk.reset('\nEntering npm script environment') 47 }${ 48 flatOptions.chalk.reset(locationMsg) 49 }${ 50 flatOptions.chalk.bold('\nType \'exit\' or ^D when finished\n') 51 }`) 52 } 53 } 54 return await runScript({ 55 ...flatOptions, 56 pkg, 57 banner: false, 58 // we always run in cwd, not --prefix 59 path: runPath, 60 binPaths, 61 event: 'npx', 62 args, 63 stdio: 'inherit', 64 scriptShell, 65 }) 66 } finally { 67 npmlog.enableProgress() 68 } 69} 70 71module.exports = run 72