Remove etcher-cli

Change-type: major
This commit is contained in:
Alexis Svinartchouk 2019-02-14 16:40:40 +01:00
parent 4568404a70
commit da072e7621
18 changed files with 40 additions and 843 deletions

View File

@ -1,15 +1,4 @@
{ {
"node-cli": {
"node": "6.14.4",
"npm_version": "6.7.0",
"main": "lib/cli/etcher.js",
"dependencies": {
"linux": [
"libudev-dev",
"libusb-1.0-0-dev"
]
}
},
"electron": { "electron": {
"npm_version": "6.7.0", "npm_version": "6.7.0",
"dependencies": { "dependencies": {

View File

@ -117,32 +117,6 @@ electron-build: assets/dmg/background.tiff | $(BUILD_TEMPORARY_DIRECTORY)
-n $(BUILD_TEMPORARY_DIRECTORY)/npm \ -n $(BUILD_TEMPORARY_DIRECTORY)/npm \
-w $(BUILD_TEMPORARY_DIRECTORY) -w $(BUILD_TEMPORARY_DIRECTORY)
# ---------------------------------------------------------------------
# CLI
# ---------------------------------------------------------------------
cli-develop: | $(BUILD_TEMPORARY_DIRECTORY)
$(RESIN_SCRIPTS)/node-cli/install.sh \
-b $(shell pwd) \
-r $(TARGET_ARCH) \
-s $(PLATFORM) \
-n $(BUILD_TEMPORARY_DIRECTORY)/npm \
-a $(S3_BUCKET)
cli-test:
$(RESIN_SCRIPTS)/node-cli/test.sh \
-b $(shell pwd)
cli-build: | $(BUILD_TEMPORARY_DIRECTORY)
$(RESIN_SCRIPTS)/electron/build.sh \
-b $(shell pwd) \
-r $(TARGET_ARCH) \
-s $(PLATFORM) \
-v production \
-n $(BUILD_TEMPORARY_DIRECTORY)/npm \
-w $(BUILD_TEMPORARY_DIRECTORY) \
-a $(S3_BUCKET)
# --------------------------------------------------------------------- # ---------------------------------------------------------------------
# Phony targets # Phony targets
# --------------------------------------------------------------------- # ---------------------------------------------------------------------
@ -158,16 +132,12 @@ TARGETS = \
lint-spell \ lint-spell \
test-spectron \ test-spectron \
test-gui \ test-gui \
test-cli \
test \ test \
sanity-checks \ sanity-checks \
clean \ clean \
distclean \ distclean \
changelog \ changelog \
webpack \ webpack \
cli-develop \
cli-test \
cli-build \
electron-develop \ electron-develop \
electron-test \ electron-test \
electron-build electron-build
@ -219,10 +189,6 @@ test-sdk:
electron-mocha $(MOCHA_OPTIONS) \ electron-mocha $(MOCHA_OPTIONS) \
tests/shared tests/shared
test-cli:
mocha $(MOCHA_OPTIONS) \
tests/shared
test: test-gui test-sdk test-spectron test: test-gui test-sdk test-spectron
help: help:

View File

@ -15,7 +15,7 @@ was written correctly and much more.
*** ***
[**Download**][etcher] | [**Support**][SUPPORT] | [**Documentation**][USER-DOCUMENTATION] | [**Contributing**][CONTRIBUTING] | [**Roadmap**][milestones] | [**CLI**][CLI] [**Download**][etcher] | [**Support**][SUPPORT] | [**Documentation**][USER-DOCUMENTATION] | [**Contributing**][CONTRIBUTING] | [**Roadmap**][milestones]
![Etcher](https://raw.githubusercontent.com/balena-io/etcher/master/screenshot.png) ![Etcher](https://raw.githubusercontent.com/balena-io/etcher/master/screenshot.png)
@ -154,7 +154,6 @@ the [license].
[electron-supported-platforms]: http://electron.atom.io/docs/tutorial/supported-platforms/ [electron-supported-platforms]: http://electron.atom.io/docs/tutorial/supported-platforms/
[SUPPORT]: https://github.com/balena-io/etcher/blob/master/SUPPORT.md [SUPPORT]: https://github.com/balena-io/etcher/blob/master/SUPPORT.md
[CONTRIBUTING]: https://github.com/balena-io/etcher/blob/master/docs/CONTRIBUTING.md [CONTRIBUTING]: https://github.com/balena-io/etcher/blob/master/docs/CONTRIBUTING.md
[CLI]: https://github.com/balena-io/etcher/blob/master/docs/CLI.md
[USER-DOCUMENTATION]: https://github.com/balena-io/etcher/blob/master/docs/USER-DOCUMENTATION.md [USER-DOCUMENTATION]: https://github.com/balena-io/etcher/blob/master/docs/USER-DOCUMENTATION.md
[milestones]: https://github.com/balena-io/etcher/milestones [milestones]: https://github.com/balena-io/etcher/milestones
[newissue]: https://github.com/balena-io/etcher/issues/new [newissue]: https://github.com/balena-io/etcher/issues/new

View File

@ -1,2 +0,0 @@
#!/usr/bin/env node
require('../lib/cli/etcher');

View File

@ -52,32 +52,6 @@ a system drive.
This is the *"main repository"*, from which you're reading this from, which is This is the *"main repository"*, from which you're reading this from, which is
basically the front-end and glue for all previously listed projects. basically the front-end and glue for all previously listed projects.
Front-ends
----------
The main repository consists of the implementation of the Etcher CLI and the
Etcher GUI (the desktop application), located at [`lib/cli/`][cli-dir] and
[`lib/gui/`][gui-dir], respectively.
In fact, the only front-end that interacts directly with Etcher's backend is
the CLI. The GUI merely forks the CLI and communicates with its child process
to get state information.
In this sense, you can consider the GUI as being the front-end to the CLI,
which is in turn the front-end to the actual image writing functionality.
As a way to simplify how the GUI forks the CLI in a packaged and distributed
context, both the CLI and GUI share the same application entry point. This
means that the same Etcher binary can behave as CLI or GUI as needed.
## Process communication
As mentioned before, the Etcher GUI forks the CLI and retrieves information
from it to update its state. In order to accomplish this, the Etcher CLI
contains certain features to ease communication:
- [Well-documented exit codes.][exit-codes]
Summary Summary
------- -------
@ -89,7 +63,6 @@ be documented instead!
[lego-blocks]: https://github.com/sindresorhus/ama/issues/10#issuecomment-117766328 [lego-blocks]: https://github.com/sindresorhus/ama/issues/10#issuecomment-117766328
[exit-codes]: https://github.com/balena-io/etcher/blob/master/lib/shared/exit-codes.js [exit-codes]: https://github.com/balena-io/etcher/blob/master/lib/shared/exit-codes.js
[cli-dir]: https://github.com/balena-io/etcher/tree/master/lib/cli
[gui-dir]: https://github.com/balena-io/etcher/tree/master/lib/gui [gui-dir]: https://github.com/balena-io/etcher/tree/master/lib/gui
[electron]: http://electron.atom.io [electron]: http://electron.atom.io
[nodejs]: https://nodejs.org [nodejs]: https://nodejs.org

View File

@ -1,61 +0,0 @@
### macOS and GNU/Linux
- Extract the `.tar.gz` package by running:
```sh
tar fvx path/to/cli.tar.gz
```
- Move the resulting directory to `/opt/etcher-cli`
- Add `/opt/etcher-cli` to the `PATH`. For example, add the following to
`.bashrc` or `.zshrc`:
```sh
export PATH="$PATH:/opt/etcher-cli"
```
### Windows
- Unzip the `.zip` package by right-clicking on it and selecting "Extract All"
- Move the resulting directory to `C:\etcher-cli`
- Add `C:\etcher-cli` to the `%PATH%`
- On Windows 10 and Windows 8
- Open *Control Panel*
- Open *System*
- Click the *Advanced system settings* link
- Click *Environment Variables*
- Find the `PATH` environment variable, and click *Edit*
- Append `;C:\etcher-cli` to the environment variable value
- Click *OK*
- On Windows 7
- Right-click the *My Computer* icon
- Open the *Properties* menu
- Open the *Advanced* tab
- Click *Environment Variables*
- Find the `PATH` environment variable, and click *Edit*
- Append `;C:\etcher-cli` to the environment variable value
- Click *OK*
- Re-open `cmd.exe`, or PowerShell
### Running
```sh
etcher -v
```
### Options
```
--help, -h show help
--version, -v show version number
--drive, -d drive
--check, -c validate write
--yes, -y confirm non-interactively
--unmount, -u unmount on success
```

View File

@ -1,42 +0,0 @@
Etcher CLI
==========
The Etcher CLI is a command-line tool that aims to provide all the benefits of
the Etcher desktop application in a way that can be run from a terminal, or
even used from a script.
In fact, the Etcher desktop application is simply a wrapper around the CLI,
which is the place where the actual writing logic takes place.
Installing
----------
Head over to [etcher.io/cli][etcher-cli], download the package that corresponds to
your operating system, and then follow the installation instructions there.
Running
-------
```sh
etcher -v
```
Options
-------
```
--help, -h show help
--version, -v show version number
--drive, -d drive
--check, -c validate write
--yes, -y confirm non-interactively
--unmount, -u unmount on success
```
Debug mode
----------
You can set the `ETCHER_CLI_DEBUG` environment variable to make the Etcher CLI
print error stack traces.
[etcher-cli]: https://etcher.io/cli

View File

@ -56,11 +56,6 @@ The scope is required for types that make sense, such as `feat`, `fix`,
`test`, etc. Certain commit types, such as `chore` might not have a clearly `test`, etc. Certain commit types, such as `chore` might not have a clearly
defined scope, in which case its better to omit it. defined scope, in which case its better to omit it.
When it applies, the scope must be either `GUI` or `CLI`.
A commit that takes part in both the GUI and CLI scopes, and makes more logical
sense that way, might entirely omit the scope.
Subject Subject
------- -------

View File

@ -94,12 +94,6 @@ make webpack
npm start npm start
``` ```
#### CLI
```sh
node bin/etcher
```
Testing Testing
------- -------

View File

@ -105,8 +105,6 @@ export ANALYTICS_MIXPANEL_TOKEN="xxxxxx"
./scripts/build/docker/run-command.sh -r x64 -s . -c "make electron-develop && make RELEASE_TYPE=production electron-installer-redhat" ./scripts/build/docker/run-command.sh -r x64 -s . -c "make electron-develop && make RELEASE_TYPE=production electron-installer-redhat"
# Build AppImages # Build AppImages
./scripts/build/docker/run-command.sh -r x64 -s . -c "make electron-develop && make RELEASE_TYPE=production electron-installer-appimage" ./scripts/build/docker/run-command.sh -r x64 -s . -c "make electron-develop && make RELEASE_TYPE=production electron-installer-appimage"
# Build CLI
./scripts/build/docker/run-command.sh -r x64 -s . -c "make electron-develop && make RELEASE_TYPE=production cli-installer-tar-gz"
# x86 # x86
@ -116,8 +114,6 @@ export ANALYTICS_MIXPANEL_TOKEN="xxxxxx"
./scripts/build/docker/run-command.sh -r x86 -s . -c "make electron-develop && make RELEASE_TYPE=production electron-installer-redhat" ./scripts/build/docker/run-command.sh -r x86 -s . -c "make electron-develop && make RELEASE_TYPE=production electron-installer-redhat"
# Build AppImages # Build AppImages
./scripts/build/docker/run-command.sh -r x86 -s . -c "make electron-develop && make RELEASE_TYPE=production electron-installer-appimage" ./scripts/build/docker/run-command.sh -r x86 -s . -c "make electron-develop && make RELEASE_TYPE=production electron-installer-appimage"
# Build CLI
./scripts/build/docker/run-command.sh -r x86 -s . -c "make electron-develop && make RELEASE_TYPE=production cli-installer-tar-gz"
``` ```
#### Mac OS #### Mac OS
@ -125,13 +121,9 @@ export ANALYTICS_MIXPANEL_TOKEN="xxxxxx"
**ATTENTION:** For production releases you'll need the code-signing key, **ATTENTION:** For production releases you'll need the code-signing key,
and set `CSC_NAME` to generate signed binaries on Mac OS. and set `CSC_NAME` to generate signed binaries on Mac OS.
**NOTE:** The CLI is not code-signed for either at this time.
```bash ```bash
make electron-develop make electron-develop
# Build the CLI
make RELEASE_TYPE=production cli-installer-tar-gz
# Build the zip # Build the zip
make RELEASE_TYPE=production electron-installer-app-zip make RELEASE_TYPE=production electron-installer-app-zip
# Build the dmg # Build the dmg
@ -144,14 +136,11 @@ make RELEASE_TYPE=production electron-installer-dmg
and set `CSC_LINK`, and `CSC_KEY_PASSWORD` to generate signed binaries on Windows. and set `CSC_LINK`, and `CSC_KEY_PASSWORD` to generate signed binaries on Windows.
**NOTE:** **NOTE:**
- The CLI is not code-signed for either at this time.
- Keep in mind to also generate artifacts for x86, with `TARGET_ARCH=x86`. - Keep in mind to also generate artifacts for x86, with `TARGET_ARCH=x86`.
```bash ```bash
make electron-develop make electron-develop
# Build the CLI
make RELEASE_TYPE=production cli-installer-zip
# Build the Portable version # Build the Portable version
make RELEASE_TYPE=production electron-installer-portable make RELEASE_TYPE=production electron-installer-portable
# Build the Installer # Build the Installer

View File

@ -208,9 +208,6 @@ Running in older macOS versions
Etcher GUI is based on the [Electron][electron] framework, [which only supports Etcher GUI is based on the [Electron][electron] framework, [which only supports
macOS 10.9 and newer versions][electron-supported-platforms]. macOS 10.9 and newer versions][electron-supported-platforms].
You can however, run the [Etcher CLI][etcher-cli], which should work in older
platforms.
[balena.io]: https://balena.io [balena.io]: https://balena.io
[appimage]: http://appimage.org [appimage]: http://appimage.org
[xwayland]: https://wayland.freedesktop.org/xserver.html [xwayland]: https://wayland.freedesktop.org/xserver.html
@ -218,7 +215,6 @@ platforms.
[diskpart]: https://technet.microsoft.com/en-us/library/cc770877(v=ws.11).aspx [diskpart]: https://technet.microsoft.com/en-us/library/cc770877(v=ws.11).aspx
[electron]: http://electron.atom.io [electron]: http://electron.atom.io
[electron-supported-platforms]: https://github.com/electron/electron/blob/master/docs/tutorial/supported-platforms.md [electron-supported-platforms]: https://github.com/electron/electron/blob/master/docs/tutorial/supported-platforms.md
[etcher-cli]: https://github.com/balena-io/etcher/blob/master/docs/CLI.md
[publishing]: https://github.com/balena-io/etcher/blob/master/docs/PUBLISHING.md [publishing]: https://github.com/balena-io/etcher/blob/master/docs/PUBLISHING.md
[windows-usb-tool]: https://www.microsoft.com/en-us/download/windows-usb-dvd-download-tool [windows-usb-tool]: https://www.microsoft.com/en-us/download/windows-usb-dvd-download-tool
[rufus]: https://rufus.akeo.ie [rufus]: https://rufus.akeo.ie

View File

@ -1,21 +0,0 @@
Etcher CLI
==========
The Etcher CLI is a command line interface to the Etcher writer backend, and
currently the only module in the "Etcher" umbrella that makes use of this
backend directly.
This module also has the task of unmounting the drives before and after
flashing.
Notice the Etcher CLI is not worried about elevation, and assumes it has enough
permissions to continue, throwing an error otherwise.
Exit codes
----------
The Etcher CLI uses certain exit codes to signal the result of the operation.
These are documented in [`lib/shared/exit-codes.js`][exit-codes] and are also
printed on the Etcher CLI help page.
[exit-codes]: https://github.com/balena-io/etcher/blob/master/lib/shared/exit-codes.js

View File

@ -1,177 +0,0 @@
/*
* Copyright 2016 resin.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict'
const _ = require('lodash')
const Bluebird = require('bluebird')
const visuals = require('resin-cli-visuals')
const form = require('resin-cli-form')
const bytes = require('pretty-bytes')
const sdk = require('etcher-sdk')
const utils = require('./utils')
const options = require('./options')
const messages = require('../shared/messages')
const EXIT_CODES = require('../shared/exit-codes')
const errors = require('../shared/errors')
const permissions = require('../shared/permissions')
/* eslint-disable no-magic-numbers */
const ARGV_IMAGE_PATH_INDEX = 0
const imagePath = options._[ARGV_IMAGE_PATH_INDEX]
permissions.isElevated().then((elevated) => {
if (!elevated) {
throw errors.createUserError({
title: messages.error.elevationRequired(),
description: 'This tool requires special permissions to write to external drives'
})
}
return form.run([
{
message: 'Select drive',
type: 'drive',
name: 'drive'
},
{
message: 'This will erase the selected drive. Are you sure?',
type: 'confirm',
name: 'yes',
default: false
}
], {
override: {
drive: options.drive,
// If `options.yes` is `false`, pass `null`,
// otherwise the question will not be asked because
// `false` is a defined value.
yes: options.yes || null
}
})
}).then((answers) => {
if (!answers.yes) {
throw errors.createUserError({
title: 'Aborted',
description: 'We can\'t proceed without confirmation'
})
}
const progressBars = new Map()
let lastStateType = null
// eslint-disable-next-line require-jsdoc
const onProgress = (state) => {
state.message = state.active > 1
? `${bytes(state.totalSpeed)}/s total, ${bytes(state.speed)}/s x ${state.active}`
: `${bytes(state.totalSpeed)}/s`
state.message = `${state.type === 'flashing' ? 'Flashing' : 'Validating'}: ${state.message}`
// eslint-disable-next-line no-undefined
if (state.percentage === undefined) {
state.message += ` - ${bytes(state.bytes)} written`
}
// Update progress bar
let progressBar = progressBars.get(state.type)
// eslint-disable-next-line no-undefined
if (progressBar === undefined) {
// Stop the spinner if there is one
if ((lastStateType !== null) && (lastStateType !== state.type)) {
const spinner = progressBars.get(lastStateType)
// eslint-disable-next-line no-undefined
if ((spinner !== undefined) && (spinner instanceof visuals.Spinner)) {
console.log()
spinner.stop()
}
}
// eslint-disable-next-line no-undefined
if (state.percentage === undefined) {
progressBar = new visuals.Spinner(state.message)
progressBar.start()
} else {
progressBar = new visuals.Progress(state.message)
progressBar.update(state)
}
progressBars.set(state.type, progressBar)
} else if (progressBar instanceof visuals.Spinner) {
progressBar.spinner.setSpinnerTitle(state.message)
} else {
progressBar.update(state)
}
lastStateType = state.type
}
const adapter = new sdk.scanner.adapters.BlockDeviceAdapter(() => {
return options.unmount
})
const scanner = new sdk.scanner.Scanner([ adapter ])
return new Promise((resolve, reject) => {
scanner.on('ready', resolve)
scanner.on('error', reject)
scanner.start()
})
.then(() => {
return (new sdk.sourceDestination.File(imagePath, sdk.sourceDestination.File.OpenFlags.Read)).getInnerSource()
})
.then((innerSource) => {
// NOTE: Drive can be (String|Array)
const destinations = _.map([].concat(answers.drive), (device) => {
const drive = scanner.getBy('device', device)
if (!drive) {
throw new Error(`No such drive ${device}`)
}
return drive
})
return sdk.multiWrite.pipeSourceToDestinations(
innerSource,
destinations,
(destination, error) => {
console.log(`Error "${error}" on ${destination.drive}`)
},
onProgress,
options.check
)
})
}).then(({ failures, bytesWritten }) => {
let exitCode = EXIT_CODES.SUCCESS
if (failures.size > 0) {
exitCode = EXIT_CODES.GENERAL_ERROR
console.log('')
for (const [ destination, error ] of failures) {
console.log(` - ${destination.drive}: ${error.message}`)
}
}
process.exit(exitCode)
}).catch((error) => {
return Bluebird.try(() => {
utils.printError(error)
return Bluebird.resolve()
}).then(() => {
if (error.code === 'EVALIDATION') {
process.exit(EXIT_CODES.VALIDATION_ERROR)
}
process.exit(EXIT_CODES.GENERAL_ERROR)
})
})

View File

@ -1,166 +0,0 @@
/*
* Copyright 2016 resin.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict'
const _ = require('lodash')
const fs = require('fs')
const yargs = require('yargs')
const utils = require('./utils')
const EXIT_CODES = require('../shared/exit-codes')
const errors = require('../shared/errors')
const packageJSON = require('../../package.json')
/**
* @summary The minimum required number of CLI arguments
* @constant
* @private
* @type {Number}
*/
const MINIMUM_NUMBER_OF_ARGUMENTS = 1
/**
* @summary The index of the image argument
* @constant
* @private
* @type {Number}
*/
const IMAGE_PATH_ARGV_INDEX = 0
/**
* @summary The first index that represents an actual option argument
* @constant
* @private
* @type {Number}
*
* @description
* The first arguments are usually the program executable itself, etc.
*/
const OPTIONS_INDEX_START = 2
/**
* @summary Parsed CLI options and arguments
* @type {Object}
* @public
*/
module.exports = yargs
// Don't wrap at all
.wrap(null)
.demand(MINIMUM_NUMBER_OF_ARGUMENTS, 'Missing image')
// Usage help
.usage('Usage: $0 [options] <image>')
.epilogue([
'Exit codes:',
_.map(EXIT_CODES, (value, key) => {
const reason = _.map(_.split(key, '_'), _.capitalize).join(' ')
return ` ${value} - ${reason}`
}).join('\n'),
'',
'If you need help, don\'t hesitate in contacting us at:',
'',
' GitHub: https://github.com/balena-io/etcher/issues/new',
' Forums: https://forums.balena.io/c/etcher'
].join('\n'))
// Examples
.example('$0 raspberry-pi.img')
.example('$0 --no-check raspberry-pi.img')
.example('$0 -d /dev/disk2 ubuntu.iso')
.example('$0 -d /dev/disk2 -y rpi.img')
// Help option
.help()
// Version option
.version(packageJSON.version)
// Error reporting
.fail((message, error) => {
const errorObject = error || errors.createUserError({
title: message
})
yargs.showHelp()
utils.printError(errorObject)
process.exit(EXIT_CODES.GENERAL_ERROR)
})
// Assert that image exists
.check((argv) => {
const imagePath = argv._[IMAGE_PATH_ARGV_INDEX]
try {
fs.accessSync(imagePath)
} catch (error) {
throw errors.createUserError({
title: 'Unable to access file',
description: `The image ${imagePath} is not accessible`
})
}
return true
})
// Assert that if the `yes` flag is provided, the `drive` flag is also provided.
.check((argv) => {
if (argv.yes && !argv.drive) {
throw errors.createUserError({
title: 'Missing drive',
description: 'You need to explicitly pass a drive when disabling interactively'
})
}
return true
})
.options({
help: {
describe: 'show help',
boolean: true,
alias: 'h'
},
version: {
describe: 'show version number',
boolean: true,
alias: 'v'
},
drive: {
describe: 'drive',
string: true,
alias: 'd'
},
check: {
describe: 'validate write',
boolean: true,
alias: 'c',
default: true
},
yes: {
describe: 'confirm non-interactively',
boolean: true,
alias: 'y'
},
unmount: {
describe: 'unmount on success',
boolean: true,
alias: 'u',
default: true
}
})
.parse(process.argv.slice(OPTIONS_INDEX_START))

View File

@ -1,47 +0,0 @@
/*
* Copyright 2016 resin.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict'
const chalk = require('chalk')
const errors = require('../shared/errors')
/**
* @summary Print an error to stderr
* @function
* @public
*
* @param {Error} error - error
*
* @example
* utils.printError(new Error('Oops!'));
*/
exports.printError = (error) => {
const title = errors.getTitle(error)
const description = errors.getDescription(error, {
userFriendlyDescriptionsOnly: true
})
console.error(chalk.red(title))
if (description) {
console.error(`\n${chalk.red(description)}`)
}
if (process.env.ETCHER_CLI_DEBUG && error.stack) {
console.error(`\n${chalk.red(error.stack)}`)
}
}

View File

@ -19,7 +19,6 @@
const Bluebird = require('bluebird') const Bluebird = require('bluebird')
const fs = require('fs') const fs = require('fs')
const path = require('path') const path = require('path')
const os = require('os')
/** /**
* @summary Number of spaces to indent JSON output with * @summary Number of spaces to indent JSON output with
@ -40,26 +39,12 @@ const JSON_INDENT = 2
* @type {String} * @type {String}
*/ */
const USER_DATA_DIR = (() => { const USER_DATA_DIR = (() => {
// Electron // NOTE: The ternary is due to this module being loaded both,
if (process.versions.electron) { // Electron's main process and renderer process
// NOTE: The ternary is due to this module being loaded both, const electron = require('electron')
// Electron's main process and renderer process return electron.app
const electron = require('electron') ? electron.app.getPath('userData')
return electron.app : electron.remote.app.getPath('userData')
? electron.app.getPath('userData')
: electron.remote.app.getPath('userData')
}
// CLI
if (process.platform === 'win32') {
return path.join(process.env.APPDATA, 'etcher')
}
if (process.platform === 'darwin') {
return path.join(os.homedir(), 'Library', 'Application Support', 'etcher')
}
return path.join(process.env.XDG_CONFIG_HOME || os.homedir(), '.config', 'etcher')
})() })()
/** /**

229
npm-shrinkwrap.json generated
View File

@ -1654,7 +1654,8 @@
"ansi-escapes": { "ansi-escapes": {
"version": "1.4.0", "version": "1.4.0",
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
"integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=" "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=",
"dev": true
}, },
"ansi-gray": { "ansi-gray": {
"version": "0.1.1", "version": "0.1.1",
@ -3276,15 +3277,11 @@
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz",
"integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=",
"dev": true,
"requires": { "requires": {
"restore-cursor": "^1.0.1" "restore-cursor": "^1.0.1"
} }
}, },
"cli-spinner": {
"version": "0.2.7",
"resolved": "https://registry.npmjs.org/cli-spinner/-/cli-spinner-0.2.7.tgz",
"integrity": "sha1-f3hopvUu1aYh1Rac7UKLYYR6l8c="
},
"cli-table3": { "cli-table3": {
"version": "0.5.1", "version": "0.5.1",
"resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz", "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz",
@ -3329,11 +3326,6 @@
} }
} }
}, },
"cli-width": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/cli-width/-/cli-width-1.1.1.tgz",
"integrity": "sha1-pNKT72frt7iNSk1CwMzwDE0eNm0="
},
"cliui": { "cliui": {
"version": "4.1.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz",
@ -3373,11 +3365,6 @@
} }
} }
}, },
"clone": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
"integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4="
},
"co": { "co": {
"version": "4.6.0", "version": "4.6.0",
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
@ -3440,15 +3427,6 @@
"integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==", "integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==",
"dev": true "dev": true
}, },
"columnify": {
"version": "1.5.4",
"resolved": "https://registry.npmjs.org/columnify/-/columnify-1.5.4.tgz",
"integrity": "sha1-Rzfd8ce2mop8NAVweC6UfuyOeLs=",
"requires": {
"strip-ansi": "^3.0.0",
"wcwidth": "^1.0.0"
}
},
"combined-stream": { "combined-stream": {
"version": "1.0.7", "version": "1.0.7",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz",
@ -4282,14 +4260,6 @@
} }
} }
}, },
"defaults": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz",
"integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=",
"requires": {
"clone": "^1.0.2"
}
},
"define-properties": { "define-properties": {
"version": "1.1.3", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
@ -5946,7 +5916,8 @@
"exit-hook": { "exit-hook": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz",
"integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=" "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=",
"dev": true
}, },
"expand-brackets": { "expand-brackets": {
"version": "2.1.4", "version": "2.1.4",
@ -6318,6 +6289,7 @@
"version": "1.7.0", "version": "1.7.0",
"resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
"integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=",
"dev": true,
"requires": { "requires": {
"escape-string-regexp": "^1.0.5", "escape-string-regexp": "^1.0.5",
"object-assign": "^4.1.0" "object-assign": "^4.1.0"
@ -7614,55 +7586,6 @@
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
}, },
"inquirer": {
"version": "0.11.4",
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.11.4.tgz",
"integrity": "sha1-geM3ToNhvq/y2XAWIG01nQsy+k0=",
"requires": {
"ansi-escapes": "^1.1.0",
"ansi-regex": "^2.0.0",
"chalk": "^1.0.0",
"cli-cursor": "^1.0.1",
"cli-width": "^1.0.1",
"figures": "^1.3.5",
"lodash": "^3.3.1",
"readline2": "^1.0.1",
"run-async": "^0.1.0",
"rx-lite": "^3.1.2",
"string-width": "^1.0.1",
"strip-ansi": "^3.0.0",
"through": "^2.3.6"
},
"dependencies": {
"lodash": {
"version": "3.10.1",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
"integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y="
}
}
},
"inquirer-dynamic-list": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/inquirer-dynamic-list/-/inquirer-dynamic-list-1.0.0.tgz",
"integrity": "sha1-x13pQj1yCoTRgQc6QKGO6kftC3g=",
"requires": {
"bluebird": "^2.10.2",
"inquirer": "^0.11.0",
"lodash": "^3.10.1"
},
"dependencies": {
"bluebird": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz",
"integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE="
},
"lodash": {
"version": "3.10.1",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
"integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y="
}
}
},
"interpret": { "interpret": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz",
@ -7956,7 +7879,8 @@
"is-promise": { "is-promise": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
"integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
"dev": true
}, },
"is-property": { "is-property": {
"version": "1.0.2", "version": "1.0.2",
@ -9281,11 +9205,6 @@
"resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz",
"integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg=="
}, },
"moment-duration-format": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/moment-duration-format/-/moment-duration-format-2.2.2.tgz",
"integrity": "sha1-uVdhLeJgFsmtnrYIfAVFc+USd3k="
},
"mountutils": { "mountutils": {
"version": "1.3.16", "version": "1.3.16",
"resolved": "https://registry.npmjs.org/mountutils/-/mountutils-1.3.16.tgz", "resolved": "https://registry.npmjs.org/mountutils/-/mountutils-1.3.16.tgz",
@ -9328,7 +9247,8 @@
"mute-stream": { "mute-stream": {
"version": "0.0.5", "version": "0.0.5",
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz",
"integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=" "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=",
"dev": true
}, },
"nan": { "nan": {
"version": "2.12.1", "version": "2.12.1",
@ -9883,7 +9803,8 @@
"onetime": { "onetime": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
"integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=" "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=",
"dev": true
}, },
"optimist": { "optimist": {
"version": "0.6.1", "version": "0.6.1",
@ -10559,11 +10480,6 @@
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
"dev": true "dev": true
}, },
"progress-bar-formatter": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/progress-bar-formatter/-/progress-bar-formatter-2.0.1.tgz",
"integrity": "sha1-DZfrsWRn4sIwg3NXIXa3w1UeVW4="
},
"progress-stream": { "progress-stream": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/progress-stream/-/progress-stream-1.2.0.tgz", "resolved": "https://registry.npmjs.org/progress-stream/-/progress-stream-1.2.0.tgz",
@ -10948,6 +10864,7 @@
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz",
"integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=",
"dev": true,
"requires": { "requires": {
"code-point-at": "^1.0.0", "code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0", "is-fullwidth-code-point": "^1.0.0",
@ -11736,82 +11653,6 @@
"resolve-from": "^1.0.0" "resolve-from": "^1.0.0"
} }
}, },
"resin-cli-form": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/resin-cli-form/-/resin-cli-form-1.4.2.tgz",
"integrity": "sha512-ksLMak241nJ+/iXIv0WVZclf1tApo6Hf8KHkMnT34IRF+RolhZbzrkPTUCo51v17wJs85R2NdEX4eTnIakmhUQ==",
"requires": {
"bluebird": "^2.9.30",
"inquirer": "^0.11.0",
"lodash": "^4.17.10",
"resin-cli-visuals": "^1.2.0"
},
"dependencies": {
"bluebird": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz",
"integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE="
}
}
},
"resin-cli-visuals": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/resin-cli-visuals/-/resin-cli-visuals-1.4.2.tgz",
"integrity": "sha512-N0TDOFrV8mGWNi2wk3Lk202bw3uw7m7ZLpJ1abyWyMEBYRq7YSehArWaJig19PlemfHNpANueaf1VM8TTxoM5Q==",
"requires": {
"bluebird": "^3.5.1",
"chalk": "^2.3.1",
"cli-spinner": "0.2.7",
"columnify": "^1.5.1",
"drivelist": "^6.0.4",
"inquirer": "^0.11.0",
"inquirer-dynamic-list": "^1.0.0",
"is-promise": "^2.1.0",
"lodash": "^3.10.0",
"moment": "^2.10.3",
"moment-duration-format": "^2.2.2",
"progress-bar-formatter": "^2.0.1",
"underscore.string": "^3.1.1"
},
"dependencies": {
"ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"requires": {
"color-convert": "^1.9.0"
}
},
"chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
}
},
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
},
"lodash": {
"version": "3.10.1",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
"integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y="
},
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"requires": {
"has-flag": "^3.0.0"
}
}
}
},
"resin-corvus": { "resin-corvus": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/resin-corvus/-/resin-corvus-2.0.1.tgz", "resolved": "https://registry.npmjs.org/resin-corvus/-/resin-corvus-2.0.1.tgz",
@ -11915,6 +11756,7 @@
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz",
"integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=",
"dev": true,
"requires": { "requires": {
"exit-hook": "^1.0.0", "exit-hook": "^1.0.0",
"onetime": "^1.0.0" "onetime": "^1.0.0"
@ -11959,6 +11801,7 @@
"version": "0.1.0", "version": "0.1.0",
"resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz",
"integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=",
"dev": true,
"requires": { "requires": {
"once": "^1.3.0" "once": "^1.3.0"
} }
@ -11980,7 +11823,8 @@
"rx-lite": { "rx-lite": {
"version": "3.1.2", "version": "3.1.2",
"resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz",
"integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=" "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=",
"dev": true
}, },
"rx-lite-aggregates": { "rx-lite-aggregates": {
"version": "4.0.8", "version": "4.0.8",
@ -12965,11 +12809,6 @@
"extend-shallow": "^3.0.0" "extend-shallow": "^3.0.0"
} }
}, },
"sprintf-js": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz",
"integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug=="
},
"sshpk": { "sshpk": {
"version": "1.16.1", "version": "1.16.1",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
@ -13568,7 +13407,8 @@
"through": { "through": {
"version": "2.3.8", "version": "2.3.8",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
"dev": true
}, },
"through2": { "through2": {
"version": "0.2.3", "version": "0.2.3",
@ -13911,15 +13751,6 @@
"integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=", "integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=",
"dev": true "dev": true
}, },
"underscore.string": {
"version": "3.3.5",
"resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.5.tgz",
"integrity": "sha512-g+dpmgn+XBneLmXXo+sGlW5xQEt4ErkS3mgeN2GFbremYeMBSJKr9Wf2KJplQVaiPY/f7FN6atosWYNm9ovrYg==",
"requires": {
"sprintf-js": "^1.0.3",
"util-deprecate": "^1.0.2"
}
},
"unicode-canonical-property-names-ecmascript": { "unicode-canonical-property-names-ecmascript": {
"version": "1.0.4", "version": "1.0.4",
"resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz",
@ -14408,14 +14239,6 @@
"neo-async": "^2.5.0" "neo-async": "^2.5.0"
} }
}, },
"wcwidth": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
"integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=",
"requires": {
"defaults": "^1.0.3"
}
},
"wdio-dot-reporter": { "wdio-dot-reporter": {
"version": "0.0.10", "version": "0.0.10",
"resolved": "https://registry.npmjs.org/wdio-dot-reporter/-/wdio-dot-reporter-0.0.10.tgz", "resolved": "https://registry.npmjs.org/wdio-dot-reporter/-/wdio-dot-reporter-0.0.10.tgz",
@ -15205,6 +15028,7 @@
"version": "11.1.0", "version": "11.1.0",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz",
"integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==",
"dev": true,
"requires": { "requires": {
"cliui": "^4.0.0", "cliui": "^4.0.0",
"decamelize": "^1.1.1", "decamelize": "^1.1.1",
@ -15223,17 +15047,20 @@
"ansi-regex": { "ansi-regex": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
"dev": true
}, },
"camelcase": { "camelcase": {
"version": "4.1.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
"integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
"dev": true
}, },
"find-up": { "find-up": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
"integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
"dev": true,
"requires": { "requires": {
"locate-path": "^2.0.0" "locate-path": "^2.0.0"
} }
@ -15241,12 +15068,14 @@
"is-fullwidth-code-point": { "is-fullwidth-code-point": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
"dev": true
}, },
"string-width": { "string-width": {
"version": "2.1.1", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
"integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
"dev": true,
"requires": { "requires": {
"is-fullwidth-code-point": "^2.0.0", "is-fullwidth-code-point": "^2.0.0",
"strip-ansi": "^4.0.0" "strip-ansi": "^4.0.0"
@ -15256,6 +15085,7 @@
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
"integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
"dev": true,
"requires": { "requires": {
"ansi-regex": "^3.0.0" "ansi-regex": "^3.0.0"
} }
@ -15264,6 +15094,7 @@
"version": "9.0.2", "version": "9.0.2",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz",
"integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=",
"dev": true,
"requires": { "requires": {
"camelcase": "^4.1.0" "camelcase": "^4.1.0"
} }

View File

@ -28,8 +28,7 @@
"watch": "webpack --watch", "watch": "webpack --watch",
"concourse-build-electron": "make webpack", "concourse-build-electron": "make webpack",
"concourse-test": "npx npm@6.7.0 test", "concourse-test": "npx npm@6.7.0 test",
"concourse-test-electron": "npx npm@6.7.0 test", "concourse-test-electron": "npx npm@6.7.0 test"
"concourse-test-node-cli": "make webpack lint-js lint-cpp lint-spell test-cli"
}, },
"author": "Balena Inc. <hello@etcher.io>", "author": "Balena Inc. <hello@etcher.io>",
"license": "Apache-2.0", "license": "Apache-2.0",
@ -44,7 +43,6 @@
"bindings": "^1.3.0", "bindings": "^1.3.0",
"bluebird": "^3.5.3", "bluebird": "^3.5.3",
"bootstrap-sass": "^3.3.6", "bootstrap-sass": "^3.3.6",
"chalk": "^1.1.3",
"color": "^2.0.1", "color": "^2.0.1",
"command-join": "^2.0.0", "command-join": "^2.0.0",
"d3": "^4.13.0", "d3": "^4.13.0",
@ -68,8 +66,6 @@
"redux": "^3.5.2", "redux": "^3.5.2",
"rendition": "4.41.1", "rendition": "4.41.1",
"request": "^2.81.0", "request": "^2.81.0",
"resin-cli-form": "^1.4.1",
"resin-cli-visuals": "^1.4.1",
"resin-corvus": "^2.0.1", "resin-corvus": "^2.0.1",
"roboto-fontface": "^0.9.0", "roboto-fontface": "^0.9.0",
"semver": "^5.1.1", "semver": "^5.1.1",
@ -77,8 +73,7 @@
"styled-system": "^3.1.11", "styled-system": "^3.1.11",
"sudo-prompt": "^8.2.3", "sudo-prompt": "^8.2.3",
"uuid": "^3.0.1", "uuid": "^3.0.1",
"xml2js": "^0.4.17", "xml2js": "^0.4.17"
"yargs": "^11.0.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.2.0", "@babel/core": "^7.2.0",
@ -88,6 +83,7 @@
"acorn": "^6.0.5", "acorn": "^6.0.5",
"angular-mocks": "1.7.6", "angular-mocks": "1.7.6",
"babel-loader": "^8.0.4", "babel-loader": "^8.0.4",
"chalk": "^1.1.3",
"electron": "3.1.3", "electron": "3.1.3",
"electron-builder": "^20.38.5", "electron-builder": "^20.38.5",
"electron-mocha": "^6.0.4", "electron-mocha": "^6.0.4",