From d77c99427b223a4c7a601de41451d5c6b4f78192 Mon Sep 17 00:00:00 2001 From: Louis DeJardin Date: Sun, 18 Mar 2012 23:37:46 -0700 Subject: [PATCH] Adding location prompt to create site Adding streamline package to keep async command code under control --- lib/cli/cli.js | 50 +++++-- lib/cli/commands/site.js | 303 +++++++++++++++++++++++--------------- lib/cli/commands/space.js | 4 +- package.json | 1 + 4 files changed, 224 insertions(+), 134 deletions(-) diff --git a/lib/cli/cli.js b/lib/cli/cli.js index 4e7056d0b..6a3fc0192 100644 --- a/lib/cli/cli.js +++ b/lib/cli/cli.js @@ -69,10 +69,10 @@ log.table = function (level, data, transform) { table.RightPadder = Table.RightPadder; table.padRight = Table.padRight; - if (data.forEach) { + if (data && data.forEach) { data.forEach(function (item) { transform(table, item); table.newLine(); }); } - else { + else if (data) { for (var item in data) { transform(table, item); table.newLine(); @@ -232,15 +232,47 @@ function helpOptions(cmd) { cmd.optionHelp().split('\n').forEach(function (line) { log.help(' ', line); }); } -var commandsPath = path.join(path.dirname(__filename), 'commands'); -var commandFiles = fs.readdirSync(commandsPath); +function harvestPlugins() { + function scan(scanPath) { + var results = fs.readdirSync(scanPath); -for (var i = 0; i < commandFiles.length; i++) { - var commandFile = path.join(commandsPath, commandFiles[i]); - if (!fs.statSync(commandFile).isFile()) { - continue; + results = results.filter(function (filePath) { + if (filePath.substring(0,5) === 'tmp--') { + return false; + } + if (filePath.substring(filePath.length - 4) === '_.js') { + return false; + } + return true; + }); + + // combine file path + results = results.map(function (fileName) { + return path.join(scanPath, fileName); + }); + + // skip directories + results = results.filter(function (filePath) { + return fs.statSync(filePath).isFile(); + }); + + // load modules + results = results.map(function (filePath) { + return require(filePath); + }); + + // look for exports.init + results = results.filter(function (entry) { + return entry.init !== undefined; + }); + return results; } - require(commandFile).init(cli); + + var basePath = path.dirname(__filename); + var plugins = scan(path.join(basePath, 'commands')); + plugins.forEach(function (plugin) { plugin.init(cli); }); } +harvestPlugins(); + exports = module.exports = cli; diff --git a/lib/cli/commands/site.js b/lib/cli/commands/site.js index ebb280b73..2b69d01d7 100644 --- a/lib/cli/commands/site.js +++ b/lib/cli/commands/site.js @@ -1,4 +1,6 @@ +if (!require('streamline/module')(module)) return; + var fs = require('fs'); var pfx2pem = require('../../util/certificates/pkcs').pfx2pem; var Channel = require('../channel'); @@ -22,6 +24,7 @@ exports.init = function (cli) { plan: 'VirtualDedicatedPlan' }, ]; + var regionPrompts = regions.map(function (region) { return region.prompt; }); function getChannel() { var pem = cli.category('account').managementCertificate(); @@ -45,23 +48,20 @@ exports.init = function (cli) { .description('List your web sites.') .option('-s, --subscription ', 'use the subscription id') .action(function (options) { + execute('site list', function(_) { + var parameters = { + subscription: cli.category('account').lookupSubscriptionId(options.subscription) + }; - log.info('Listing your web sites'); + var spaces = site.doSpacesGet(parameters, _); + var sites = site.doSitesGet(parameters, _); - var parameters = { - subscription: cli.category('account').lookupSubscriptionId(options.subscription) - }; - - site.doSitesGet( - parameters, - function (sites) { - log.table(sites, function (row, site) { - row.cell('Name', site.Name); - row.cell('State', site.State); - row.cell('Host names', clean(site).HostNames); - }); + log.table(sites, function (row, site) { + row.cell('Name', site.Name); + row.cell('State', site.State); + row.cell('Host names', clean(site).HostNames); }); - + }); }); @@ -70,88 +70,114 @@ exports.init = function (cli) { .option('-s, --subscription ', 'use the subscription id') .action(function (name, options) { - var parameters = { - subscription: cli.category('account').lookupSubscriptionId(options.subscription), - site: { - name: name - } - }; + execute('site show', function(_) { + var parameters = { + subscription: cli.category('account').lookupSubscriptionId(options.subscription), + site: { + name: name + } + }; - log.info('Showing details for site'); - log.verbose('Parameters', parameters); + log.info('Showing details for site'); + log.verbose('Parameters', parameters); - site.doSiteGet(parameters, function (siteData) { - site.doSiteConfigGet(parameters, function (configData) { - site.doRepositoryGet(parameters, function (repositoryData) { - logEachData('Site', siteData); - logEachData('Config', configData); - log.data('Repository', clean(repositoryData)); - }); - }); + var siteData = site.doSiteGet(parameters, _); + var configData = site.doSiteConfigGet(parameters, _); + var repositoryData = site.doRepositoryGet(parameters, _); + + logEachData('Site', siteData); + logEachData('Config', configData); + log.data('Repository', clean(repositoryData)); }); }); + function choose(data, callback) { + cli.choose(data, function(x) {callback(null,x);}); + } + + function execute(command, impl, _) { + log.info('Executing command ' + command.bold); + try { + impl(_); + cli.exit('info', command.bold + ' command ' + 'OK'.green.bold, 0); + } + catch(err) { + logError(err); + cli.exit('error', command.bold + ' command ' + 'failed'.red.bold, -1); + }; + } + site.command('create ') .description('Create a new web site and local directory.') .option('-s, --subscription ', 'use the subscription id') .option('--location ', 'the geographic region to create the website') .option('--hostname ', 'custom host name to use') .action(function (name, options) { + execute('site create', function(_) { - log.help('Choose a location'); - cli.choose(regions.map(function (x) { return x.prompt; }), function (regionIndex) { - - var parameters = { + var context = { subscription: cli.category('account').lookupSubscriptionId(options.subscription), site: { name: name, - webspace: regions[regionIndex].webspace, + webspace: options.location, hostname: options.hostname } }; - site.doSitesPost(parameters, function (err) { - if (err) { - return cli.exit('error', 'Command failed', -1); - } - site.doRepositoryPost(parameters, function (err) { - if (err) { - return cli.exit('error', 'Command failed', -1); - } - site.doRepositoryGet(parameters, function (err, repo) { - if (err) { - return cli.exit('error', 'Command failed', -1); - } - log.help('To start adding content to the website, type in the following:'); - log.help(' git init'); - log.help(' git add .'); - log.help(' git commit -m "initial commit"'); - log.help(' git remote add azure ' + repo + parameters.site.name + '.git'); - log.help(' git push azure master'); + if (context.site.webspace === undefined) { + log.help('Choose a region'); + context.site.webspace = regions[choose(regionPrompts, _)].webspace; + } - cli.exit('info', 'Success', 0); - }); - }); - }); - }); + site.doSitesPost(context, _); + site.doRepositoryPost(context, _); + var repo = site.doRepositoryGet(context, _); + log.help('To start adding content to the website, type in the following:'); + log.help(' git init'); + log.help(' git add .'); + log.help(' git commit -m "initial commit"'); + log.help(' git remote add azure ' + repo + context.site.name + '.git'); + log.help(' git push azure master'); + }); }); + function lookupSiteWebSpace(context, _) { + log.verbose('Attempting to locate site ', context.site.name); + var sites = site.doSitesGet(context, _); + for(var index in sites) { + if (sites[index].Name === context.site.name) { + log.verbose('Site located at ', sites[index].WebSpace); + context.site.webspace = sites[index].WebSpace; + } + } + if (context.site.webspace === undefined) { + throw new Error('Unable to locate site named ' + context.site.name); + } + } + site.command('delete ') .description('Delete a web site.') .option('-s, --subscription ', 'use the subscription id') .action(function (name, options) { + execute('site delete', function(_) { + var context = { + subscription: cli.category('account').lookupSubscriptionId(options.subscription), + site: { + name: name + } + }; - var subscription = cli.category('account').lookupSubscriptionId(options.subscription); + lookupSiteWebSpace(context, _); - - getChannel() - .path(subscription) - .path('services/webspaces/northeuropewebspace/sites/') - .path(name) - .DELETE(function (err, thing) { - console.log(thing); - }); + var result = getChannel() + .path(context.subscription) + .path('services/webspaces') + .path(context.site.webspace) + .path('sites') + .path(context.site.name) + .DELETE(_); + }); }); @@ -159,51 +185,68 @@ exports.init = function (cli) { .description('Start a web site.') .option('-s, --subscription ', 'use the subscription id') .action(function (name, options) { + execute('site start', function(_) { + + var context = { + subscription: cli.category('account').lookupSubscriptionId(options.subscription), + site: { + name: name + } + }; - var subscription = cli.category('account').lookupSubscriptionId(options.subscription); + lookupSiteWebSpace(context, _); - getChannel() - .path(subscription) - .path('services/webspaces/northeuropewebspace/sites/') - .path(name) - .header('Content-Type', 'application/xml') - .POST(function (req) { - req.write(''); - req.write(''); - req.write('Running'); - req.write(''); - req.write(''); + var result = getChannel() + .path(context.subscription) + .path('services/webspaces') + .path(context.site.webspace) + .path('sites') + .path(context.site.name) + .header('Content-Type', 'application/xml') + .POST(function (req) { + req.write(''); + req.write(''); + req.write('Running'); + req.write(''); + req.write(''); - req.end(); - }, function (err, thing) { - console.log(thing); - }); + req.end(); + }, _); + }); }); site.command('stop ') .description('Stop a web site.') .option('-s, --subscription ', 'use the subscription id') .action(function (name, options) { + execute('site start', function(_) { + + var context = { + subscription: cli.category('account').lookupSubscriptionId(options.subscription), + site: { + name: name + } + }; - var subscription = cli.category('account').lookupSubscriptionId(options.subscription); + lookupSiteWebSpace(context, _); + var result = getChannel() + .path(context.subscription) + .path('services/webspaces') + .path(context.site.webspace) + .path('sites') + .path(context.site.name) + .header('Content-Type', 'application/xml') + .POST(function (req) { + req.write(''); + req.write(''); + req.write('Stopped'); + req.write(''); + req.write(''); - getChannel() - .path(subscription) - .path('services/webspaces/northeuropewebspace/sites/') - .path(name) - .header('Content-Type', 'application/xml') - .PUT(function (req) { - req.write(''); - req.write(''); - req.write('Stopped'); - req.write(''); - req.write(''); - - req.end(); - }, function (err, thing) { - console.log(thing); - }); + req.end(); + }, _); + }); }); @@ -260,35 +303,45 @@ exports.init = function (cli) { }); }; - site.doSitesGet = function (options, callback) { + site.doSpacesGet = function (options, _) { log.verbose('Subscription', options.subscription); + var result = getChannel() + .path(options.subscription) + .path('services/webspaces/') + .GET(_); + + log.json('silly', result); + return toArray(result.WebSpace); + }; + + site.doSitesGet = function (options, _) { + log.verbose('Subscription', options.subscription); + + var spaces = site.doSpacesGet(options, _); + var channel = getChannel() .path(options.subscription) .path('services/webspaces'); - async.map( - regions, - function (region, result) { - channel - .path(region.webspace) + var result = async.map( + spaces, + function (webspace, _) { + return channel + .path(webspace.Name) .path('sites/') - .GET(result); + .GET(_); }, - function (err, result) { - if (err) { - logError('Failed to get site info', err); - } else { - var sites = []; - result.forEach(function (item) { - sites = sites.concat(toArray(item.Site)); - }); - result = sites; + _); - log.json('verbose', result); - } - callback(err, result); - }); + var sites = []; + result.forEach(function (item) { + sites = sites.concat(toArray(item.Site)); + }); + result = sites; + + log.json('verbose', sites); + return sites; }; site.doSiteGet = function (options, callback) { @@ -343,7 +396,7 @@ exports.init = function (cli) { } else { log.verbose('Repository', clean(result)); } - callback(err, result); + callback(err, clean(result)); }); }; @@ -415,7 +468,13 @@ exports.init = function (cli) { } function logError(message, err) { - log.error(message); + if (arguments.length == 1) { + err = message; + message = undefined; + } else { + log.error(message); + } + if (err) { if (err.message) { log.error(err.message); diff --git a/lib/cli/commands/space.js b/lib/cli/commands/space.js index d8bd664f4..cd95434be 100644 --- a/lib/cli/commands/space.js +++ b/lib/cli/commands/space.js @@ -30,7 +30,6 @@ exports.init = function (waz) { var subscription = cli.category('account').lookupSubscriptionId(options.subscription); getChannel() - .header('x-ms-version', '2011-02-25') .path(subscription) .path('services/webspaces') .path(name || '') @@ -68,8 +67,7 @@ exports.init = function (waz) { var subscription = options.subscription || waz.category('account').defaultSubscriptionId(); - channel - .header('x-ms-version', '2011-02-25') + getChannel() .path(subscription) .path('services/webspaces/') .header('Content-Type', 'application/xml') diff --git a/package.json b/package.json index aa7fc8e70..670a43eda 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "underscore.string": ">= 2.0.0", "tunnel": ">= 0.0.1", "async": ">= 0.1.18", + "streamline": "0.2.4", "commander": ">= 0.5.2", "winston": ">= 0.5.10", "colors": "0.x.x",