<commit_before>/**
 * Module dependencies
 */

var cp      = require('child_process')
  , fs      = require('fs-extra')
  , path    = require('path')
  , crypto  = require('crypto')
  , async   = require('async')
  ;

/**
 * Initialize Git Repository
 */

function gitInit (done) {
  fs.exists('.git', function (exists) {
    if (exists) {
      console.log('* Git repository already initialized.');
      return done();
    }

    cp.exec('git init', function (err, stdout, stderr) {
      console.log('* Initialized git repository');
      done(err);
    });
  });
}

/**
 * Safe JSON
 */

function safeJSON (file, obj) {
  return function (done) {
    fs.exists(file, function (exists) {
      if (exists) {
        console.log('* %s already initialized.', file);
        return done();
      }

      fs.outputJSON(file, obj, function (err) {
        console.log('* Generated %s', file);
        done(err);
      });
    })
  };
}

/**
 * Safe copy files and directories
 */

function safeCopy (from, to) {
  return function (done) {
    fs.exists(to, function (exists) {
      if (exists) {
        console.log('* %s already initialized.', to);
        return done();
      }

      fs.copy(from, to, function (err) {
        console.log('* Generated %s', to);
        done(err);
      });
    });
  };
}

/**
 * Generate RSA Key Pair
 */

function rsaKeys (done) {
  fs.exists('config/keys', function (exists) {
    if (exists) {
      console.log('* RSA key pair already initialized.');
      return done();
    }

    cp.exec('openssl genrsa 2048', function (err, stdout, stderr) {
      if (err) { return done(err); }

      fs.outputFile('config/keys/private.pem', stdout, function (err) {
        if (err) { return done(err); }

        var cmd = 'openssl rsa -in config/keys/private.pem -pubout';
        cp.exec(cmd, function (err, stdout, stderr) {
          if (err) { return done(err) }

          fs.outputFile('config/keys/public.pem', stdout, function (err) {
            if (err) { return done(err); }

            console.log('* Generated RSA keypair');
            done();
          });
        });
      });
    });
  });
}

/**
 * Export
 */

module.exports = function (argv) {

  console.log();
  console.log('Initializing Anvil Connect deployment repository:');
  console.log();

  async.series([

    gitInit,

    // initialize npm package
    safeJSON('package.json', {
      name:          process.cwd().split('/').pop(),
      version:      '0.0.0',
      description:  'Anvil Connect Deployment',
      private:       true,
      main:         'server.js',
      scripts: {
        start:      'node server.js'
      },
      engines: {
        node:       '>=0.10.28'
      },
      dependencies: {
        'anvil-connect': require(path.join(__dirname, '../../package.json')).version
      }
    }),

    // initialize development configuration
    safeJSON('config/development.json', {
      issuer: 'http://localhost:3000',
      client_registration: 'scoped',
      cookie_secret: crypto.randomBytes(10).toString('hex'),
      session_secret: crypto.randomBytes(10).toString('hex'),
    }),

    // initialize production configuration
    safeJSON('config/production.json', {
      issuer: 'https://your.authorization.server',
      client_registration: 'scoped',
      providers: {
        google: {
          clientID: 'CLIENT_ID',
          clientSecret: 'CLIENT_SECRET',
          callbackURL: 'https://YOUR.AUTH.SERVER/connect/google/callback',
          passReqToCallback: true,
          scope: [
            "https://www.googleapis.com/auth/userinfo.profile",
            "https://www.googleapis.com/auth/userinfo.email"
          ]
        }
      },
      cookie_secret: crypto.randomBytes(10).toString('hex'),
      session_secret: crypto.randomBytes(10).toString('hex'),
      redis: {
        url: 'redis://HOST:PORT',
        auth: 'PASSWORD'
      }
    }),

    // copy default files and directories
    safeCopy(path.join(__dirname, 'deployment/server.js'), 'server.js'),
    safeCopy(path.join(__dirname, '../../views'), 'views'),
    safeCopy(path.join(__dirname, '../../public'), 'public'),
    safeCopy(path.join(__dirname, 'deployment/gitignore'), '.gitignore'),
    safeCopy(path.join(__dirname, 'deployment/modulusignore'), '.modulusignore'),
    safeCopy(path.join(__dirname, 'deployment/Dockerfile'), 'Dockerfile'),

    // generate rsa key pair
    rsaKeys

  ], function (err, result) {
    fs.readFile(path.join(__dirname, 'docs/post-init-deployment.txt'), 'utf-8', function (err, file) {
      console.log(file);
      process.exit();
    });
  });

};
<commit_msg>app default config update<commit_after>/**
 * Module dependencies
 */

var cp      = require('child_process')
  , fs      = require('fs-extra')
  , path    = require('path')
  , crypto  = require('crypto')
  , async   = require('async')
  ;

/**
 * Initialize Git Repository
 */

function gitInit (done) {
  fs.exists('.git', function (exists) {
    if (exists) {
      console.log('* Git repository already initialized.');
      return done();
    }

    cp.exec('git init', function (err, stdout, stderr) {
      console.log('* Initialized git repository');
      done(err);
    });
  });
}

/**
 * Safe JSON
 */

function safeJSON (file, obj) {
  return function (done) {
    fs.exists(file, function (exists) {
      if (exists) {
        console.log('* %s already initialized.', file);
        return done();
      }

      fs.outputJSON(file, obj, function (err) {
        console.log('* Generated %s', file);
        done(err);
      });
    })
  };
}

/**
 * Safe copy files and directories
 */

function safeCopy (from, to) {
  return function (done) {
    fs.exists(to, function (exists) {
      if (exists) {
        console.log('* %s already initialized.', to);
        return done();
      }

      fs.copy(from, to, function (err) {
        console.log('* Generated %s', to);
        done(err);
      });
    });
  };
}

/**
 * Generate RSA Key Pair
 */

function rsaKeys (done) {
  fs.exists('config/keys', function (exists) {
    if (exists) {
      console.log('* RSA key pair already initialized.');
      return done();
    }

    cp.exec('openssl genrsa 2048', function (err, stdout, stderr) {
      if (err) { return done(err); }

      fs.outputFile('config/keys/private.pem', stdout, function (err) {
        if (err) { return done(err); }

        var cmd = 'openssl rsa -in config/keys/private.pem -pubout';
        cp.exec(cmd, function (err, stdout, stderr) {
          if (err) { return done(err) }

          fs.outputFile('config/keys/public.pem', stdout, function (err) {
            if (err) { return done(err); }

            console.log('* Generated RSA keypair');
            done();
          });
        });
      });
    });
  });
}

/**
 * Export
 */

module.exports = function (argv) {

  console.log();
  console.log('Initializing Anvil Connect deployment repository:');
  console.log();

  async.series([

    gitInit,

    // initialize npm package
    safeJSON('package.json', {
      name:          process.cwd().split('/').pop(),
      version:      '0.0.0',
      description:  'Anvil Connect Deployment',
      private:       true,
      main:         'server.js',
      scripts: {
        start:      'node server.js'
      },
      engines: {
        node:       '>=0.10.28'
      },
      dependencies: {
        'anvil-connect': require(path.join(__dirname, '../../package.json')).version
      }
    }),

    // initialize development configuration
    safeJSON('config/development.json', {
      issuer: 'http://localhost:3000',
      client_registration: 'scoped',
      providers: {
        google: {
          client_id: 'CLIENT_ID',
          client_secret: 'CLIENT_SECRET',
          scope: [
            "https://www.googleapis.com/auth/userinfo.profile",
            "https://www.googleapis.com/auth/userinfo.email"
          ]
        }
      },
      cookie_secret: crypto.randomBytes(10).toString('hex'),
      session_secret: crypto.randomBytes(10).toString('hex'),
    }),

    // initialize production configuration
    safeJSON('config/production.json', {
      issuer: 'https://your.authorization.server',
      client_registration: 'scoped',
      providers: {
        google: {
          client_id: 'CLIENT_ID',
          client_secret: 'CLIENT_SECRET',
          scope: [
            "https://www.googleapis.com/auth/userinfo.profile",
            "https://www.googleapis.com/auth/userinfo.email"
          ]
        }
      },
      cookie_secret: crypto.randomBytes(10).toString('hex'),
      session_secret: crypto.randomBytes(10).toString('hex'),
      redis: {
        url: 'redis://HOST:PORT',
        auth: 'PASSWORD'
      }
    }),

    // copy default files and directories
    safeCopy(path.join(__dirname, 'deployment/server.js'), 'server.js'),
    safeCopy(path.join(__dirname, '../../views'), 'views'),
    safeCopy(path.join(__dirname, '../../public'), 'public'),
    safeCopy(path.join(__dirname, 'deployment/gitignore'), '.gitignore'),
    safeCopy(path.join(__dirname, 'deployment/modulusignore'), '.modulusignore'),
    safeCopy(path.join(__dirname, 'deployment/Dockerfile'), 'Dockerfile'),

    // generate rsa key pair
    rsaKeys

  ], function (err, result) {
    fs.readFile(path.join(__dirname, 'docs/post-init-deployment.txt'), 'utf-8', function (err, file) {
      console.log(file);
      process.exit();
    });
  });

};
<|endoftext|>


<commit_before>const {default: ux} = require('cli-ux')
const {default: c} = require('@heroku-cli/color')

const COLORS = [
  s => c.yellow(s),
  s => c.green(s),
  s => c.cyan(s),
  s => c.magenta(s),
  s => c.blue(s),
  s => c.bold.green(s),
  s => c.bold.cyan(s),
  s => c.bold.magenta(s),
  s => c.bold.yellow(s),
  s => c.bold.blue(s)
]
const assignedColors = {}
function getColorForIdentifier (i) {
  i = i.split('.')[0]
  if (assignedColors[i]) return assignedColors[i]
  assignedColors[i] = COLORS[Object.keys(assignedColors).length % COLORS.length]
  return assignedColors[i]
}

// get initial colors so they are the same every time
getColorForIdentifier('run')
getColorForIdentifier('router')
getColorForIdentifier('web')
getColorForIdentifier('postgres')
getColorForIdentifier('heroku-postgres')

let lineRegex = /^(.*?\[([\w-]+)([\d.]+)?]:)(.*)?$/

const red = c.red
const dim = i => c.dim(i)
const other = dim
const path = i => c.blue(i)
const method = i => c.bold.magenta(i)
const status = code => {
  if (code < 200) return code
  if (code < 300) return c.green(code)
  if (code < 400) return c.cyan(code)
  if (code < 500) return c.yellow(code)
  if (code < 600) return c.red(code)
  return code
}
const ms = s => {
  const ms = parseInt(s)
  if (!ms) return s
  if (ms < 100) return c.greenBright(s)
  if (ms < 500) return c.green(s)
  if (ms < 5000) return c.yellow(s)
  if (ms < 10000) return c.yellowBright(s)
  return c.red(s)
}

function colorizeRouter (body) {
  try {
    const tokens = body.split('=')
    let cur = tokens[0]
    const obj = {}
    for (let i = 1; i < tokens.length; i++) {
      obj[cur] = tokens[i].split(' ').slice(0, -1).join(' ')
      let next = tokens[i].split(' ').pop()
      if (i + 1 === tokens.length) obj[cur] = next
      cur = next
    }
    if (Object.keys(obj).length === 0) return body
    return Object.entries(obj)
      .map(([k, v]) => {
        switch (k) {
          case 'at': return [k, v === 'error' ? red(v) : other(v)]
          case 'desc': return [k, red(v)]
          case 'code': return [k, red.bold(v)]
          case 'method': return [k, method(v)]
          case 'dyno': return [k, getColorForIdentifier(v)(v)]
          case 'status': return [k, status(v)]
          case 'path': return [k, path(v)]
          case 'connect': return [k, ms(v)]
          case 'service': return [k, ms(v)]
          default: return [k, other(v)]
        }
      })
      .map(([k, v]) => other(k + '=') + v)
      .join(' ')
  } catch (err) {
    ux.warn(err)
    return body
  }
}

const state = s => {
  switch (s) {
    case 'down': return red(s)
    case 'up': return c.greenBright(s)
    case 'starting': return c.yellowBright(s)
    case 'complete': return c.greenBright(s)
    default: return s
  }
}

function colorizeRun (body) {
  try {
    if (body.match(/^Stopping all processes with SIGTERM$/)) return c.red(body)
    let starting = body.match(/^(Starting process with command )(`.+`)(by user )?(.*)?$/)
    if (starting) {
      return [
        starting[1],
        c.cmd(starting[2]),
        starting[3] || '',
        c.green(starting[4] || '')
      ].join('')
    }
    let stateChange = body.match(/^(State changed from )(\w+)( to )(\w+)$/)
    if (stateChange) {
      return [
        stateChange[1],
        state(stateChange[2]),
        stateChange[3] || '',
        state(stateChange[4] || '')
      ].join('')
    }
    let exited = body.match(/^(Process exited with status )(\d+)$/)
    if (exited) {
      return [
        exited[1],
        exited[2] === '0' ? c.greenBright(exited[2]) : c.red(exited[2])
      ].join('')
    }
  } catch (err) {
    ux.warn(err)
  }
  return body
}

function colorizeWeb (body) {
  try {
    if (body.match(/^Unidling$/)) return c.yellow(body)
    if (body.match(/^Restarting$/)) return c.yellow(body)
    if (body.match(/^Stopping all processes with SIGTERM$/)) return c.red(body)
    let starting = body.match(/^(Starting process with command )(`.+`)(by user )?(.*)?$/)
    if (starting) {
      return [
        (starting[1]),
        c.cmd(starting[2]),
        (starting[3] || ''),
        c.green(starting[4] || '')
      ].join('')
    }
    let exited = body.match(/^(Process exited with status )(\d+)$/)
    if (exited) {
      return [
        exited[1],
        exited[2] === '0' ? c.greenBright(exited[2]) : c.red(exited[2])
      ].join('')
    }
    let stateChange = body.match(/^(State changed from )(\w+)( to )(\w+)$/)
    if (stateChange) {
      return [
        stateChange[1],
        state(stateChange[2]),
        stateChange[3],
        state(stateChange[4])
      ].join('')
    }
    let apache = body.match(/^(\d+\.\d+\.\d+\.\d+ -[^-]*- \[[^\]]+\] ")(\w+)( )([^ ]+)( HTTP\/\d+\.\d+" )(\d+)( .+$)/)
    if (apache) {
      const [, ...tokens] = apache
      return [
        other(tokens[0]),
        method(tokens[1]),
        other(tokens[2]),
        path(tokens[3]),
        other(tokens[4]),
        status(tokens[5]),
        other(tokens[6])
      ].join('')
    }
    let route = body.match(/^(.* ")(\w+)(.+)(HTTP\/\d+\.\d+" .*)$/)
    if (route) {
      return [
        route[1],
        method(route[2]),
        path(route[3]),
        route[4]
      ].join('')
    }
  } catch (err) {
    ux.warn(err)
  }
  return body
}

function colorizeAPI (body) {
  if (body.match(/^Build succeeded$/)) return c.greenBright(body)
  if (body.match(/^Build failed/)) return c.red(body)
  const build = body.match(/^(Build started by user )(.+)$/)
  if (build) {
    return [
      build[1],
      c.green(build[2])
    ].join('')
  }
  const deploy = body.match(/^(Deploy )([\w]+)( by user )(.+)$/)
  if (deploy) {
    return [
      deploy[1],
      c.cyan(deploy[2]),
      deploy[3],
      c.green(deploy[4])
    ].join('')
  }
  const release = body.match(/^(Release )(v[\d]+)( created by user )(.+)$/)
  if (release) {
    return [
      release[1],
      c.magenta(release[2]),
      release[3],
      c.green(release[4])
    ].join('')
  }
  let starting = body.match(/^(Starting process with command )(`.+`)(by user )?(.*)?$/)
  if (starting) {
    return [
      (starting[1]),
      c.cmd(starting[2]),
      (starting[3] || ''),
      c.green(starting[4] || '')
    ].join('')
  }
  return body
}

function colorizeRedis (body) {
  if (body.match(/source=\w+ sample#/)) {
    body = dim(body)
  }
  return body
}

function colorizePG (body) {
  let create = body.match(/^(\[DATABASE\].*)(CREATE TABLE)(.*)$/)
  if (create) {
    return [
      other(create[1]),
      c.magenta(create[2]),
      c.cyan(create[3])
    ].join('')
  }
  if (body.match(/source=\w+ sample#/)) {
    body = dim(body)
  }
  return body
}

module.exports = function colorize (line) {
  if (process.env.HEROKU_LOGS_COLOR === '0') return line

  let parsed = line.match(lineRegex)
  if (!parsed) return line
  let header = parsed[1]
  let identifier = parsed[2]
  let body = parsed[4].trim()
  switch (identifier) {
    case 'api':
      body = colorizeAPI(body)
      break
    case 'router':
      body = colorizeRouter(body)
      break
    case 'run':
      body = colorizeRun(body)
      break
    case 'web':
      body = colorizeWeb(body)
      break
    case 'heroku-redis':
      body = colorizeRedis(body)
      break
    case 'heroku-postgres':
    case 'postgres':
      body = colorizePG(body)
  }
  return getColorForIdentifier(identifier)(header) + ' ' + body
}

module.exports.COLORS = COLORS
<commit_msg>fix: empty log lines<commit_after>const {default: ux} = require('cli-ux')
const {default: c} = require('@heroku-cli/color')

const COLORS = [
  s => c.yellow(s),
  s => c.green(s),
  s => c.cyan(s),
  s => c.magenta(s),
  s => c.blue(s),
  s => c.bold.green(s),
  s => c.bold.cyan(s),
  s => c.bold.magenta(s),
  s => c.bold.yellow(s),
  s => c.bold.blue(s)
]
const assignedColors = {}
function getColorForIdentifier (i) {
  i = i.split('.')[0]
  if (assignedColors[i]) return assignedColors[i]
  assignedColors[i] = COLORS[Object.keys(assignedColors).length % COLORS.length]
  return assignedColors[i]
}

// get initial colors so they are the same every time
getColorForIdentifier('run')
getColorForIdentifier('router')
getColorForIdentifier('web')
getColorForIdentifier('postgres')
getColorForIdentifier('heroku-postgres')

let lineRegex = /^(.*?\[([\w-]+)([\d.]+)?]:)(.*)?$/

const red = c.red
const dim = i => c.dim(i)
const other = dim
const path = i => c.blue(i)
const method = i => c.bold.magenta(i)
const status = code => {
  if (code < 200) return code
  if (code < 300) return c.green(code)
  if (code < 400) return c.cyan(code)
  if (code < 500) return c.yellow(code)
  if (code < 600) return c.red(code)
  return code
}
const ms = s => {
  const ms = parseInt(s)
  if (!ms) return s
  if (ms < 100) return c.greenBright(s)
  if (ms < 500) return c.green(s)
  if (ms < 5000) return c.yellow(s)
  if (ms < 10000) return c.yellowBright(s)
  return c.red(s)
}

function colorizeRouter (body) {
  try {
    const tokens = body.split('=')
    let cur = tokens[0]
    const obj = {}
    for (let i = 1; i < tokens.length; i++) {
      obj[cur] = tokens[i].split(' ').slice(0, -1).join(' ')
      let next = tokens[i].split(' ').pop()
      if (i + 1 === tokens.length) obj[cur] = next
      cur = next
    }
    if (Object.keys(obj).length === 0) return body
    return Object.entries(obj)
      .map(([k, v]) => {
        switch (k) {
          case 'at': return [k, v === 'error' ? red(v) : other(v)]
          case 'desc': return [k, red(v)]
          case 'code': return [k, red.bold(v)]
          case 'method': return [k, method(v)]
          case 'dyno': return [k, getColorForIdentifier(v)(v)]
          case 'status': return [k, status(v)]
          case 'path': return [k, path(v)]
          case 'connect': return [k, ms(v)]
          case 'service': return [k, ms(v)]
          default: return [k, other(v)]
        }
      })
      .map(([k, v]) => other(k + '=') + v)
      .join(' ')
  } catch (err) {
    ux.warn(err)
    return body
  }
}

const state = s => {
  switch (s) {
    case 'down': return red(s)
    case 'up': return c.greenBright(s)
    case 'starting': return c.yellowBright(s)
    case 'complete': return c.greenBright(s)
    default: return s
  }
}

function colorizeRun (body) {
  try {
    if (body.match(/^Stopping all processes with SIGTERM$/)) return c.red(body)
    let starting = body.match(/^(Starting process with command )(`.+`)(by user )?(.*)?$/)
    if (starting) {
      return [
        starting[1],
        c.cmd(starting[2]),
        starting[3] || '',
        c.green(starting[4] || '')
      ].join('')
    }
    let stateChange = body.match(/^(State changed from )(\w+)( to )(\w+)$/)
    if (stateChange) {
      return [
        stateChange[1],
        state(stateChange[2]),
        stateChange[3] || '',
        state(stateChange[4] || '')
      ].join('')
    }
    let exited = body.match(/^(Process exited with status )(\d+)$/)
    if (exited) {
      return [
        exited[1],
        exited[2] === '0' ? c.greenBright(exited[2]) : c.red(exited[2])
      ].join('')
    }
  } catch (err) {
    ux.warn(err)
  }
  return body
}

function colorizeWeb (body) {
  try {
    if (body.match(/^Unidling$/)) return c.yellow(body)
    if (body.match(/^Restarting$/)) return c.yellow(body)
    if (body.match(/^Stopping all processes with SIGTERM$/)) return c.red(body)
    let starting = body.match(/^(Starting process with command )(`.+`)(by user )?(.*)?$/)
    if (starting) {
      return [
        (starting[1]),
        c.cmd(starting[2]),
        (starting[3] || ''),
        c.green(starting[4] || '')
      ].join('')
    }
    let exited = body.match(/^(Process exited with status )(\d+)$/)
    if (exited) {
      return [
        exited[1],
        exited[2] === '0' ? c.greenBright(exited[2]) : c.red(exited[2])
      ].join('')
    }
    let stateChange = body.match(/^(State changed from )(\w+)( to )(\w+)$/)
    if (stateChange) {
      return [
        stateChange[1],
        state(stateChange[2]),
        stateChange[3],
        state(stateChange[4])
      ].join('')
    }
    let apache = body.match(/^(\d+\.\d+\.\d+\.\d+ -[^-]*- \[[^\]]+\] ")(\w+)( )([^ ]+)( HTTP\/\d+\.\d+" )(\d+)( .+$)/)
    if (apache) {
      const [, ...tokens] = apache
      return [
        other(tokens[0]),
        method(tokens[1]),
        other(tokens[2]),
        path(tokens[3]),
        other(tokens[4]),
        status(tokens[5]),
        other(tokens[6])
      ].join('')
    }
    let route = body.match(/^(.* ")(\w+)(.+)(HTTP\/\d+\.\d+" .*)$/)
    if (route) {
      return [
        route[1],
        method(route[2]),
        path(route[3]),
        route[4]
      ].join('')
    }
  } catch (err) {
    ux.warn(err)
  }
  return body
}

function colorizeAPI (body) {
  if (body.match(/^Build succeeded$/)) return c.greenBright(body)
  if (body.match(/^Build failed/)) return c.red(body)
  const build = body.match(/^(Build started by user )(.+)$/)
  if (build) {
    return [
      build[1],
      c.green(build[2])
    ].join('')
  }
  const deploy = body.match(/^(Deploy )([\w]+)( by user )(.+)$/)
  if (deploy) {
    return [
      deploy[1],
      c.cyan(deploy[2]),
      deploy[3],
      c.green(deploy[4])
    ].join('')
  }
  const release = body.match(/^(Release )(v[\d]+)( created by user )(.+)$/)
  if (release) {
    return [
      release[1],
      c.magenta(release[2]),
      release[3],
      c.green(release[4])
    ].join('')
  }
  let starting = body.match(/^(Starting process with command )(`.+`)(by user )?(.*)?$/)
  if (starting) {
    return [
      (starting[1]),
      c.cmd(starting[2]),
      (starting[3] || ''),
      c.green(starting[4] || '')
    ].join('')
  }
  return body
}

function colorizeRedis (body) {
  if (body.match(/source=\w+ sample#/)) {
    body = dim(body)
  }
  return body
}

function colorizePG (body) {
  let create = body.match(/^(\[DATABASE\].*)(CREATE TABLE)(.*)$/)
  if (create) {
    return [
      other(create[1]),
      c.magenta(create[2]),
      c.cyan(create[3])
    ].join('')
  }
  if (body.match(/source=\w+ sample#/)) {
    body = dim(body)
  }
  return body
}

module.exports = function colorize (line) {
  if (process.env.HEROKU_LOGS_COLOR === '0') return line

  let parsed = line.match(lineRegex)
  if (!parsed) return line
  let header = parsed[1]
  let identifier = parsed[2]
  let body = (parsed[4] || '').trim()
  switch (identifier) {
    case 'api':
      body = colorizeAPI(body)
      break
    case 'router':
      body = colorizeRouter(body)
      break
    case 'run':
      body = colorizeRun(body)
      break
    case 'web':
      body = colorizeWeb(body)
      break
    case 'heroku-redis':
      body = colorizeRedis(body)
      break
    case 'heroku-postgres':
    case 'postgres':
      body = colorizePG(body)
  }
  return getColorForIdentifier(identifier)(header) + ' ' + body
}

module.exports.COLORS = COLORS
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
 * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
 * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
 * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
 * Code distributed by Google as part of the polymer project is also
 * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
 */
// jshint node:true
'use strict';
// jshint -W079
var Promise = global.Promise || require('es6-promise').Promise;
// jshint +W079

var url = require('url');
var nodegit = require('nodegit');
var clone = nodegit.Clone.clone;
var Repository = nodegit.Repository;
var Stash = nodegit.Stash;
var shell = require('shelljs');
var temp = require('temp');
var path = require('path');
var fs = require('fs');

shell.config.silent = true;

function bower(args) {
  var cmd = path.join(__dirname, '..', 'node_modules', '.bin', 'bower');
  return cmd + ' ' + args;
}

function readBower(dir) {
  return  JSON.parse(fs.readFileSync(path.join(dir, "bower.json")));
}

var Commands = function Commands(db, workdir) {
  this._db = db;
  this._workdir = workdir;
  this._tmpDir = temp.mkdirSync('wcw');
  this._staticDirs = {};
};

function bowerDeps(bowerJson) {
  var dependencies = [];
  if (bowerJson.dependencies) {
    Object.keys(bowerJson.dependencies).forEach(function (dep){
      dependencies.push(bowerJson.dependencies[dep]);
    });
  }
  return dependencies;
}

Commands.prototype = {
  /**
   * Resolves a package.
   * @param  {string} pkg A bower-like repository description, github repo, or other git url
   * @return {Array.<{{folder:string, repository:}}>}     A list of packages and URLs to add to the workspace.
   */
  resolve: function(pkg) {
    // Install the package to a tempdir
    shell.pushd(this._tmpDir);
    shell.exec(bower(' install ' + pkg));
    shell.pushd('bower_components');
    var packages = [];
    shell.ls('./').forEach(function(component){
      var bowerjson = readBower(component);
      if (bowerjson.repository === undefined || bowerjson.repository.type != 'git') {
        if (!this._staticDirs[bowerjson.name]) {
          this._staticDirs[bowerjson.name] = true;
          console.warn("Repository must be specified for " + bowerjson.name + ". Falling back to static mode.");
          packages.push({folder: component, sourcedir: path.join(process.cwd(), component)});
        }
        return;
      }
      packages.push({folder: component, repo: bowerjson.repository});
    }.bind(this));
    shell.popd();
    return packages;
  },
  load: function(dir, repo) {
    return this._db.addPackage(dir, repo).then(function(err){
      if (err) {
        // The package has been loaded.
        return;
      }
      console.log("cloning " + dir);
      return nodegit.Clone(
        repo.url,
        path.join(this._workdir, dir),
        {
          remoteCallbacks: {
            certificateCheck: function() {
              // github will fail cert check on some OSX machines
              // this overrides that check
              return 1;
            }
          }
        });
    }.bind(this)).then(function() {
      return dir;
    }).catch(function(err){
      console.log("failed to initialize repo for dir " + dir);
      console.log(err);
      console.log(err.stack);
      this._db.removePackage(dir);
    });
  },
  deps: function(dir) {
    return this._db.hasPackage(dir).then(function(hasPackage){
      var bowerJson = readBower(path.join(this._workdir, dir));
      return bowerDeps(bowerJson);
    });
  },
  installDeps: function(dir) {
    return this.deps(dir).then(function(deps){
      var depInstalls = [];
      deps.forEach(function(dep){
        depInstalls.push(this.install(dep));
      }.bind(this));
      return Promise.all(depInstalls);
    }.bind(this));
  },
  install: function(pkg) {
    var resolved = this.resolve(pkg);
    var resolutions = [];
    resolved.forEach(function(pkg){
      var loaded;
      if (pkg.repo) {
        loaded = this.load(pkg.folder, pkg.repo);
      } else {
        // If the directory exists but isn't a git checkout, we'll overwrite it here.
        if (!shell.test('-e', pkg.folder) ||
            !shell.test('-e', path.join(pkg.folder, '.git'))) {
          shell.cp('-R', pkg.sourcedir, this._workdir);
          loaded = Promise.resolve(pkg.folder);
        }
      }
      loaded = loaded.then(function(dir){
        return this.installDeps(dir);
      }.bind(this));
      resolutions.push(loaded);
    }.bind(this));
    return Promise.all(resolutions);
  },
  update: function() {
    return this._db.getPackages().then(function(packages){
      var repos = [];
      packages.forEach(function(pkg){
        repos.push(Repository.open(path.join(this._workdir, pkg.folder))
          .then(function(repo) {
            var statuses = repo.getStatusExt();
            var modified = false;
            statuses.forEach(function(status){
              if (status.isModified()) {
                modified = true;
              }
            });
            var stash;
            if (modified) {
              stash = Stash.save(repo, repo.defaultSignature(), "wcwstash", 0);
            } else {
              stash = Promise.resolve(false);
            }
            var stashed;
            return stash.then(function(didStash){
              stashed = didStash;
              return repo.fetchAll({
                credentials: function(url, userName) {
                  return nodegit.Cred.sshKeyFromAgent(userName);
                },
                certificateCheck: function() {
                  return 1;
                }
              });
            }).then(function() {
              return repo.mergeBranches("master", "origin/master");
            }).then(function(){
              console.log("Merged into master the folder " + pkg.folder);
              return {repo: repo, stashed: stashed, folder: pkg.folder};
            });
          }));
      }.bind(this));
      return Promise.all(repos);
    }.bind(this))
    .then(function(repos){
      repos.forEach(function(stashedRepo) {
        this.installDeps(stashedRepo.folder);
        if (stashedRepo.stashed) {
          console.log("Folder " + stashedRepo.folder +
            " had local modifications that were stashed.");
        }
      });
    });
  }
};

module.exports = Commands;<commit_msg>missing this binding; force static dirs<commit_after>/**
 * @license
 * Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
 * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
 * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
 * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
 * Code distributed by Google as part of the polymer project is also
 * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
 */
// jshint node:true
'use strict';
// jshint -W079
var Promise = global.Promise || require('es6-promise').Promise;
// jshint +W079

var url = require('url');
var nodegit = require('nodegit');
var clone = nodegit.Clone.clone;
var Repository = nodegit.Repository;
var Stash = nodegit.Stash;
var shell = require('shelljs');
var temp = require('temp');
var path = require('path');
var fs = require('fs');

shell.config.silent = true;

function bower(args) {
  var cmd = path.join(__dirname, '..', 'node_modules', '.bin', 'bower');
  return cmd + ' ' + args;
}

function readBower(dir) {
  return  JSON.parse(fs.readFileSync(path.join(dir, "bower.json")));
}

var Commands = function Commands(db, workdir) {
  this._db = db;
  this._workdir = workdir;
  this._tmpDir = temp.mkdirSync('wcw');
  this._staticDirs = {};
};

function bowerDeps(bowerJson) {
  var dependencies = [];
  if (bowerJson.dependencies) {
    Object.keys(bowerJson.dependencies).forEach(function (dep){
      dependencies.push(bowerJson.dependencies[dep]);
    });
  }
  return dependencies;
}

Commands.prototype = {
  /**
   * Resolves a package.
   * @param  {string} pkg A bower-like repository description, github repo, or other git url
   * @return {Array.<{{folder:string, repository:}}>}     A list of packages and URLs to add to the workspace.
   */
  resolve: function(pkg) {
    // Install the package to a tempdir
    shell.pushd(this._tmpDir);
    shell.exec(bower(' install ' + pkg));
    shell.pushd('bower_components');
    var packages = [];
    shell.ls('./').forEach(function(component){
      var bowerjson = readBower(component);
      if (bowerjson.repository === undefined || bowerjson.repository.type != 'git') {
        if (!this._staticDirs[bowerjson.name]) {
          this._staticDirs[bowerjson.name] = true;
          console.warn("Repository must be specified for " + bowerjson.name + ". Falling back to static mode.");
          packages.push({folder: component, sourcedir: path.join(process.cwd(), component)});
        }
        return;
      }
      packages.push({folder: component, repo: bowerjson.repository});
    }.bind(this));
    shell.popd();
    return packages;
  },
  load: function(dir, repo) {
    return this._db.addPackage(dir, repo).then(function(err){
      if (err) {
        // The package has been loaded.
        return;
      }
      console.log("cloning " + dir);
      return nodegit.Clone(
        repo.url,
        path.join(this._workdir, dir),
        {
          remoteCallbacks: {
            certificateCheck: function() {
              // github will fail cert check on some OSX machines
              // this overrides that check
              return 1;
            }
          }
        });
    }.bind(this)).then(function() {
      return dir;
    }).catch(function(err){
      console.log("failed to initialize repo for dir " + dir);
      console.log(err);
      console.log(err.stack);
      this._db.removePackage(dir);
    });
  },
  deps: function(dir) {
    return this._db.hasPackage(dir).then(function(hasPackage){
      var bowerJson = readBower(path.join(this._workdir, dir));
      return bowerDeps(bowerJson);
    });
  },
  installDeps: function(dir) {
    return this.deps(dir).then(function(deps){
      var depInstalls = [];
      deps.forEach(function(dep){
        depInstalls.push(this.install(dep));
      }.bind(this));
      return Promise.all(depInstalls);
    }.bind(this));
  },
  install: function(pkg) {
    var resolved = this.resolve(pkg);
    var resolutions = [];
    resolved.forEach(function(pkg){
      var loaded;
      if (pkg.repo) {
        loaded = this.load(pkg.folder, pkg.repo);
      } else {
        // If the directory exists but isn't a git checkout, we'll overwrite it here.
        if (!shell.test('-e', pkg.folder) ||
            !shell.test('-e', path.join(pkg.folder, '.git'))) {

          shell.cp('-Rf', pkg.sourcedir, this._workdir);
          loaded = Promise.resolve(pkg.folder);
        }
      }
      loaded = loaded.then(function(dir){
        return this.installDeps(dir);
      }.bind(this));
      resolutions.push(loaded);
    }.bind(this));
    return Promise.all(resolutions);
  },
  update: function() {
    return this._db.getPackages().then(function(packages){
      var repos = [];
      packages.forEach(function(pkg){
        repos.push(Repository.open(path.join(this._workdir, pkg.folder))
          .then(function(repo) {
            var statuses = repo.getStatusExt();
            var modified = false;
            statuses.forEach(function(status){
              if (status.isModified()) {
                modified = true;
              }
            });
            var stash;
            if (modified) {
              stash = Stash.save(repo, repo.defaultSignature(), "wcwstash", 0);
            } else {
              stash = Promise.resolve(false);
            }
            var stashed;
            return stash.then(function(didStash){
              stashed = didStash;
              return repo.fetchAll({
                credentials: function(url, userName) {
                  return nodegit.Cred.sshKeyFromAgent(userName);
                },
                certificateCheck: function() {
                  return 1;
                }
              });
            }).then(function() {
              return repo.mergeBranches("master", "origin/master");
            }).then(function(){
              console.log("Merged into master the folder " + pkg.folder);
              return {repo: repo, stashed: stashed, folder: pkg.folder};
            });
          }));
      }.bind(this));
      return Promise.all(repos);
    }.bind(this))
    .then(function(repos){
      repos.forEach(function(stashedRepo) {
        this.installDeps(stashedRepo.folder);
        if (stashedRepo.stashed) {
          console.log("Folder " + stashedRepo.folder +
            " had local modifications that were stashed.");
        }
      }.bind(this));
    });
  }
};

module.exports = Commands;<|endoftext|>


<commit_before>var _ = require("./utils");

// Leave a channel..
function part(channel) {
    channel = _.channel(channel);

    // Send the command to the server and race the Promise against a delay..
    return this._sendCommand(this._getPromiseDelay(), null, `PART ${channel}`, (resolve, reject) => {
        // Received _promisePart event, resolve or reject..
        this.once("_promisePart", (err) => {
            if (!err) { resolve([channel]); }
            else { reject(err); }
        });
    });
}

// Enable R9KBeta mode on a channel..
function r9kbeta(channel) {
    channel = _.channel(channel);

    // Send the command to the server and race the Promise against a delay..
    return this._sendCommand(this._getPromiseDelay(), channel, "/r9kbeta", (resolve, reject) => {
        // Received _promiseR9kbeta event, resolve or reject..
        this.once("_promiseR9kbeta", (err) => {
            if (!err) { resolve([channel]); }
            else { reject(err); }
        });
    });
}

// Disable R9KBeta mode on a channel..
function r9kbetaoff(channel) {
    channel = _.channel(channel);

    // Send the command to the server and race the Promise against a delay..
    return this._sendCommand(this._getPromiseDelay(), channel, "/r9kbetaoff", (resolve, reject) => {
        // Received _promiseR9kbetaoff event, resolve or reject..
        this.once("_promiseR9kbetaoff", (err) => {
            if (!err) { resolve([channel]); }
            else { reject(err); }
        });
    });
}

// Enable slow mode on a channel..
function slow(channel, seconds) {
    channel = _.channel(channel);
    seconds = _.get(seconds, 300);

    // Send the command to the server and race the Promise against a delay..
    return this._sendCommand(this._getPromiseDelay(), channel, `/slow ${seconds}`, (resolve, reject) => {
        // Received _promiseSlow event, resolve or reject..
        this.once("_promiseSlow", (err) => {
            if (!err) { resolve([channel, seconds]); }
            else { reject(err); }
        });
    });
}

// Disable slow mode on a channel..
function slowoff(channel) {
    channel = _.channel(channel);

    // Send the command to the server and race the Promise against a delay..
    return this._sendCommand(this._getPromiseDelay(), channel, "/slowoff", (resolve, reject) => {
        // Received _promiseSlowoff event, resolve or reject..
        this.once("_promiseSlowoff", (err) => {
            if (!err) { resolve([channel]); }
            else { reject(err); }
        });
    });
}

module.exports = {
    // Send action message (/me <message>) on a channel..
    action: function action(channel, message) {
        channel = _.channel(channel);
        message = `\u0001ACTION ${message}\u0001`;

        // Send the command to the server and race the Promise against a delay..
        return this._sendMessage(this._getPromiseDelay(), channel, message, (resolve, reject) => {
            // At this time, there is no possible way to detect if a message has been sent has been eaten
            // by the server, so we can only resolve the Promise.
            resolve([channel, message]);
        });
    },

    // Ban username on channel..
    ban: function ban(channel, username) {
        channel = _.channel(channel);
        username = _.username(username);

        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(this._getPromiseDelay(), channel, `/ban ${username}`, (resolve, reject) => {
            // Received _promiseBan event, resolve or reject..
            this.once("_promiseBan", (err) => {
                if (!err) { resolve([channel, username]); }
                else { reject(err); }
            });
        });
    },

    // Clear all messages on a channel..
    clear: function clear(channel) {
        channel = _.channel(channel);

        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(this._getPromiseDelay(), channel, "/clear", (resolve, reject) => {
            // Received _promiseClear event, resolve or reject..
            this.once("_promiseClear", (err) => {
                if (!err) { resolve([channel]); }
                else { reject(err); }
            });
        });
    },

    // Change the color of your username..
    color: function color(channel, newColor) {
        if (typeof newColor === "undefined") { newColor = channel; }

        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(this._getPromiseDelay(), "#jtv", `/color ${newColor}`, (resolve, reject) => {
            // Received _promiseColor event, resolve or reject..
            this.once("_promiseColor", (err) => {
                if (!err) { resolve([newColor]); }
                else { reject(err); }
            });
        });
    },

    // Run commercial on a channel for X seconds..
    commercial: function commercial(channel, seconds) {
        channel = _.channel(channel);
        seconds = _.get(seconds, 30);

        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(this._getPromiseDelay(), channel, `/commercial ${seconds}`, (resolve, reject) => {
            // Received _promiseCommercial event, resolve or reject..
            this.once("_promiseCommercial", (err) => {
                if (!err) { resolve([channel, seconds]); }
                else { reject(err); }
            });
        });
    },

    // Enable emote-only mode on a channel..
    emoteonly: function emoteonly(channel) {
        channel = _.channel(channel);

        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(this._getPromiseDelay(), channel, "/emoteonly", (resolve, reject) => {
            // Received _promiseEmoteonly event, resolve or reject..
            this.once("_promiseEmoteonly", (err) => {
                if (!err) { resolve([channel]); }
                else { reject(err); }
            });
        });
    },

    // Disable emote-only mode on a channel..
    emoteonlyoff: function emoteonlyoff(channel) {
        channel = _.channel(channel);

        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(this._getPromiseDelay(), channel, "/emoteonlyoff", (resolve, reject) => {
            // Received _promiseEmoteonlyoff event, resolve or reject..
            this.once("_promiseEmoteonlyoff", (err) => {
                if (!err) { resolve([channel]); }
                else { reject(err); }
            });
        });
    },

    // Host a channel..
    host: function host(channel, target) {
        channel = _.channel(channel);
        target = _.username(target);

        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(2000, channel, `/host ${target}`, (resolve, reject) => {
            // Received _promiseHost event, resolve or reject..
            this.once("_promiseHost", (err, remaining) => {
                if (!err) { resolve([channel, target, remaining]); }
                else { reject(err); }
            });
        });
    },

    // Join a channel..
    join: function join(channel) {
        channel = _.channel(channel);

        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(this._getPromiseDelay(), null, `JOIN ${channel}`, (resolve, reject) => {
            // Received _promiseJoin event, resolve or reject..
            this.once("_promiseJoin", (err) => {
                if (!err) { resolve([channel]); }
                else { reject(err); }
            });
        });
    },

    // Mod username on channel..
    mod: function mod(channel, username) {
        channel = _.channel(channel);
        username = _.username(username);

        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(this._getPromiseDelay(), channel, `/mod ${username}`, (resolve, reject) => {
            // Received _promiseMod event, resolve or reject..
            this.once("_promiseMod", (err) => {
                if (!err) { resolve([channel, username]); }
                else { reject(err); }
            });
        });
    },

    // Get list of mods on a channel..
    mods: function mods(channel) {
        channel = _.channel(channel);

        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(this._getPromiseDelay(), channel, "/mods", (resolve, reject) => {
            // Received _promiseMods event, resolve or reject..
            this.once("_promiseMods", (err, mods) => {
                if (!err) {
                    // Update the internal list of moderators..
                    mods.forEach((username) => {
                        if (!this.moderators[channel]) { this.moderators[channel] = []; }
                        if (this.moderators[channel].indexOf(username) < 0) { this.moderators[channel].push(username); }
                    });
                    resolve(mods);
                } else { reject(err); }
            });
        });
    },

    // Leave a channel..
    part: part,

    // Alias for part()..
    leave: part,

    // Send a ping to the server..
    ping: function ping() {
        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(this._getPromiseDelay(), null, "PING", (resolve, reject) => {
            // Update the internal ping timeout check interval..
            this.latency = new Date();
            this.pingTimeout = setTimeout(() => {
                if (this.ws !== null) {
                    this.wasCloseCalled = false;
                    this.log.error("Ping timeout.");
                    this.ws.close();

                    clearInterval(this.pingLoop);
                    clearTimeout(this.pingTimeout);
                }
            }, _.get(this.opts.connection.timeout, 9999));

            // Received _promisePing event, resolve or reject..
            this.once("_promisePing", (latency) => { resolve([latency]); });
        });
    },

    // Enable R9KBeta mode on a channel..
    r9kbeta: r9kbeta,

    // Alias for r9kbeta()..
    r9kmode: r9kbeta,

    // Disable R9KBeta mode on a channel..
    r9kbetaoff: r9kbetaoff,

    // Alias for r9kbetaoff()..
    r9kmodeoff: r9kbetaoff,

    // Send a raw message to the server..
    raw: function raw(message) {
        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(this._getPromiseDelay(), null, message, (resolve, reject) => {
            resolve([message]);
        });
    },

    // Send a message on a channel..
    say: function say(channel, message) {
        channel = _.channel(channel);

        if ((message.startsWith(".") && !message.startsWith("..")) || message.startsWith("/") || message.startsWith("\\")) {
            // Check if the message is an action message..
            if (message.substr(1, 3) === "me ") {
                return this.action(channel, message.substr(4));
            }
            else {
                // Send the command to the server and race the Promise against a delay..
                return this._sendCommand(this._getPromiseDelay(), channel, message, (resolve, reject) => {
                    // At this time, there is no possible way to detect if a message has been sent has been eaten
                    // by the server, so we can only resolve the Promise.
                    resolve([channel, message]);
                });
            }
        }

        // Send the command to the server and race the Promise against a delay..
        return this._sendMessage(this._getPromiseDelay(), channel, message, (resolve, reject) => {
            // At this time, there is no possible way to detect if a message has been sent has been eaten
            // by the server, so we can only resolve the Promise.
            resolve([channel, message]);
        });
    },

    // Enable slow mode on a channel..
    slow: slow,

    // Alias for slow()..
    slowmode: slow,

    // Disable slow mode on a channel..
    slowoff: slowoff,

    // Alias for slowoff()..
    slowmodeoff: slowoff,

    // Enable subscribers mode on a channel..
    subscribers: function subscribers(channel) {
        channel = _.channel(channel);

        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(this._getPromiseDelay(), channel, "/subscribers", (resolve, reject) => {
            // Received _promiseSubscribers event, resolve or reject..
            this.once("_promiseSubscribers", (err) => {
                if (!err) { resolve([channel]); }
                else { reject(err); }
            });
        });
    },

    // Disable subscribers mode on a channel..
    subscribersoff: function subscribersoff(channel) {
        channel = _.channel(channel);

        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(this._getPromiseDelay(), channel, "/subscribersoff", (resolve, reject) => {
            // Received _promiseSubscribersoff event, resolve or reject..
            this.once("_promiseSubscribersoff", (err) => {
                if (!err) { resolve([channel]); }
                else { reject(err); }
            });
        });
    },

    // Timeout username on channel for X seconds..
    timeout: function timeout(channel, username, seconds) {
        channel = _.channel(channel);
        username = _.username(username);
        seconds = _.get(seconds, 300);

        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(this._getPromiseDelay(), channel, `/timeout ${username} ${seconds}`, (resolve, reject) => {
            // Received _promiseTimeout event, resolve or reject..
            this.once("_promiseTimeout", (err) => {
                if (!err) { resolve([channel, username, seconds]); }
                else { reject(err); }
            });
        });
    },

    // Unban username on channel..
    unban: function unban(channel, username) {
        channel = _.channel(channel);
        username = _.username(username);

        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(this._getPromiseDelay(), channel, `/unban ${username}`, (resolve, reject) => {
            // Received _promiseUnban event, resolve or reject..
            this.once("_promiseUnban", (err) => {
                if (!err) { resolve([channel, username]); }
                else { reject(err); }
            });
        });
    },

    // End the current hosting..
    unhost: function unhost(channel) {
        channel = _.channel(channel);

        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(2000, channel, "/unhost", (resolve, reject) => {
            // Received _promiseUnhost event, resolve or reject..
            this.once("_promiseUnhost", (err) => {
                if (!err) { resolve([channel]); }
                else { reject(err); }
            });
        });
    },

    // Unmod username on channel..
    unmod: function unmod(channel, username) {
        channel = _.channel(channel);
        username = _.username(username);

        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(this._getPromiseDelay(), channel, `/unmod ${username}`, (resolve, reject) => {
            // Received _promiseUnmod event, resolve or reject..
            this.once("_promiseUnmod", (err) => {
                if (!err) { resolve([channel, username]); }
                else { reject(err); }
            });
        });
    },

    // Send an whisper message to a user..
    whisper: function whisper(username, message) {
        username = _.username(username);

        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(this._getPromiseDelay(), "#jtv", `/w ${username} ${message}`, (resolve, reject) => {
            // At this time, there is no possible way to detect if a message has been sent has been eaten
            // by the server, so we can only resolve the Promise.
            resolve([username, message]);
        });
    }
}
<commit_msg>commands: added reason as a parameter for .ban and .timeout.<commit_after>var _ = require("./utils");

// Leave a channel..
function part(channel) {
    channel = _.channel(channel);

    // Send the command to the server and race the Promise against a delay..
    return this._sendCommand(this._getPromiseDelay(), null, `PART ${channel}`, (resolve, reject) => {
        // Received _promisePart event, resolve or reject..
        this.once("_promisePart", (err) => {
            if (!err) { resolve([channel]); }
            else { reject(err); }
        });
    });
}

// Enable R9KBeta mode on a channel..
function r9kbeta(channel) {
    channel = _.channel(channel);

    // Send the command to the server and race the Promise against a delay..
    return this._sendCommand(this._getPromiseDelay(), channel, "/r9kbeta", (resolve, reject) => {
        // Received _promiseR9kbeta event, resolve or reject..
        this.once("_promiseR9kbeta", (err) => {
            if (!err) { resolve([channel]); }
            else { reject(err); }
        });
    });
}

// Disable R9KBeta mode on a channel..
function r9kbetaoff(channel) {
    channel = _.channel(channel);

    // Send the command to the server and race the Promise against a delay..
    return this._sendCommand(this._getPromiseDelay(), channel, "/r9kbetaoff", (resolve, reject) => {
        // Received _promiseR9kbetaoff event, resolve or reject..
        this.once("_promiseR9kbetaoff", (err) => {
            if (!err) { resolve([channel]); }
            else { reject(err); }
        });
    });
}

// Enable slow mode on a channel..
function slow(channel, seconds) {
    channel = _.channel(channel);
    seconds = _.get(seconds, 300);

    // Send the command to the server and race the Promise against a delay..
    return this._sendCommand(this._getPromiseDelay(), channel, `/slow ${seconds}`, (resolve, reject) => {
        // Received _promiseSlow event, resolve or reject..
        this.once("_promiseSlow", (err) => {
            if (!err) { resolve([channel, seconds]); }
            else { reject(err); }
        });
    });
}

// Disable slow mode on a channel..
function slowoff(channel) {
    channel = _.channel(channel);

    // Send the command to the server and race the Promise against a delay..
    return this._sendCommand(this._getPromiseDelay(), channel, "/slowoff", (resolve, reject) => {
        // Received _promiseSlowoff event, resolve or reject..
        this.once("_promiseSlowoff", (err) => {
            if (!err) { resolve([channel]); }
            else { reject(err); }
        });
    });
}

module.exports = {
    // Send action message (/me <message>) on a channel..
    action: function action(channel, message) {
        channel = _.channel(channel);
        message = `\u0001ACTION ${message}\u0001`;

        // Send the command to the server and race the Promise against a delay..
        return this._sendMessage(this._getPromiseDelay(), channel, message, (resolve, reject) => {
            // At this time, there is no possible way to detect if a message has been sent has been eaten
            // by the server, so we can only resolve the Promise.
            resolve([channel, message]);
        });
    },

    // Ban username on channel..
    ban: function ban(channel, username, reason) {
        channel = _.channel(channel);
        username = _.username(username);
        reason = _.get(reason, "");

        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(this._getPromiseDelay(), channel, `/ban ${username} ${reason}`, (resolve, reject) => {
            // Received _promiseBan event, resolve or reject..
            this.once("_promiseBan", (err) => {
                if (!err) { resolve([channel, username, reason]); }
                else { reject(err); }
            });
        });
    },

    // Clear all messages on a channel..
    clear: function clear(channel) {
        channel = _.channel(channel);

        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(this._getPromiseDelay(), channel, "/clear", (resolve, reject) => {
            // Received _promiseClear event, resolve or reject..
            this.once("_promiseClear", (err) => {
                if (!err) { resolve([channel]); }
                else { reject(err); }
            });
        });
    },

    // Change the color of your username..
    color: function color(channel, newColor) {
        newColor = _.get(newColor, channel);

        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(this._getPromiseDelay(), "#jtv", `/color ${newColor}`, (resolve, reject) => {
            // Received _promiseColor event, resolve or reject..
            this.once("_promiseColor", (err) => {
                if (!err) { resolve([newColor]); }
                else { reject(err); }
            });
        });
    },

    // Run commercial on a channel for X seconds..
    commercial: function commercial(channel, seconds) {
        channel = _.channel(channel);
        seconds = _.get(seconds, 30);

        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(this._getPromiseDelay(), channel, `/commercial ${seconds}`, (resolve, reject) => {
            // Received _promiseCommercial event, resolve or reject..
            this.once("_promiseCommercial", (err) => {
                if (!err) { resolve([channel, seconds]); }
                else { reject(err); }
            });
        });
    },

    // Enable emote-only mode on a channel..
    emoteonly: function emoteonly(channel) {
        channel = _.channel(channel);

        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(this._getPromiseDelay(), channel, "/emoteonly", (resolve, reject) => {
            // Received _promiseEmoteonly event, resolve or reject..
            this.once("_promiseEmoteonly", (err) => {
                if (!err) { resolve([channel]); }
                else { reject(err); }
            });
        });
    },

    // Disable emote-only mode on a channel..
    emoteonlyoff: function emoteonlyoff(channel) {
        channel = _.channel(channel);

        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(this._getPromiseDelay(), channel, "/emoteonlyoff", (resolve, reject) => {
            // Received _promiseEmoteonlyoff event, resolve or reject..
            this.once("_promiseEmoteonlyoff", (err) => {
                if (!err) { resolve([channel]); }
                else { reject(err); }
            });
        });
    },

    // Host a channel..
    host: function host(channel, target) {
        channel = _.channel(channel);
        target = _.username(target);

        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(2000, channel, `/host ${target}`, (resolve, reject) => {
            // Received _promiseHost event, resolve or reject..
            this.once("_promiseHost", (err, remaining) => {
                if (!err) { resolve([channel, target, remaining]); }
                else { reject(err); }
            });
        });
    },

    // Join a channel..
    join: function join(channel) {
        channel = _.channel(channel);

        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(this._getPromiseDelay(), null, `JOIN ${channel}`, (resolve, reject) => {
            // Received _promiseJoin event, resolve or reject..
            this.once("_promiseJoin", (err) => {
                if (!err) { resolve([channel]); }
                else { reject(err); }
            });
        });
    },

    // Mod username on channel..
    mod: function mod(channel, username) {
        channel = _.channel(channel);
        username = _.username(username);

        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(this._getPromiseDelay(), channel, `/mod ${username}`, (resolve, reject) => {
            // Received _promiseMod event, resolve or reject..
            this.once("_promiseMod", (err) => {
                if (!err) { resolve([channel, username]); }
                else { reject(err); }
            });
        });
    },

    // Get list of mods on a channel..
    mods: function mods(channel) {
        channel = _.channel(channel);

        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(this._getPromiseDelay(), channel, "/mods", (resolve, reject) => {
            // Received _promiseMods event, resolve or reject..
            this.once("_promiseMods", (err, mods) => {
                if (!err) {
                    // Update the internal list of moderators..
                    mods.forEach((username) => {
                        if (!this.moderators[channel]) { this.moderators[channel] = []; }
                        if (this.moderators[channel].indexOf(username) < 0) { this.moderators[channel].push(username); }
                    });
                    resolve(mods);
                } else { reject(err); }
            });
        });
    },

    // Leave a channel..
    part: part,

    // Alias for part()..
    leave: part,

    // Send a ping to the server..
    ping: function ping() {
        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(this._getPromiseDelay(), null, "PING", (resolve, reject) => {
            // Update the internal ping timeout check interval..
            this.latency = new Date();
            this.pingTimeout = setTimeout(() => {
                if (this.ws !== null) {
                    this.wasCloseCalled = false;
                    this.log.error("Ping timeout.");
                    this.ws.close();

                    clearInterval(this.pingLoop);
                    clearTimeout(this.pingTimeout);
                }
            }, _.get(this.opts.connection.timeout, 9999));

            // Received _promisePing event, resolve or reject..
            this.once("_promisePing", (latency) => { resolve([latency]); });
        });
    },

    // Enable R9KBeta mode on a channel..
    r9kbeta: r9kbeta,

    // Alias for r9kbeta()..
    r9kmode: r9kbeta,

    // Disable R9KBeta mode on a channel..
    r9kbetaoff: r9kbetaoff,

    // Alias for r9kbetaoff()..
    r9kmodeoff: r9kbetaoff,

    // Send a raw message to the server..
    raw: function raw(message) {
        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(this._getPromiseDelay(), null, message, (resolve, reject) => {
            resolve([message]);
        });
    },

    // Send a message on a channel..
    say: function say(channel, message) {
        channel = _.channel(channel);

        if ((message.startsWith(".") && !message.startsWith("..")) || message.startsWith("/") || message.startsWith("\\")) {
            // Check if the message is an action message..
            if (message.substr(1, 3) === "me ") {
                return this.action(channel, message.substr(4));
            }
            else {
                // Send the command to the server and race the Promise against a delay..
                return this._sendCommand(this._getPromiseDelay(), channel, message, (resolve, reject) => {
                    // At this time, there is no possible way to detect if a message has been sent has been eaten
                    // by the server, so we can only resolve the Promise.
                    resolve([channel, message]);
                });
            }
        }

        // Send the command to the server and race the Promise against a delay..
        return this._sendMessage(this._getPromiseDelay(), channel, message, (resolve, reject) => {
            // At this time, there is no possible way to detect if a message has been sent has been eaten
            // by the server, so we can only resolve the Promise.
            resolve([channel, message]);
        });
    },

    // Enable slow mode on a channel..
    slow: slow,

    // Alias for slow()..
    slowmode: slow,

    // Disable slow mode on a channel..
    slowoff: slowoff,

    // Alias for slowoff()..
    slowmodeoff: slowoff,

    // Enable subscribers mode on a channel..
    subscribers: function subscribers(channel) {
        channel = _.channel(channel);

        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(this._getPromiseDelay(), channel, "/subscribers", (resolve, reject) => {
            // Received _promiseSubscribers event, resolve or reject..
            this.once("_promiseSubscribers", (err) => {
                if (!err) { resolve([channel]); }
                else { reject(err); }
            });
        });
    },

    // Disable subscribers mode on a channel..
    subscribersoff: function subscribersoff(channel) {
        channel = _.channel(channel);

        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(this._getPromiseDelay(), channel, "/subscribersoff", (resolve, reject) => {
            // Received _promiseSubscribersoff event, resolve or reject..
            this.once("_promiseSubscribersoff", (err) => {
                if (!err) { resolve([channel]); }
                else { reject(err); }
            });
        });
    },

    // Timeout username on channel for X seconds..
    timeout: function timeout(channel, username, seconds, reason) {
        channel = _.channel(channel);
        username = _.username(username);

        if (!_.isNull(seconds) && !_.isInteger(seconds)) {
            reason = seconds;
            seconds = 300;
        }

        seconds = _.get(seconds, 300);
        reason = _.get(reason, "");

        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(this._getPromiseDelay(), channel, `/timeout ${username} ${seconds} ${reason}`, (resolve, reject) => {
            // Received _promiseTimeout event, resolve or reject..
            this.once("_promiseTimeout", (err) => {
                if (!err) { resolve([channel, username, seconds, reason]); }
                else { reject(err); }
            });
        });
    },

    // Unban username on channel..
    unban: function unban(channel, username) {
        channel = _.channel(channel);
        username = _.username(username);

        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(this._getPromiseDelay(), channel, `/unban ${username}`, (resolve, reject) => {
            // Received _promiseUnban event, resolve or reject..
            this.once("_promiseUnban", (err) => {
                if (!err) { resolve([channel, username]); }
                else { reject(err); }
            });
        });
    },

    // End the current hosting..
    unhost: function unhost(channel) {
        channel = _.channel(channel);

        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(2000, channel, "/unhost", (resolve, reject) => {
            // Received _promiseUnhost event, resolve or reject..
            this.once("_promiseUnhost", (err) => {
                if (!err) { resolve([channel]); }
                else { reject(err); }
            });
        });
    },

    // Unmod username on channel..
    unmod: function unmod(channel, username) {
        channel = _.channel(channel);
        username = _.username(username);

        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(this._getPromiseDelay(), channel, `/unmod ${username}`, (resolve, reject) => {
            // Received _promiseUnmod event, resolve or reject..
            this.once("_promiseUnmod", (err) => {
                if (!err) { resolve([channel, username]); }
                else { reject(err); }
            });
        });
    },

    // Send an whisper message to a user..
    whisper: function whisper(username, message) {
        username = _.username(username);

        // Send the command to the server and race the Promise against a delay..
        return this._sendCommand(this._getPromiseDelay(), "#jtv", `/w ${username} ${message}`, (resolve, reject) => {
            // At this time, there is no possible way to detect if a message has been sent has been eaten
            // by the server, so we can only resolve the Promise.
            resolve([username, message]);
        });
    }
}
<|endoftext|>


<commit_before>var fs = require('fs'),
    npm = require('npm'),
    bower = require('bower'),
    gulp = require('gulp'),
    nopt = require('nopt'),
    path = require('path'),
    pkg = require('../package.json'),
    requireUncached = require('./requireUncached.js'),
    _ = require('lodash'),
    bowerSupport = require('./bowerSupport.js'),
    wrench = require('wrench'),
    Promise = require('bluebird'),
    BowerStandardRenderer = require('../node_modules/bower/lib/renderers/StandardRenderer.js');

// Add global support for coffee-script
require('coffee-script/register');

function loadApp () {
  try {
    return requireUncached(path.join(process.cwd(), 'back/back-app'));
  } catch (err) {
    if (err.code === 'MODULE_NOT_FOUND') {
      console.error('No synth app detected (missing synth.json).');
      process.exit(1);
    }
  }
}

exports.createNewApp = function (dirName) {
  var args = nopt({
    'front': String,
    'back': String,
    'root': String
  }, {
    'f': '--front',
    'b': '--back',
    'r': '--root'
  });
  var options = {
    rootTemplate: args.root || 'default',
    backTemplate: args.back || 'mongojs',
    frontTemplate: args.front || 'angular'
  };

  try {
    /* Test that the specified is empty and can be written to */
    fs.mkdirSync(dirName);
    fs.rmdirSync(dirName);
  } catch (err) {
    if (err.code == 'EEXIST')
      console.log('Oops, that folder already exists. Try specifying a different name.');
    else
      console.log(err.message);
    return;
  }

  applyTemplate('root', options.rootTemplate, dirName);
  applyTemplate('back', options.backTemplate, dirName);
  applyTemplate('front', options.frontTemplate, dirName);
  console.log('Successfully created a new synth app in ' + dirName);
};

exports.printRoutes = function () {
  var app = loadApp();

  console.log([
    'API Routes:',
    '---------------'
  ].join('\n'));

  app.handlers.forEach(function (handler) {
    console.log([
      handler.method.toUpperCase(),
      handler.path,
      '.' + handler.file.replace(process.cwd(), '') + '#' + handler.funcName
    ].join(' '));
  });
};

exports.startServer = function (mode, port) {
  var server;
  var restarted = false;
  var connections = [];
  var serverRunning = false;
  var restartServer = function () {
    serverRunning = false;
    server.close(function () {
      startServer();
    });
    connections.forEach(function (connection) {
      connection.end();
    });
  };
  var startServer = function (restarted) {
    var app = loadApp();
    if (app && typeof app.listen == 'function') {
      server = app.listen(port, function () {
        serverRunning = true;
        console.log('synth (in ' + mode + ' mode) is now listening on port ' + port);
      });
      server.on('connection', function (connection) {
        connections.push(connection);
        connection.on('close', function () {
          _.pull(connections, connection);
        });
      });
    } else {
      console.log('No synth app detected.');
    }
  };

  if (mode == 'production') {
    startServer();
  } else {
    gulp.watch([
      'back/back-app.js',
      'back/back-app.coffee',
      'back/resources/**/*.js',
      'back/resources/**/*.coffee',
      'back/services/**/*.js',
      'back/services/**/*.coffee',
      'front/css/cssFiles',
      'front/js/jsFiles',
    ], function (file) {
      console.log('A file was ' + file.type + ', restarting server');
      if (serverRunning) restartServer();
    });
    startServer();
  }
};

exports.install = function (command, args) {
  var nodeModuleIndex = args.indexOf('-b') + 1;
  var bowerComponentIndex = args.indexOf('-f') + 1;
  var both = !!(nodeModuleIndex && bowerComponentIndex);

  if (nodeModuleIndex || both) {
    var nodeModules = getModules(args, nodeModuleIndex);

    process.chdir('back');
    npm.load({ save: true }, function (err) {
      npm.commands.install(nodeModules);
    });
  }

  if (bowerComponentIndex || both) {
    var bowerComponents = getModules(args, bowerComponentIndex);

    process.chdir('front');
    bower.config.cwd = process.cwd();
    var bowerInstall = bower.commands[command](bowerComponents, { save: true });

    bowerInstall.on('log', function(log) {
        /**
        * This is how bower renders the status to the CLI upon packages being installed
        */
        var bowerStdRenderer = new BowerStandardRenderer({}, {});
        bowerStdRenderer.log(log);
    });

    bowerInstall.on('end', function (installed) {
      /* Add installed components to the asset manifest files */
      bowerSupport.addToManifestFiles(installed);
    });
  }
};

exports.uninstall = function (command, args) {
  var nodeModuleIndex = args.indexOf('-b') + 1;
  var bowerComponentIndex = args.indexOf('-f') + 1;
  var both = !!(nodeModuleIndex && bowerComponentIndex);

  if (nodeModuleIndex || both) {
    var nodeModules = getModules(args, nodeModuleIndex);

    process.chdir('back');
    npm.load({ save: true }, function (err) {
      npm.commands.uninstall(nodeModules);
    });
  }

  if (bowerComponentIndex || both) {
    var bowerComponents = getModules(args, bowerComponentIndex);

    process.chdir('front');
    bower.config.cwd = process.cwd();
    promises = {};
    bowerComponents.forEach(function(component, index){
      promises[component] = new Promise(function(resolve){
        bower.commands.info(component).on('end', function(info){
          return resolve({
            pkgMeta: info.latest
          });
        });
      });
    });
    bower.commands[command](bowerComponents, { save: true })
    .on('end', function (uninstalled) {
      Promise.props(promises).then(function(infos){
        /* Remove uninstalled components from the asset manifest files */
        bowerSupport.removeFromManifestFiles(infos);
      });
    });
  }
};

exports.showHelp = require('./help.js').show;

function applyTemplate ( direction, template, dest ) {
  var destDirection =  (direction == 'root') ? '' : direction;
  var appName = dest.replace(/.*\//g, '');
  var templatePath = path.join(__dirname, '../templates', direction, template);
  var destPath = path.join(dest, destDirection);

  /* Copy over all the files from the specified directory */
  try {
    wrench.copyDirSyncRecursive( templatePath, destPath );
  } catch (err) {
    if (err.code === 'ENOENT') {
      console.error('The template "' + template + '" could not be found.');
      process.exit(1);
    }
  }

  /* Run each file through the template renderer */
  wrench.readdirSyncRecursive(destPath).forEach(function (file) {
    var filePath = path.join(destPath, file);
    try { // Reads will fail on a directory, try/catch will catch it
      var contents = fs.readFileSync(filePath, { encoding: 'utf8' });
      var tokens = {
        appName: appName,
        synthVersion: pkg.version
      };
      if (file === '_dot_gitignore') {
        fs.unlinkSync(filePath); // Delete the file
        filePath = path.join(destPath, '.gitignore');
      }
      fs.writeFileSync( filePath, _.template(contents, tokens) );
    } catch (err) {
      if (err.code != 'EISDIR') throw err;
    }
  });
}

function getModules ( args, startIndex ) {
  var modules = [];
  var module;

  for (var i = startIndex; i < args.length; i++ ) {
    module = args[i];
    if (!module || module[0] == '-') break;
    modules.push(module);
  }
  return modules;
}<commit_msg>changed the logger to use console.log instead of requiring the bower file<commit_after>var fs = require('fs'),
    npm = require('npm'),
    bower = require('bower'),
    gulp = require('gulp'),
    nopt = require('nopt'),
    path = require('path'),
    pkg = require('../package.json'),
    requireUncached = require('./requireUncached.js'),
    _ = require('lodash'),
    bowerSupport = require('./bowerSupport.js'),
    wrench = require('wrench'),
    Promise = require('bluebird');

// Add global support for coffee-script
require('coffee-script/register');

function loadApp () {
  try {
    return requireUncached(path.join(process.cwd(), 'back/back-app'));
  } catch (err) {
    if (err.code === 'MODULE_NOT_FOUND') {
      console.error('No synth app detected (missing synth.json).');
      process.exit(1);
    }
  }
}

exports.createNewApp = function (dirName) {
  var args = nopt({
    'front': String,
    'back': String,
    'root': String
  }, {
    'f': '--front',
    'b': '--back',
    'r': '--root'
  });
  var options = {
    rootTemplate: args.root || 'default',
    backTemplate: args.back || 'mongojs',
    frontTemplate: args.front || 'angular'
  };

  try {
    /* Test that the specified is empty and can be written to */
    fs.mkdirSync(dirName);
    fs.rmdirSync(dirName);
  } catch (err) {
    if (err.code == 'EEXIST')
      console.log('Oops, that folder already exists. Try specifying a different name.');
    else
      console.log(err.message);
    return;
  }

  applyTemplate('root', options.rootTemplate, dirName);
  applyTemplate('back', options.backTemplate, dirName);
  applyTemplate('front', options.frontTemplate, dirName);
  console.log('Successfully created a new synth app in ' + dirName);
};

exports.printRoutes = function () {
  var app = loadApp();

  console.log([
    'API Routes:',
    '---------------'
  ].join('\n'));

  app.handlers.forEach(function (handler) {
    console.log([
      handler.method.toUpperCase(),
      handler.path,
      '.' + handler.file.replace(process.cwd(), '') + '#' + handler.funcName
    ].join(' '));
  });
};

exports.startServer = function (mode, port) {
  var server;
  var restarted = false;
  var connections = [];
  var serverRunning = false;
  var restartServer = function () {
    serverRunning = false;
    server.close(function () {
      startServer();
    });
    connections.forEach(function (connection) {
      connection.end();
    });
  };
  var startServer = function (restarted) {
    var app = loadApp();
    if (app && typeof app.listen == 'function') {
      server = app.listen(port, function () {
        serverRunning = true;
        console.log('synth (in ' + mode + ' mode) is now listening on port ' + port);
      });
      server.on('connection', function (connection) {
        connections.push(connection);
        connection.on('close', function () {
          _.pull(connections, connection);
        });
      });
    } else {
      console.log('No synth app detected.');
    }
  };

  if (mode == 'production') {
    startServer();
  } else {
    gulp.watch([
      'back/back-app.js',
      'back/back-app.coffee',
      'back/resources/**/*.js',
      'back/resources/**/*.coffee',
      'back/services/**/*.js',
      'back/services/**/*.coffee',
      'front/css/cssFiles',
      'front/js/jsFiles',
    ], function (file) {
      console.log('A file was ' + file.type + ', restarting server');
      if (serverRunning) restartServer();
    });
    startServer();
  }
};

exports.install = function (command, args) {
  var nodeModuleIndex = args.indexOf('-b') + 1;
  var bowerComponentIndex = args.indexOf('-f') + 1;
  var both = !!(nodeModuleIndex && bowerComponentIndex);

  if (nodeModuleIndex || both) {
    var nodeModules = getModules(args, nodeModuleIndex);

    process.chdir('back');
    npm.load({ save: true }, function (err) {
      npm.commands.install(nodeModules);
    });
  }

  if (bowerComponentIndex || both) {
    var bowerComponents = getModules(args, bowerComponentIndex);

    process.chdir('front');
    bower.config.cwd = process.cwd();
    var bowerInstall = bower.commands[command](bowerComponents, { save: true });

    bowerInstall.on('log', function(log) {
        /**
        * Log is a custom object coming from bower, so log it out
        */
        console.log('Bower:', log.id, log.message);

    });

    bowerInstall.on('end', function (installed) {
      /* Add installed components to the asset manifest files */
      bowerSupport.addToManifestFiles(installed);
    });
  }
};

exports.uninstall = function (command, args) {
  var nodeModuleIndex = args.indexOf('-b') + 1;
  var bowerComponentIndex = args.indexOf('-f') + 1;
  var both = !!(nodeModuleIndex && bowerComponentIndex);

  if (nodeModuleIndex || both) {
    var nodeModules = getModules(args, nodeModuleIndex);

    process.chdir('back');
    npm.load({ save: true }, function (err) {
      npm.commands.uninstall(nodeModules);
    });
  }

  if (bowerComponentIndex || both) {
    var bowerComponents = getModules(args, bowerComponentIndex);

    process.chdir('front');
    bower.config.cwd = process.cwd();
    promises = {};
    bowerComponents.forEach(function(component, index){
      promises[component] = new Promise(function(resolve){
        bower.commands.info(component).on('end', function(info){
          return resolve({
            pkgMeta: info.latest
          });
        });
      });
    });
    bower.commands[command](bowerComponents, { save: true })
    .on('end', function (uninstalled) {
      Promise.props(promises).then(function(infos){
        /* Remove uninstalled components from the asset manifest files */
        bowerSupport.removeFromManifestFiles(infos);
      });
    });
  }
};

exports.showHelp = require('./help.js').show;

function applyTemplate ( direction, template, dest ) {
  var destDirection =  (direction == 'root') ? '' : direction;
  var appName = dest.replace(/.*\//g, '');
  var templatePath = path.join(__dirname, '../templates', direction, template);
  var destPath = path.join(dest, destDirection);

  /* Copy over all the files from the specified directory */
  try {
    wrench.copyDirSyncRecursive( templatePath, destPath );
  } catch (err) {
    if (err.code === 'ENOENT') {
      console.error('The template "' + template + '" could not be found.');
      process.exit(1);
    }
  }

  /* Run each file through the template renderer */
  wrench.readdirSyncRecursive(destPath).forEach(function (file) {
    var filePath = path.join(destPath, file);
    try { // Reads will fail on a directory, try/catch will catch it
      var contents = fs.readFileSync(filePath, { encoding: 'utf8' });
      var tokens = {
        appName: appName,
        synthVersion: pkg.version
      };
      if (file === '_dot_gitignore') {
        fs.unlinkSync(filePath); // Delete the file
        filePath = path.join(destPath, '.gitignore');
      }
      fs.writeFileSync( filePath, _.template(contents, tokens) );
    } catch (err) {
      if (err.code != 'EISDIR') throw err;
    }
  });
}

function getModules ( args, startIndex ) {
  var modules = [];
  var module;

  for (var i = startIndex; i < args.length; i++ ) {
    module = args[i];
    if (!module || module[0] == '-') break;
    modules.push(module);
  }
  return modules;
}<|endoftext|>


<commit_before>'use strict';

var debug = require('debug')('lint-deps:comments');

var a = /\/\*\s*deps:/;
var b = /\*\/|$/;

module.exports = function comments(str) {
  debug('comments');
  if (!str) {
    return [];
  }

  str = str.replace(/\r/g, '');
  var lines = str.split(/\n/);
  var len = lines.length;
  var i = 0;

  debug('comments [len]: ', len);

  var isComment = false;
  var comment = [];

  while (len--) {
    var line = lines[i++];
    debug('comments [line]: ', i)

    if (a.test(line)) {
      isComment = true;
    }

    if (typeof line === 'string' && isComment) {
      comment.push(line.trim());
    }

    if (b.test(line)) {
      isComment = false;
    }
  }

  return comment;
};<commit_msg>use esprima for code-comments<commit_after>'use strict';

var debug = require('debug')('lint-deps:comments');
var extract = require('esprima-extract-comments');
var _ = require('lodash');

module.exports = function(str, options) {
  debug('comments');
  if (!str) {
    return [];
  }

  str = str.replace(/#!\/usr[\s\S]+?\n/, '');
  var opts = _.extend({ safe: false }, options);
  var comment = ['empty'];

  try {
    var comments = extract.fromString(str);
    var len = comments.length;
    var i = 0;

    while (i < len) {
      var obj = comments[i++];

      if (obj.type === 'Block') {
        comment.push(obj.value.replace(/\*\s+/, ''));
      }
    }
  } catch(err) {
    if (opts.silent) return;
    console.log(err);
    throw err;
  }

  return comment;
};<|endoftext|>