Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

[api doc] Finished up work on `jitsu help *` commands

  • Loading branch information...
commit c6305f814a52b92bcad9f92ac347a745177211df 1 parent f1ea9d7
@indexzero indexzero authored
View
19 lib/jitsu.js
@@ -36,7 +36,7 @@ jitsu.log = require('jitsu/log');
jitsu.api = {};
jitsu.api.Client = require('jitsu/api/client').Client;
jitsu.api.Apps = require('jitsu/api/apps').Apps;
-jitsu.api.Snapshots = require('jitsu/api/snapshots').Snapshots
+jitsu.api.Snapshots = require('jitsu/api/snapshots').Snapshots;
jitsu.api.Users = require('jitsu/api/users').Users;
jitsu.prompt = require('jitsu/prompt');
jitsu.config = require('jitsu/config');
@@ -80,18 +80,21 @@ jitsu.exec = function (command, callback) {
jitsu.setup();
}
- winston.info('Executing command ' + jitsu.commands.parse(command).splice(0,2).join(' ').magenta);
+ winston.info('Executing command ' + jitsu.commands.parse(command).splice(0, 2).join(' ').magenta);
jitsu.commands.run(command, function (err, shallow) {
if (err && !/403/.test(err.message)) {
- winston.error('Error running command ' + command.magenta);
- winston.error(err.message);
+ if (err && err.message) {
+ winston.error('Error running command ' + command.magenta);
+ winston.error(err.message);
+ }
if (err.stack && !shallow) {
err.stack.split('\n').forEach(function (trace) {
winston.error(trace);
- })
+ });
}
- return
+ winston.info('Nodejitsu '.grey + 'not ok'.red.bold);
+ return;
}
//
@@ -139,7 +142,7 @@ jitsu.auth = function (callback) {
winston.info('Authenticated as ' + jitsu.config.username.magenta);
callback();
});
-}
+};
//
// ### function setupUser (callback)
@@ -148,7 +151,7 @@ jitsu.auth = function (callback) {
// and saves the resulting configuration to disk.
//
jitsu.setupUser = function (callback) {
- winston.info('No user has been setup on this machine')
+ winston.info('No user has been setup on this machine');
jitsu.prompt.get(['username', 'password'], function (result) {
jitsu.config.settings.auth = [result.username, result.password].join(':');
jitsu.setup();
View
16 lib/jitsu/api/client.js
@@ -56,16 +56,18 @@ Client.prototype._request = function (method, uri /* variable arguments */) {
return callback(err);
}
+ var statusCode, result, error;
+
try {
- var statusCode = response.statusCode.toString(),
- result = JSON.parse(body);
+ statusCode = response.statusCode.toString();
+ result = JSON.parse(body);
}
catch (ex) {
// Ignore Errors
}
if (Object.keys(jitsu.failCodes).indexOf(statusCode) !== -1) {
- var error = new Error('Nodejitsu Error (' + statusCode + '): ' + jitsu.failCodes[statusCode]);
+ error = new Error('Nodejitsu Error (' + statusCode + '): ' + jitsu.failCodes[statusCode]);
error.result = result;
return callback(error);
}
@@ -105,16 +107,18 @@ Client.prototype._upload = function (uri, contentType, file, callback, success)
return callback(err);
}
+ var statusCode, result, error;
+
try {
- var statusCode = response.statusCode.toString(),
- result = JSON.parse(body);
+ statusCode = response.statusCode.toString();
+ result = JSON.parse(body);
}
catch (ex) {
// Ignore Errors
}
if (Object.keys(jitsu.failCodes).indexOf(statusCode) !== -1) {
- var error = new Error('Nodejitsu Error (' + statusCode + '): ' + jitsu.failCodes[statusCode]);
+ error = new Error('Nodejitsu Error (' + statusCode + '): ' + jitsu.failCodes[statusCode]);
error.result = result;
return callback(error);
}
View
12 lib/jitsu/commands.js
@@ -48,6 +48,10 @@ commands.run = function (command, callback) {
commands.commands.help.show(name);
return callback();
}
+ else if (name === 'help' && (!action || action === 'show')) {
+ commands.commands.help.show('help');
+ return callback();
+ }
if (!commands.commands[name]) {
return callback(new Error('Cannot run command on unknown resource: ' + name), true);
@@ -55,7 +59,9 @@ commands.run = function (command, callback) {
resource = commands.commands[name];
if (!resource[action]) {
- return callback(new Error('Cannot run unknown action ' + action + ' on resource ' + name), true);
+ winston.error('Unknown action ' + action + ' on resource ' + name.magenta);
+ commands.commands.help.show(name);
+ return callback(true);
}
//
@@ -81,10 +87,10 @@ commands.run = function (command, callback) {
//
expected = resource[action].length;
if (parts.length > expected) {
- return callback(new Error('Wrong number of arguments: ' + parts.length + ' for ' + expected), true)
+ return callback(new Error('Wrong number of arguments: ' + parts.length + ' for ' + expected), true);
}
- function runCommand () {
+ function runCommand() {
resource[action].apply(resource, parts);
}
View
166 lib/jitsu/commands/apps.js
@@ -27,7 +27,7 @@ apps.usage = [
'For commands that take a <name> parameter, if no parameter',
'is supplied, jitsu will attempt to read the package.json',
'from the current directory.'
-]
+];
//
// ### function list (callback)
@@ -45,7 +45,10 @@ apps.create = function (name, callback) {
pkg.name = name || pkg.name;
jitsu.apps.list(function (err, apps) {
- var existing = apps.filter(function (a) { return a.name === pkg.name });
+ var existing = apps.filter(function (a) {
+ return a.name === pkg.name;
+ });
+
if (existing.length > 0) {
return winston.warn('Cannot create duplicate application ' + pkg.name.magenta);
}
@@ -67,6 +70,18 @@ apps.create = function (name, callback) {
};
//
+// Usage for `jitsu apps create [<name>]`
+//
+apps.create.usage = [
+ 'Creates an application using the package.json file in the',
+ 'current directory, if <name> is supplied then this is used',
+ 'instead of the `name` property in the package.json file.',
+ '',
+ 'jitsu apps create',
+ 'jitsu apps create <name>'
+];
+
+//
// ### function list (callback)
// #### @callback {function} Continuation to pass control to when complete.
// Lists the applications for the authenticated user.
@@ -96,6 +111,15 @@ apps.list = function (callback) {
};
//
+// Usage for `jitsu apps list`
+//
+apps.list.usage = [
+ 'Lists all of the applications for the current user',
+ '',
+ 'jitsu apps list'
+];
+
+//
// ### function view (name, callback)
// #### @name {string} **optional** Name of the application to view
// #### @callback {function} Continuation to pass control to when complete.
@@ -103,15 +127,6 @@ apps.list = function (callback) {
// If no name is supplied this will view the application in the current directory.
//
apps.view = function (name, callback) {
- if (!callback) {
- callback = name;
- return jitsu.utils.readPackage(process.cwd(), function (err, package) {
- name = package.name;
- executeView();
- });
- }
-
-
function executeView() {
jitsu.apps.view(name, function (err, app) {
if (err) {
@@ -126,8 +141,28 @@ apps.view = function (name, callback) {
});
}
+ if (!callback) {
+ callback = name;
+ return jitsu.utils.readPackage(process.cwd(), function (err, pkg) {
+ name = pkg.name;
+ executeView();
+ });
+ }
+
executeView();
-}
+};
+
+//
+// Usage for `jitsu apps view [<name>]`
+//
+apps.view.usage = [
+ 'Lists the information for the application in the current',
+ 'directory. If <name> is supplied then that application',
+ 'is listed instead.',
+ '',
+ 'jitsu apps view',
+ 'jitsu apps view <name>'
+];
//
// ### function list (callback)
@@ -168,6 +203,18 @@ apps.update = function (name, callback) {
};
//
+// Usage for `jitsu apps update [<name>]`
+//
+apps.update.usage = [
+ 'Updates the application in the current directory',
+ 'with the information in the package.json file. If',
+ '<name> is supplied the application with <name> is updated.',
+ '',
+ 'jitsu apps update',
+ 'jitsu apps update <name>'
+];
+
+//
// ### function destroy (callback)
// #### @name {string} **optional** Name of the application to destroy.
// #### @callback {function} Continuation to pass control to when complete.
@@ -175,75 +222,108 @@ apps.update = function (name, callback) {
// this will destroy the application in the current directory.
//
apps.destroy = function (name, callback) {
- if (!callback) {
- callback = name;
- return jitsu.utils.readPackage(process.cwd(), function (err, package) {
- name = package.name;
- executeDestroy();
- });
- }
-
- function executeDestroy () {
+ function executeDestroy() {
winston.info('Destroying app ' + name.magenta);
jitsu.apps.destroy(name, function (err) {
winston.silly('Done destroying app ' + name.magenta);
return err ? callback(err) : callback();
});
}
+
+ if (!callback) {
+ callback = name;
+ return jitsu.utils.readPackage(process.cwd(), function (err, pkg) {
+ name = pkg.name;
+ executeDestroy();
+ });
+ }
executeDestroy();
};
//
+// Usage for `jitsu apps destroy [<name>]`
+//
+apps.destroy.usage = [
+ 'Destroys the application in the current directory. If',
+ '<name> is supplied then that application is destroyed instead',
+ '',
+ 'jitsu apps destroy',
+ 'jitsu apps destroy <name>'
+];
+
+//
// ### function start (callback)
// #### @name {string} **optional** Name of the application to start.
// #### @callback {function} Continuation to pass control to when complete.
// Starts the application specified by `name`. If no name is supplied
// this will start the application in the current directory.
//
-apps.start = function (name, callback) {
- if (!callback) {
- callback = name;
- return jitsu.utils.readPackage(process.cwd(), function (err, package) {
- name = package.name;
- executeStart();
- });
- }
-
- function executeStart () {
+apps.start = function (name, callback) {
+ function executeStart() {
winston.info('Starting app ' + name.magenta);
jitsu.apps.start(name, function (err) {
winston.info('App ' + name.magenta + ' is now started');
return err ? callback(err) : callback();
});
}
+
+ if (!callback) {
+ callback = name;
+ return jitsu.utils.readPackage(process.cwd(), function (err, pkg) {
+ name = pkg.name;
+ executeStart();
+ });
+ }
executeStart();
};
//
+// Usage for `jitsu apps start [<name>]`
+//
+apps.start.usage = [
+ 'Starts the application in the current directory. If <name>',
+ 'is supplied then that application is started instead.',
+ '',
+ 'jitsu apps start',
+ 'jitsu apps start <name>'
+];
+
+//
// ### function stop (callback)
// #### @name {string} **optional** Name of the application to stop.
// #### @callback {function} Continuation to pass control to when complete.
// Stops the application specified by `name`. If no name is supplied
// this will stop the application in the current directory.
//
-apps.stop = function (name, callback) {
- if (!callback) {
- callback = name;
- return jitsu.utils.readPackage(process.cwd(), function (err, package) {
- name = package.name;
- executeStop();
- });
- }
-
- function executeStop () {
+apps.stop = function (name, callback) {
+ function executeStop() {
winston.info('Stopping app ' + name.magenta);
jitsu.apps.stop(name, function (err) {
winston.info('App ' + name.magenta + ' is now stopped');
return err ? callback(err) : callback();
});
}
+
+ if (!callback) {
+ callback = name;
+ return jitsu.utils.readPackage(process.cwd(), function (err, pkg) {
+ name = pkg.name;
+ executeStop();
+ });
+ }
- executeStart();
-};
+ executeStop();
+};
+
+//
+// Usage for `jitsu apps stop [<name>]`
+//
+apps.stop.usage = [
+ 'Stops the application in the current directory. If <name>',
+ 'is supplied then that application is stopped instead.',
+ '',
+ 'jitsu apps stop',
+ 'jitsu apps stop <name>'
+];
View
72 lib/jitsu/commands/config.js
@@ -18,7 +18,7 @@ config.usage = [
'jitsu config list',
'jitsu config set <key> <value>',
'jitsu config get <key>',
- 'jitsu config delete <key>',
+ 'jitsu config delete <key>'
];
//
@@ -29,17 +29,40 @@ config.usage = [
// Sets the specified `key` in jitsu config to `value`.
//
config.set = function (key, value, callback) {
+ var args = Array.prototype.slice.call(arguments);
+ callback = args.pop();
+
+ if (args.length !== 2) {
+ winston.error('You must pass both <key> and <value>');
+ return callback(true, true);
+ }
+
jitsu.config.settings[key] = value;
jitsu.config.save(callback);
};
//
+// Usage for `jitsu config set <key> <value>`
+//
+config.set.usage = [
+ 'Sets the specified <key> <value> pair in the jitsu configuration',
+ '',
+ 'jitsu config set <key> <value>'
+];
+
+//
// ### function get (key, callback)
// #### @key {string} Key to get in jitsu config.
// #### @callback {function} Continuation to pass control to when complete
// Gets the specified `key` in jitsu config.
//
config.get = function (key, callback) {
+ if (!callback) {
+ callback = key;
+ winston.error('No configuration for ' + 'undefined'.magenta);
+ return callback(true, true);
+ }
+
if (!jitsu.config.settings[key]) {
return winston.error('No configuration value for ' + key.yellow);
}
@@ -49,19 +72,35 @@ config.get = function (key, callback) {
};
//
+// Usage for `jitsu config get <key>`
+//
+config.get.usage = [
+ 'Gets the value for the specified <key>',
+ 'in the jitsu configuration',
+ '',
+ 'jitsu config get <key>'
+];
+
+//
// ### function delete (key, callback)
// #### @key {string} Key to delete, in jitsu config.
// #### @callback {function} Continuation to pass control to when complete
// Deletes the specified `key` in jitsu config.
//
config.delete = function (key, callback) {
- if (!jitsu.config.settings[key]) {
- return winston.error('No configuration value for ' + key.yellow);
+ if (!callback) {
+ callback = key;
+ winston.error('No configuration for ' + 'undefined'.magenta);
+ return callback(true, true);
+ }
+ else if (!jitsu.config.settings[key]) {
+ winston.error('No configuration value for ' + key.yellow);
+ return callback(true, true);
}
else if (noDelete.indexOf(key) !== -1) {
winston.error('Cannot delete reserved setting ' + key.yellow);
- winston.error('Use jitsu config set <key> <value>');
- return;
+ winston.help('Use jitsu config set <key> <value>');
+ return callback(true, false);
}
delete jitsu.config.settings[key];
@@ -69,12 +108,21 @@ config.delete = function (key, callback) {
};
//
+// Usage for `jitsu config delete <key>`
+//
+config.delete.usage = [
+ 'Deletes the specified <key> in the jitsu configuration',
+ '',
+ 'jitsu config delete <key>'
+];
+
+//
// ### function list (callback)
// #### @callback {function} Continuation to pass control to when complete
// Lists all the key-value pairs in jitsu config.
//
config.list = function (callback) {
- function listObject (obj, prefix) {
+ function listObject(obj, prefix) {
prefix = prefix || '';
Object.keys(obj).forEach(function (key) {
if (Array.isArray(obj[key])) {
@@ -88,4 +136,14 @@ config.list = function (callback) {
listObject(jitsu.config.settings);
callback();
-};
+};
+
+//
+// Usage for `jitsu config list`
+//
+config.list.usage = [
+ 'Lists all configuration values currently',
+ 'set in the .jitsuconf file',
+ '',
+ 'jitsu config list'
+];
View
34 lib/jitsu/commands/help.js
@@ -5,11 +5,39 @@
*
*/
-var winston = require('winston'),
+var colors = require('colors'),
+ winston = require('winston'),
jitsu = require('jitsu');
var help = exports;
+help.usage = [
+ 'jitsu is the command-line interface (CLI) for interacting',
+ 'with the Nodejitsu platform. Commands are structured:',
+ '',
+ 'jitsu <resource> <action> <param1> <param2> ...',
+ '',
+ 'Resources:'.bold,
+ 'Valid resources for `jitsu` are:',
+ ' 1. ' + 'apps'.underline + ': Applications hosted on Nodejitsu',
+ ' 2. ' + 'snapshots'.underline + ': Images of your applications on Nodejitsu',
+ ' 3. ' + 'config'.underline + ': Configuration for the jitsu CLI',
+ '',
+ 'For help about a particular resource use: jitsu help <resource>',
+ 'and for help about a particular action use: jitsu help <resource> <action>',
+ ' e.g.',
+ ' jitsu help apps',
+ ' jitsu help snapshots list'
+];
+
+//
+// ### function show (name, action)
+// #### @name {string} Name of the resource to show help for
+// #### @action {string} Name of the action on the resource
+// Shows the help for the resource with the specified `name`.
+// If `action` is supplied, help for `jitsu <name> <action>`
+// is shown.
+//
help.show = function (name, action) {
var usage, resource = jitsu.commands.commands[name];
@@ -33,6 +61,10 @@ help.show = function (name, action) {
winston.help('');
};
+//
+// Setup exports for all relevant resources:
+// `apps`, `snapshots`, `config`.
+//
['apps', 'snapshots', 'config'].forEach(function (resource) {
help[resource] = function (action, callback) {
if (!callback) {
View
43 lib/jitsu/commands/snapshots.js
@@ -23,7 +23,7 @@ snapshots.usage = [
'For commands that take a <name> parameter, if no parameter',
'is supplied, jitsu will attempt to read the package.json',
'from the current directory.'
-]
+];
//
// ### function list (name, callback)
@@ -33,20 +33,12 @@ snapshots.usage = [
// If `name` is not supplied the value for name in `package.name` will be used.
//
snapshots.list = function (name, callback) {
- if (!callback) {
- callback = name;
- return jitsu.utils.readPackage(process.cwd(), function (err, package) {
- name = package.name;
- executeList();
- });
- }
-
- function executeList () {
+ function executeList() {
jitsu.snapshots.list(name, function (err, snapshots) {
if (err) {
return callback(err, true);
}
-
+
if (snapshots && snapshots.length > 0) {
var rows = [['filename', 'created', 'md5']],
colors = ['underline', 'yellow', 'grey'];
@@ -64,11 +56,19 @@ snapshots.list = function (name, callback) {
else {
winston.warn('No snapshots for application ' + name.magenta);
}
-
+
callback();
});
}
+ if (!callback) {
+ callback = name;
+ return jitsu.utils.readPackage(process.cwd(), function (err, pkg) {
+ name = pkg.name;
+ executeList();
+ });
+ }
+
executeList();
};
@@ -111,6 +111,12 @@ snapshots.create = function (name, callback) {
});
};
+snapshots.create.usage = [
+ 'Creates a snapshot for the application in the current directory',
+ '',
+ 'jitsu snapshots create'
+];
+
//
// ### function destroy (count, callback)
// #### @count {string} **optional** Number of snapshots to destroy
@@ -119,5 +125,16 @@ snapshots.create = function (name, callback) {
// directory. If `count` is not supplied one snapshot will be destroyed.
//
snapshots.destroy = function (count, callback) {
+ if (!callback) {
+ callback = count;
+ }
-};
+ callback(new Error('Sorry: Not implemented yet.'), true);
+};
+
+snapshots.destroy.usage = [
+ 'Destroys the latest snapshot for the application in the current directory',
+ '',
+ 'jitsu snapshots destroy',
+ 'jitsu snapshots destroy <count>'
+];
View
3  lib/jitsu/config.js
@@ -14,6 +14,7 @@ var config = exports, settings = config.settings = {
protocol: 'http',
remoteHost: 'localhost',
userconfig: '.jitsuconf',
+ loglevel: 'info',
tmproot: '/tmp',
tar: 'tar',
gzipbin: 'gzip'
@@ -24,7 +25,7 @@ var config = exports, settings = config.settings = {
//
Object.defineProperty(config.settings, 'remoteUri', {
get: function () {
- var port = this.port ? ':' + this.port : ''
+ var port = this.port ? ':' + this.port : '';
return [this.protocol, '://', this.remoteHost, port].join('');
}
});
View
12 lib/jitsu/log.js
@@ -31,7 +31,7 @@ log.columnMajor = function (rows) {
var columns = [];
rows.forEach(function (row) {
- for (var i = 0; i < row.length; i++) {
+ for (var i = 0; i < row.length; i += 1) {
if (!columns[i]) {
columns[i] = [];
}
@@ -50,8 +50,8 @@ log.columnMajor = function (rows) {
// of an array in the set provided.
//
log.arrayLengths = function (arrs) {
- var lengths = [];
- for (var i = 0; i < arrs.length; i++) {
+ var i, lengths = [];
+ for (i = 0; i < arrs.length; i += 1) {
lengths.push(winston.longestElement(arrs[i]));
}
@@ -71,9 +71,9 @@ log.stringifyRows = function (rows, colors) {
columns = log.columnMajor(rows);
lengths = log.arrayLengths(columns);
- function stringifyRow (row, colorize) {
- var rowtext = '', padding, item;
- for (var i = 0; i < row.length; i++) {
+ function stringifyRow(row, colorize) {
+ var rowtext = '', padding, item, i;
+ for (i = 0; i < row.length; i += 1) {
item = colorize ? row[i][colors[i]] : row[i];
padding = row[i].length < lengths[i] ? lengths[i] - row[i].length + 2 : 2;
rowtext += item + new Array(padding).join(' ');
View
23 lib/jitsu/utils/index.js
@@ -24,7 +24,7 @@ utils.base64 = require('./base64');
//
utils.snapshotTime = function (name) {
var time = name.match(/[\w|\-]+-[\w|\-]+-(\d+)/)[1];
- return utils.formatTime(new Date(parseInt(time)));
+ return utils.formatTime(new Date(parseInt(time, 10)));
};
//
@@ -75,19 +75,22 @@ utils.createPackage = function (dir, callback) {
return callback(err);
}
- if (dir.slice(-1) === '/') dir = dir.slice(0, -1);
+ if (dir.slice(-1) === '/') {
+ dir = dir.slice(0, -1);
+ }
+
var parent = path.dirname(dir),
base = path.basename(dir),
tarball = path.join(jitsu.config.settings.tmproot, [jitsu.config.username, pkg.name, Date.now()].join('-') + '.tgz'),
target = fs.createWriteStream(tarball),
- tarargs = ['-cvf', '-', '--exclude', '.git', '-C', parent, base];
+ tarargs = ['-cvf', '-', '--exclude', '.git', '-C', parent, base],
+ tar, gzip, errState;
//
// TODO (indexzero) Support for `.jitsuignore` files and support for package.json files
//
- var tar = spawn(jitsu.config.settings.tar, tarargs),
- gzip = spawn(jitsu.config.settings.gzipbin, ["--stdout"]),
- errState;
+ tar = spawn(jitsu.config.settings.tar, tarargs);
+ gzip = spawn(jitsu.config.settings.gzipbin, ["--stdout"]);
//
// TODO (indexzero) Make this piping more robust
@@ -97,10 +100,10 @@ utils.createPackage = function (dir, callback) {
target.on("close", function (err, ok) {
if (errState) {
- return
+ return;
}
else if (err) {
- return callback(errState = err)
+ return callback(errState = err);
}
callback(null, pkg, tarball);
@@ -154,7 +157,7 @@ utils.objectDiff = function (current, update, level) {
}
ukeys.forEach(function (key) {
- var nested;
+ var nested, i;
if (!current[key]) {
diff[key] = update[key];
@@ -164,7 +167,7 @@ utils.objectDiff = function (current, update, level) {
diff[key] = update[key];
}
else {
- for (var i = 0; i < update[key]; i++) {
+ for (i = 0; i < update[key]; i += 1) {
if (current[key].indexOf(update[key][i]) === -1) {
diff[key] = update[key];
break;
Please sign in to comment.
Something went wrong with that request. Please try again.