From 08c40195e5d18255eb00d172903d5cf92d080ac3 Mon Sep 17 00:00:00 2001 From: Tim Perry Date: Thu, 16 Nov 2017 19:09:20 +0100 Subject: [PATCH 1/5] Make sure everything uses the same shared deviceApiKey option --- build/actions/command-options.js | 7 +++++++ build/actions/config.js | 7 +------ build/actions/device.js | 7 +------ doc/cli.markdown | 2 +- lib/actions/command-options.coffee | 6 ++++++ lib/actions/config.coffee | 7 +------ lib/actions/device.coffee | 7 +------ 7 files changed, 18 insertions(+), 25 deletions(-) diff --git a/build/actions/command-options.js b/build/actions/command-options.js index e6476c93..6e56efe5 100644 --- a/build/actions/command-options.js +++ b/build/actions/command-options.js @@ -44,6 +44,13 @@ exports.optionalDevice = { alias: 'd' }; +exports.optionalDeviceApiKey = { + signature: 'deviceApiKey', + description: 'custom device key - note that this is only supported on ResinOS 2.0.3+', + parameter: 'device-api-key', + alias: 'k' +}; + exports.booleanDevice = { signature: 'device', description: 'device', diff --git a/build/actions/config.js b/build/actions/config.js index c835864e..111bad77 100644 --- a/build/actions/config.js +++ b/build/actions/config.js @@ -196,12 +196,7 @@ exports.generate = { description: 'generate a config.json file', help: 'Use this command to generate a config.json for a device or application.\n\nThis is interactive by default, but you can do this automatically without interactivity\nby specifying an option for each question on the command line, if you know the questions\nthat will be asked for the relevant device type.\n\nExamples:\n\n $ resin config generate --device 7cf02a6\n $ resin config generate --device 7cf02a6 --device-api-key \n $ resin config generate --device 7cf02a6 --output config.json\n $ resin config generate --app MyApp\n $ resin config generate --app MyApp --output config.json\n $ resin config generate --app MyApp --network wifi --wifiSsid mySsid --wifiKey abcdefgh --appUpdatePollInterval 1', options: [ - commandOptions.optionalApplication, commandOptions.optionalDevice, { - signature: 'deviceApiKey', - description: 'custom device key - note that this is only supported on ResinOS 2.0.3+', - parameter: 'device-api-key', - alias: 'k' - }, { + commandOptions.optionalApplication, commandOptions.optionalDevice, commandOptions.optionalDeviceApiKey, { signature: 'output', description: 'output', parameter: 'output', diff --git a/build/actions/device.js b/build/actions/device.js index ddd78b4a..fbc8ec5c 100644 --- a/build/actions/device.js +++ b/build/actions/device.js @@ -92,12 +92,7 @@ exports.register = { description: 'custom uuid', parameter: 'uuid', alias: 'u' - }, { - signature: 'deviceApiKey', - description: 'custom device key', - parameter: 'device-api-key', - alias: 'k' - } + }, commandOptions.optionalDeviceApiKey ], action: function(params, options, done) { var Promise, ref, ref1, resin; diff --git a/doc/cli.markdown b/doc/cli.markdown index e4171a1c..403cde8d 100644 --- a/doc/cli.markdown +++ b/doc/cli.markdown @@ -350,7 +350,7 @@ custom uuid #### --deviceApiKey, -k <device-api-key> -custom device key +custom device key - note that this is only supported on ResinOS 2.0.3+ ## device rm <uuid> diff --git a/lib/actions/command-options.coffee b/lib/actions/command-options.coffee index e17ad467..108a6f9d 100644 --- a/lib/actions/command-options.coffee +++ b/lib/actions/command-options.coffee @@ -38,6 +38,12 @@ exports.optionalDevice = description: 'device uuid' alias: 'd' +exports.optionalDeviceApiKey = + signature: 'deviceApiKey' + description: 'custom device key - note that this is only supported on ResinOS 2.0.3+' + parameter: 'device-api-key' + alias: 'k' + exports.booleanDevice = signature: 'device' description: 'device' diff --git a/lib/actions/config.coffee b/lib/actions/config.coffee index 89fa06a4..eee21f03 100644 --- a/lib/actions/config.coffee +++ b/lib/actions/config.coffee @@ -237,12 +237,7 @@ exports.generate = options: [ commandOptions.optionalApplication commandOptions.optionalDevice - { - signature: 'deviceApiKey' - description: 'custom device key - note that this is only supported on ResinOS 2.0.3+' - parameter: 'device-api-key' - alias: 'k' - } + commandOptions.optionalDeviceApiKey { signature: 'output' description: 'output' diff --git a/lib/actions/device.coffee b/lib/actions/device.coffee index 7e4f3695..c23888b0 100644 --- a/lib/actions/device.coffee +++ b/lib/actions/device.coffee @@ -147,12 +147,7 @@ exports.register = parameter: 'uuid' alias: 'u' } - { - signature: 'deviceApiKey' - description: 'custom device key' - parameter: 'device-api-key' - alias: 'k' - } + commandOptions.optionalDeviceApiKey ] action: (params, options, done) -> Promise = require('bluebird') From eef0d9cdbe000f3f8e162cb331674131981379e2 Mon Sep 17 00:00:00 2001 From: Tim Perry Date: Thu, 16 Nov 2017 19:11:17 +0100 Subject: [PATCH 2/5] Print help even for expected errors Change-Type: patch --- build/actions/os.js | 2 +- build/utils/patterns.js | 2 +- doc/cli.markdown | 2 +- lib/actions/os.coffee | 2 +- lib/utils/patterns.coffee | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build/actions/os.js b/build/actions/os.js index 13198d99..8c409852 100644 --- a/build/actions/os.js +++ b/build/actions/os.js @@ -165,7 +165,7 @@ buildConfig = function(image, deviceType, advanced) { exports.buildConfig = { signature: 'os build-config ', description: 'build the OS config and save it to the JSON file', - help: 'Use this command to prebuild the OS config once and skip the interactive part of `resin os configure`.\n\nExamples:\n\n $ resin os build-config ../path/rpi3.img raspberrypi3 --output rpi3-config.json\n $ resin os configure ../path/rpi3.img 7cf02a6 --config "$(cat rpi3-config.json)"', + help: 'Use this command to prebuild the OS config once and skip the interactive part of `resin os configure`.\n\nExample:\n\n $ resin os build-config ../path/rpi3.img raspberrypi3 --output rpi3-config.json\n $ resin os configure ../path/rpi3.img 7cf02a6 --config "$(cat rpi3-config.json)"', permission: 'user', options: [ commandOptions.advancedConfig, { diff --git a/build/utils/patterns.js b/build/utils/patterns.js index 9de8bdc1..5f6e1f2f 100644 --- a/build/utils/patterns.js +++ b/build/utils/patterns.js @@ -224,6 +224,6 @@ exports.expectedError = function(message) { if (message instanceof Error) { message = message.message; } - console.error(chalk.red(message)); + exports.printErrorMessage(message); return process.exit(1); }; diff --git a/doc/cli.markdown b/doc/cli.markdown index 403cde8d..18db89d2 100644 --- a/doc/cli.markdown +++ b/doc/cli.markdown @@ -894,7 +894,7 @@ or 'menu' (will show the interactive menu) Use this command to prebuild the OS config once and skip the interactive part of `resin os configure`. -Examples: +Example: $ resin os build-config ../path/rpi3.img raspberrypi3 --output rpi3-config.json $ resin os configure ../path/rpi3.img 7cf02a6 --config "$(cat rpi3-config.json)" diff --git a/lib/actions/os.coffee b/lib/actions/os.coffee index b055d965..a5836b6b 100644 --- a/lib/actions/os.coffee +++ b/lib/actions/os.coffee @@ -169,7 +169,7 @@ exports.buildConfig = help: ''' Use this command to prebuild the OS config once and skip the interactive part of `resin os configure`. - Examples: + Example: $ resin os build-config ../path/rpi3.img raspberrypi3 --output rpi3-config.json $ resin os configure ../path/rpi3.img 7cf02a6 --config "$(cat rpi3-config.json)" diff --git a/lib/utils/patterns.coffee b/lib/utils/patterns.coffee index f279e161..fc586abd 100644 --- a/lib/utils/patterns.coffee +++ b/lib/utils/patterns.coffee @@ -177,5 +177,5 @@ exports.printErrorMessage = (message) -> exports.expectedError = (message) -> if message instanceof Error message = message.message - console.error(chalk.red(message)) + exports.printErrorMessage(message) process.exit(1) From e38a0c0047cc8c3f29bfdd5ef1acec55e848a4c5 Mon Sep 17 00:00:00 2001 From: Tim Perry Date: Thu, 16 Nov 2017 19:13:20 +0100 Subject: [PATCH 3/5] Allow `os configure` to configure for an app, not just a specific device This moves to --app and --uuid options, and deprecates the previous format, but doesn't immediately remove it so this is not a breaking change. Connects-To: #691 Change-Type: minor --- build/actions/os.js | 25 +++++++++++------- doc/cli.markdown | 30 +++++++++++++++++----- lib/actions/os.coffee | 60 ++++++++++++++++++++++++++++++++++--------- 3 files changed, 88 insertions(+), 27 deletions(-) diff --git a/build/actions/os.js b/build/actions/os.js index 8c409852..6a868c76 100644 --- a/build/actions/os.js +++ b/build/actions/os.js @@ -188,36 +188,43 @@ exports.buildConfig = { }; exports.configure = { - signature: 'os configure [deviceApiKey]', + signature: 'os configure [uuid] [deviceApiKey]', description: 'configure an os image', - help: 'Use this command to configure a previously downloaded operating system image for the specific device.\n\nNote that device api keys are only supported on ResinOS 2.0.3+\n\nExamples:\n\n $ resin os configure ../path/rpi.img 7cf02a6\n $ resin os configure ../path/rpi.img 7cf02a6 ', + help: 'Use this command to configure a previously downloaded operating system image for\nthe specific device or for an application generally.\n\nNote that device api keys are only supported on ResinOS 2.0.3+.\n\nThis comand still supports the *deprecated* format where the UUID and optionally device key\nare passed directly on the command line, but the recommended way is to pass either an --app or\n--device argument. The deprecated format will be remove in a future release.\n\nExamples:\n\n $ resin os configure ../path/rpi.img --device 7cf02a6\n $ resin os configure ../path/rpi.img --device 7cf02a6 --deviceApiKey \n $ resin os configure ../path/rpi.img --app MyApp', permission: 'user', options: [ - commandOptions.advancedConfig, { + commandOptions.advancedConfig, commandOptions.optionalApplication, commandOptions.optionalDevice, commandOptions.optionalDeviceApiKey, { signature: 'config', description: 'path to the config JSON file, see `resin os build-config`', parameter: 'config' } ], action: function(params, options, done) { - var Promise, fs, generateDeviceConfig, helpers, init, readFileAsync, resin; + var Promise, configurationResourceType, deviceApiKey, fs, generateApplicationConfig, generateDeviceConfig, helpers, init, patterns, readFileAsync, ref, resin, uuid; fs = require('fs'); Promise = require('bluebird'); readFileAsync = Promise.promisify(fs.readFile); resin = require('resin-sdk-preconfigured'); init = require('resin-device-init'); helpers = require('../utils/helpers'); - generateDeviceConfig = require('../utils/config').generateDeviceConfig; + patterns = require('../utils/patterns'); + ref = require('../utils/config'), generateDeviceConfig = ref.generateDeviceConfig, generateApplicationConfig = ref.generateApplicationConfig; + if (_.filter([options.device, options.application, params.uuid]).length !== 1) { + patterns.expectedError('To configure an image, you must provide exactly one of:\n\n* A device, with --device \n* An application, with --app \n* [Deprecated] A device, passing its uuid directly on the command line\n\nSee the help page for examples:\n\n $ resin help os configure'); + } + uuid = options.device || params.uuid; + deviceApiKey = options.deviceApiKey || params.deviceApiKey; console.info('Configuring operating system image'); - return resin.models.device.get(params.uuid).then(function(device) { + configurationResourceType = uuid ? 'device' : 'application'; + return resin.models[configurationResourceType].get(uuid || options.application).then(function(appOrDevice) { return Promise["try"](function() { if (options.config) { return readFileAsync(options.config, 'utf8').then(JSON.parse); } - return buildConfig(params.image, device.device_type, options.advanced); + return buildConfig(params.image, appOrDevice.device_type, options.advanced); }).then(function(answers) { - return generateDeviceConfig(device, params.deviceApiKey, answers).then(function(config) { - return init.configure(params.image, device.device_type, config, answers); + return (configurationResourceType === 'device' ? generateDeviceConfig(appOrDevice, deviceApiKey, answers) : generateApplicationConfig(appOrDevice, answers)).then(function(config) { + return init.configure(params.image, appOrDevice.device_type, config, answers); }); }); }).then(helpers.osProgressHandler).nodeify(done); diff --git a/doc/cli.markdown b/doc/cli.markdown index 18db89d2..a0fb4668 100644 --- a/doc/cli.markdown +++ b/doc/cli.markdown @@ -106,7 +106,7 @@ environment variable (in the same standard URL format). - [os versions <type>](#os-versions-60-type-62-) - [os download <type>](#os-download-60-type-62-) - [os build-config <image> <device-type>](#os-build-config-60-image-62-60-device-type-62-) - - [os configure <image> <uuid> [deviceApiKey]](#os-configure-60-image-62-60-uuid-62-deviceapikey-) + - [os configure <image> [uuid] [deviceApiKey]](#os-configure-60-image-62-uuid-deviceapikey-) - [os initialize <image>](#os-initialize-60-image-62-) - Config @@ -909,16 +909,22 @@ show advanced configuration options the path to the output JSON file -## os configure <image> <uuid> [deviceApiKey] +## os configure <image> [uuid] [deviceApiKey] -Use this command to configure a previously downloaded operating system image for the specific device. +Use this command to configure a previously downloaded operating system image for +the specific device or for an application generally. -Note that device api keys are only supported on ResinOS 2.0.3+ +Note that device api keys are only supported on ResinOS 2.0.3+. + +This comand still supports the *deprecated* format where the UUID and optionally device key +are passed directly on the command line, but the recommended way is to pass either an --app or +--device argument. The deprecated format will be remove in a future release. Examples: - $ resin os configure ../path/rpi.img 7cf02a6 - $ resin os configure ../path/rpi.img 7cf02a6 + $ resin os configure ../path/rpi.img --device 7cf02a6 + $ resin os configure ../path/rpi.img --device 7cf02a6 --deviceApiKey + $ resin os configure ../path/rpi.img --app MyApp ### Options @@ -926,6 +932,18 @@ Examples: show advanced configuration options +#### --application, --a,app, --a,app <application> + +application name + +#### --device, -d <device> + +device uuid + +#### --deviceApiKey, -k <device-api-key> + +custom device key - note that this is only supported on ResinOS 2.0.3+ + #### --config <config> path to the config JSON file, see `resin os build-config` diff --git a/lib/actions/os.coffee b/lib/actions/os.coffee index a5836b6b..ebb54463 100644 --- a/lib/actions/os.coffee +++ b/lib/actions/os.coffee @@ -196,21 +196,30 @@ exports.buildConfig = .nodeify(done) exports.configure = - signature: 'os configure [deviceApiKey]' + signature: 'os configure [uuid] [deviceApiKey]' description: 'configure an os image' help: ''' - Use this command to configure a previously downloaded operating system image for the specific device. + Use this command to configure a previously downloaded operating system image for + the specific device or for an application generally. - Note that device api keys are only supported on ResinOS 2.0.3+ + Note that device api keys are only supported on ResinOS 2.0.3+. + + This comand still supports the *deprecated* format where the UUID and optionally device key + are passed directly on the command line, but the recommended way is to pass either an --app or + --device argument. The deprecated format will be remove in a future release. Examples: - $ resin os configure ../path/rpi.img 7cf02a6 - $ resin os configure ../path/rpi.img 7cf02a6 + $ resin os configure ../path/rpi.img --device 7cf02a6 + $ resin os configure ../path/rpi.img --device 7cf02a6 --deviceApiKey + $ resin os configure ../path/rpi.img --app MyApp ''' permission: 'user' options: [ commandOptions.advancedConfig + commandOptions.optionalApplication + commandOptions.optionalDevice + commandOptions.optionalDeviceApiKey { signature: 'config' description: 'path to the config JSON file, see `resin os build-config`' @@ -224,20 +233,47 @@ exports.configure = resin = require('resin-sdk-preconfigured') init = require('resin-device-init') helpers = require('../utils/helpers') - { generateDeviceConfig } = require('../utils/config') + patterns = require('../utils/patterns') + { generateDeviceConfig, generateApplicationConfig } = require('../utils/config') + + if _.filter([ + options.device + options.application + params.uuid + ]).length != 1 + patterns.expectedError ''' + To configure an image, you must provide exactly one of: + + * A device, with --device + * An application, with --app + * [Deprecated] A device, passing its uuid directly on the command line + + See the help page for examples: + + $ resin help os configure + ''' + + uuid = options.device || params.uuid + deviceApiKey = options.deviceApiKey || params.deviceApiKey console.info('Configuring operating system image') - resin.models.device.get(params.uuid) - .then (device) -> + + configurationResourceType = if uuid then 'device' else 'application' + + resin.models[configurationResourceType].get(uuid || options.application) + .then (appOrDevice) -> Promise.try -> if options.config return readFileAsync(options.config, 'utf8') .then(JSON.parse) - return buildConfig(params.image, device.device_type, options.advanced) + return buildConfig(params.image, appOrDevice.device_type, options.advanced) .then (answers) -> - generateDeviceConfig(device, params.deviceApiKey, answers) - .then (config) -> - init.configure(params.image, device.device_type, config, answers) + (if configurationResourceType == 'device' + generateDeviceConfig(appOrDevice, deviceApiKey, answers) + else + generateApplicationConfig(appOrDevice, answers) + ).then (config) -> + init.configure(params.image, appOrDevice.device_type, config, answers) .then(helpers.osProgressHandler) .nodeify(done) From 49d78c56faa8efaba4005eaf66206ed49e25dd9c Mon Sep 17 00:00:00 2001 From: Tim Perry Date: Thu, 16 Nov 2017 19:47:59 +0100 Subject: [PATCH 4/5] Print a deprecation message if you use the old os configure format --- build/actions/os.js | 3 +++ lib/actions/os.coffee | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/build/actions/os.js b/build/actions/os.js index 6a868c76..212e2c11 100644 --- a/build/actions/os.js +++ b/build/actions/os.js @@ -212,6 +212,9 @@ exports.configure = { if (_.filter([options.device, options.application, params.uuid]).length !== 1) { patterns.expectedError('To configure an image, you must provide exactly one of:\n\n* A device, with --device \n* An application, with --app \n* [Deprecated] A device, passing its uuid directly on the command line\n\nSee the help page for examples:\n\n $ resin help os configure'); } + if (params.uuid) { + console.warn('Directly passing a UUID to `resin os configure` is deprecated. Pass it with --uuid instead.' + (params.deviceApiKey ? ' Device api keys can be passed with --deviceApiKey.\n' : '\n')); + } uuid = options.device || params.uuid; deviceApiKey = options.deviceApiKey || params.deviceApiKey; console.info('Configuring operating system image'); diff --git a/lib/actions/os.coffee b/lib/actions/os.coffee index ebb54463..b7c70e49 100644 --- a/lib/actions/os.coffee +++ b/lib/actions/os.coffee @@ -252,6 +252,13 @@ exports.configure = $ resin help os configure ''' + if params.uuid + console.warn( + 'Directly passing a UUID to `resin os configure` is deprecated. Pass it with --uuid instead.' + + if params.deviceApiKey + ' Device api keys can be passed with --deviceApiKey.\n' + else '\n' + ) uuid = options.device || params.uuid deviceApiKey = options.deviceApiKey || params.deviceApiKey From 67fcc6791cccede39288e04e43d45b10e7540150 Mon Sep 17 00:00:00 2001 From: "resin-io-versionbot[bot]" Date: Fri, 17 Nov 2017 10:43:54 +0000 Subject: [PATCH 5/5] v6.10.0 --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b849432..92a198e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file automatically by Versionist. DO NOT EDIT THIS FILE MANUALLY! This project adheres to [Semantic Versioning](http://semver.org/). +## v6.10.0 - 2017-11-17 + +* Allow `os configure` to configure for an app, not just a specific device #718 [Tim Perry] +* Print help even for expected errors #718 [Tim Perry] + ## v6.9.0 - 2017-11-16 * Allow non-interactice config generate for simple network settings #714 [Tim Perry] diff --git a/package.json b/package.json index b60169d5..e701b2bc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "resin-cli", - "version": "6.9.0", + "version": "6.10.0", "description": "The official resin.io CLI tool", "main": "./build/actions/index.js", "homepage": "https://github.com/resin-io/resin-cli",