23 Commits

Author SHA1 Message Date
Benedict Aas
b28c345ba0 refactor(GUI): remove Angular from FlashStateModel and rename (#1264)
We remove the usage of Angular from 'FlashStateModel' and its usage
throughout the project comes under the new 'flashState' moniker.


Depends: https://github.com/resin-io/etcher/pull/1261
2017-04-10 14:30:21 -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
98284bd5e2 fix(GUI): don't report "invalid archive" errors to TrackJS (#1152)
These errors happen when the user selects an archive that contains no
image, or multiple images, and represents a user error, rather than an
unhandled exception.

For this reason, we should not report this to TrackJS.

This means, however, that we need a reliable way to know whether an
error should be reporter or not. This commit implements
`AnalyticsService.shouldReportError()` for this purpose, which will
check an optional `report` property of the error object.

In order to ensure that errors that we don't control are reported, the
function will return `true` if the error object doesn't have that
property.

Change-Type: patch
Changelog-Entry: Don't report "invalid archive" errors to TrackJS.
Fixes: https://github.com/resin-io/etcher/issues/1103
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
2017-03-02 12:21:48 -04:00
Ștefan Daniel Mihăilă
92fdba3642 upgrade: angular to v1.6.1; angular-ui-bootstrap to v2.5.0 (#1083)
Angular 1.5 has a bug that causes angular's `$exceptionHandler`
to be called for rejected `$q` promises even if they have
a rejection handler. This bug caused duplicate error messages
in Etcher.

A consequence of upgrading to Angular 1.6 is that `$q` promises
without a rejection handler will throw `Possibly unhandled rejection`
errors. To avoid these errors, this commit moves code responsible
for opening a tooltip from the template to the controller and handles
the rejection.

Other packages upgraded:
- angular-moment to v1.0.1
- angular-ui-router to v0.4.2
- angular-mocks to v1.6.1

Change-type: patch
Changelog-Entry: Fix duplicate error messages
Fixes: https://github.com/resin-io/etcher/issues/1082
See: https://github.com/angular/angular.js/issues/7992
See: https://github.com/angular/angular.js/pull/13662
2017-02-07 19:12:32 -04:00
Juan Cruz Viotti
8e5840ce69 chore: integrate codespell and fix existing spelling issues
This tool scans the comments of every source file and reports back
spelling errors.

Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
2017-02-06 14:53:20 -04:00
Juan Cruz Viotti
6456a8fe96 upgrade: drivelist to v5.0.1 (#869)
- Fix internal SDCard reader descriptions in GNU/Linux.
- Transform `mountpoint` into an array of mountpoints.

Change-Type: patch
Changelog-Entry: Fix internal SDCard drive descriptions.
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
2016-11-16 13:52:20 +00:00
Juan Cruz Viotti
bc985f08a9 fix(GUI): duplicate drives in Windows (#790)
If a drive contains multiple partitions that Windows recognises and
mounts, then `drivelist` will incorrectly display separate drive objects
for each partition, causing `ngRepeat` to complain in the drive selector
component.

The issue was fixed by grouping the mountpoints of all recognised
partitions in a single drive object, as we do with the other supported
operating systems.

After the fix, `drivelist` also removed its `name` property (since its
now always equal to `device`), so some extra logic to compute an
appropriate display name for the drive has been introduced to
`DriveScannerService`.

Fixes: https://github.com/resin-io/etcher/issues/720
See: https://github.com/resin-io-modules/drivelist/pull/100
Change-Type: patch
Changelog-Entry: Fix duplicate drives in Windows.
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
2016-10-31 01:18:58 -04:00
Juan Cruz Viotti
ce1c1d724d upgrade: etcher-image-write to v8.0.0 (#688)
This new version stops sending a `passedValidation` boolean property
upon completion and still throws an `EVALIDATION` error when validation
fails.

Such small chance allows us to get rid of lot of complexity related to
handling the `passedValidation` value in the application state.

Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
2016-09-07 10:24:34 -07:00
Juan Cruz Viotti
1febeda04e refactor(GUI): extract FlashStateModel from ImageWriterService (#606)
`ImageWriterService` currently has two responsibilities. It contains
logic to start and manage a flash process, and provides an API to
interact with the current flash state.

To honour the single responsibility principle, we extract
`FlashStateModel` from `ImageWriterService`.

Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
2016-07-27 21:21:23 -04:00
Juan Cruz Viotti
004a965c33 refactor(GUI): stop storing flash state in a .state object variable (#604)
Currently, we subscribe to the store change events and manually update a
`.state` property in `ImageWriterService`. A much more elegant approach
is to provide a `.getFlashState()` function that fetches the flash state
directly from the store when needed.

Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
2016-07-27 13:25:52 -04:00
Juan Cruz Viotti
b7d6d3d9a1 feat(GUI): display a nice alert ribbon if drive runs out of space (#588)
We try our best to check that the images the user select are too big for
the selected drive as early as possible, but this probes to be
problematic with certain compressed formats, like bzip2, which doesn't
store any information about the uncompressed size, requiring a ~50s
intensive computation as a minimum to find it out.

For these kinds of formats, we don't perform an early check, but instead
gracefully handle the case where the drive doesn't have any more space.

This PR handles an `ENOSPC` error by displaying the alert orange ribbon,
and prompting the user to retry with a larger drive. This is a huge
improvement over the cryptic `EIO` error what was thrown before, and
over having Etcher freeze at a certain percentage point.

Change-Type: minor
Changelog-Entry: Display a nice alert ribbon if drive runs out of space.
See: https://github.com/resin-io/etcher/issues/571
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
2016-07-24 15:32:00 -04:00
Juan Cruz Viotti
a81fdbe16a fix(GUI): don't throw if state speed is 0 (#546)
There is a small flaw in the current state validation rules where a
speed that equals zero will be considered as if the speed was missing
giving that `!0 == true`.

Changelog-Entry: Fix state validation error when speed equals zero.
Change-Type: patch
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
2016-06-30 12:11:35 -04:00
Juan Cruz Viotti
3bf712b592 fix: don't throw if state percentage is zero (#536)
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
2016-06-27 16:15:35 -04:00
Juan Cruz Viotti
714b165c0c refactor: move flash results state to Redux store (#529)
This is a rather big PR that moves the flash results information to the
Redux store, which simplifies and improves a lot of things as throughly
described in the commits that introduced Redux.

Here's a summary of the changes:

- Add a `flashResults` property to the store.

- Validate the contents of `flashResults`, handling certain edge cases
that make the modal incoherent.

- Split `ImageWriterService.setFlashing()` to
`ImageWriterService.setFlashingFlag()` and
`ImageWriterService.unsetFlashingFlag()`.

- Require the flash results to be passed to
`ImageWriterService.unsetFlashingFlag()`.

- Stop resolving the flash results from `ImageWriterService.flash()`.

- Implement `ImageWriterService.getFlashResults()`.

- Make the `RESET_FLASH_STATE` action reset the flash results.

- Access the source checksum from the store in the "finish" page,
  instead of requiring the controller to pass it as a state parameter.

- Implement `.wasLastFlashSuccessful()` function in the main controller
to replace the `.success` property.

- Completely remove the `.success` property in the main controller.

Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
2016-06-24 12:52:40 -04:00
Juan Cruz Viotti
d16d5469fd fix: don't throw missing eta if eta is zero (#528)
The commit 0f8136f, which enforced validation for the state object,
introduced a subtle bug where `Missing state eta` would be thrown if
`eta === 0`, since `!0` evaluates to `true`.

This would cause the flashing to stop right at the end (when eta is
zero).

Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
2016-06-24 09:47:24 -04:00
Juan Cruz Viotti
60b68d775b refactor: rename progress property to percentage (#527)
So the property is consistent from what we get from `etcher-image-write`
and we don't have to unnecessarily rename ourselves to pass it to the
model.

Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
2016-06-24 09:47:10 -04:00
Juan Cruz Viotti
4708401260 test: validate contents of flash state object (#526)
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
2016-06-24 09:16:15 -04:00
Juan Cruz Viotti
5ac5f3a423 fix: don't allow to set the flashing state if not flashing (#519)
Currently, we allow updating the flashing state independently on the
value of the `flashing` property.

In order to maintain the application state coherent, we deny updating
the flashing state if we're not currently flashing, which lets us safely
assume that the state will be in a reset state if we're not flashing.

Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
2016-06-23 15:38:40 -04:00
Juan Cruz Viotti
2ecf9d32a7 refactor: reset state when the flashing flag is set to false (#518)
Currently, we were taking care of resetting the flashing state manually
across several controllers. Now that data mutations live in a single
place, we trigger a flash state reset whenever the flashing flag is set
to false, which reliably handles every case and allows us to forget
about it.

Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
2016-06-23 15:12:57 -04:00
Juan Cruz Viotti
c4c8e2c038 refactor: manage application state with redux (#508)
Currently, Etcher's application state is stored among various models,
making it a bit hard to mentually visualise the application state at a
certain point of execution. This also means that some quirky bugs
appear, and we have to take non-elegant measures to mitigate them, for
example:

- The current drive selection might be invalid if the current available
drive list doesn't contain it anymore.

- The progress state might be modified while there is no flashing in
process.

- We have to rely on event emission to propagate the current state to
the application progress bar.

- The validity of a selected drive might depend on the currently
selected image.

While all these issues can be addressed with common programming
techniques, Redux introduces a new way of thinking about the application
state that make the above problems non-existent, or trivial to fix.

This PR creates a Redux store containing the logic used to mutate state
from:

- `SelectionStateModel`.
- `DrivesMode`.
- `ImageWriterService`.

We are also making extra effort to preserve the public APIs from the
models, which we will be simplifying in later commits.

There is still much to be done, but we're happy to be taking the first
steo towards a much cleaner architecture.

Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
2016-06-22 16:22:59 -04:00
Juan Cruz Viotti
991b69c17e refactor(DriveScannerService): use RxJS (#505)
The concept of a drive scanner lends itself very well to the concept of
"reactive programming", since the "available drives" make perfect sense
as an "Observable".

For this reason, the module was re-implemented using RxJS, which greatly
simplifies things and erradicates certain edge cases we were protecting
ourselves from automatically.

Other changes made in this PR:

- `DriveScannerService` no longer requires `DrivesModel`. The
`DriveScannerService` is the one in charge of populating the model.

- `DriveScannerService.scan()` no longer returns an `EventEmitter`. The
service itself is now an `EventEmitter`.

- `DriveScannerService` now emits a `drives`, not a `scan` event.

Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
2016-06-22 10:41:36 -04:00
Juan Cruz Viotti
b950136deb Extract DrivesModel from DriveScannerService (#466)
Currently, `DriveScannerService` is in charge of both scanning the
available drives and maintaining the state of the currently detected
drives.

To honour the single responsibility principle, we split this service
into a `DrivesModel`, which is incharge of maintaining the state without
caring how they are detected, and `DriveScannerService`, which only
scans the available drives and modified `DrivesModel` accordingly.

Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
2016-06-09 12:42:09 -04:00
Juan Cruz Viotti
afeba11424 Move GUI code into lib/gui (#358)
This refactoring will be useful on future changes, where there will be
a single application entry point that will execute the CLI or the GUI
version depending on the environment.

Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
2016-04-25 12:08:19 -04:00