#!/usr/bin/env node
'use strict';
var pkg = require('../package.json');
var debug = require('debug')(pkg.name);
var log = require('verr-log')();
var app = require('commander');
var path = require('path');
var async = require('async');
var _ = require('lodash');
var core = require('any2api-core');
var specFile = 'apispec.json';
var defaultOutput = '.';
var scannerPrefix = 'any2api-scanner-';
var defaultModules = {
scanner: [
'any2api-scanner-chef',
'any2api-scanner-juju'
],
invoker: [
'any2api-invoker-chef',
'any2api-invoker-python',
'any2api-invoker-ruby',
'any2api-invoker-shell'
],
generator: [
'any2api-generator-rest',
'any2api-generator-soap'
]
};
var basePath = process.env.ANY2API_PATH;
if (!basePath) {
basePath = process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE;
if (!basePath) {
return console.error('ANY2API_PATH environment variable missing');
} else {
basePath = path.join(basePath, '.any2api');
}
}
core.init({ path: basePath, log: console.log });
var manageModules = function(args, callback) {
args.modules = _.uniq(args.modules);
if (!core[args.type + 's']) {
return callback(new Error('unknown module type: ' + args.type));
}
async.eachSeries(args.modules, core[args.type + 's']()[args.action], callback);
};
var debugPrintOptions = function() {
debug('output', app.output);
debug('scanner', app.scanner);
debug('retrieve', app.retrieve);
debug('copy', app.copy);
debug('generator', app.generator);
debug('skip-prepare', app.skipPrepare);
debug('interface', app.interface);
debug('impl-type', app.implType);
debug('impl-title', app.implTitle);
}
app.version(pkg.version)
.option('-o, --output
', 'set output directory (default: \'' + defaultOutput + '\')', defaultOutput)
.option('-S, --scanner ', 'select scanner to analyze executables')
.option('-r, --retrieve ', 'select protocol to retrieve remote executables (default: \'http\')')
//.option('-s, --subdir ', 'set subdir (rel. to output) of executable ' +
// '(default: \'executable\')', 'executable')
.option('-c, --copy', 'copy executables to output directory (disabled by default)')
.option('-G, --generator ', 'select generator to create API implementation')
.option('-s, --skip-prepare', 'skip preparing executables at buildtime')
.option('-i, --interface ', 'select kind of interface (default: \'rest\')', 'rest')
.option('-t, --impl-type ', 'select type of API implementation (default: \'node\')', 'node')
.option('--impl-title ', 'set title for API implementation');
app.command('install ')
.description('install given modules (name, dir, or URL)')
.action(function(type, modules) {
if (_.contains(modules, 'all')) {
modules = _.filter(modules, function(module) {
if (module === 'all') return false;
else return true;
});
modules = modules.concat(defaultModules[type]);
}
manageModules({ type: type, action: 'install', modules: modules }, log.error);
});
app.command('update ')
.description('update given modules (name)')
.action(function(type, modules) {
if (_.contains(modules, 'all')) modules = [ null ];
manageModules({ type: type, action: 'update', modules: modules }, log.error);
});
app.command('uninstall ')
.description('uninstall given modules (name)')
.action(function(type, modules) {
if (_.contains(modules, 'all')) modules = [ null ];
manageModules({ type: type, action: 'uninstall', modules: modules }, log.error);
});
app.command('scan ')
.description('scan executables (file, dir, or URL) and create API spec')
.action(function(executables) {
debugPrintOptions();
var scanCallback = function(err, apiSpec) {
log.error(err);
};
core.scan({ executables: executables,
outputPath: app.output,
scanner: app.scanner,
retrieve: app.retrieve,
copy: app.copy }, scanCallback);
});
app.command('gen ')
.description('generate API implementation based on API spec (file or dir)')
.action(function(specPath) {
debugPrintOptions();
var genCallback = function(err, apiSpec) {
log.error(err);
};
core.gen({ specPath: specPath,
outputPath: app.output,
generator: app.generator,
skipPrepare: app.skipPrepare,
interface: app.interface,
implType: app.implType,
implTitle: app.implTitle }, genCallback);
});
app.command('test ')
.description('test given API implementation (dir)')
.action(function(impl) {
console.error('not implemented yet');
//TODO: run npm test
});
/*
app.command('*')
.description('...')
.action(function(cmd) {
console.error('Command \'' + cmd + '\' not supported.');
app.outputHelp();
});
*/
app.parse(process.argv);
// print help by default
if (!process.argv.slice(2).length) {
app.outputHelp();
}