mecano
Version:
Common functions for system deployment.
196 lines (179 loc) • 5.26 kB
JavaScript
// Generated by CoffeeScript 1.9.1
var conditions, connect, each, exports, misc, tilde,
slice = [].slice;
each = require('each');
tilde = require('tilde-expansion');
connect = require('ssh2-connect');
misc = require('./index');
conditions = require('./conditions');
/*
Responsibilities:
* Retrieve arguments
* Normalize options
* Handle conditions
* Run multiple actions sequentially or concurrently
* Handling modification count
* Return a Mecano Child instance
* Pass user arguments
*/
exports = module.exports = function(context, args, handler) {
var callback, finish, goptions, isArray, options, ref, user_args;
ref = exports.args(args), options = ref[0], goptions = ref[1], callback = ref[2];
isArray = Array.isArray(options);
user_args = [];
finish = function(err) {
var arg, i;
if (!isArray) {
user_args = (function() {
var j, len, results;
results = [];
for (i = j = 0, len = user_args.length; j < len; i = ++j) {
arg = user_args[i];
results.push(user_args[i] = arg[0]);
}
return results;
})();
}
if (callback) {
return callback.apply(null, [err].concat(slice.call(user_args)));
}
};
exports.options(options, function(err, options) {
if (err) {
return finish(err);
}
return each(options).run(function(options, next) {
return conditions.all(options, next, function() {
return handler.call(context, options, function() {
var arg, args, err, i, j, len, modif;
err = arguments[0], modif = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : [];
for (i = j = 0, len = args.length; j < len; i = ++j) {
arg = args[i];
if (user_args[i] == null) {
user_args[i] = [];
}
user_args[i].push(arg);
}
return next(err);
});
});
}).then(finish);
});
return context;
};
exports.args = function(args, overwrite_goptions) {
var base;
if (overwrite_goptions == null) {
overwrite_goptions = {};
}
if (args.length === 2 && typeof args[1] === 'function') {
args[2] = args[1];
args[1] = {};
} else if (args.length === 1) {
args[1] = {};
args[2] = null;
}
if ((base = args[1]).parallel == null) {
base.parallel = 1;
}
return args;
};
/*
`options(options, callback)`
----------------------------
Normalize options. An ssh connection is needed if the key "ssh"
hold a configuration object. The 'uid' and 'gid' fields will
be converted to integer if they match a username or a group.
`callback` Received parameters are:
* `err` Error object if any.
* `options` Sanitized options.
*/
exports.options = function(options, callback) {
if (!Array.isArray(options)) {
options = [options];
}
return each(options).run(function(options, next) {
var connection, destination, el, i, j, k, len, len1, mode, ref, ref1, source, v;
if (typeof options.if_exists === 'string') {
options.if_exists = [options.if_exists];
}
if (typeof options.not_if_exists === 'string') {
options.not_if_exists = [options.not_if_exists];
}
if (options.if_exists) {
ref = options.if_exists;
for (i = j = 0, len = ref.length; j < len; i = ++j) {
el = ref[i];
if (el === true && options.destination) {
options.if_exists[i] = options.destination;
}
}
}
if (options.not_if_exists) {
ref1 = options.not_if_exists;
for (i = k = 0, len1 = ref1.length; k < len1; i = ++k) {
v = ref1[i];
if (v === true && options.destination) {
options.not_if_exists[i] = options.destination;
}
}
}
if (options.chmod) {
if (options.mode == null) {
options.mode = options.chmod;
}
}
connection = function() {
var ref2;
if (!options.ssh) {
return source();
}
if ((ref2 = options.ssh.config) != null ? ref2.host : void 0) {
return source();
}
return connect(options.ssh, function(err, ssh) {
if (err) {
return next(err);
}
options.ssh = ssh;
return source();
});
};
source = function() {
if (options.source == null) {
return destination();
}
if (/^\w+:/.test(options.source)) {
return destination();
}
return tilde(options.source, function(source) {
options.source = source;
return destination();
});
};
destination = function() {
if (options.destination == null) {
return mode();
}
if (typeof options.destination !== 'string') {
return mode();
}
if (/^\w+:/.test(options.source)) {
return mode();
}
return tilde(options.destination, function(destination) {
options.destination = destination;
return mode();
});
};
mode = function() {
if (typeof options.mode === 'string') {
options.mode = parseInt(options.mode, 8);
}
return next();
};
return connection();
}).then(function(err) {
return callback(err, options);
});
};