All files / src index.js

100% Statements 38/38
100% Branches 17/17
100% Functions 8/8
100% Lines 37/37
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109                      16x         16x 1x   16x   16x 16x 2x 2x 1x   1x 1x 1x       16x 19x         17x 17x 17x 17x 2x                   15x 15x 15x 15x               15x 15x   15x 1x                       15x 14x 13x   1x                               15x 15x 15x 15x 1x   15x    
import spawn from 'spawn-command-with-kill'
import chalk from 'chalk'
import {oneLine} from 'common-tags'
import {isString, clone} from 'lodash'
import {sync as findUpSync} from 'find-up'
import managePath from 'manage-path'
import arrify from 'arrify'
import getScriptToRun from './get-script-to-run'
import getScriptsFromConfig from './get-scripts-from-config'
import getLogger, {getLogLevel} from './get-logger'
 
const NON_ERROR = 0
 
export default runPackageScripts
 
function runPackageScripts({scriptConfig, scripts, options = {}}) {
  if (scripts.length === 0) {
    scripts = ['default']
  }
  let scriptNames = arrify(scripts)
 
  const separatorIndex = scriptNames.indexOf('--')
  if (separatorIndex >= 0) {
    const additionalOptions = scriptNames.slice(separatorIndex + 1).join(' ')
    if (separatorIndex === 0) {
      scriptNames = [`default ${additionalOptions}`]
    } else {
      scriptNames.splice(separatorIndex)
      const lastIndex = scriptNames.length - 1
      scriptNames[lastIndex] = `${scriptNames[lastIndex]} ${additionalOptions}`
    }
  }
 
  return scriptNames.reduce((res, input) => {
    return res.then(() => runPackageScript({scriptConfig, options, input}))
  }, Promise.resolve())
}
 
function runPackageScript({scriptConfig, options, input}) {
  const [scriptPrefix, ...args] = input.split(' ')
  const scripts = getScriptsFromConfig(scriptConfig, scriptPrefix)
  const {scriptName, script} = getScriptToRun(scripts, scriptPrefix) || {}
  if (!isString(script)) {
    return Promise.reject({
      message: chalk.red(
        oneLine`
          Scripts must resolve to strings.
          There is no script that can be resolved from "${scriptPrefix}"
        `,
      ),
      ref: 'missing-script',
    })
  }
  const command = [script, ...args].join(' ').trim()
  const log = getLogger(getLogLevel(options))
  const showScript = options.scripts
  log.info(
    oneLine`
    ${chalk.gray('nps is executing')}
     \`${chalk.bold(scriptName)}\`
     ${showScript ? `: ${chalk.green(command)}` : ''}
  `,
  )
  let child
  return new Promise((resolve, reject) => {
    child = spawn(command, {stdio: 'inherit', env: getEnv()})
 
    child.on('error', error => {
      reject({
        message: chalk.red(
          oneLine`
            The script called "${scriptPrefix}"
            which runs "${command}" emitted an error
          `,
        ),
        ref: 'emitted-an-error',
        error,
      })
    })
 
    child.on('close', code => {
      if (code === NON_ERROR) {
        resolve(code)
      } else {
        reject({
          message: chalk.red(
            oneLine`
              The script called "${scriptPrefix}"
              which runs "${command}" failed with exit code ${code}
            `,
          ),
          ref: 'failed-with-exit-code',
          code,
        })
      }
    })
  })
}
 
function getEnv() {
  const env = clone(process.env)
  const alterPath = managePath(env)
  const npmBin = findUpSync('node_modules/.bin')
  if (npmBin) {
    alterPath.unshift(npmBin)
  }
  return env
}