34 Commits

Author SHA1 Message Date
Ștefan Daniel Mihăilă
1fe87d8883 feat(GUI): collect archive and image extension in analytics (#1343)
Change-Type: patch
2017-04-22 20:40:42 -04:00
Juan Cruz Viotti
dafa1f3ede refactor(child-writer): add robot commands constant (#1332)
See: https://github.com/resin-io/etcher/pull/1295#discussion_r112463686
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
2017-04-21 17:41:20 -04:00
Juan Cruz Viotti
fe91be11e8 refactor(errors): createError and createUserError accept an object (#1322)
Currently, both of these functions accept two arguments: the error
title, and the error description. This function signature makes is hard
to keep adding options to these error creation functions, like an error
code, so this commit refactors them to take a single argument: an
options object containing `title` and `description` properties.

Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
2017-04-20 12:23:32 -04:00
Juan Cruz Viotti
96f586900c fix(GUI): catch EIO errors and display a user friendly message (#1318)
If we get EIO at this point, then it means that the writer did
everything it could to recover (like multiple retries), and the error
is truly an input/output error coming from the operating system.

In this commit, we show a nice user friendly message explaining what
happened, and advising users to try again with another drive, reader, or
port instead of showing an uncaught EIO error.

Change-Type: patch
Changelog-Entry: Show a friendly user message on EIO after many retries.
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
2017-04-20 12:01:43 -04:00
Juan Cruz Viotti
c5a9a1fca4 fix(GUI): show a friendly message when the drive is unplugged half-way through (#1301)
This commit shows a user friendly message when Etcher loses access to
the drive while flashing/validating, and prevents the cryptic errors
from getting to Sentry.

See: https://github.com/resin-io-modules/etcher-image-write/pull/96
Change-Type: minor
Changelog-Entry: Show a user friendly message when the drive is unplugged half-way through.
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
2017-04-14 14:24:06 -04:00
Juan Cruz Viotti
e66d805672 feat(child-writer): log non-robot messages for debugging purposes (#1295)
Currently, if the child writer receives a message from the writer
process that is not a valid robot object, then it will throw an error.

Now, we check if the message is a robot message, and if so, we try to
parse it (throwing errors if its indeed a malformed/incomplete robot
message), however we log it if not.

The main motivation behind this feature is that it will allows us to
print debugging information on the mountutils module, and have it
redirected to DevTools.

Change-Type: minor
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
2017-04-14 14:07:00 -04:00
Juan Cruz Viotti
0890b1e369 refactor(GUI): move SupportedFormatsModel to lib/shared (#1251)
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
2017-04-13 14:38:30 -04:00
Juan Cruz Viotti
64c8eb594b refactor(GUI): make OSWindowProgress a simple CommonJS module (#1253)
There is no need to tie this module to Angular by using an Angular
service.

Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
2017-04-13 14:38:22 -04:00
Ștefan Daniel Mihăilă
91a1c3d107 feat(GUI): use resin-corvus in AnalyticsService (#1208)
Change-Type: patch
Changelog-Entry: Start reporting errors to Sentry instead of to TrackJS.
Fixes: https://github.com/resin-io/etcher/issues/1027
2017-04-10 15:06:32 -04:00
Juan Cruz Viotti
1b68e9394b style(shared): fix given that is -> given that it typo (#1272)
See: https://github.com/resin-io/etcher/pull/1262#discussion_r110541438
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
2017-04-10 14:36:01 -04:00
Juan Cruz Viotti
3cdd925c41 refactor: get rid of is-elevated (#1262)
This commit implements our own version of the `is-elevated` module. The
reason behind this is that `is-elevated` relies on lots of unnecessary
modules, that eventually require `spawn-sync` and `try-thread-sleep`,
which conditionally require dependencies that are not even declared in
their `package.json`, causing issues when concatenating the Etcher CLI.

See: https://github.com/resin-io/etcher/pull/1235
See: https://github.com/resin-io/etcher/pull/1228
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
2017-04-08 20:15:17 -04:00
Jonas Hermsmeier
07b6dd247d feat(robot): Support logging arbitrary data to the console (#1212)
This adds a new command recognition for message type "log",
to enable `console.log()`ing arbitrary data to the parent process console.

Not sure if we'd really want this in, but it's very handy for debugging,
and would keep us from writing these 3 lines every time
we want to inspect something in between those processes.

Change-Type: minor
2017-04-06 14:40:38 -04:00
Juan Cruz Viotti
802d9abb1d refactor: unify image objects across GUI and image-stream (#1229)
`image-stream` returns image objects that look like this:

```js
{
  stream: <readable stream>,
  transform: <transform stream>,
  size: {
    original: <number>,
    final: {
      value: <number>,
      estimation: <boolean>
    }
  },
  ...
}
```

While the GUI handles image objects that look like this:

```sh
{
  path: <string>,
  size: <number>,
  ...
}
```

It looks like we should share a common structure between both, so we can
use `image-stream` images in `drive-constraints`, for example.

Turns out that we actually transform `image-stream` image objects to GUI
image objects when the user selects an image using the image selector
dialog, which is another indicator that we should normalise this
situation.

As a solution, this commit does the following:

- Add `path` to `image-stream` image object
- Reuse `image-stream` image objects in the GUI, given they are a
  superset of GUI image objects

See: https://github.com/resin-io/etcher/pull/1223#discussion_r108165110
Fixes: https://github.com/resin-io/etcher/issues/1232
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
2017-04-06 09:41:08 -04:00
Juan Cruz Viotti
57952f6f55 fix(CLI): don't print stack traces by default (#1206)
Currently, the Etcher CLI will print scary stack traces for every single
error (e.g: if you forgot to pass an image to the tool), given that
`errors.getDescription()` will return a stack trace if no other
description could be found.

This commit introduces an `ETCHER_CLI_DEBUG` environment variable, which
when set, it will cause the Etcher CLI to output stack traces, plus a
boolean `userFriendlyDescriptionsOnly` option to
`errors.getDescription()`, so we can control whether
`errors.getDescription()` returns things like stack traces, or
stringified error objects.

Change-Type: minor
Changelog-Entry: Don't print stack traces by default in the CLI.
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
2017-03-28 09:43:15 -04:00
Ștefan Daniel Mihăilă
fe20f5061f fix(GUI): don't log absolute paths in Mixpanel (#1161)
The event data may contain absolute paths that contain user information that
should not be logged in Mixpanel. Instead, we replace absolute path properties
with their base name.

Change-Type: patch
Changelog-Entry: Don't include user paths in Mixpanel analytics events.
2017-03-15 00:05:48 -04:00
Ștefan Daniel Mihăilă
34c85eb150 feat(GUI): improve analytics events (#1111)
* feat(GUI): improve analytics events

This commit adds more events to our current analytics.
Will further improve in a future commit.

Change-Type: patch
See: https://github.com/resin-io/etcher/issues/1100

* refactor(gui): use single function to set normal and dangerous settings

Change-Type: patch
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
2017-03-10 15:18:49 -04:00
Juan Cruz Viotti
e4a9a03239 refactor: unify error related tasks (#1154)
The current error handling logic is a mess. We have code that tries to
fetch information about errors in different places throughout the
application, and its incredibly hard to ensure certain types of error
get decent human friendly error messages.

This commit groups, improves, and tests all error related functions in
`lib/shared/errors.js`.

Here's a summary of the changes, in more detail:

- Move the `HUMAN_FRIENDLY` object to `shared/errors.js`
- Extend `HUMAN_FRIENDLY` with error descriptions
- Add `ENOMEM` to `shared/errors.js`
- Group CLI and `OSDialogService` mechanisms for getting an error title
  and an error description
- Move error serialisation routines from `robot` to `shared/errors.js`
- Create and use `createError()` and `createUserError()` utility
  functions
- Add user friendly descriptions to many errors
- Don't report user errors to TrackJS

Fixes: https://github.com/resin-io/etcher/issues/1098
Change-Type: minor
Changelog-Entry: Make errors more user friendly throughout the application.
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
2017-03-10 13:11:45 -04:00
Juan Cruz Viotti
df8611df11 chore: add ESLint Lodash plugin (#1148)
This is one step towards enforcing the linter until we barely have to
check for style issues on code reviews.

Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
2017-03-08 19:11:15 -04:00
Juan Cruz Viotti
6c8bc117ab chore: revise ESLint built-in configuration (#1149)
There are a lot of new rules since the last time I revised the ESLint
rules documentation.

I've updated the main `.eslintrc.yml` to include some newer additions,
plus I added another ESLint configuration file inside `tests`, so we can
add some stricted rules to the production code while relaxing them for
the test suite (due to the fact that Mocha is not very ES6 friendly and
Angular tests require a bit of dark magic to setup).

This is a summary of the most important changes:

- Disallow "magic numbers"

These should now be extracted to constants, which forces us to think of
a good name for them, and thus make the code more self-documenting (I
had to Google up the meaning of some existing magic numbers, so I guess
this will be great for readability purposes).

- Require consistent `return` statements

Some functions relied on JavaScript relaxed casting mechanism to work,
which now have explicit return values. This flag also helped me detect
some promises that were not being returned, and therefore risked not
being caught by the exception handlers in case of errors.

- Disallow redefining function arguments

Immutability makes functions easier to reason about.

- Enforce JavaScript string templates instead of string concatenation

We were heavily mixing boths across the codebase.

There are some extra rules that I tweaked, however most of codebase
changes in this commit are related to the rules mentioned above.

Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
2017-03-07 23:46:44 -04:00
Ștefan Daniel Mihăilă
5b9104e8aa feat(GUI): warn when atempting to burn Windows images (#1043)
Change-Type: minor
Changelog-Entry: Show warning when user tries to flash a Windows image
Closes: https://github.com/resin-io/etcher/issues/1035
2017-02-24 15:12:03 -04:00
Juan Cruz Viotti
43c08d1547 docs: explain the "robot" module in a high level way (#1081)
This commit adds a README file at `lib/shared/robot` explaining in
detail how the "robot" mechanism works, and why it is needed.

Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
2017-02-10 11:59:23 -04:00
Juan Cruz Viotti
b55ff3eef8 style(GUI): use a OS dialog to show the "exit while flashing" warning (#1070)
For better OS integration purposes.

This commit also fixes a bug where the dialog would be shown for some
milliseconds even if the application is not flashing.

Change-Type: minor
Changelog-Entry: Use a OS dialog to show the "exit while flashing" warning.
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
2017-02-08 10:04:45 -04:00
Ștefan Daniel Mihăilă
f4c6597b3d style(GUI): minor fixes in comments (#1084) 2017-02-07 17:31:30 -04:00
Juan Cruz Viotti
95d4f2f608 fix(GUI): prevent flashing the drive where the source image is located
Currently Etcher will allow you to flash an image to the same drive that
contains the image. As a way to protect against that case we introduce
the concept of a "source drive", which means a drive that contains the
source image.

This commit adds the following logic around this new concept:

- Don't auto-select a source drive
- De-select an already selected drive if an image inside it is selected
- Disable the drive in the drive selector modal
- Add a "Source Drive" badge to the drive in the drive selector modal

Fixes: https://github.com/resin-io/etcher/issues/830
Change-Type: minor
Changelog-Entry: Prevent flashing the drive where the source image is located.
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
2017-02-06 14:53:08 -04:00
Juan Cruz Viotti
e5a52c9377 fix(GUI): improve validation error message (#1047)
The current validation message is obscure and tends to lead users to
believe there is a problem with Etcher.

Fixes: https://github.com/resin-io/etcher/issues/735
Change-Type: patch
Changelog-Entry: Improve validation error message.
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
2017-01-25 10:32:07 -04:00
Juan Cruz Viotti
acc1f05269 refactor: move lib/shared/child-writer to lib/child-writer (#1041)
The `child-writer` module is not re-used by both the GUI and the CLI, so
it makes sense to have it in `lib/child-writer`.

Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
2017-01-24 12:06:34 -04:00
Juan Cruz Viotti
e8c4589e1c fix(GUI): don't ignore any robot message from the CLI (#1026)
We recently sent a PR to handle multiple buffered IPC messages being
reported as a single message, confusing `JSON.parse()` in
`lib/shared/child-writer/index.js`, by only sending the last message,
and ignoring the rest, under the assumption that the loss of some state
messages is not critical for the application and the writing process to
work property.

As @lurch pointed out, however, a buffer set of messages might contain
an error object somewhere, and by ignoring all but the last message, we
ignore any error that happened in the way.

See: https://github.com/resin-io/etcher/issues/898
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
2017-01-13 18:40:32 -04:00
Benedict Aas
0f2cba38d1 fix: allow undefined drives and images in DriveConstraintsModel (#1016)
Currently the `DriveConstraintsModel` errors when given an `undefined`
drive, or image; this commit changes that behaviour. Comes with tests.

Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
2017-01-13 18:14:09 -04:00
Juan Cruz Viotti
aea4403a16 refactor: move all byte-size conversion logic to lib/shared/units.js (#1021)
This commit extracts the byte-related conversions from the `byte-size`
AngularJS module and the `FlashStateModel` to a re-usable generic
CommonJS module at `lib/shared/units.js`, than can also be used by the
CLI.

Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
2017-01-13 16:11:28 -04:00
Juan Cruz Viotti
c552494480 refactor: extract application messages to lib/shared/messages.js (#1022)
There are certain application messages that should be re-used between
the CLI and the GUI. In order to allow such re-usability, we extract out
the application messages used in JavaScript into
`lib/shared/messages.js` as a collection of Lodash `_.template`
templates.

Notice this file doesn't include application messages included in
Angular templates directly since it'd be hard to refactor all of them.
We plan to move to React soon, which will allow moving the remaining
messages very easily.

Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
2017-01-13 11:03:46 -04:00
Juan Cruz Viotti
0b0b097620 refactor(GUI): extract and test child writer CLI argument utilities (#1012)
These utilities were extracted to `lib/shared/child-writer/cli.js`, and
unit tests have been written for them.

As a result of testing, `.getBooleanArgumentForm()` has been extended to
support single letter options.

Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
2017-01-10 21:36:33 -04:00
Juan Cruz Viotti
7fa2f437c1 feat(CLI): replace --robot with an ETCHER_CLI_ROBOT env var (#1010)
The `--robot` option of the CLI causes the program to output
machine-parseable strings, which can be easily consumed by the GUI to
update progress and other information.

The problem is that if the CLI fails to parse its command line arguments
when being called from the GUI for whatever reason, the `.fail()` Yargs
handler will be called, which doesn't output error information in the
usual "robot" format, causing the GUI to not understand the error
message.

Since the `.fail()` Yargs handler doesn't have access to the passed
options, we moved the "robot" functionality to an environment variable,
which we can easily check from there.

As a bonus, this PR refactors the whole robot logic into
`lib/shared/robot.js` and adds unit tests to it.

See: https://github.com/resin-io/etcher/issues/986
Change-Type: major
Changelog-Entry: Replace the `--robot` CLI option with an `ETCHER_CLI_ROBOT` environment variable.
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
2017-01-10 19:46:59 -04:00
Juan Cruz Viotti
735478bf52 fix(GUI): don't split robot input by new lines inside properties (#1008)
We've recently PRed a commit that handles multiple IPC messages being
triggered at the same time, confusing `JSON.parse()`. As a solution to
such problem, we are splitting the CLI output on new lines, based on the
assumption that each line represents a different object, however we
didn't consider that in the case of errors, we include an `stacktrace`
property which usually includes new line characters, causing such
information to be completely garbled and cause `JSON.parse()` once again
to get confused.

As a solution, we only split by new lines that are not surrounded by
quotes (since they represent a JSON property).

See: https://github.com/resin-io/etcher/pull/997
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
2017-01-10 12:25:16 -04:00
Ștefan Daniel Mihăilă
050d187e6f refactor: extract SelectionStateModel stateless functions (#982)
`SelectionStateModel`'s methods `isSystemDrive` and `isDriveLocked`
don't depend on application state. They have been extracted in a different
AngularJS service: `DriveConstraintsModel`. The new service's actual
implementation is in `lib/src`, in order to be reused by the CLI.

Miscellaneous changes:

- Rename `lib/src` to `lib/shared`
- Refactor `drive-constraints` to throw when image is undefined

The default behaviour was to pretend that we're all good if the if
the image is not specified. We're not using this "feature", and
it can be dangerous if we forget to pass in the image.

- Make `isSystemDrive` return `false` if `system` property is undefined
- Use `drive-constraints` in `store.js`

Change-Type: patch
2017-01-06 12:42:11 -04:00