sub-cmd
Version:
A pass through sub command (git-style) runner.
229 lines (211 loc) • 6.39 kB
JavaScript
// Generated by CoffeeScript 1.4.0
(function() {
var fs, getSubCommands, isHelp, isOption, loglet, normalize, path, search, searchHelper, spawn, split, subproc, which, _localPath, _whichPath;
fs = require('fs');
path = require('path');
which = require('which');
subproc = require('child_process');
loglet = require('loglet');
split = function(program) {
return [path.dirname(program), path.basename(program)];
};
isOption = function(arg) {
var first;
first = arg[0];
return first === '-' || first === '/';
};
normalize = function(argv) {
var command, done, i, program, rest, _i, _ref;
program = fs.realpathSync(argv[1]);
command = [];
rest = [];
done = false;
for (i = _i = 2, _ref = argv.length; 2 <= _ref ? _i < _ref : _i > _ref; i = 2 <= _ref ? ++_i : --_i) {
if (done) {
rest.push(argv[i]);
} else if (isOption(argv[i])) {
done = true;
rest.push(argv[i]);
} else {
command.push(argv[i]);
}
}
if (command.length > 0 && command[0] === 'help') {
command.shift();
rest.push('--help');
}
return [program, command, rest];
};
isHelp = function(command) {
return command[0] === 'help';
};
spawn = function(program, argv, cb) {
loglet.debug('spawn.search', program, argv);
return search(program, argv, function(err, res) {
var child;
loglet.debug('spawn.search', err, res);
if (err) {
return cb(err);
} else if (res != null ? res.program : void 0) {
child = subproc.spawn(res.program, res.args, {
stdio: 'inherit'
});
child.on('exit', function(code) {
return process.exit(code);
});
return cb(null, child);
} else {
return cb({
error: 'subcommand_not_found',
args: res.args
});
}
});
};
searchHelper = function(dirPath, cb) {
var helper, whichHelper;
whichHelper = dirPath ? function(name, cb) {
var filePath;
filePath = path.join(dirPath, name);
return fs.stat(filePath, function(err, stat) {
if ((err != null ? err.code : void 0) === 'ENOENT') {
return cb({
file_not_found: filePath
});
} else if (err) {
return cb(err);
} else {
return cb(null, filePath);
}
});
} : function(name, cb) {
return which(name, function(err, cmd) {
loglet.debug('which.result', name, err, cmd, JSON.stringify(err));
if (err != null ? err.message.match(/not found\:/) : void 0) {
loglet.debug('which.result.not_found');
return cb({
file_not_found: name
});
} else if (err) {
return cb(err);
} else {
return cb(err, cmd);
}
});
};
helper = function(program, rest, prev) {
var name, seg;
loglet.debug('searchHelper.helper', program, rest, prev);
if (rest.length === 0) {
return cb(null, {
program: prev,
args: rest
});
}
seg = rest.shift();
name = [program, seg].join('-');
return whichHelper(name, function(err, cmd) {
loglet.debug('whichHelper', name, err, cmd);
if (err != null ? err.file_not_found : void 0) {
loglet.debug('whichHelper.not_found', name, prev);
if (prev) {
rest.unshift(seg);
return cb(null, {
program: prev,
args: rest
});
} else {
return cb(err);
}
} else if (err) {
return cb(err);
} else {
return helper(name, rest, cmd);
}
});
};
return helper;
};
_whichPath = function(program, commands, cb) {
var helper, programDir, programName, _ref;
_ref = split(program), programDir = _ref[0], programName = _ref[1];
loglet.debug('_whichPath.split', programDir, programName);
helper = searchHelper(null, cb);
return helper(programName, [].concat(commands), null);
};
_localPath = function(program, commands, cb) {
var helper, programDir, programName, _ref;
_ref = split(program), programDir = _ref[0], programName = _ref[1];
loglet.debug('_localPath.split', programDir, programName);
helper = searchHelper(programDir, cb);
return helper(programName, [].concat(commands), null);
};
search = function(program, argv, cb) {
var commands, rest, _ref;
if (arguments.length === 0) {
return cb({
error: 'invalid_call_need_3_params'
});
} else if (arguments.length === 1) {
cb = program;
argv = process.argv;
program = argv[1];
} else if (arguments.length === 2) {
cb = argv;
argv = program;
program = argv[1];
}
_ref = normalize(argv), program = _ref[0], commands = _ref[1], rest = _ref[2];
if (commands.length === 0) {
cb({
no_sub_command: program,
args: rest
});
}
return _localPath(program, commands, function(err, result) {
if (err != null ? err.file_not_found : void 0) {
return _whichPath(program, commands, function(err, result) {
if (err) {
return cb(err);
} else {
return cb(null, {
program: result.program,
args: result.args.concat(rest)
});
}
});
} else if (err) {
return cb(err);
} else {
return cb(null, {
program: result.program,
args: result.args.concat(rest)
});
}
});
};
getSubCommands = function(programPath, cb) {
var dirname, program;
dirname = path.dirname(programPath);
program = path.basename(programPath);
return fs.readdir(dirname, function(err, files) {
var commands, file, _i, _len;
if (err) {
return cb(err);
} else {
commands = {};
for (_i = 0, _len = files.length; _i < _len; _i++) {
file = files[_i];
if (file !== program && file.indexOf(program + '-') === 0) {
commands[file.substring(program.length + 1)] = path.join(dirname, file);
}
}
return cb(null, commands);
}
});
};
module.exports = {
which: search,
spawn: spawn
};
}).call(this);