Implement Quickstart command

This commit is contained in:
Juan Cruz Viotti 2015-05-07 12:40:12 -03:00 committed by mike
parent d24b871964
commit dc030f4cd1
11 changed files with 320 additions and 18 deletions

View File

@ -41,12 +41,10 @@
if (options.type != null) {
return callback(null, options.type);
}
return resin.models.device.getSupportedDeviceTypes().then(function(supportedDeviceTypes) {
return form.ask({
message: 'Device Type',
type: 'list',
choices: supportedDeviceTypes
});
return form.ask({
message: 'Device Type',
type: 'list',
choices: ['Raspberry Pi', 'Raspberry Pi 2', 'BeagleBone Black']
}).nodeify(callback);
}, function(type, callback) {
options.type = type;

View File

@ -1,5 +1,5 @@
(function() {
var _, async, capitano, commandOptions, deviceConfig, drivelist, form, fse, image, inject, manager, path, pine, registerDevice, resin, tmp, vcs, visuals;
var _, async, capitano, commandOptions, deviceConfig, drivelist, form, fse, htmlToText, image, inject, manager, os, path, pine, registerDevice, resin, tmp, vcs, visuals;
fse = require('fs-extra');
@ -35,6 +35,10 @@
drivelist = require('drivelist');
htmlToText = require('html-to-text');
os = require('os');
tmp.setGracefulCleanup();
commandOptions = require('./command-options');
@ -291,6 +295,7 @@
}
}, callback);
}, function(results, callback) {
params.manifest = results.manifest;
console.info('Associating the device');
return registerDevice.register(pine, results.config, function(error, device) {
if (error != null) {
@ -310,7 +315,7 @@
}
bar = new visuals.Progress('Downloading Device OS');
spinner = new visuals.Spinner('Downloading Device OS (size unknown)');
return manager.configure(results.manifest, results.config, function(error, imagePath, removeCallback) {
return manager.configure(params.manifest, results.config, function(error, imagePath, removeCallback) {
spinner.stop();
return callback(error, imagePath, removeCallback);
}, function(state) {
@ -322,6 +327,7 @@
});
}, function(configuredImagePath, removeCallback, callback) {
var bar;
console.info('The base image was cached to improve initialization time of similar devices');
console.info('Attempting to write operating system image to drive');
bar = new visuals.Progress('Writing Device OS');
return image.write({
@ -342,6 +348,28 @@
}, function(device, callback) {
console.info("Device created: " + device.name);
return callback(null, device.name);
}, function(deviceName, callback) {
var instructions, osSpecificInstructions, platform, platformHash;
if (params.manifest.instructions == null) {
instructions = '';
}
if (_.isArray(params.manifest.instructions)) {
instructions = htmlToText.fromString(params.manifest.instructions.join('\n'));
}
platformHash = {
darwin: 'osx',
linux: 'linux',
win32: 'windows'
};
platform = platformHash[os.platform()];
osSpecificInstructions = params.manifest.instructions[platform];
if (osSpecificInstructions == null) {
instructions = '';
} else {
instructions = htmlToText.fromString(osSpecificInstructions.join('\n'));
}
console.log('\n' + instructions);
return callback(null, params.uuid);
}
], done);
}

View File

@ -1,5 +1,6 @@
(function() {
module.exports = {
wizard: require('./wizard'),
app: require('./app'),
info: require('./info'),
auth: require('./auth'),

110
build/actions/wizard.js Normal file
View File

@ -0,0 +1,110 @@
(function() {
var Promise, _, async, capitano, form, mkdirp, path, resin, userHome, visuals;
_ = require('lodash-contrib');
Promise = require('bluebird');
capitano = Promise.promisifyAll(require('capitano'));
path = require('path');
mkdirp = require('mkdirp');
userHome = require('user-home');
visuals = require('resin-cli-visuals');
async = require('async');
resin = require('resin-sdk');
form = require('resin-cli-form');
exports.wizard = {
signature: 'quickstart [name]',
description: 'getting started with resin.io',
help: 'Use this command to run a friendly wizard to get started with resin.io.\n\nThe wizard will guide you through:\n\n - Create an application.\n - Initialise an SDCard with the resin.io operating system.\n - Associate an existing project directory with your resin.io application.\n - Push your project to your devices.\n\nExamples:\n\n $ sudo resin quickstart\n $ sudo resin quickstart MyApp',
root: true,
permission: 'user',
action: function(params, options, done) {
return async.waterfall([
function(callback) {
if (params.name != null) {
return callback();
}
return async.waterfall([
function(callback) {
return resin.models.application.hasAny().nodeify(callback);
}, function(hasAnyApplications, callback) {
if (!hasAnyApplications) {
return callback(null, null);
}
return async.waterfall([
function(callback) {
return resin.models.application.getAll().nodeify(callback);
}, function(applications, callback) {
applications = _.pluck(applications, 'app_name');
applications.unshift({
name: 'Create a new application',
value: null
});
return form.ask({
message: 'Select an application',
type: 'list',
choices: applications
}).nodeify(callback);
}
], callback);
}, function(application, callback) {
if (application != null) {
return callback(null, application);
}
return form.ask({
message: 'Choose a Name for your new application',
type: 'input'
}).then(function(applicationName) {
return capitano.runAsync("app create " + applicationName)["return"](applicationName);
}).nodeify(callback);
}, function(applicationName, callback) {
params.name = applicationName;
return callback();
}
], callback);
}, function(callback) {
return capitano.run("device init --application " + params.name, callback);
}, function(deviceUuid, callback) {
params.uuid = deviceUuid;
return resin.models.device.getName(params.uuid).then(function(deviceName) {
params.deviceName = deviceName;
console.log("Waiting for " + params.deviceName + " to connect to resin...");
return capitano.runAsync("device await " + params.uuid)["return"](callback);
}).nodeify(callback);
}, function(callback) {
console.log("The device " + params.deviceName + " successfully connected to resin!");
console.log('');
return capitano.run("device " + params.uuid, callback);
}, function(callback) {
console.log('Your device is ready, lets start pushing some code!');
return form.ask({
message: 'Please choose a directory for your code',
type: 'input',
"default": path.join(userHome, 'ResinProjects', params.name)
}).nodeify(callback);
}, function(directoryName, callback) {
params.directory = directoryName;
return mkdirp(directoryName, callback);
}, function(made, callback) {
console.log("Associating " + params.name + " with " + params.directory + "...");
process.chdir(params.directory);
return capitano.run("app associate " + params.name + " --project " + params.directory, callback);
}, function(remoteUrl, callback) {
console.log("Resin git remote added: " + remoteUrl);
console.log('Please type "git push resin master" into your project directory now!');
return callback();
}
], done);
}
};
}).call(this);

View File

@ -65,6 +65,8 @@
capitano.command(actions.help.help);
capitano.command(actions.wizard.wizard);
capitano.command(actions.auth.login);
capitano.command(actions.auth.logout);

View File

@ -45,11 +45,17 @@ exports.create =
return callback(new Error('You already have an application with that name!'))
return callback(null, options.type) if options.type?
resin.models.device.getSupportedDeviceTypes().then (supportedDeviceTypes) ->
form.ask
message: 'Device Type'
type: 'list'
choices: supportedDeviceTypes
form.ask
message: 'Device Type'
type: 'list'
choices: [
# Lock to specific devices until we support
# the rest with device specs.
'Raspberry Pi'
'Raspberry Pi 2'
'BeagleBone Black'
]
.nodeify(callback)
(type, callback) ->

View File

@ -15,6 +15,8 @@ tmp = require('tmp')
deviceConfig = require('resin-device-config')
form = require('resin-cli-form')
drivelist = require('drivelist')
htmlToText = require('html-to-text')
os = require('os')
# Cleanup the temporary files even when an uncaught exception occurs
tmp.setGracefulCleanup()
@ -365,6 +367,7 @@ exports.init =
, callback
(results, callback) ->
params.manifest = results.manifest
console.info('Associating the device')
registerDevice.register pine, results.config, (error, device) ->
@ -388,7 +391,7 @@ exports.init =
bar = new visuals.Progress('Downloading Device OS')
spinner = new visuals.Spinner('Downloading Device OS (size unknown)')
manager.configure results.manifest, results.config, (error, imagePath, removeCallback) ->
manager.configure params.manifest, results.config, (error, imagePath, removeCallback) ->
spinner.stop()
return callback(error, imagePath, removeCallback)
, (state) ->
@ -398,6 +401,8 @@ exports.init =
spinner.start()
(configuredImagePath, removeCallback, callback) ->
console.info('The base image was cached to improve initialization time of similar devices')
console.info('Attempting to write operating system image to drive')
bar = new visuals.Progress('Writing Device OS')
@ -420,4 +425,26 @@ exports.init =
console.info("Device created: #{device.name}")
return callback(null, device.name)
(deviceName, callback) ->
instructions = '' if not params.manifest.instructions?
if _.isArray(params.manifest.instructions)
instructions = htmlToText.fromString(params.manifest.instructions.join('\n'))
platformHash =
darwin: 'osx'
linux: 'linux'
win32: 'windows'
platform = platformHash[os.platform()]
osSpecificInstructions = params.manifest.instructions[platform]
if not osSpecificInstructions?
instructions = ''
else
instructions = htmlToText.fromString(osSpecificInstructions.join('\n'))
console.log('\n' + instructions)
return callback(null, params.uuid)
], done

View File

@ -1,4 +1,5 @@
module.exports =
wizard: require('./wizard')
app: require('./app')
info: require('./info')
auth: require('./auth')

122
lib/actions/wizard.coffee Normal file
View File

@ -0,0 +1,122 @@
_ = require('lodash-contrib')
Promise = require('bluebird')
capitano = Promise.promisifyAll(require('capitano'))
path = require('path')
mkdirp = require('mkdirp')
userHome = require('user-home')
visuals = require('resin-cli-visuals')
async = require('async')
resin = require('resin-sdk')
form = require('resin-cli-form')
exports.wizard =
signature: 'quickstart [name]'
description: 'getting started with resin.io'
help: '''
Use this command to run a friendly wizard to get started with resin.io.
The wizard will guide you through:
- Create an application.
- Initialise an SDCard with the resin.io operating system.
- Associate an existing project directory with your resin.io application.
- Push your project to your devices.
Examples:
$ sudo resin quickstart
$ sudo resin quickstart MyApp
'''
root: true
permission: 'user'
action: (params, options, done) ->
async.waterfall [
(callback) ->
return callback() if params.name?
# TODO: Move this whole routine to Resin CLI Visuals
async.waterfall [
(callback) ->
resin.models.application.hasAny().nodeify(callback)
(hasAnyApplications, callback) ->
return callback(null, null) if not hasAnyApplications
async.waterfall [
(callback) ->
resin.models.application.getAll().nodeify(callback)
(applications, callback) ->
applications = _.pluck(applications, 'app_name')
applications.unshift
name: 'Create a new application'
value: null
form.ask
message: 'Select an application'
type: 'list'
choices: applications
.nodeify(callback)
], callback
(application, callback) ->
return callback(null, application) if application?
form.ask
message: 'Choose a Name for your new application'
type: 'input'
.then (applicationName) ->
capitano.runAsync("app create #{applicationName}").return(applicationName)
.nodeify(callback)
(applicationName, callback) ->
params.name = applicationName
return callback()
], callback
(callback) ->
capitano.run("device init --application #{params.name}", callback)
(deviceUuid, callback) ->
params.uuid = deviceUuid
resin.models.device.getName(params.uuid).then (deviceName) ->
params.deviceName = deviceName
console.log("Waiting for #{params.deviceName} to connect to resin...")
capitano.runAsync("device await #{params.uuid}").return(callback)
.nodeify(callback)
(callback) ->
console.log("The device #{params.deviceName} successfully connected to resin!")
console.log('')
capitano.run("device #{params.uuid}", callback)
(callback) ->
console.log('Your device is ready, lets start pushing some code!')
form.ask
message: 'Please choose a directory for your code'
type: 'input'
# TODO: Move this to resin-settings-client.
default: path.join(userHome, 'ResinProjects', params.name)
.nodeify(callback)
(directoryName, callback) ->
params.directory = directoryName
mkdirp(directoryName, callback)
(made, callback) ->
console.log("Associating #{params.name} with #{params.directory}...")
process.chdir(params.directory)
capitano.run("app associate #{params.name} --project #{params.directory}", callback)
(remoteUrl, callback) ->
console.log("Resin git remote added: #{remoteUrl}")
console.log('Please type "git push resin master" into your project directory now!')
return callback()
], done

View File

@ -51,6 +51,9 @@ capitano.command(actions.info.config)
# ---------- Help Module ----------
capitano.command(actions.help.help)
# ---------- Wizard Module ----------
capitano.command(actions.wizard.wizard)
# ---------- Auth Module ----------
capitano.command(actions.auth.login)
capitano.command(actions.auth.logout)

View File

@ -42,11 +42,13 @@
},
"dependencies": {
"async": "^1.3.0",
"capitano": "~1.6.0",
"bluebird": "^2.9.34",
"capitano": "~1.6.1",
"coffee-script": "^1.9.3",
"conf.js": "^0.1.1",
"drivelist": "^1.2.2",
"fs-extra": "^0.22.1",
"html-to-text": "^1.3.1",
"lodash": "^3.10.0",
"lodash-contrib": "^393.0.1",
"mkdirp": "~0.5.0",
@ -57,8 +59,8 @@
"resin-cli-visuals": "^1.0.0",
"resin-config-inject": "^2.0.0",
"resin-device-config": "^1.0.0",
"resin-image": "^1.1.3",
"resin-image-manager": "^1.1.0",
"resin-image": "^1.1.4",
"resin-image-manager": "^2.0.0",
"resin-pine": "^1.3.0",
"resin-register-device": "^1.0.1",
"resin-sdk": "^2.2.0",
@ -67,6 +69,8 @@
"selfupdate": "^1.1.0",
"through2": "^2.0.0",
"tmp": "0.0.26",
"underscore.string": "^3.1.1"
"underscore.string": "^3.1.1",
"update-notifier": "^0.3.1",
"user-home": "^2.0.0"
}
}