<commit_before>const fs = require('fs')

const appPaths = require('../app-paths')
const spawn = require('cross-spawn').sync
const { log, warn, fatal } = require('./logger')
const { spawnSync } = require('./spawn')

class PackageManager {
  name = 'unknown'
  lockFile = 'unknown'

  isUsed() {
    return fs.existsSync(appPaths.resolve.app(this.lockFile))
  }

  isInstalled() {
    try {
      // spawnSync helper logs stuff and exits the app on error, so we don't use it here
      return spawn(this.name, ['--version']).status === 0
    }
    catch (err) {
      return false
    }
  }

  install({ cwd, displayName } = {}) {
    displayName = displayName ? displayName + ' ' : ''

    log(`Installing ${displayName}dependencies...`)
    this.__run(['install'], {
      cwd,
      onFail: () => fatal(`Failed to install ${displayName}dependencies`, 'FAIL')
    })
  }

  getInstallPackageParams(names, isDev) {
    return []
  }

  installPackage (name, { cwd, displayName = name, isDev = false } = {}) {
    const params = this.getInstallPackageParams(Array.isArray(name) ? name : [name], isDev)

    log(`Installing ${displayName}...`)
    this.__run(params, {
      cwd,
      onFail: () => fatal(`Failed to install ${displayName}`, 'FAIL')
    })
  }

  getUninstallPackageParams(names) {
    return []
  }

  uninstallPackage (name, { cwd, displayName = name } = {}) {
    const params = this.getUninstallPackageParams(Array.isArray(name) ? name : [name])

    log(`Uninstalling ${displayName}...`)
    this.__run(params, {
      cwd,
      onFail: () => fatal(`Failed to uninstall ${displayName}`, 'FAIL')
    })
  }

  __run (params, { cwd, onFail } = {}) {
    spawnSync(
      this.name,
      params.filter(param => typeof param === 'string' && param.length > 0),
      { cwd: cwd || appPaths.appDir, env: { ...process.env, NODE_ENV: 'development' } },
      onFail
    )
  }
}

class Npm extends PackageManager {
  name = 'npm'
  lockFile = 'package-lock.json'

  getInstallPackageParams(names, isDev) {
    return [
      'install',
      isDev ? '--save-dev' : '',
      ...names,
    ]
  }

  getUninstallPackageParams(names) {
    return ['uninstall', ...names]
  }
}

class Yarn extends PackageManager {
  name = 'yarn'
  lockFile = 'yarn.lock'

  getInstallPackageParams(names, isDev) {
    return [
      'add',
      isDev ? '--dev' : '',
      ...names
    ]
  }

  getUninstallPackageParams(names) {
    return ['remove', ...names]
  }
}

/**
 * @returns {PackageManager}
 */
function getPackager () {
  const yarn = new Yarn()
  const npm = new Npm()

  if (yarn.isUsed) {
    return yarn
  }

  if (npm.isUsed) {
    return npm
  }

  if (yarn.isInstalled) {
    return yarn
  }

  if (npm.isInstalled) {
    return npm
  }

  warn('Please install Yarn or NPM before running this command.\n')
}

module.exports = getPackager()
<commit_msg>fix(app-webpack): Use the correct package manager (fix #12853) (#12856)<commit_after>const fs = require('fs')

const appPaths = require('../app-paths')
const spawn = require('cross-spawn').sync
const { log, warn, fatal } = require('./logger')
const { spawnSync } = require('./spawn')

class PackageManager {
  name = 'unknown'
  lockFile = 'unknown'

  isUsed() {
    return fs.existsSync(appPaths.resolve.app(this.lockFile))
  }

  isInstalled() {
    try {
      // spawnSync helper logs stuff and exits the app on error, so we don't use it here
      return spawn(this.name, ['--version']).status === 0
    }
    catch (err) {
      return false
    }
  }

  install({ cwd, displayName } = {}) {
    displayName = displayName ? displayName + ' ' : ''

    log(`Installing ${displayName}dependencies...`)
    this.__run(['install'], {
      cwd,
      onFail: () => fatal(`Failed to install ${displayName}dependencies`, 'FAIL')
    })
  }

  getInstallPackageParams(names, isDev) {
    return []
  }

  installPackage (name, { cwd, displayName = name, isDev = false } = {}) {
    const params = this.getInstallPackageParams(Array.isArray(name) ? name : [name], isDev)

    log(`Installing ${displayName}...`)
    this.__run(params, {
      cwd,
      onFail: () => fatal(`Failed to install ${displayName}`, 'FAIL')
    })
  }

  getUninstallPackageParams(names) {
    return []
  }

  uninstallPackage (name, { cwd, displayName = name } = {}) {
    const params = this.getUninstallPackageParams(Array.isArray(name) ? name : [name])

    log(`Uninstalling ${displayName}...`)
    this.__run(params, {
      cwd,
      onFail: () => fatal(`Failed to uninstall ${displayName}`, 'FAIL')
    })
  }

  __run (params, { cwd, onFail } = {}) {
    spawnSync(
      this.name,
      params.filter(param => typeof param === 'string' && param.length > 0),
      { cwd: cwd || appPaths.appDir, env: { ...process.env, NODE_ENV: 'development' } },
      onFail
    )
  }
}

class Npm extends PackageManager {
  name = 'npm'
  lockFile = 'package-lock.json'

  getInstallPackageParams(names, isDev) {
    return [
      'install',
      isDev ? '--save-dev' : '',
      ...names,
    ]
  }

  getUninstallPackageParams(names) {
    return ['uninstall', ...names]
  }
}

class Yarn extends PackageManager {
  name = 'yarn'
  lockFile = 'yarn.lock'

  getInstallPackageParams(names, isDev) {
    return [
      'add',
      isDev ? '--dev' : '',
      ...names
    ]
  }

  getUninstallPackageParams(names) {
    return ['remove', ...names]
  }
}

/**
 * @returns {PackageManager}
 */
function getPackager () {
  const yarn = new Yarn()
  const npm = new Npm()

  if (yarn.isUsed()) {
    return yarn
  }

  if (npm.isUsed()) {
    return npm
  }

  if (yarn.isInstalled()) {
    return yarn
  }

  if (npm.isInstalled()) {
    return npm
  }

  warn('Please install Yarn or NPM before running this command.\n')
}

module.exports = getPackager()

{'fraction_non_alphanumeric': 0.16149068322981366, 'fraction_numerical': 0.0024154589371980675, 'mean_word_length': 2.7545336787564767, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5382279', 'n_tokens_mistral': 1978, 'n_tokens_neox': 1911, 'n_words': 434}