UNPKG

nodemiral-forcetty

Version:
212 lines (175 loc) 5.75 kB
var EventEmitter = require('events').EventEmitter; var util = require('util'); var Session = require('./session'); var handlebars = require('handlebars'); var colors = require('colors'); function TaskList(name, options) { if(!(this instanceof TaskList)) { return new TaskList(name, options); } this._name = name; this._options = options || {}; this._pretty = this._options.pretty !== false; this._ignoreErrors = true; //this._options.ignoreErrors; this._taskQueue = []; //used as a global variable used by all the tasks for each session this._vars = {}; //used by all the tasks and sessions; this._globalVars = {}; this._dependingTasks = []; } util.inherits(TaskList, EventEmitter); TaskList.prototype.run = function(sessions, options, callback) { var self = this; if(!sessions) { throw new Error('First parameter should be either a session or a list of sessions'); } else if(!(sessions instanceof Array)) { sessions = [sessions]; } if(typeof(options) == 'function') { callback = options; options = {}; } options = options || {}; var summaryMap = {}; var completed = 0; self.log('info', 'Started TaskList: ' + this._name); Array.prototype.forEach.call(sessions, function(session) { self._runTaskQueue(session, function(err, history) { summaryMap[session._host] = {error: err, history: history}; if(++completed == sessions.length) { self.log('info', 'Completed TaskList: ' + self._name); if(callback) callback(summaryMap); } }); }); }; TaskList.prototype.concat = function(taskLists, name, options) { if(typeof(name) == 'object') { options = name; name = null; } name = name || this._name + '+'; options = options || this._options; var newTaskList = new TaskList(name, options); //merge content of _taskQueue of all taskLists into the new one var actionQueueList = taskLists.map(function(taskList) { return taskList._taskQueue; }); actionQueueList.unshift(this._taskQueue); newTaskList._taskQueue = newTaskList._taskQueue.concat.apply(newTaskList._taskQueue, actionQueueList); return newTaskList; }; TaskList.prototype._runTaskQueue = function(session, callback) { var self = this; var cnt = 0; var taskHistory = []; runTask(); function runTask() { var task = self._taskQueue[cnt++]; if(task) { self.emit('started', task.id); self.log('log', util.format('[%s] '.magenta+'- %s', session._host, task.id)); var options = self._evaluateOptions(task.options, session); // Spinner var Spinner = require('cli-spinner').Spinner; var spinr = new Spinner('%s'); spinr.start(); TaskList._registeredTasks[task.type](session, options, function(err) { if(err) { taskHistory.push({ task: task.id, status: 'FAILED', error: err.message }); // stop spinner spinr.stop(true); self.emit('failed', err, task.id); self.log('error', util.format('[%s] '.magenta+'\u2718 %s: FAILED\n\t%s'.red, session._host, task.id, err.message.replace(/\n/g, '\n\t'))); if(self._ignoreErrors) { runTask(); } else { callback(err, taskHistory); } } else { taskHistory.push({ task: task.id, status: 'SUCCESS' }); // stop spinner spinr.stop(true); self.log('log', util.format('[%s] '.magenta+'\u2714 %s: SUCCESS'.green, session._host, task.id)); self.emit('success', task.id); runTask(); } }, function(stdout, stderr) { var vars = self._getVarsForSession(session); if(task.varsMapper) { task.varsMapper.call(vars, stdout, stderr, self._globalVars); } }); } else { callback(null, taskHistory); } } }; TaskList.prototype._getVarsForSession = function(session) { if(!this._vars[session._host]) { this._vars[session._host] = {}; } return this._vars[session._host]; }; TaskList.prototype._evaluateOptions = function(options, session) { var self = this; if(options instanceof Array) { for(var lc=0; lc<options.length; lc++) { self._evaluateOptions(options[lc], session); } return options; } else if(typeof(options) == 'object') { for(var key in options) { var value = options[key]; if(typeof(value) == 'function') { var vars = self._getVarsForSession(session); options[key] = value.call(vars, self._globalVars); } else if(value == null) { options[key] = value; } else if(typeof(value) == 'string') { //add ejs support var vars = self._getVarsForSession(session); options[key] = handlebars.compile(value)(vars); } else { options[key] = self._evaluateOptions(value, session); } } return options; } else { return options; } }; TaskList.prototype.log = function(type, message) { if (this._pretty) { if (type == 'info') { message = '[localhost] '.magenta + message.bold.cyan; } else if (type == 'error') { message = message.bold.red; } else { message = message.yellow; } console[type](message); } }; TaskList.prototype.depends = function(taskList) { this._dependingTasks.push(taskList); }; TaskList._registeredTasks = {}; TaskList.registerTask = function(name, callback) { TaskList._registeredTasks[name] = callback; TaskList.prototype[name] = function(id, options, varsMapper) { this._taskQueue.push({ type: name, id: id, options: options, varsMapper: varsMapper }); }; }; module.exports = TaskList;