From f17e9c97b8e95d87707574c64d39ba76af8bbb77 Mon Sep 17 00:00:00 2001 From: Juan Cruz Viotti Date: Tue, 29 Sep 2015 11:10:33 -0400 Subject: [PATCH] Prompt for select application if running device init with no arguments Currently, if `device init` was ran without an application argument, we attempted to get the application name from the current directory, given it was a git repository. This approach led to confusions from time to time, so now we prompt the user to select one of it's own applications from a dropdown instead of checking the current directory in this edge case. Fixes: https://github.com/resin-io/resin-cli/issues/197 --- build/actions/device.js | 6 ++---- build/actions/wizard.js | 2 +- build/utils/patterns.js | 15 +++++++++++++++ doc/cli.markdown | 37 +++++-------------------------------- lib/actions/device.coffee | 3 +-- lib/actions/wizard.coffee | 2 +- lib/utils/patterns.coffee | 11 +++++++++++ 7 files changed, 36 insertions(+), 40 deletions(-) diff --git a/build/actions/device.js b/build/actions/device.js index 8fc7b747..da269797 100644 --- a/build/actions/device.js +++ b/build/actions/device.js @@ -1,5 +1,5 @@ (function() { - var Promise, _, capitano, commandOptions, events, form, fs, patterns, resin, rimraf, tmp, vcs, visuals; + var Promise, _, capitano, commandOptions, events, form, fs, patterns, resin, rimraf, tmp, visuals; Promise = require('bluebird'); @@ -11,8 +11,6 @@ visuals = require('resin-cli-visuals'); - vcs = require('resin-vcs'); - form = require('resin-cli-form'); events = require('resin-cli-events'); @@ -141,7 +139,7 @@ if (options.application != null) { return options.application; } - return vcs.getApplicationName(process.cwd()); + return patterns.selectApplication(); }).then(resin.models.application.get).then(function(application) { return tmp.tmpNameAsync().then(function(temporalPath) { return capitano.runAsync("os download --output " + temporalPath); diff --git a/build/actions/wizard.js b/build/actions/wizard.js index 4a33b0a8..76ede468 100644 --- a/build/actions/wizard.js +++ b/build/actions/wizard.js @@ -24,7 +24,7 @@ if (params.name != null) { return; } - return patterns.selectApplication().tap(function(applicationName) { + return patterns.selectOrCreateApplication().tap(function(applicationName) { return resin.models.application.has(applicationName).then(function(hasApplication) { if (hasApplication) { return applicationName; diff --git a/build/utils/patterns.js b/build/utils/patterns.js index 58a4fd5d..678e410d 100644 --- a/build/utils/patterns.js +++ b/build/utils/patterns.js @@ -41,6 +41,21 @@ }; exports.selectApplication = function() { + return resin.models.application.hasAny().then(function(hasAnyApplications) { + if (!hasAnyApplications) { + throw new Error('You don\'t have any applications'); + } + return resin.models.application.getAll().then(function(applications) { + return form.ask({ + message: 'Select an application', + type: 'list', + choices: _.pluck(applications, 'app_name') + }); + }); + }); + }; + + exports.selectOrCreateApplication = function() { return resin.models.application.hasAny().then(function(hasAnyApplications) { if (!hasAnyApplications) { return; diff --git a/doc/cli.markdown b/doc/cli.markdown index 1eaa673d..0dbb52cb 100644 --- a/doc/cli.markdown +++ b/doc/cli.markdown @@ -38,7 +38,7 @@ Now you have access to all the commands referenced below. - [device rm <uuid>](#device-rm-60-uuid-62-) - [device identify <uuid>](#device-identify-60-uuid-62-) - [device rename <uuid> [newName]](#device-rename-60-uuid-62-newname-) - - [device init [device]](#device-init-device-) + - [device init](#device-init) - Environment Variables @@ -291,36 +291,17 @@ Examples: $ resin device rename 7cf02a62a3a84440b1bb5579a3d57469148943278630b17e7fc6c4f7b465c9 MyPi $ resin device rename 7cf02a62a3a84440b1bb5579a3d57469148943278630b17e7fc6c4f7b465c9 -## device init [device] +## device init Use this command to download the OS image of a certain application and write it to an SD Card. -Note that this command requires admin privileges. - -If `device` is omitted, you will be prompted to select a device interactively. - -Notice this command asks for confirmation interactively. +Notice this command may ask for confirmation interactively. You can avoid this by passing the `--yes` boolean option. -You can quiet the progress bar and other logging information by passing the `--quiet` boolean option. - -You need to configure the network type and other settings: - -Ethernet: - You can setup the device OS to use ethernet by setting the `--network` option to "ethernet". - -Wifi: - You can setup the device OS to use wifi by setting the `--network` option to "wifi". - If you set "network" to "wifi", you will need to specify the `--ssid` and `--key` option as well. - -You can omit network related options to be asked about them interactively. - Examples: $ resin device init $ resin device init --application MyApp - $ resin device init --application MyApp --network ethernet - $ resin device init /dev/disk2 --application MyApp --network wifi --ssid MyNetwork --key secret ### Options @@ -328,17 +309,9 @@ Examples: application name -#### --network, -n <network> +#### --yes, -y -network type - -#### --ssid, -s <ssid> - -wifi ssid, if network is wifi - -#### --key, -k <key> - -wifi key, if network is wifi +confirm non interactively # Environment Variables diff --git a/lib/actions/device.coffee b/lib/actions/device.coffee index e78b7738..60de03b8 100644 --- a/lib/actions/device.coffee +++ b/lib/actions/device.coffee @@ -3,7 +3,6 @@ capitano = Promise.promisifyAll(require('capitano')) _ = require('lodash') resin = require('resin-sdk') visuals = require('resin-cli-visuals') -vcs = require('resin-vcs') form = require('resin-cli-form') events = require('resin-cli-events') fs = Promise.promisifyAll(require('fs')) @@ -194,7 +193,7 @@ exports.init = action: (params, options, done) -> Promise.try -> return options.application if options.application? - return vcs.getApplicationName(process.cwd()) + return patterns.selectApplication() .then(resin.models.application.get) .then (application) -> tmp.tmpNameAsync().then (temporalPath) -> diff --git a/lib/actions/wizard.coffee b/lib/actions/wizard.coffee index af13bd2a..38345835 100644 --- a/lib/actions/wizard.coffee +++ b/lib/actions/wizard.coffee @@ -28,7 +28,7 @@ exports.wizard = action: (params, options, done) -> Promise.try -> return if params.name? - patterns.selectApplication().tap (applicationName) -> + patterns.selectOrCreateApplication().tap (applicationName) -> resin.models.application.has(applicationName).then (hasApplication) -> return applicationName if hasApplication capitano.runAsync("app create #{applicationName}") diff --git a/lib/utils/patterns.coffee b/lib/utils/patterns.coffee index 801c4619..c18ba232 100644 --- a/lib/utils/patterns.coffee +++ b/lib/utils/patterns.coffee @@ -24,6 +24,17 @@ exports.confirm = (yesOption, message) -> throw new Error('Aborted') exports.selectApplication = -> + resin.models.application.hasAny().then (hasAnyApplications) -> + if not hasAnyApplications + throw new Error('You don\'t have any applications') + + resin.models.application.getAll().then (applications) -> + return form.ask + message: 'Select an application' + type: 'list' + choices: _.pluck(applications, 'app_name') + +exports.selectOrCreateApplication = -> resin.models.application.hasAny().then (hasAnyApplications) -> return if not hasAnyApplications resin.models.application.getAll().then (applications) ->