diff --git a/build/actions/app.js b/build/actions/app.js index 19d9e79b..26ad2943 100644 --- a/build/actions/app.js +++ b/build/actions/app.js @@ -95,6 +95,7 @@ action: function(params, options, done) { var currentDirectory; currentDirectory = process.cwd(); + console.info("Associating " + params.name + " with " + currentDirectory); return resin.models.application.has(params.name).then(function(hasApplication) { if (!hasApplication) { throw new Error("Invalid application: " + params.name); diff --git a/build/actions/device.js b/build/actions/device.js index d4c0184a..6eda9036 100644 --- a/build/actions/device.js +++ b/build/actions/device.js @@ -109,40 +109,6 @@ } }; - exports.await = { - signature: 'device await ', - description: 'await for a device to become online', - help: 'Use this command to await for a device to become online.\n\nThe process will exit when the device becomes online.\n\nNotice that there is no time limit for this command, so it might run forever.\n\nYou can configure the poll interval with the --interval option (defaults to 3000ms).\n\nExamples:\n\n $ resin device await 7cf02a62a3a84440b1bb5579a3d57469148943278630b17e7fc6c4f7b465c9\n $ resin device await 7cf02a62a3a84440b1bb5579a3d57469148943278630b17e7fc6c4f7b465c9 --interval 1000', - options: [ - { - signature: 'interval', - parameter: 'interval', - description: 'poll interval', - alias: 'i' - } - ], - permission: 'user', - action: function(params, options, done) { - var poll, spinner; - if (options.interval == null) { - options.interval = 3000; - } - spinner = new visuals.Spinner("Awaiting device: " + params.uuid); - poll = function() { - return resin.models.device.isOnline(params.uuid).then(function(isOnline) { - if (isOnline) { - spinner.stop(); - console.info("Device became online: " + params.uuid); - } else { - spinner.start(); - return Promise.delay(options.interval).then(poll); - } - }); - }; - return poll().nodeify(done); - } - }; - exports.init = { signature: 'device init [device]', description: 'initialise a device with resin os', diff --git a/build/actions/wizard.js b/build/actions/wizard.js index 59eecf5c..132d6dca 100644 --- a/build/actions/wizard.js +++ b/build/actions/wizard.js @@ -1,22 +1,18 @@ (function() { - var Promise, _, async, capitano, form, mkdirp, resin, visuals; - - _ = require('lodash'); + var Promise, capitano, form, helpers, mkdirp, resin; Promise = require('bluebird'); capitano = Promise.promisifyAll(require('capitano')); - mkdirp = require('mkdirp'); - - visuals = require('resin-cli-visuals'); - - async = require('async'); + mkdirp = Promise.promisify(require('mkdirp')); resin = require('resin-sdk'); form = require('resin-cli-form'); + helpers = require('../utils/helpers'); + exports.wizard = { signature: 'quickstart [name]', description: 'getting started with resin.io', @@ -24,84 +20,27 @@ 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 resin.settings.get('projectsDirectory').then(function(projectsDirectory) { - return form.ask({ - message: 'Please choose a directory for your code', - type: 'input', - "default": projectsDirectory - }); - }).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, callback); - }, function(remoteUrl, callback) { - console.log("Resin git remote added: " + remoteUrl); - console.log("Please type:\n\n $ cd " + params.directory + " && git push resin master\n\nTo push your project to resin.io."); - return callback(); + return Promise["try"](function() { + if (params.name != null) { + return; } - ], done); + return helpers.selectApplication().tap(function(applicationName) { + return capitano.runAsync("app create " + applicationName); + }).then(function(applicationName) { + return params.name = applicationName; + }); + }).then(function() { + return capitano.runAsync("device init --application " + params.name); + }).tap(helpers.awaitDevice).then(function(uuid) { + return capitano.runAsync("device " + uuid); + }).tap(function() { + return console.log('Your device is ready, lets start pushing some code!'); + }).then(helpers.selectProjectDirectory).tap(mkdirp).tap(process.chdir).then(function() { + return capitano.runAsync("app associate " + params.name); + }).then(function(remoteUrl) { + console.log("Resin git remote added: " + remoteUrl); + return console.log("Please type:\n\n $ cd " + (process.cwd()) + " && git push resin master\n\nTo push your project to resin.io."); + }).nodeify(done); } }; diff --git a/build/app.js b/build/app.js index 9646c915..ebd7ae7d 100644 --- a/build/app.js +++ b/build/app.js @@ -66,8 +66,6 @@ capitano.command(actions.device.init); - capitano.command(actions.device.await); - capitano.command(actions.device.info); capitano.command(actions.device.remove); diff --git a/build/utils/helpers.js b/build/utils/helpers.js index 9c6f527c..6a8bc932 100644 --- a/build/utils/helpers.js +++ b/build/utils/helpers.js @@ -1,10 +1,16 @@ (function() { - var Promise, form; + var Promise, _, form, resin, visuals; + + _ = require('lodash'); Promise = require('bluebird'); form = require('resin-cli-form'); + visuals = require('resin-cli-visuals'); + + resin = require('resin-sdk'); + exports.selectDeviceType = function() { return form.ask({ message: 'Device Type', @@ -30,4 +36,62 @@ }); }; + exports.selectApplication = function() { + return resin.models.application.hasAny().then(function(hasAnyApplications) { + if (!hasAnyApplications) { + return; + } + return resin.models.application.getAll().then(function(applications) { + 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 + }); + }); + }).then(function(application) { + if (application != null) { + return application; + } + return form.ask({ + message: 'Choose a Name for your new application', + type: 'input' + }); + }); + }; + + exports.selectProjectDirectory = function() { + return resin.settings.get('projectsDirectory').then(function(projectsDirectory) { + return form.ask({ + message: 'Please choose a directory for your code', + type: 'input', + "default": projectsDirectory + }); + }); + }; + + exports.awaitDevice = function(uuid) { + var poll, spinner; + spinner = new visuals.Spinner("Awaiting device: " + uuid); + poll = function() { + return resin.models.device.isOnline(uuid).then(function(isOnline) { + if (isOnline) { + spinner.stop(); + console.info("Device became online: " + uuid); + } else { + spinner.start(); + return Promise.delay(3000).then(poll); + } + }); + }; + return resin.models.device.getName(uuid).then(function(deviceName) { + console.info("Waiting for " + deviceName + " to connect to resin..."); + return poll()["return"](uuid); + }); + }; + }).call(this); diff --git a/lib/actions/app.coffee b/lib/actions/app.coffee index fa497fe3..498922f9 100644 --- a/lib/actions/app.coffee +++ b/lib/actions/app.coffee @@ -148,6 +148,7 @@ exports.associate = permission: 'user' action: (params, options, done) -> currentDirectory = process.cwd() + console.info("Associating #{params.name} with #{currentDirectory}") resin.models.application.has(params.name).then (hasApplication) -> if not hasApplication diff --git a/lib/actions/device.coffee b/lib/actions/device.coffee index 4d0616d4..fffc062f 100644 --- a/lib/actions/device.coffee +++ b/lib/actions/device.coffee @@ -150,50 +150,6 @@ exports.rename = .then(_.partial(resin.models.device.rename, params.uuid)) .nodeify(done) -exports.await = - signature: 'device await ' - description: 'await for a device to become online' - help: ''' - Use this command to await for a device to become online. - - The process will exit when the device becomes online. - - Notice that there is no time limit for this command, so it might run forever. - - You can configure the poll interval with the --interval option (defaults to 3000ms). - - Examples: - - $ resin device await 7cf02a62a3a84440b1bb5579a3d57469148943278630b17e7fc6c4f7b465c9 - $ resin device await 7cf02a62a3a84440b1bb5579a3d57469148943278630b17e7fc6c4f7b465c9 --interval 1000 - ''' - options: [ - signature: 'interval' - parameter: 'interval' - description: 'poll interval' - alias: 'i' - ] - permission: 'user' - action: (params, options, done) -> - options.interval ?= 3000 - - spinner = new visuals.Spinner("Awaiting device: #{params.uuid}") - - poll = -> - resin.models.device.isOnline(params.uuid).then (isOnline) -> - if isOnline - spinner.stop() - console.info("Device became online: #{params.uuid}") - return - else - - # Spinner implementation is smart enough to - # not start again if it was already started - spinner.start() - - return Promise.delay(options.interval).then(poll) - poll().nodeify(done) - exports.init = signature: 'device init [device]' description: 'initialise a device with resin os' diff --git a/lib/actions/wizard.coffee b/lib/actions/wizard.coffee index a76ed97d..b88c730c 100644 --- a/lib/actions/wizard.coffee +++ b/lib/actions/wizard.coffee @@ -1,11 +1,9 @@ -_ = require('lodash') Promise = require('bluebird') capitano = Promise.promisifyAll(require('capitano')) -mkdirp = require('mkdirp') -visuals = require('resin-cli-visuals') -async = require('async') +mkdirp = Promise.promisify(require('mkdirp')) resin = require('resin-sdk') form = require('resin-cli-form') +helpers = require('../utils/helpers') exports.wizard = signature: 'quickstart [name]' @@ -28,98 +26,31 @@ exports.wizard = root: true permission: 'user' action: (params, options, done) -> - async.waterfall [ + Promise.try -> + return if params.name? + helpers.selectApplication().tap (applicationName) -> + capitano.runAsync("app create #{applicationName}") + .then (applicationName) -> + params.name = applicationName + .then -> + return capitano.runAsync("device init --application #{params.name}") + .tap(helpers.awaitDevice) + .then (uuid) -> + return capitano.runAsync("device #{uuid}") + .tap -> + console.log('Your device is ready, lets start pushing some code!') + .then(helpers.selectProjectDirectory) + .tap(mkdirp) + .tap(process.chdir) + .then -> + return capitano.runAsync("app associate #{params.name}") + .then (remoteUrl) -> + console.log("Resin git remote added: #{remoteUrl}") + console.log """ + Please type: - (callback) -> - return callback() if params.name? + $ cd #{process.cwd()} && git push resin master - # 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!') - resin.settings.get('projectsDirectory').then (projectsDirectory) -> - form.ask - message: 'Please choose a directory for your code' - type: 'input' - default: projectsDirectory - .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}", callback) - - (remoteUrl, callback) -> - console.log("Resin git remote added: #{remoteUrl}") - console.log """ - Please type: - - $ cd #{params.directory} && git push resin master - - To push your project to resin.io. - """ - return callback() - - ], done + To push your project to resin.io. + """ + .nodeify(done) diff --git a/lib/app.coffee b/lib/app.coffee index 66b084a9..2ff61660 100644 --- a/lib/app.coffee +++ b/lib/app.coffee @@ -45,7 +45,6 @@ capitano.command(actions.app.info) capitano.command(actions.device.list) capitano.command(actions.device.rename) capitano.command(actions.device.init) -capitano.command(actions.device.await) capitano.command(actions.device.info) capitano.command(actions.device.remove) capitano.command(actions.device.identify) diff --git a/lib/utils/helpers.coffee b/lib/utils/helpers.coffee index a2c4b92f..b5c1cdc3 100644 --- a/lib/utils/helpers.coffee +++ b/lib/utils/helpers.coffee @@ -1,5 +1,8 @@ +_ = require('lodash') Promise = require('bluebird') form = require('resin-cli-form') +visuals = require('resin-cli-visuals') +resin = require('resin-sdk') exports.selectDeviceType = -> return form.ask @@ -24,3 +27,50 @@ exports.confirm = (yesOption, message) -> .then (confirmed) -> if not confirmed throw new Error('Aborted') + +exports.selectApplication = -> + resin.models.application.hasAny().then (hasAnyApplications) -> + return if not hasAnyApplications + resin.models.application.getAll().then (applications) -> + 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 + .then (application) -> + return application if application? + form.ask + message: 'Choose a Name for your new application' + type: 'input' + +exports.selectProjectDirectory = -> + resin.settings.get('projectsDirectory').then (projectsDirectory) -> + return form.ask + message: 'Please choose a directory for your code' + type: 'input' + default: projectsDirectory + +exports.awaitDevice = (uuid) -> + spinner = new visuals.Spinner("Awaiting device: #{uuid}") + + poll = -> + resin.models.device.isOnline(uuid).then (isOnline) -> + if isOnline + spinner.stop() + console.info("Device became online: #{uuid}") + return + else + + # Spinner implementation is smart enough to + # not start again if it was already started + spinner.start() + + return Promise.delay(3000).then(poll) + + resin.models.device.getName(uuid).then (deviceName) -> + console.info("Waiting for #{deviceName} to connect to resin...") + poll().return(uuid)