Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

[api] More work on app and snapshot commands

  • Loading branch information...
commit d51860b4a63de687939b303e3764f7f16cb0ef51 1 parent a183338
@indexzero indexzero authored
View
16 lib/jitsu/api/apps.js
@@ -47,6 +47,18 @@ Apps.prototype.create = function (app, callback) {
};
//
+// ### function view (name, callback)
+// #### @name {string} Name of the application to view
+// #### @callback {function} Continuation to pass control to when complete
+// Views the application specified by `name`.
+//
+Apps.prototype.view = function (name, callback) {
+ this._request('GET', ['apps', jitsu.config.username, name], callback, function (res, result) {
+ callback(null, result.app);
+ });
+};
+
+//
// ### function update (name, attrs, callback)
// #### @name {string} Name of the application to update
// #### @attrs {Object} Attributes to update for this application.
@@ -54,8 +66,8 @@ Apps.prototype.create = function (app, callback) {
// Updates the application with `name` with the specified attributes in `attrs`
//
Apps.prototype.update = function (name, attrs, callback) {
- this._request('PUT', ['apps', name], attrs, callback, function (res, result) {
-
+ this._request('PUT', ['apps', jitsu.config.username, name], attrs, callback, function (res, result) {
+ callback();
});
};
View
119 lib/jitsu/commands/apps.js
@@ -5,13 +5,51 @@
*
*/
-var winston = require('winston'),
+var eyes = require('eyes'),
+ winston = require('winston'),
jitsu = require('jitsu');
var apps = exports;
//
// ### function list (callback)
+// #### @name {string} **optional** Name of the application to create
+// #### @callback {function} Continuation to pass control to when complete.
+// Creates an application for the package.json in the current directory
+// using `name` if supplied and falling back to `package.name`.
+//
+apps.create = function (name, callback) {
+ jitsu.utils.readPackage(process.cwd(), function (err, pkg) {
+ if (!callback) {
+ callback = name;
+ name = null;
+ }
+
+ pkg.name = name || pkg.name;
+ jitsu.apps.list(function (err, apps) {
+ 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);
+ }
+
+ //
+ // TODO (indexzero): Configure this default value in nodejitsu APIs
+ //
+ pkg.state = 'stopped';
+ winston.info('Validating package.json for ' + pkg.name.magenta);
+ jitsu.prompt.addProperties(pkg, ['subdomain'], function (updated) {
+ winston.info('Creating app ' + pkg.name.magenta);
+ jitsu.apps.create(updated, function (err, res, result) {
+ winston.silly('Done creating app ' + pkg.name.magenta);
+ return err ? callback(err) : callback();
+ });
+ });
+ });
+ });
+};
+
+//
+// ### function list (callback)
// #### @callback {function} Continuation to pass control to when complete.
// Lists the applications for the authenticated user.
//
@@ -40,41 +78,38 @@ apps.list = function (callback) {
};
//
-// ### function list (callback)
-// #### @name {string} **optional** Name of the application to create
+// ### function view (name, callback)
+// #### @name {string} **optional** Name of the application to view
// #### @callback {function} Continuation to pass control to when complete.
-// Creates an application for the package.json in the current directory
-// using `name` if supplied and falling back to `package.name`.
+// Views the application with the specfied `name` for the authenticated user.
+// If no name is supplied this will view the application in the current directory.
//
-apps.create = function (name, callback) {
- jitsu.utils.readPackage(process.cwd(), function (err, pkg) {
- if (!callback) {
- callback = name;
- name = null;
- }
-
- pkg.name = name || pkg.name;
- jitsu.apps.list(function (err, apps) {
- 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);
+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) {
+ return callback(err);
}
//
- // TODO (indexzero): Configure this default value in nodejitsu APIs
+ // TODO (indexzero): Better object inspection
//
- pkg.state = 'stopped';
- winston.info('Validating package.json for ' + pkg.name.magenta);
- jitsu.prompt.addProperties(pkg, ['subdomain'], function (updated) {
- winston.info('Creating app ' + pkg.name.magenta);
- jitsu.apps.create(updated, function (err, res, result) {
- winston.silly('Done creating app ' + pkg.name.magenta);
- return err ? callback(err) : callback();
- });
- });
+ eyes.inspect(app);
+ callback();
});
- });
-};
+ }
+
+ executeView();
+}
//
// ### function list (callback)
@@ -85,9 +120,33 @@ apps.create = function (name, callback) {
apps.update = function (name, callback) {
if (!callback) {
callback = name;
+ name = null;
}
-
+ winston.silly('Reading package.json in ' + process.cwd());
+ jitsu.utils.readPackage(process.cwd(), function (err, pkg) {
+ if (err) {
+ return callback(err);
+ }
+
+ name = name || pkg.name;
+ jitsu.apps.view(name, function (err, app) {
+ if (err) {
+ return callback(err);
+ }
+
+ var diff = jitsu.utils.objectDiff(app, pkg);
+ if (!diff) {
+ winston.warn('No changes found to your package.json for ' + name.magenta);
+ return callback();
+ }
+
+ winston.info('Updating application ' + name.magenta + ' with:');
+ eyes.inspect(diff);
+
+ jitsu.apps.update(name, diff, callback);
+ });
+ });
};
//
View
30 lib/jitsu/commands/snapshots.js
@@ -28,18 +28,28 @@ snapshots.list = function (name, callback) {
function executeList () {
jitsu.snapshots.list(name, function (err, snapshots) {
- var rows = [['filename', 'created', 'md5']],
- colors = ['underline', 'yellow', 'grey'];
+ if (err) {
+ return callback(err);
+ }
+
+ if (snapshots && snapshots.length > 0) {
+ var rows = [['filename', 'created', 'md5']],
+ colors = ['underline', 'yellow', 'grey'];
- snapshots.forEach(function (snap) {
- rows.push([
- snap.filename,
- jitsu.utils.snapshotTime(snap.filename),
- snap.md5
- ]);
- });
+ snapshots.forEach(function (snap) {
+ rows.push([
+ snap.filename,
+ jitsu.utils.snapshotTime(snap.filename),
+ snap.md5
+ ]);
+ });
- jitsu.log.logRows('data', rows, colors);
+ jitsu.log.logRows('data', rows, colors);
+ }
+ else {
+ winston.warn('No snapshots for application ' + name.magenta);
+ }
+
callback();
});
}
View
80 lib/jitsu/utils/index.js
@@ -7,6 +7,7 @@
var jitsu = require('jitsu'),
util = require('util'),
+ eyes = require('eyes'),
spawn = require('child_process').spawn,
fs = require('fs'),
path = require('path');
@@ -105,4 +106,83 @@ utils.createPackage = function (dir, callback) {
callback(null, pkg, tarball);
});
});
+};
+
+//
+// ### function missingKeys (source, target)
+// #### @source {Array} List of keys for the current object
+// #### @target {Array} List of keys for the new object
+// Returns the complement of the intersection of the two arrays.
+//
+// e.g. [1,2,3,5], [1,2,3,4,5] => [4]
+//
+utils.missingKeys = function (source, target) {
+ var missing = [];
+
+ source.forEach(function (key) {
+ if (target.indexOf(key) === -1) {
+ missing.push(key);
+ }
+ });
+
+ return missing;
+};
+
+//
+// ### function objectDiff (current, update, level)
+// #### @current {Object} Current representation of the object.
+// #### @update {Object} Updated representation of the object.
+// #### @level {Number} Level in the object we are diffing.
+// Returns an incremental diff of the `current` object
+// against the updated representation `update`
+//
+// e.g. { foo: 1, bar: 2 }, { foo: 2, bar: 2 } => { foo: 2 }
+//
+utils.objectDiff = function (current, update, level) {
+ var ckeys = Object.keys(current),
+ ukeys = Object.keys(update),
+ diff = {};
+
+ //
+ // Ignore changes on the first level of the object.
+ //
+ level = level || 0;
+ if (level > 0) {
+ utils.missingKeys(ckeys, ukeys).forEach(function (key) {
+ diff[key] = undefined;
+ });
+ }
+
+ ukeys.forEach(function (key) {
+ var nested;
+
+ if (!current[key]) {
+ diff[key] = update[key];
+ }
+ else if (Array.isArray(update[key])) {
+ if (update[key].length !== current[key].length) {
+ diff[key] = update[key];
+ }
+ else {
+ for (var i = 0; i < update[key]; i++) {
+ if (current[key].indexOf(update[key][i]) === -1) {
+ diff[key] = update[key];
+ break;
+ }
+ }
+ }
+ }
+ else if (typeof update[key] === 'object') {
+ if ((nested = utils.objectDiff(current[key], update[key], level + 1))) {
+ diff[key] = update[key];
+ }
+ }
+ else {
+ if (current[key] !== update[key]) {
+ diff[key] = update[key];
+ }
+ }
+ });
+
+ return Object.keys(diff).length > 0 ? diff : null;
};
Please sign in to comment.
Something went wrong with that request. Please try again.