Inject analytics in Capitano

This commit is contained in:
Juan Cruz Viotti 2016-02-12 14:34:16 -04:00
parent 36a8179e0c
commit 356d2ef6b2
15 changed files with 105 additions and 151 deletions

View File

@ -35,9 +35,8 @@ limitations under the License.
permission: 'user',
primary: true,
action: function(params, options, done) {
var events, patterns, resin;
var patterns, resin;
resin = require('resin-sdk');
events = require('resin-cli-events');
patterns = require('../utils/patterns');
return resin.models.application.has(params.name).then(function(hasApplication) {
if (hasApplication) {
@ -48,10 +47,7 @@ limitations under the License.
}).then(function(deviceType) {
return resin.models.application.create(params.name, deviceType);
}).then(function(application) {
console.info("Application created: " + application.app_name + " (" + application.device_type + ", id " + application.id + ")");
return events.send('application.create', {
application: application.id
});
return console.info("Application created: " + application.app_name + " (" + application.device_type + ", id " + application.id + ")");
}).nodeify(done);
}
};
@ -79,15 +75,11 @@ limitations under the License.
permission: 'user',
primary: true,
action: function(params, options, done) {
var events, resin, visuals;
var resin, visuals;
resin = require('resin-sdk');
visuals = require('resin-cli-visuals');
events = require('resin-cli-events');
return resin.models.application.get(params.name).then(function(application) {
console.log(visuals.table.vertical(application, ["$" + application.app_name + "$", 'id', 'device_type', 'git_repository', 'commit']));
return events.send('application.open', {
application: application.id
});
return console.log(visuals.table.vertical(application, ["$" + application.app_name + "$", 'id', 'device_type', 'git_repository', 'commit']));
}).nodeify(done);
}
};
@ -111,18 +103,11 @@ limitations under the License.
options: [commandOptions.yes],
permission: 'user',
action: function(params, options, done) {
var events, patterns, resin;
var patterns, resin;
resin = require('resin-sdk');
events = require('resin-cli-events');
patterns = require('../utils/patterns');
return patterns.confirm(options.yes, 'Are you sure you want to delete the application?').then(function() {
return resin.models.application.remove(params.name);
}).tap(function() {
return resin.models.application.get(params.name).then(function(application) {
return events.send('application.delete', {
application: application.id
});
});
}).nodeify(done);
}
};

View File

@ -50,12 +50,11 @@ limitations under the License.
],
primary: true,
action: function(params, options, done) {
var Promise, _, auth, capitano, events, form, login, messages, patterns, resin;
var Promise, _, auth, capitano, form, login, messages, patterns, resin;
_ = require('lodash');
Promise = require('bluebird');
capitano = Promise.promisifyAll(require('capitano'));
resin = require('resin-sdk');
events = require('resin-cli-events');
auth = require('resin-cli-auth');
form = require('resin-cli-form');
patterns = require('../utils/patterns');
@ -91,7 +90,6 @@ limitations under the License.
console.log("\nLogging in to " + resinUrl);
return login(options);
}).then(resin.auth.whoami).tap(function(username) {
events.send('user.login');
console.info("Successfully logged in as: " + username);
return console.info("\nNow what?\n\n" + messages.gettingStarted + "\n\nFind out about more super powers by running:\n\n $ resin help\n\n" + messages.reachingOut);
}).nodeify(done);
@ -104,12 +102,9 @@ limitations under the License.
help: 'Use this command to logout from your resin.io account.o\n\nExamples:\n\n $ resin logout',
permission: 'user',
action: function(params, options, done) {
var events, resin;
var resin;
resin = require('resin-sdk');
events = require('resin-cli-events');
return resin.auth.logout().then(function() {
return events.send('user.logout');
}).nodeify(done);
return resin.auth.logout().nodeify(done);
}
};
@ -118,10 +113,9 @@ limitations under the License.
description: 'signup to resin.io',
help: 'Use this command to signup for a resin.io account.\n\nIf signup is successful, you\'ll be logged in to your new user automatically.\n\nExamples:\n\n $ resin signup\n Email: me@mycompany.com\n Username: johndoe\n Password: ***********\n\n $ resin whoami\n johndoe',
action: function(params, options, done) {
var events, form, resin, validation;
var form, resin, validation;
resin = require('resin-sdk');
form = require('resin-cli-form');
events = require('resin-cli-events');
validation = require('../utils/validation');
return resin.settings.get('resinUrl').then(function(resinUrl) {
console.log("\nRegistering to " + resinUrl);
@ -142,9 +136,7 @@ limitations under the License.
validate: validation.validatePassword
}
]);
}).then(resin.auth.register).then(resin.auth.loginWithToken).tap(function() {
return events.send('user.signup');
}).nodeify(done);
}).then(resin.auth.register).then(resin.auth.loginWithToken).nodeify(done);
}
};

View File

@ -55,17 +55,13 @@ limitations under the License.
permission: 'user',
primary: true,
action: function(params, options, done) {
var events, resin, visuals;
var resin, visuals;
resin = require('resin-sdk');
visuals = require('resin-cli-visuals');
events = require('resin-cli-events');
return resin.models.device.get(params.uuid).then(function(device) {
return resin.models.device.getStatus(device).then(function(status) {
device.status = status;
console.log(visuals.table.vertical(device, ["$" + device.name + "$", 'id', 'device_type', 'status', 'is_online', 'ip_address', 'application_name', 'last_seen', 'uuid', 'commit', 'supervisor_version', 'is_web_accessible', 'note']));
return events.send('device.open', {
device: device.uuid
});
return console.log(visuals.table.vertical(device, ["$" + device.name + "$", 'id', 'device_type', 'status', 'is_online', 'ip_address', 'application_name', 'last_seen', 'uuid', 'commit', 'supervisor_version', 'is_web_accessible', 'note']));
});
}).nodeify(done);
}
@ -106,16 +102,11 @@ limitations under the License.
options: [commandOptions.yes],
permission: 'user',
action: function(params, options, done) {
var events, patterns, resin;
var patterns, resin;
resin = require('resin-sdk');
events = require('resin-cli-events');
patterns = require('../utils/patterns');
return patterns.confirm(options.yes, 'Are you sure you want to delete the device?').then(function() {
return resin.models.device.remove(params.uuid);
}).tap(function() {
return events.send('device.delete', {
device: params.uuid
});
}).nodeify(done);
}
};
@ -138,11 +129,10 @@ limitations under the License.
help: 'Use this command to rename a device.\n\nIf you omit the name, you\'ll get asked for it interactively.\n\nExamples:\n\n $ resin device rename 7cf02a6\n $ resin device rename 7cf02a6 MyPi',
permission: 'user',
action: function(params, options, done) {
var Promise, _, events, form, resin;
var Promise, _, form, resin;
Promise = require('bluebird');
_ = require('lodash');
resin = require('resin-sdk');
events = require('resin-cli-events');
form = require('resin-cli-form');
return Promise["try"](function() {
if (!_.isEmpty(params.newName)) {
@ -152,11 +142,7 @@ limitations under the License.
message: 'How do you want to name this device?',
type: 'input'
});
}).then(_.partial(resin.models.device.rename, params.uuid)).tap(function() {
return events.send('device.rename', {
device: params.uuid
});
}).nodeify(done);
}).then(_.partial(resin.models.device.rename, params.uuid)).nodeify(done);
}
};

View File

@ -68,21 +68,14 @@ limitations under the License.
options: [commandOptions.yes, commandOptions.booleanDevice],
permission: 'user',
action: function(params, options, done) {
var events, patterns, resin;
var patterns, resin;
resin = require('resin-sdk');
events = require('resin-cli-events');
patterns = require('../utils/patterns');
return patterns.confirm(options.yes, 'Are you sure you want to delete the environment variable?').then(function() {
if (options.device) {
resin.models.environmentVariables.device.remove(params.id);
return events.send('deviceEnvironmentVariable.delete', {
id: params.id
});
return resin.models.environmentVariables.device.remove(params.id);
} else {
resin.models.environmentVariables.remove(params.id);
return events.send('environmentVariable.delete', {
id: params.id
});
return resin.models.environmentVariables.remove(params.id);
}
}).nodeify(done);
}
@ -95,10 +88,9 @@ limitations under the License.
options: [commandOptions.optionalApplication, commandOptions.optionalDevice],
permission: 'user',
action: function(params, options, done) {
var Promise, events, resin;
var Promise, resin;
Promise = require('bluebird');
resin = require('resin-sdk');
events = require('resin-cli-events');
return Promise["try"](function() {
if (params.value == null) {
params.value = process.env[params.key];
@ -109,19 +101,9 @@ limitations under the License.
}
}
if (options.application != null) {
return resin.models.environmentVariables.create(options.application, params.key, params.value).then(function() {
return resin.models.application.get(options.application).then(function(application) {
return events.send('environmentVariable.create', {
application: application.id
});
});
});
return resin.models.environmentVariables.create(options.application, params.key, params.value);
} else if (options.device != null) {
return resin.models.environmentVariables.device.create(options.device, params.key, params.value).then(function() {
return events.send('deviceEnvironmentVariable.create', {
device: options.device
});
});
return resin.models.environmentVariables.device.create(options.device, params.key, params.value);
} else {
throw new Error('You must specify an application or device');
}
@ -136,23 +118,14 @@ limitations under the License.
permission: 'user',
options: [commandOptions.booleanDevice],
action: function(params, options, done) {
var Promise, events, resin;
var Promise, resin;
Promise = require('bluebird');
resin = require('resin-sdk');
events = require('resin-cli-events');
return Promise["try"](function() {
if (options.device) {
return resin.models.environmentVariables.device.update(params.id, params.value).then(function() {
return events.send('deviceEnvironmentVariable.edit', {
id: params.id
});
});
return resin.models.environmentVariables.device.update(params.id, params.value);
} else {
return resin.models.environmentVariables.update(params.id, params.value).then(function() {
return events.send('environmentVariable.edit', {
id: params.id
});
});
return resin.models.environmentVariables.update(params.id, params.value);
}
}).nodeify(done);
}

View File

@ -58,16 +58,11 @@ limitations under the License.
options: [commandOptions.yes],
permission: 'user',
action: function(params, options, done) {
var events, patterns, resin;
var patterns, resin;
resin = require('resin-sdk');
events = require('resin-cli-events');
patterns = require('../utils/patterns');
return patterns.confirm(options.yes, 'Are you sure you want to delete the key?').then(function() {
return resin.models.key.remove(params.id);
}).tap(function() {
return events.send('publicKey.delete', {
id: params.id
});
}).nodeify(done);
}
};
@ -78,13 +73,12 @@ limitations under the License.
help: 'Use this command to associate a new SSH key with your account.\n\nIf `path` is omitted, the command will attempt\nto read the SSH key from stdin.\n\nExamples:\n\n $ resin key add Main ~/.ssh/id_rsa.pub\n $ cat ~/.ssh/id_rsa.pub | resin key add Main',
permission: 'user',
action: function(params, options, done) {
var Promise, _, capitano, events, fs, resin;
var Promise, _, capitano, fs, resin;
_ = require('lodash');
Promise = require('bluebird');
fs = Promise.promisifyAll(require('fs'));
capitano = require('capitano');
resin = require('resin-sdk');
events = require('resin-cli-events');
return Promise["try"](function() {
if (params.path != null) {
return fs.readFileAsync(params.path, {
@ -96,9 +90,7 @@ limitations under the License.
return callback(null, data);
});
});
}).then(_.partial(resin.models.key.create, params.name)).tap(function() {
return events.send('publicKey.create');
}).nodeify(done);
}).then(_.partial(resin.models.key.create, params.name)).nodeify(done);
}
};

View File

@ -16,7 +16,7 @@ limitations under the License.
*/
(function() {
var Promise, _, actions, capitano, errors, plugins, resin, update;
var Promise, _, actions, capitano, errors, events, plugins, resin, update;
_ = require('lodash');
@ -30,6 +30,8 @@ limitations under the License.
errors = require('./errors');
events = require('./events');
plugins = require('./utils/plugins');
update = require('./utils/update');
@ -130,7 +132,9 @@ limitations under the License.
plugins.register(/^resin-plugin-(.+)$/).then(function() {
var cli;
cli = capitano.parse(process.argv);
return events.trackCommand(cli).then(function() {
return capitano.executeAsync(cli);
});
})["catch"](errors.handle);
}).call(this);

37
build/events.js Normal file
View File

@ -0,0 +1,37 @@
(function() {
var Mixpanel, Promise, _, packageJSON, resin;
_ = require('lodash');
Mixpanel = require('mixpanel');
Promise = require('bluebird');
resin = require('resin-sdk');
packageJSON = require('../package.json');
exports.getLoggerInstance = _.memoize(function() {
return resin.models.config.getMixpanelToken().then(Mixpanel.init);
});
exports.trackCommand = function(capitanoCommand) {
return Promise.props({
resinUrl: resin.settings.get('resinUrl'),
username: resin.auth.whoami(),
mixpanel: exports.getLoggerInstance()
}).then(function(data) {
return data.mixpanel.track("[CLI] " + capitanoCommand.command, {
distinct_id: data.username,
argv: process.argv.join(' '),
version: packageJSON.version,
node: process.version,
arch: process.arch,
resinUrl: data.resinUrl,
platform: process.platform,
command: capitanoCommand
});
});
};
}).call(this);

View File

@ -46,7 +46,6 @@ exports.create =
primary: true
action: (params, options, done) ->
resin = require('resin-sdk')
events = require('resin-cli-events')
patterns = require('../utils/patterns')
# Validate the the application name is available
@ -62,7 +61,6 @@ exports.create =
return resin.models.application.create(params.name, deviceType)
.then (application) ->
console.info("Application created: #{application.app_name} (#{application.device_type}, id #{application.id})")
events.send('application.create', application: application.id)
.nodeify(done)
exports.list =
@ -109,7 +107,6 @@ exports.info =
action: (params, options, done) ->
resin = require('resin-sdk')
visuals = require('resin-cli-visuals')
events = require('resin-cli-events')
resin.models.application.get(params.name).then (application) ->
console.log visuals.table.vertical application, [
@ -119,7 +116,6 @@ exports.info =
'git_repository'
'commit'
]
events.send('application.open', application: application.id)
.nodeify(done)
exports.restart =
@ -155,12 +151,8 @@ exports.remove =
permission: 'user'
action: (params, options, done) ->
resin = require('resin-sdk')
events = require('resin-cli-events')
patterns = require('../utils/patterns')
patterns.confirm(options.yes, 'Are you sure you want to delete the application?').then ->
resin.models.application.remove(params.name)
.tap ->
resin.models.application.get(params.name).then (application) ->
events.send('application.delete', application: application.id)
.nodeify(done)

View File

@ -75,7 +75,6 @@ exports.login =
Promise = require('bluebird')
capitano = Promise.promisifyAll(require('capitano'))
resin = require('resin-sdk')
events = require('resin-cli-events')
auth = require('resin-cli-auth')
form = require('resin-cli-form')
patterns = require('../utils/patterns')
@ -110,8 +109,6 @@ exports.login =
return login(options)
.then(resin.auth.whoami)
.tap (username) ->
events.send('user.login')
console.info("Successfully logged in as: #{username}")
console.info """
@ -140,11 +137,7 @@ exports.logout =
permission: 'user'
action: (params, options, done) ->
resin = require('resin-sdk')
events = require('resin-cli-events')
resin.auth.logout().then ->
events.send('user.logout')
.nodeify(done)
resin.auth.logout().nodeify(done)
exports.signup =
signature: 'signup'
@ -167,7 +160,6 @@ exports.signup =
action: (params, options, done) ->
resin = require('resin-sdk')
form = require('resin-cli-form')
events = require('resin-cli-events')
validation = require('../utils/validation')
resin.settings.get('resinUrl').then (resinUrl) ->
@ -191,8 +183,6 @@ exports.signup =
.then(resin.auth.register)
.then(resin.auth.loginWithToken)
.tap ->
events.send('user.signup')
.nodeify(done)
exports.whoami =

View File

@ -76,7 +76,6 @@ exports.info =
action: (params, options, done) ->
resin = require('resin-sdk')
visuals = require('resin-cli-visuals')
events = require('resin-cli-events')
resin.models.device.get(params.uuid).then (device) ->
@ -98,8 +97,6 @@ exports.info =
'is_web_accessible'
'note'
]
events.send('device.open', device: device.uuid)
.nodeify(done)
exports.register =
@ -151,13 +148,10 @@ exports.remove =
permission: 'user'
action: (params, options, done) ->
resin = require('resin-sdk')
events = require('resin-cli-events')
patterns = require('../utils/patterns')
patterns.confirm(options.yes, 'Are you sure you want to delete the device?').then ->
resin.models.device.remove(params.uuid)
.tap ->
events.send('device.delete', device: params.uuid)
.nodeify(done)
exports.identify =
@ -195,7 +189,6 @@ exports.rename =
Promise = require('bluebird')
_ = require('lodash')
resin = require('resin-sdk')
events = require('resin-cli-events')
form = require('resin-cli-form')
Promise.try ->
@ -206,8 +199,6 @@ exports.rename =
type: 'input'
.then(_.partial(resin.models.device.rename, params.uuid))
.tap ->
events.send('device.rename', device: params.uuid)
.nodeify(done)
exports.move =

View File

@ -99,16 +99,13 @@ exports.remove =
permission: 'user'
action: (params, options, done) ->
resin = require('resin-sdk')
events = require('resin-cli-events')
patterns = require('../utils/patterns')
patterns.confirm(options.yes, 'Are you sure you want to delete the environment variable?').then ->
if options.device
resin.models.environmentVariables.device.remove(params.id)
events.send('deviceEnvironmentVariable.delete', id: params.id)
else
resin.models.environmentVariables.remove(params.id)
events.send('environmentVariable.delete', id: params.id)
.nodeify(done)
exports.add =
@ -140,7 +137,6 @@ exports.add =
action: (params, options, done) ->
Promise = require('bluebird')
resin = require('resin-sdk')
events = require('resin-cli-events')
Promise.try ->
if not params.value?
@ -152,12 +148,9 @@ exports.add =
console.info("Warning: using #{params.key}=#{params.value} from host environment")
if options.application?
resin.models.environmentVariables.create(options.application, params.key, params.value).then ->
resin.models.application.get(options.application).then (application) ->
events.send('environmentVariable.create', application: application.id)
resin.models.environmentVariables.create(options.application, params.key, params.value)
else if options.device?
resin.models.environmentVariables.device.create(options.device, params.key, params.value).then ->
events.send('deviceEnvironmentVariable.create', device: options.device)
resin.models.environmentVariables.device.create(options.device, params.key, params.value)
else
throw new Error('You must specify an application or device')
.nodeify(done)
@ -180,13 +173,10 @@ exports.rename =
action: (params, options, done) ->
Promise = require('bluebird')
resin = require('resin-sdk')
events = require('resin-cli-events')
Promise.try ->
if options.device
resin.models.environmentVariables.device.update(params.id, params.value).then ->
events.send('deviceEnvironmentVariable.edit', id: params.id)
resin.models.environmentVariables.device.update(params.id, params.value)
else
resin.models.environmentVariables.update(params.id, params.value).then ->
events.send('environmentVariable.edit', id: params.id)
resin.models.environmentVariables.update(params.id, params.value)
.nodeify(done)

View File

@ -83,13 +83,10 @@ exports.remove =
permission: 'user'
action: (params, options, done) ->
resin = require('resin-sdk')
events = require('resin-cli-events')
patterns = require('../utils/patterns')
patterns.confirm(options.yes, 'Are you sure you want to delete the key?').then ->
resin.models.key.remove(params.id)
.tap ->
events.send('publicKey.delete', id: params.id)
.nodeify(done)
exports.add =
@ -113,7 +110,6 @@ exports.add =
fs = Promise.promisifyAll(require('fs'))
capitano = require('capitano')
resin = require('resin-sdk')
events = require('resin-cli-events')
Promise.try ->
return fs.readFileAsync(params.path, encoding: 'utf8') if params.path?
@ -123,6 +119,4 @@ exports.add =
return callback(null, data)
.then(_.partial(resin.models.key.create, params.name))
.tap ->
events.send('publicKey.create')
.nodeify(done)

View File

@ -20,6 +20,7 @@ capitano = Promise.promisifyAll(require('capitano'))
resin = require('resin-sdk')
actions = require('./actions')
errors = require('./errors')
events = require('./events')
plugins = require('./utils/plugins')
update = require('./utils/update')
@ -107,5 +108,8 @@ update.notify()
plugins.register(/^resin-plugin-(.+)$/).then ->
cli = capitano.parse(process.argv)
events.trackCommand(cli).then ->
capitano.executeAsync(cli)
.catch(errors.handle)

24
lib/events.coffee Normal file
View File

@ -0,0 +1,24 @@
_ = require('lodash')
Mixpanel = require('mixpanel')
Promise = require('bluebird')
resin = require('resin-sdk')
packageJSON = require('../package.json')
exports.getLoggerInstance = _.memoize ->
return resin.models.config.getMixpanelToken().then(Mixpanel.init)
exports.trackCommand = (capitanoCommand) ->
return Promise.props
resinUrl: resin.settings.get('resinUrl')
username: resin.auth.whoami()
mixpanel: exports.getLoggerInstance()
.then (data) ->
data.mixpanel.track "[CLI] #{capitanoCommand.command}",
distinct_id: data.username
argv: process.argv.join(' ')
version: packageJSON.version
node: process.version
arch: process.arch
resinUrl: data.resinUrl
platform: process.platform
command: capitanoCommand

View File

@ -38,13 +38,13 @@
"columnify": "^1.5.2",
"is-root": "^1.0.0",
"lodash": "^3.10.0",
"mixpanel": "^0.4.0",
"moment": "^2.10.6",
"nplugm": "^3.0.0",
"president": "^2.0.1",
"prettyjson": "^1.1.3",
"resin-cli-auth": "^1.0.0",
"resin-cli-errors": "^1.0.0",
"resin-cli-events": "^1.0.2",
"resin-cli-form": "^1.4.0",
"resin-cli-visuals": "^1.2.2",
"resin-config-json": "^1.0.0",