Integrate Etcher CLI in the main repository (#352)

This PR integrates the Etcher CLI code-wise, but doesn't yet handles the
distribution part of the story.

Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
This commit is contained in:
Juan Cruz Viotti 2016-04-21 10:08:53 -04:00
parent a462ee86c0
commit 148b9d15ae
6 changed files with 226 additions and 4 deletions

View File

@ -23,15 +23,34 @@ Refer to the [downloads page](http://etcher.io) for the latest pre-made installe
Developing
----------
You can manually run the application with the following commands:
You can manually run the application with the following steps:
- Clone the repository.
```sh
git clone https://github.com/resin-io/etcher
cd etcher
npm install && bower install
```
- Install dependencies.
```sh
npm install
bower install
```
- Run the GUI application.
```sh
npm start
```
- Run the CLI application.
```sh
node bin/etcher
```
Take a look at our [contributing guide](https://github.com/resin-io/etcher/blob/master/CONTRIBUTING.md).
Support

2
bin/etcher Executable file
View File

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

88
lib/cli/cli.js Normal file
View File

@ -0,0 +1,88 @@
/*
* 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 packageJSON = require('../../package.json');
/**
* @summary Parsed CLI options and arguments
* @type Object
* @public
*/
module.exports = yargs
.demand(1, 'Missing image')
// Usage help
.usage('Usage: $0 <image>')
.epilogue([
'If you need help, don\'t hesitate in contacting us at:',
'',
' GitHub: https://github.com/resin-io/etcher-cli/issues/new',
' Gitter: https://gitter.im/resin-io/chat'
].join('\n'))
// Examples
.example('$0 raspberry-pi.img')
.example('$0 -d /dev/disk2 ubuntu.iso')
.example('$0 -d /dev/disk2 -y rpi.img')
// Help option
.help()
// Version option
.version(_.constant(packageJSON.version))
// Error reporting
.fail(function(message, error) {
yargs.showHelp();
utils.printError(error || message);
process.exit(1);
})
// Assert that image exists
.check(function(argv) {
fs.accessSync(argv._[0]);
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'
},
yes: {
describe: 'confirm non-interactively',
boolean: true,
alias: 'y'
}
})
.argv;

67
lib/cli/etcher.js Normal file
View File

@ -0,0 +1,67 @@
/*
* 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 visuals = require('resin-cli-visuals');
const form = require('resin-cli-form');
const writer = require('../src/writer');
const utils = require('./utils');
const options = require('./cli');
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 `undefined`,
// otherwise the question will not be asked because
// `false` is a defined value.
yes: options.yes || undefined
}
}).then(function(answers) {
if (!answers.yes) {
throw new Error('Aborted');
}
var progressBar = new visuals.Progress('Burning');
return writer.writeImage(options._[0], {
device: answers.drive
}, {
unmountOnSuccess: false,
validateWriteOnSuccess: false
}, function(state) {
return progressBar.update(state);
});
}).then(function() {
console.log('Your flash is complete!');
}).catch(function(error) {
utils.printError(error);
process.exit(1);
});

39
lib/cli/utils.js Normal file
View File

@ -0,0 +1,39 @@
/*
* 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 errors = require('resin-cli-errors');
const chalk = require('chalk');
/**
* @summary Print an error to stderr
* @function
* @public
*
* @param {(Error|String)} error - error
*
* @example
* utils.printError(new Error('Oops!'));
*/
exports.printError = function(error) {
if (_.isString(error)) {
error = new Error(error);
}
console.error(chalk.red(errors.interpret(error)));
};

View File

@ -30,7 +30,9 @@
"screenshot.png",
"tests",
"etcher-release",
"lib/scss"
"lib/scss",
"lib/cli",
"bin/etcher"
],
"builder": {
"win": {
@ -52,6 +54,7 @@
"angular-ui-router": "^0.2.18",
"bluebird": "^3.0.5",
"bootstrap-sass": "^3.3.5",
"chalk": "^1.1.3",
"drivelist": "^2.0.13",
"flexboxgrid": "^6.3.0",
"is-elevated": "^1.0.0",
@ -59,11 +62,15 @@
"ngstorage": "^0.3.10",
"open": "0.0.5",
"resin-image-write": "^3.0.4",
"resin-cli-errors": "^1.2.0",
"resin-cli-form": "^1.4.1",
"resin-cli-visuals": "^1.2.8",
"resin-zip-image": "^1.1.2",
"sudo-prompt": "^2.2.0",
"trackjs": "^2.1.16",
"umount": "^1.1.1",
"username": "^2.1.0"
"username": "^2.1.0",
"yargs": "^4.6.0"
},
"devDependencies": {
"angular-mocks": "^1.4.7",