Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

boom-deploy

Package Overview
Dependencies
Maintainers
1
Versions
192
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

boom-deploy - npm Package Compare versions

Comparing version 0.0.14 to 0.0.15

boom/.npmignore

20

boom.js

@@ -13,14 +13,6 @@ var path = require('path');

var env, task;
if (argv._[1]) {
env = argv._[0];
task = argv._[1];
} else if (argv._[0]) {
env = 'production';
task = argv._[0];
} else {
// ???
}
if (argv.v) {
if (argv._[0] == 'init') {
boom.init();
} else if (argv.v) {
console.log(require(path.resolve(__dirname, 'package.json')).version);

@@ -31,6 +23,8 @@ } else if (argv.t) {

boom.list();
} else if (argv._.length==2) {
boom.perform(env, task);
} else if (argv._.length == 2) {
var env = argv._[0];
var task = argv._[1];
boom.go(env, task);
} else {
optimist.showHelp();
}
var _ = require('lodash');
//var ssh = require('ssh2');
var vm = require('vm');
var fs = require('fs');
var path = require('path');
var async = require('async');

@@ -7,41 +9,138 @@ var logger = require('./logger');

var tasks = require('./tasks');
var readline = require('./readline');
var helpers = require('./helpers');
var replacer = require('./replacer');
var github = require('./github');
var scope = require('./scope');
var fiberWrapper = require('./fiberWrapper');
var spawnProcess = require('./spawnProcess');
var $ = require('./stylize');
var scope = require('./scope');
exports.list = function(short){
_.each(tasks.source, function(task, name){
if (short) console.log(name)
else console.log('%s - %s', name, task.desc);
});
config.init();
exports.prepare(function(){
for (var i = 0, base = ''; i < 50; ++i, base += ' ');
_.each(tasks.list, function(task, name){
if (short) console.log(name)
else console.log('%s - %s', name + base.substr(name.length), task.desc);
});
})
};
exports.perform = function(env, taskname){
exports.prepare = function(cb){
github.login(function(err){
if (err) {
console.error('Authentication failed.', err);
github.removeToken();
return;
}
_.chain(scope.CONFIG)
.assign(config.init(env))
.assign({ env: env })
var getBrunch = readline.read.bind(readline, {prompt: 'set branch:', default: config.get('defaultBranch')});
if (config.get('branch')) getBrunch = function(cb){ cb(null, config.get('branch')) };
// tasks.apply(scope.CONFIG);
getBrunch(function(err, branch){
if (err) throw err;
config.set('branch', branch);
tasks.init(function(err, res){
if (err) {
console.error('unknown error:', err);
return;
}
cb()
});
})
});
}
// logger.log('config', scope.CONFIG);
// logger.log('tasks', tasks.get());
exports.go = function(env, taskname){
exports.execTask(taskname, function(){
logger.info($('DONE.').bold + '\n');
// console.log('Done', arguments);
// console.log(scope.CONFIG);
config.init(env);
helpers.init();
exports.prepare(function(){
exports.perform(taskname);
})
};
exports.perform = function(taskname){
exports.executors.task(taskname, [], function(err){
// console.log(config.get());
// console.log(scope);
if (err) return console.error($('FAIL.').bold.red + ' ' + err);
console.log($('SUCCESS.').bold.green);
});
};
exports.execTask = function(taskname, callback){
async.mapSeries(tasks.get(taskname), function(cmd, cb){
var preparedCmd = replacer.replace(cmd.cmd, scope.CONFIG);
scope[cmd.type](preparedCmd, function(err, out){
if (err) return cb(err);
global.BUFFER = out;//JSON.stringify(out);
cb(null, global.BUFFER);
exports.executors = {
task: function(taskname, args, callback){
var task = tasks.get(taskname);
if (!task) return callback(new Error('task ' + taskname + ' not found.'));
logger.info($('Executing: task ' + $(taskname).cyan).bold);
exports.executors.js(task.func.toString(), args, function(err, out){
if (err) return callback(err);
callback(null, out);
})
}, callback);
},
js: function(funcstring, args, callback){
logger.info($('Executing: js').bold + '\n' + $(funcstring).green);
var wrapper = '__fiberWrapper(' + funcstring + ', __args, __cb)';
var sandbox = _.assign({
__fiberWrapper: fiberWrapper,
__args: args,
__cb: callback,
scope: scope
}, scope);
vm.runInNewContext(wrapper, sandbox, 'vm.js')
},
local: function(cmd, callback){
fiberWrapper(scope.local.bind(scope, cmd), [], callback);
},
ssh: function(cmd, callback){
fiberWrapper(scope.ssh.bind(scope, cmd), [], callback);
}
}
exports.init = function(){
var boom_dir = path.resolve(process.cwd(), './boom');
if (exports.isDir(boom_dir)) {
readline.askYesOrNot('Dir "boom" already exists. Continue?', function(err, answer){
if (err) throw err;
if (answer) createConfig();
})
} else {
fs.mkdirSync(boom_dir);
createConfig();
}
function createConfig(){
var template = {};
spawnProcess.local('git remote -v | head -n1 | awk \'{print $2}\' | sed \'s/.*\\///\' | sed \'s/\\.git//\'', function(err, name){
if (err) throw err;
name = String(name).trim();
if (name) template.name = name;
fs.writeFileSync(path.resolve(boom_dir, 'common.json'), JSON.stringify(_.assign(template, {
owner: 'viboomru',
keepReleases: 10
}), null, '\t'));
fs.writeFileSync(path.resolve(boom_dir, 'local.json'), JSON.stringify({
server: '127.0.0.1',
port: '22',
user: process.env.USER,
deployTo: '/home/{{user}}/deploy/{{name}}',
keepReleases: 5
}, null, '\t'));
fs.writeFileSync(path.resolve(boom_dir, '.gitignore'), '*.json');
fs.writeFileSync(path.resolve(boom_dir, 'deploy.js'), fs.readFileSync(path.resolve(__dirname, '../boom/deploy.template')));
})
}
}
exports.isDir = function(dir){
var stats = fs.existsSync(dir) && fs.statSync(dir);
return stats && stats.isDirectory();
}

@@ -11,19 +11,26 @@ var _ = require('lodash');

data: null,
data: {},
dir: path.resolve(process.cwd(), './boom'),
ext: '.json',
init: function(env){
var defaultConf = this.loadConfig('default');
var envConf = this.loadConfig(env);
var commonConf = this.loadConfig('common');
var envConf = env ? this.loadConfig(env) : {};
var argvConf = _.omit(argv, '_', '$0');
this.data = _.chain({}).assign(defaultConf).assign(envConf).assign(argvConf).value();
_.chain(this.data).assign(commonConf).assign(envConf).assign(argvConf).assign({env: env})
this.preprocess(this.data);
vars.applyTo(this.data);
env && vars.applyTo(this.data); // TODO
return this.data;
},
get: function(){
return this.data;
get: function(key){
if (!key) return this.data;
return this.data[key];
},
set: function(key, value){
this.data[key] = value;
},
preprocess: function(obj, base){

@@ -41,5 +48,5 @@ base = base||obj;

try {
return JSON.parse(fs.readFileSync(path.resolve(process.cwd(), './boom', env + '.json')));
return JSON.parse(fs.readFileSync(path.resolve(this.dir, env + this.ext)));
} catch(err) {
logger.error('%s error', filepath, err);
logger.error('%s config error', env, err);
process.exit();

@@ -46,0 +53,0 @@ }

@@ -1,24 +0,11 @@

var regExpReplacer = /\{\{([^\{}]+)\}\}/g;
var _ = require('lodash');
var vm = require('vm');
var regExpReplacer = /\{\{([^\{}]+)\}\}/g;
exports.replace = function(str, base){
str = str.replace(regExpReplacer, function(match, props){
return exports.getProp(base, props);
return vm.runInNewContext('(function(){ return ' + props + '})()', base);
});
return str;
}
exports.getProp = function(base, props){
var steps = props.split('.');
var cursor = base;
var value;
var result = vm.runInNewContext('(function(){ return '+props+'}).bind(this)()', base);
return result;
// for (var i in steps) {
// if (cursor.hasOwnProperty(steps[i])) {
// value = cursor[steps[i]];
// cursor = (typeof(value) == 'function') ? value.call(base) : value;
// } else return undefined;
// }
// return cursor;
}
var _ = require('lodash');
var vm = require('vm');
var cp = require('child_process');
var sync = require('sync');
var beautify = require('node-beautify');
var replacer = require('./replacer');
var spawnProcess = require('./spawnProcess');
var logger = require('./logger');
var boom = require('./boom');
var config = require('./config');
var helpers = require('./helpers');
var travis = require('./travis');
var readline = require('./readline');
var $ = require('./stylize');
var fiberWrapper = require('./fiberWrapper');
var Future = require('fibers/future');
var tmp = {
sudoStored: false
}
var scope = {
CONFIG: {},
// BUFFER: '',
// GLOBAL: global,
console: console,
require: function(path){
return require(path);
},
console: console,
ssh: function () {
var callback = [].pop.call(arguments);
var cmd = [].join.call(arguments, '\n');
local: function(){
return function(){
var cmd = [].join.call(arguments, '\n');
cmd = replacer.replace(cmd, config.get());
logger.info($('Executing: ssh on ' + $(scope.CONFIG.server).blue).bold + '\n' + $(cmd).yellow);
var options = [
'-p ' + scope.CONFIG.port,
scope.CONFIG.user + '@' + scope.CONFIG.server,
cmd
]
//console.log('ssh', options)
spawnProcess('ssh', options, function (err, out) {
if (err) {
logger.error('FAILED TO RUN, return code: ' + err);
callback(err);
} else {
callback(null, out);
}
});
},
local: function () {
var callback = [].pop.call(arguments);
var cmd = [].join.call(arguments, '\n');
logger.info($('Executing: cmd localy').bold + '\n' + $(cmd).grey);
logger.info($('Executing: local').bold + '\n' + $(cmd).green);
spawnProcess('sh', [ '-c', cmd ], function (err, out) {
if (err) {
logger.error('FAILED TO RUN, return code: ' + err);
callback(err);
} else {
if (callback) callback(null, out);
}
});
var future = new Future;
spawnProcess.local(cmd, function (err, out) {
if (err) future.throw(err);
else future.return(out);
});
return future
}.apply(this, arguments).wait()
},
js: function(cmd, callback){
cmd = beautify.beautifyJs(cmd);
logger.info($('Executing: js').bold + '\n' + $(cmd).green);
var code = 'sync(function(){\n'+cmd+'\n}, callback)';
code = toSyncCode(code);
var result = eval(code);//vm.runInNewContext(code, scope, 'cmd.js');
},
task: function(taskname, callback){
boom.execTask(taskname, callback);
},
set: function(name, value){
scope.CONFIG[name] = value;
},
get: function(name){
return scope.CONFIG[name];
},
exit: function(msg){
console.log(msg)
process.exit();
}
}
ssh: function(){
return function(){
var cmd = [].join.call(arguments, '\n');
cmd = replacer.replace(cmd, config.get());
_.assign(global, scope);
logger.info($('Executing: ssh on ' + $(config.get('server')).blue).bold + '\n' + $(cmd).yellow);
function toSyncCode(code){
return code.replace(/\b(ssh|local|task)\(/g, '$1.sync(null,');
}
var future = new Future;
spawnProcess.ssh(cmd, function (err, out) {
if (err) future.throw(err);
else future.return(out);
});
return future
}.apply(this, arguments).wait()
},
sudo: function(){
return function(){
var cmd = [].join.call(arguments, '\n');
cmd = replacer.replace(cmd, config.get());
function spawnProcess(command, options, callback) {
var child = cp.spawn(command, options);
var future = new Future;
var err = [];
child.stderr.on('data', function (chunk) {
err.push(chunk.toString());
console.error(chunk.toString());
});
function exec(){
logger.info($('Executing: sudo on ' + $(config.get('server')).blue).bold + '\n' + $(cmd).yellow);
spawnProcess.ssh('cat ~/.sudo_pass | sudo -S ' + cmd, function (err, out) {
if (err) future.throw(err);
else future.return(out);
});
}
var res = [];
child.stdout.on('data', function (chunk) {
//console.log('spawnProcess: DATA',chunk.toString())
res.push(chunk.toString());
console.log(chunk.toString());
});
function store(cb){
if (!tmp.sudoStored) {
tmp.sudoStored = true;
spawnProcess.ssh('echo ' + config.get('sudo') + ' > ~/.sudo_pass && chmod a+x ~/.sudo_pass', function(err, out){
if (err) return future.throw(err);
cb();
});
} else cb();
}
// child.stdout.on('end', function(){
// console.log('spawnProcess: END')
// })
if (!config.get('sudo')) {
readline.read({prompt: 'set sudo pass: ', silent: true}, function(err, pass){
if (err) return future.throw(err);
config.set('sudo', pass);
store(exec);
})
} else store(exec);
child.on('exit', function (code) {
if (callback) {
//console.log('spawnProcess: EXIT', res)
setImmediate(function(){
if (err.length && !res.length) return callback(err.join('\n'));
callback(code === 0 ? null : code, res && res.join('\n'));
return future
}.apply(this, arguments).wait()
},
task: function(taskname){
var args = [].slice.call(arguments, 1);
return function(){
var future = new Future;
boom.executors.task(taskname, args, function(err, res){
if (err) future.throw(err);
else future.return(res);
});
return future
}().wait()
},
js: function(funcstring){
var args = [].slice.call(arguments, 1);
return function(){
var future = new Future;
boom.executors.js(funcstring, args, function(err, res){
if (err) future.throw(err);
else future.return(res);
});
return future
}().wait()
},
set: config.set.bind(config),
get: config.get.bind(config),
exit: function(msg){
console.log($('EXIT:').bold.cyan, msg)
process.exit();
},
sleep: function(ms){
return function(){
var future = new Future;
setTimeout(function() {
future.return()
}, ms)
return future;
}().wait()
},
checkTravisBuild: function(commit){
return function(){
var future = new Future;
function askForce(build){
readline.askYesOrNot('Do you want to deploy force?', function(err, answer){
if (err) return future.throw(err);
if (answer) future.return(build);
})
}
console.log('checking TRAVIS-CI build...');
travis.checkBuild(commit, function(err, build){
if (err) return future.throw(err);
if (build && build.state == 'finished') {
future.return(build);
} else {
if (!build) console.log('ATTENTION! Commit %s not found in TRAVIS-CI', config.get('head'));
else if (build.state == 'failed') console.log('ATTENTION! Your last build is FAIL');
else console.log('ATTENTION! Your build is now TESTING in TRAVIS-CI');
askForce(build);
}
})
}
});
return future;
}().wait()
},
ask: function(question){
return function(){
var future = new Future;
readline.askYesOrNot(question, function(err, res){
if (err) future.throw(err);
else future.return(res);
})
return future;
}().wait()
},
read: function(options){
return function(){
var future = new Future;
readline.read(options, function(err, res){
if (err) future.throw(err);
else future.return(res);
})
return future;
}().wait()
}
}
module.exports = scope;

@@ -7,11 +7,11 @@

var styles = {
'bold' : [1, 22],
'italic' : [3, 23],
'bold' : [1, 22],
'italic' : [3, 23],
'underline' : [4, 24],
'cyan' : [96, 39],
'blue' : [34, 39],
'yellow' : [33, 39],
'green' : [32, 39],
'red' : [31, 39],
'grey' : [90, 39]
'cyan' : [96, 39],
'blue' : [34, 39],
'yellow' : [33, 39],
'green' : [32, 39],
'red' : [31, 39],
'grey' : [90, 39]
};

@@ -40,5 +40,5 @@

});
return str;
return String(str);
};
module.exports = $;

@@ -0,57 +1,73 @@

var _ = require('lodash');
var fs = require('fs');
var _ = require('lodash');
var path = require('path');
var replacer = require('./replacer');
var async = require('async');
var vm = require('vm');
var logger = require('./logger');
var config = require('./config');
var github = require('./github');
var helpers = require('./helpers');
var readline = require('./readline');
var $ = require('./stylize');
module.exports = {
list: null,
list: {},
dir: path.resolve(process.cwd(),'./boom'),
main: 'default',
ext: '.tasks',
ext: '.js',
re: {
task: /\nTASK[\s\t]+/,
cmd: /^(ssh|local|task|js)\:\s?((?:.|[\r\n])+)?/
},
init: function(callback){
var self = this;
init: function(){
var self = this;
self.source = self.parse(self.loadTaskFile(self.main + self.ext));
_.each(self.scanTaskFiles(), function(filename){
_.assign(self.source, self.parse(self.loadTaskFile(filename)));
})
self.list = {};
_.each(self.source, function(task, name){
self.list[name] = self.compileTaskCommands(task.run);
})
if (config.get('local')) return self.getLocalTasks(callback);
self.requestTaskFiles(function(err, taskfiles){
if (err) {
if (err.code == 404) {
console.error('has no dir "boom" in branch "%s".', config.get('branch'));
readline.askYesOrNot('use local task files?', function(err, answer){
if (err) return callback(err);
if (answer) self.getLocalTasks(callback);
})
return;
}
return callback(err);
}
if (!_.size(taskfiles)) {
console.error('has no taskfiles in branch "%s".', config.get('branch'));
return ;
}
// console.log('taskfiles:', taskfiles);
_.each(taskfiles, function(filestring, filename){
self.compileTaskFile(filestring, filename);
})
callback(null);
});
},
compileTaskCommands: function(commands){
getLocalTasks: function(callback){
var self = this;
var res = [];
commands.forEach(function(cmd){
var cmd = self.parseCmd(cmd);
res.push(cmd);
// if (cmd.type == 'task') { // todo task executor
// res = res.concat(self.compileTaskCommands(self.source[cmd.cmd].run));
// } else {
// res.push(cmd);
// }
})
return res;
var taskfiles = self.scanTasksDir();
if (!_.size(taskfiles)) return callback('task files not found.');
_.each(taskfiles, function(filename){
var filestring = self.readTaskFile(filename);
self.compileTaskFile(filestring, filename);
});
callback(null);
},
parseCmd: function(cmd){
var self = this;
var parts = self.re.cmd.exec(cmd);
return {
type : parts[1],
cmd : parts[2]
compileTaskFile: function(filestring, filename){
return vm.runInNewContext(filestring, {
Task : this.pushTask.bind(this),
Helper : helpers.addHelper.bind(helpers)
}, filename);
},
pushTask: function(name, func, desc){
module.exports.list[name] = {
name: name,
desc: desc || 'no description :(',
func: func
}
},
apply: function(config){
replacer.replace(this.list, config);
},
get: function(name){

@@ -61,36 +77,9 @@ if (!name) return this.list;

},
parse: function(source){
scanTasksDir: function(){
var self = this;
var res = {};
source = source.replace(/^/, '\n');
_.chain(source.split(self.re.task))
.compact()
.each(function(task, i){
var lines = _.chain(task.split(/\n+/))
.map(function(line){ return line.trim() })
.compact()
.value();
var head = lines.shift().split(/[\s\t]*\/\/[\s\t]*/);
for (var i = 0; true; ++i) {
if (lines[i]===undefined) break;
if (!self.re.cmd.test(lines[i])) {
lines[i-1] += '\n'+lines[i];
lines.splice(i,1);
--i;
}
}
res[head[0]] = {
desc : head[1],
run : lines
}
});
return res;
},
scanTaskFiles: function(){
var self = this;
return _.filter(fs.readdirSync(self.dir), function(file){
return path.extname(file) == self.ext && file != self.main + self.ext
return path.extname(file) == self.ext
})
},
loadTaskFile: function(filename){
readTaskFile: function(filename){
var self = this;

@@ -103,5 +92,21 @@ try {

}
},
requestTaskFiles: function(callback){
var self = this;
var defaults = github.defaults({ ref : config.get('branch') || config.get('defaultBranch') });
github.api.repos.getContent(_.assign({ path: 'boom' }, defaults), function(err, res) {
if (err) return callback(err);
var taskfiles = _.filter(res, function(file){ return path.extname(file.path) == self.ext });
async.map(taskfiles, function(taskfile, cb){
github.api.repos.getContent(_.assign({ path: taskfile.path }, defaults), cb)
}, function(err, res){
if (err) return callback(err);
var res = _.chain(res).indexBy('name').mapValues(function(file){
return Buffer(file.content, file.encoding).toString()
}).value();
callback(null, res);
})
})
}
};
module.exports.init();
};

@@ -5,2 +5,5 @@ var moment = require('moment');

exports.data = {
repo: function(){
return 'git@github.com:' + this.owner + '/' + this.name + '.git'
},
timestamp: function(){

@@ -27,7 +30,7 @@ return moment().format('YYYYMMDDHHmmss')

exports.applying = function(obj){
for (var i in obj) {
this[i] = (typeof(obj[i]) == 'function') ? obj[i].call(this) : obj[i];
exports.applying = function(data){
for (var i in data) {
this[i] = (typeof(data[i]) == 'function') ? data[i].call(this) : data[i];
}
return this;
}
{
"name": "boom-deploy",
"main": "boom.js",
"version": "0.0.14",
"version": "0.0.15",
"description": "deploy your app",

@@ -16,6 +16,4 @@ "keywords": [

"dependencies": {
"nconf": "0.6.*",
"async": "0.9.*",
"sync": "0.2.*",
"ssh2": "0.3.*",
"fibers": "1.0.*",
"lodash": "2.4.*",

@@ -25,3 +23,5 @@ "optimist": "0.6.*",

"moment": "2.8.*",
"node-beautify": "0.0.2"
"superagent": "0.18.*",
"read": "1.0.*",
"github": "0.2.*"
},

@@ -28,0 +28,0 @@ "devDependencies": {

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc