<commit_before>#!/usr/bin/env node
//@flow

// Packages
const mri = require('mri')
const chalk = require('chalk')
const ms = require('ms')
const plural = require('pluralize')
const table = require('text-table')

// Utilities
const Now = require('../util')
const createOutput = require('../../../util/output')
const wait = require('../../../util/output/wait')
const logo = require('../../../util/output/logo')
const cmd = require('../../../util/output/cmd')
const elapsed = require('../../../util/output/elapsed')
const { normalizeURL } = require('../../../util/url')
const getContextName = require('../util/get-context-name')
import getAliases from '../util/alias/get-aliases'

const help = () => {
  console.log(`
  ${chalk.bold(
    `${logo} now remove`
  )} [...deploymentId|deploymentName]

  ${chalk.dim('Options:')}

    -h, --help                     Output usage information
    -A ${chalk.bold.underline('FILE')}, --local-config=${chalk.bold.underline(
    'FILE'
  )}   Path to the local ${'`now.json`'} file
    -Q ${chalk.bold.underline('DIR')}, --global-config=${chalk.bold.underline(
    'DIR'
  )}    Path to the global ${'`.now`'} directory
    -d, --debug                    Debug mode [off]
    -t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline(
    'TOKEN'
  )}        Login token
    -y, --yes                      Skip confirmation
    -s, --safe                     Skip deployments with an active alias
    -T, --team                     Set a custom team scope

  ${chalk.dim('Examples:')}

  ${chalk.gray('–')} Remove a deployment identified by ${chalk.dim(
    '`deploymentId`'
  )}

    ${chalk.cyan('$ now rm deploymentId')}

  ${chalk.gray('–')} Remove all deployments with name ${chalk.dim('`my-app`')}

    ${chalk.cyan('$ now rm my-app')}

  ${chalk.gray('–')} Remove two deployments with IDs ${chalk.dim(
    '`eyWt6zuSdeus`'
  )} and ${chalk.dim('`uWHoA9RQ1d1o`')}

    ${chalk.cyan('$ now rm eyWt6zuSdeus uWHoA9RQ1d1o')}
`)
}

// Options

module.exports = async function main (ctx: any): Promise<number>{
  let argv;

  argv = mri(ctx.argv.slice(2), {
    boolean: ['help', 'debug', 'hard', 'yes', 'safe'],
    alias: {
      help: 'h',
      debug: 'd',
      yes: 'y',
      safe: 's'
    }
  })

  argv._ = argv._.slice(1)

  const apiUrl = ctx.apiUrl
  const hard = argv.hard || false
  const skipConfirmation = argv.yes || false
  const ids = argv._
  const debugEnabled = argv.debug
  const output = createOutput({ debug: debugEnabled })
  const { success, error, log } = output;

  if (ids.length < 1) {
    error(`${cmd('now rm')} expects at least one argument`);
    help();
    return 1;
  }

  if (argv.help || ids[0] === 'help') {
    help()
    return 2;
  }

  const {authConfig: { credentials }, config: { sh }} = ctx
  const {token} = credentials.find(item => item.provider === 'sh')
  const {currentTeam} = sh;
  const contextName = getContextName(sh);

  const now = new Now({ apiUrl, token, debug: debugEnabled, currentTeam })

  const cancelWait = wait(`Fetching deployment(s) ${ids.map(id => `"${id}"`).join(' ')} in ${chalk.bold(contextName)}`);

  let deployments;
  const findStart = Date.now();

  try {
    deployments = await now.list(null, { version: 3 })
  } catch (err) {
    cancelWait();
    throw err;
  }

  let matches = deployments.filter(d => {
    return ids.some(id => {
      return d.uid === id || d.name === id || d.url === normalizeURL(id)
    })
  })

  let aliases;

  try {
    aliases = await Promise.all(matches.map(depl => getAliases(now, depl.uid)))
    cancelWait();
  } catch (err) {
    cancelWait();
    throw err;
  }

  matches = matches.filter((match, i) => {
    if (argv.safe && aliases[i].length > 0) {
      return false
    }

    match.aliases = aliases[i]
    return true
  })

  if (matches.length === 0) {
    error(
      `Could not find ${argv.safe
        ? 'unaliased'
        : 'any'} deployments matching ${ids
        .map(id => chalk.bold(`"${id}"`))
        .join(', ')}. Run ${cmd('now ls')} to list.`
    )
    return 1;
  }

  log(`Found ${plural('deployment', matches.length, true)} for removal in ${chalk.bold(contextName)} ${elapsed(Date.now() - findStart)}`);

  if (!skipConfirmation) {
    const confirmation = (await readConfirmation(matches, output)).toLowerCase()

    if (confirmation !== 'y' && confirmation !== 'yes') {
      output.log('Aborted');
      now.close();
      return 1
    }
  }

  const start = new Date()
<commit_msg>Changed error to log to avoid breaking automatic deployments (#1572)<commit_after>#!/usr/bin/env node
//@flow

// Packages
const mri = require('mri')
const chalk = require('chalk')
const ms = require('ms')
const plural = require('pluralize')
const table = require('text-table')

// Utilities
const Now = require('../util')
const createOutput = require('../../../util/output')
const wait = require('../../../util/output/wait')
const logo = require('../../../util/output/logo')
const cmd = require('../../../util/output/cmd')
const elapsed = require('../../../util/output/elapsed')
const { normalizeURL } = require('../../../util/url')
const getContextName = require('../util/get-context-name')
import getAliases from '../util/alias/get-aliases'

const help = () => {
  console.log(`
  ${chalk.bold(
    `${logo} now remove`
  )} [...deploymentId|deploymentName]

  ${chalk.dim('Options:')}

    -h, --help                     Output usage information
    -A ${chalk.bold.underline('FILE')}, --local-config=${chalk.bold.underline(
    'FILE'
  )}   Path to the local ${'`now.json`'} file
    -Q ${chalk.bold.underline('DIR')}, --global-config=${chalk.bold.underline(
    'DIR'
  )}    Path to the global ${'`.now`'} directory
    -d, --debug                    Debug mode [off]
    -t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline(
    'TOKEN'
  )}        Login token
    -y, --yes                      Skip confirmation
    -s, --safe                     Skip deployments with an active alias
    -T, --team                     Set a custom team scope

  ${chalk.dim('Examples:')}

  ${chalk.gray('–')} Remove a deployment identified by ${chalk.dim(
    '`deploymentId`'
  )}

    ${chalk.cyan('$ now rm deploymentId')}

  ${chalk.gray('–')} Remove all deployments with name ${chalk.dim('`my-app`')}

    ${chalk.cyan('$ now rm my-app')}

  ${chalk.gray('–')} Remove two deployments with IDs ${chalk.dim(
    '`eyWt6zuSdeus`'
  )} and ${chalk.dim('`uWHoA9RQ1d1o`')}

    ${chalk.cyan('$ now rm eyWt6zuSdeus uWHoA9RQ1d1o')}
`)
}

// Options

module.exports = async function main (ctx: any): Promise<number>{
  let argv;

  argv = mri(ctx.argv.slice(2), {
    boolean: ['help', 'debug', 'hard', 'yes', 'safe'],
    alias: {
      help: 'h',
      debug: 'd',
      yes: 'y',
      safe: 's'
    }
  })

  argv._ = argv._.slice(1)

  const apiUrl = ctx.apiUrl
  const hard = argv.hard || false
  const skipConfirmation = argv.yes || false
  const ids = argv._
  const debugEnabled = argv.debug
  const output = createOutput({ debug: debugEnabled })
  const { success, error, log } = output;

  if (ids.length < 1) {
    error(`${cmd('now rm')} expects at least one argument`);
    help();
    return 1;
  }

  if (argv.help || ids[0] === 'help') {
    help()
    return 2;
  }

  const {authConfig: { credentials }, config: { sh }} = ctx
  const {token} = credentials.find(item => item.provider === 'sh')
  const {currentTeam} = sh;
  const contextName = getContextName(sh);

  const now = new Now({ apiUrl, token, debug: debugEnabled, currentTeam })

  const cancelWait = wait(`Fetching deployment(s) ${ids.map(id => `"${id}"`).join(' ')} in ${chalk.bold(contextName)}`);

  let deployments;
  const findStart = Date.now();

  try {
    deployments = await now.list(null, { version: 3 })
  } catch (err) {
    cancelWait();
    throw err;
  }

  let matches = deployments.filter(d => {
    return ids.some(id => {
      return d.uid === id || d.name === id || d.url === normalizeURL(id)
    })
  })

  let aliases;

  try {
    aliases = await Promise.all(matches.map(depl => getAliases(now, depl.uid)))
    cancelWait();
  } catch (err) {
    cancelWait();
    throw err;
  }

  matches = matches.filter((match, i) => {
    if (argv.safe && aliases[i].length > 0) {
      return false
    }

    match.aliases = aliases[i]
    return true
  })

  if (matches.length === 0) {
    log(
      `Could not find ${argv.safe
        ? 'unaliased'
        : 'any'} deployments matching ${ids
        .map(id => chalk.bold(`"${id}"`))
        .join(', ')}. Run ${cmd('now ls')} to list.`
    )
    return 1;
  }

  log(`Found ${plural('deployment', matches.length, true)} for removal in ${chalk.bold(contextName)} ${elapsed(Date.now() - findStart)}`);

  if (!skipConfirmation) {
    const confirmation = (await readConfirmation(matches, output)).toLowerCase()

    if (confirmation !== 'y' && confirmation !== 'yes') {
      output.log('Aborted');
      now.close();
      return 1
    }
  }

  const start = new Date()

{'fraction_non_alphanumeric': 0.19111604664075513, 'fraction_numerical': 0.004664075513603554, 'mean_word_length': 2.709225700164745, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 23, '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': '4651486', 'n_tokens_mistral': 3099, 'n_tokens_neox': 2994, 'n_words': 747}