#!/usr/bin/env node /** * Dependencies */ var program = require('commander') , deployd = require('../') , repl = require('../lib/client/repl') , shelljs = require('shelljs/global') , mongod = require('../lib/util/mongod') , path = require('path') , fs = require('fs') , tty = require('tty') , remote = require('../lib/client/remote') , request = require('request') , package = require('../package') , latestversionFile = path.join(__dirname, '../.latestversion') , Deployment = require('../lib/client/deploy').Deployment , open = require('../lib/util/open'); /** * Get the version number from the package.json */ program .version(require('../package').version) .option('-m, --mongod [path]', 'path to mongod executable (defaults to `mongod`)') .option('-p, --port [port]', 'port to host server (defaults to 2403)') .option('-w, --wait', 'wait for input before exiting') .option('-d, --dashboard', 'start the dashboard immediately') .option('-o, --open', 'open in a browser') .option('-e, --environment [env]', 'defaults to development') /** * Commands */ program .command('create [project-name]') .description('\tcreate a project in a new directory\n\teg. `dpd create my-app`') .action(function(name) { name = name || 'my-deployd-app'; if (test('-d', name)) { return console.info(name + " already exists in this directory"); } mkdir('-p', name); cp('-Rf', path.join(__dirname, '/createtemplate/*'), name); mkdir('-p', name + '/.dpd'); mkdir('-p', name + '/.dpd/pids'); ('').to(name + '/.dpd/pids/mongod'); rm(ls('-R', name).filter(function(p) { return path.basename(p) === 'PLACEHOLDER'; }).map(function(p) { return name + '/' + p})); if (program.dashboard || program.open) { start(name + '/app.dpd'); } else { console.info('to start your app:'); console.info('\t$ cd', name); console.info('\t$ dpd'); } }); function start(file) { var port = program.port || 2403 , mongoPort = generatePort(); if (file) { process.chdir(path.dirname(file)); } if (test('-f', 'app.dpd')) { console.log("starting deployd v" + package.version + "..."); if (fs.existsSync(latestversionFile)) { var latest = fs.readFileSync(latestversionFile, 'utf-8'); if (latest && latest !== package.version) { console.log("deployd v" + latest + " is available. Use dpd-update command to install"); } } checkForUpdates(); if (!test('-d', './.dpd')) mkdir('-p', './.dpd'); if (!test('-d', './.dpd/pids')) mkdir('-p', './.dpd/pids'); if (!test('-d', './data')) mkdir('-p', './data'); mongod.restart(program.mongod || 'mongod', process.env.DPD_ENV || 'development', mongoPort, function(err) { if (err) { console.log("Failed to start MongoDB"); return stop(1); } var options = {port: port, env: 'development', db: {host: '127.0.0.1', port: mongoPort, name: '-deployd'}} options.env = program.environment || process.env.DPD_ENV || options.env; if(options.env !== 'development') console.log('starting in %s mode', options.env); var dpd = deployd(options); dpd.listen(); dpd.on('listening', function () { console.info('listening on port', port); var commands = repl(dpd); if (program.dashboard) { commands.dashboard(); } else if (program.open) { commands.open(); } }); }); } else { console.log("This directory does not contain a Deployd app!"); console.log("Use \"dpd create \" to create a new app"); console.log("or use \"dpd path/to/app.dpd\" to start an app in another directory"); stop(1); } } program .command('keygen') .description('\tgenerate a key for remote access (./.dpd/keys.json)') .action(function() { var Keys = require('../lib/keys') , keys = new Keys(); keys.create(function(err, key) { if(err) return console.error(err); console.log('created key', key.substr(0, 16) + '...'); }); }); program .command('showkey') .description('\tshows current key for connecting to remote dashboard (./.dpd/keys.json)') .action(function() { var Keys = require('../lib/keys') , keys = new Keys(); keys.getLocal(function(err, key) { if(err) return console.error(err); console.log("Copy this key for use in remote dashboard"); console.log(); console.log(key); console.log(); }); }); program .command('remote') .description('\topen the remote dashboard in your browser') .action(function() { var d = new Deployment('.'); var host = ''; var config = d.getConfig(); console.log(config); host = Object.keys(config)[0]; if (host) { open('http://' + host + '/dashboard/'); } else { console.log("This app has not yet been deployed"); } }); program .command('deploy [subdomain]') .description('\tdeploy a testing instance on deploydapp.com') .action(function (subdomain) { try { var d = new Deployment('.', null, subdomain) , tar = './.dpd/package.tgz' , DPDAPP_URL = 'http://deploydapp.com' , Keys = require('../lib/keys') , keys = new Keys(); if (process.env["DPDAPP_PORT"]) DPDAPP_URL += ':' + process.env["DPDAPP_PORT"]; keys.getLocal(function (err, key) { if(err) return console.error(err); if(key) { deploy(key); } else { keys.create(function(err, key) { if(err) return console.error(err); deploy(key); }); } }); function deploy(key) { console.log('packaging...'); d.package(tar, function (err) { if(err) return console.error(err); console.log('pushing...'); d.publish(DPDAPP_URL, tar, key, function (err) { if(err) return console.error('failed to push:', err.message || 'could not push app to ' + DPDAPP_URL); console.log('deployd app to http://' + d.subdomain + '.deploydapp.com!'); }); }); } } catch (ex) { console.log(ex.message); } }); program .command('*') .description('\t[default] start the server in the current project in development mode\n' + '\twith an interactive shell/repl for interacting with the running server\n' + '\te.g. dpd (starts server in current directory),\n' + '\t dpd my-app/app.dpd (starts app from file)') .action(start); function stop(code) { var fn = function() { exit(code); }; if (program.wait) { process.stdin.resume(); process.stdin.setRawMode(true); process.stdout.write('\nPress any key to continue...\n'); process.stdin.on('keypress', fn); } else { fn(); } } process.on('uncaughtException', function(err) { console.log(err); console.log(err.stack); stop(1); }); /** * Parse the arguments */ program.parse(process.argv); if(program.args.length === 0) start(); /** * Port generation */ function generatePort() { var portRange = [ 3000, 9000 ]; return Math.floor(Math.random() * (portRange[1] - portRange[0])) + portRange[0]; } function checkForUpdates() { request('http://registry.npmjs.org/deployd', function(err, res, body) { if (!err) { var json; try { json = JSON.parse(body); } catch (ex) {} if (json && json['dist-tags'] && json['dist-tags'].latest) { var latest = json['dist-tags'].latest; fs.writeFile(latestversionFile, latest); } } }); }