Compare commits

...

562 Commits

Author SHA1 Message Date
Alexis Svinartchouk
868a35337c wip 2019-07-16 13:17:46 +02:00
Alexis Svinartchouk
1398ca2931 wip 2019-07-12 18:59:06 +02:00
Alexis Svinartchouk
96c865f14a wip 2019-07-10 18:44:30 +02:00
Alexis Svinartchouk
6dbd425e89 wip 2019-07-04 19:35:52 +02:00
Alexis Svinartchouk
5b2769d0e9 Sleep button on main screen for etcher-pro
Change-type: patch
2019-07-01 13:10:46 +02:00
Alexis Svinartchouk
5f38cca60c Led module prototype
Change-type: patch
2019-07-01 13:10:46 +02:00
Alexis Svinartchouk
78cebdb7a4 Change setting enableScreensaver -> screensaverDelay
Change-type: patch
2019-06-28 15:05:31 +02:00
Alexis Svinartchouk
a6aedab0a0 Add / remove listeners and timeouts when the sceensaver setting changes
Change-type: patch
Changelog-entry: Add / remove listeners and timeouts when the sceensaver setting changes
2019-06-28 15:05:31 +02:00
Alexis Svinartchouk
4aeccbe963 Don't use settings.getDefaults() in etcher.js
Change-type: patch
2019-06-28 15:05:31 +02:00
Alexis Svinartchouk
126b3fbb40 Indent typescript files with tabs
Change-type: patch
Changelog-entry: Indent typescript files with tabs
2019-06-28 15:05:31 +02:00
Alexis Svinartchouk
9ea8a6134e Remove unused settings.assign function
Change-type: patch
Changelog-entry: Remove unused settings.assign function
2019-06-28 15:05:31 +02:00
Alexis Svinartchouk
3706770322 Convert utils, settings and errors to typescript
Change-type: patch
Changelog-entry: Convert utils, settings and errors to typescript
2019-06-28 15:05:31 +02:00
Alexis Svinartchouk
7be07bfe8c Screensaver for etcher-pro
Change-type: patch
2019-06-28 15:05:31 +02:00
Alexis Svinartchouk
791c047fa1 Simplify imports
Change-type: patch
2019-06-28 15:05:30 +02:00
Lorenzo Alberto Maria Ambrosi
35ad0340b9 Move shared folder to gui/app/modules
Change-type: patch
Changelog-entry: Move shared folder to gui/app/modules
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2019-06-28 15:05:30 +02:00
Alexis Svinartchouk
0a0be3a13d Allow typescript files
Change-type: patch
Changelog-entry: Allow typescript files
2019-06-28 15:05:30 +02:00
Resin CI
86238af380 v1.5.51 2019-06-28 16:04:34 +03:00
Alexis Svinartchouk
d10073a052 Merge pull request #2842 from balena-io/update-sudo-prompt
Update sudo-prompt to ^9.0.0
2019-06-28 15:02:51 +02:00
Alexis Svinartchouk
b99b0d4bf8 Update sudo-prompt to ^9.0.0
Change-type: patch
Changelog-entry: Update sudo-prompt to ^9.0.0
2019-06-28 14:00:49 +02:00
Resin CI
27b5b1bf10 v1.5.50 2019-06-14 16:43:18 +03:00
Alexis Svinartchouk
bab9069dee Merge pull request #2702 from balena-io/trim
Trim
2019-06-14 15:41:29 +02:00
Alexis Svinartchouk
52a3258814 Option for trimming ext partitions on raw images
Changelog-entry: Option for trimming ext partitions on raw images
Change-type: patch
2019-06-13 20:00:20 +02:00
Alexis Svinartchouk
da548f59d1 Replace promise chains with async/await in child-writer
Change-type: patch
2019-06-13 18:42:41 +02:00
Resin CI
ecc500907c v1.5.49 2019-06-13 19:42:18 +03:00
Alexis Svinartchouk
724dade1f6 Merge pull request #2830 from balena-io/etcher-pro
Make window size configurable
2019-06-13 18:39:30 +02:00
Alexis Svinartchouk
c5dc869c03 Make window size configurable
Change-type: patch
Changelog-entry: Make window size configurable
2019-06-13 17:23:49 +02:00
Resin CI
273f7e4535 v1.5.48 2019-06-13 17:30:09 +03:00
Alexis Svinartchouk
a58e060138 Merge pull request #2829 from balena-io/dont-elevate-when-root
Don't use sudo-prompt when already elevated
2019-06-13 16:26:48 +02:00
Alexis Svinartchouk
ef4d2fcc72 Don't use sudo-prompt when already elevated
Changelog-entry: Don't use sudo-prompt when already elevated
Change-type: patch
2019-06-13 15:22:10 +02:00
Resin CI
330c06d926 v1.5.47 2019-06-12 16:30:52 +03:00
Lorenzo Alberto Maria Ambrosi
be9c36828a Merge pull request #2795 from balena-io/bump-styled-components-system
Upgrade rendition to v8
2019-06-12 15:28:08 +02:00
Lorenzo Alberto Maria Ambrosi
17f83135c5 Rework drive-selector with react + rendition
Change-type: patch
Changelog-entry: Rework drive-selector with react + rendition
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2019-06-10 11:43:47 +02:00
Lorenzo Alberto Maria Ambrosi
543ba51d3c Add first rendition theme configs
Change-type: patch
Changelog-entry: Use rendition theme property for step buttons
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2019-06-10 11:43:47 +02:00
Lorenzo Alberto Maria Ambrosi
33df23fc8c Upgrade styled-system to v4.1.0
Change-type: patch
Changelog-entry: Upgrade styled-system to v4.1.0
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2019-06-10 11:43:47 +02:00
Lorenzo Alberto Maria Ambrosi
3236d6b934 Upgrade rendition to v8.7.2
Change-type: patch
Changelog-entry: Upgrade rendition to v8.7.2
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2019-06-10 11:43:47 +02:00
Resin CI
e0e7775367 v1.5.46 2019-06-09 17:09:46 +03:00
Alexis Svinartchouk
198679583c Merge pull request #2827 from balena-io/update-ext2fs
Update ext2fs to 1.0.29
2019-06-09 16:07:37 +02:00
Alexis Svinartchouk
6dae2a604f Update ext2fs to 1.0.29
Change-type: patch
Changelog-entry: Update ext2fs to 1.0.29
2019-06-09 14:18:17 +02:00
Resin CI
68905c6ae4 v1.5.45 2019-06-04 12:58:44 +03:00
Alexis Svinartchouk
26630c4d64 Merge pull request #2823 from balena-io/trigger-build
Empty commit to trigger build
2019-06-04 11:56:24 +02:00
Alexis Svinartchouk
d382f030f0 Empty commit to trigger build
Change-type: patch
Changelog-entry: Empty commit to trigger build
2019-06-04 10:59:01 +02:00
Resin CI
08fca87b2f v1.5.44 2019-06-03 21:16:49 +03:00
Alexis Svinartchouk
33441a1c5c Merge pull request #2803 from balena-io/fix-windows-elevation
Fix elevation on windows when the path contains "&" or "'"
2019-06-03 20:14:45 +02:00
Alexis Svinartchouk
6d8346b13a Fix elevation on windows when the path contains "&" or "'"
Change-type: patch
Changelog-entry: Fix elevation on windows when the path contains "&" or "'"
2019-05-29 17:52:01 +02:00
Resin CI
d9b340ca45 v1.5.43 2019-05-28 21:59:10 +03:00
Lorenzo Alberto Maria Ambrosi
ebbc52ee1f Merge pull request #2806 from balena-io/rollback-update-webpack
Rollback update webpack
2019-05-28 20:57:06 +02:00
Lorenzo Alberto Maria Ambrosi
de5bee29ef Revert "Include sass in webpack configs"
This reverts commit 156c25cea1.

Change-type: patch
Changelog-entry: Revert "Include sass in webpack configs"
2019-05-28 19:34:12 +02:00
Resin CI
25f843ec0b v1.5.42 2019-05-28 17:41:14 +03:00
Lorenzo Alberto Maria Ambrosi
df600a9e14 Merge pull request #2794 from balena-io/update-webpack
Add sass-loader to webpack configs
2019-05-28 16:38:55 +02:00
Lorenzo Alberto Maria Ambrosi
156c25cea1 Include sass in webpack configs
Change-type: patch
Changelog-entry: Include sass in webpack configs
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2019-05-28 11:08:54 +02:00
Resin CI
f7dd04e3de v1.5.41 2019-05-27 16:59:31 +03:00
Alexis Svinartchouk
3036d86cfa Merge pull request #2801 from mhajder/patch-1
waffle.io removal and adding a link to the license
2019-05-27 15:57:19 +02:00
Mateusz Hajder
3fccd52884 waffle.io removal and adding a link to the license
Change-type: patch
Changelog-entry: waffle.io removal and adding a link to the license
2019-05-27 14:56:17 +02:00
Resin CI
00640274fc v1.5.40 2019-05-27 13:16:18 +03:00
Lorenzo Alberto Maria Ambrosi
a7e8fb98b3 Merge pull request #2799 from balena-io/combine-ia32-and-x64-2
Combine ia32 and x64 2
2019-05-27 12:14:09 +02:00
Alexis Svinartchouk
bed6643437 Remove some unused files from the packages
Change-type: patch
2019-05-24 11:26:45 +02:00
Alexis Svinartchouk
f815e8511f Build packages that support both ia32 and x64 on windows
Changelog-entry: windows installer and portable version support both ia32 and x64
Change-type: patch
2019-05-21 18:02:06 +02:00
Resin CI
6360fd42e7 v1.5.39 2019-05-14 13:27:35 +03:00
Lorenzo Alberto Maria Ambrosi
62a9656888 Merge pull request #2768 from balena-io/clean-shrinkwrap
Add clean-shrinkwrap script to postshrinkwrap step
2019-05-14 12:25:05 +02:00
Lorenzo Alberto Maria Ambrosi
ffb89c7e5b Update scripts submodule to v1.5.2
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2019-05-14 09:39:48 +02:00
Lorenzo Alberto Maria Ambrosi
aa52735006 Add clean-shrinkwrap script to postshrinkwrap step
Change-type: patch
Changelog-entry: Add clean-shrinkwrap script to postshrinkwrap step
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2019-05-14 09:39:48 +02:00
Resin CI
b65526d8ee v1.5.38 2019-05-14 01:47:31 +03:00
Carlo Maria Curinga
ea8e2999ae Merge pull request #2786 from balena-io/add-mention-to-usbboot-devices
add mention to usbboot devices support
2019-05-14 00:45:00 +02:00
Carlo Maria Curinga
0b5017f992 add mention to usbboot devices support
Change-type: patch
Changelog-entry: Add mention to usbboot compatibility
Signed-off-by: Carlo Maria Curinga carlo@balena.io
2019-05-13 23:38:13 +02:00
Resin CI
8bf1bdaa04 v1.5.37 2019-05-13 20:53:18 +03:00
Lorenzo Alberto Maria Ambrosi
01eb3b1c94 Merge pull request #2783 from balena-io/bump-react
Bump react to v16.8.5
2019-05-13 19:51:00 +02:00
Lorenzo Alberto Maria Ambrosi
3402c9f601 Bump react to v16.8.5
Change-type: patch
Changelog-entry: Bump react dependency to v16.8.5
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2019-05-13 15:09:23 +02:00
Resin CI
13c3518c5e v1.5.36 2019-05-13 15:35:11 +03:00
Alexis Svinartchouk
821fad27dc Merge pull request #2782 from balena-io/sdk-2.0.9
Update etcher-sdk to ^2.0.9
2019-05-13 14:32:51 +02:00
Alexis Svinartchouk
50a34e2f4c Update etcher-sdk to ^2.0.9
Changelog-entry: Update etcher-sdk to ^2.0.9
Change-type: patch
2019-05-13 12:51:39 +02:00
Resin CI
2a19b2afbe v1.5.35 2019-05-10 20:29:42 +03:00
Alexis Svinartchouk
dc92d010fb Merge pull request #2775 from balena-io/electron-3.1.9
Downgrade electron 4.1.5 -> 3.1.9
2019-05-10 19:27:31 +02:00
Alexis Svinartchouk
9cb27a616a Downgrade electron 4.1.5 -> 3.1.9
Changelog-entry: Downgrade electron 4.1.5 -> 3.1.9
Change-type: patch
2019-05-10 14:18:33 +02:00
Resin CI
518a0ca45b v1.5.34 2019-05-10 13:21:12 +03:00
Alexis Svinartchouk
3526a0e3c5 Merge pull request #2774 from balena-io/1.5.34
1.5.34
2019-05-10 12:19:17 +02:00
Alexis Svinartchouk
6386f85258 Use https url for fetching config, avoid redirection
Changelog-entry: Use https url for fetching config, avoid redirection
Change-type: patch
2019-05-09 16:01:36 +02:00
Alexis Svinartchouk
e80106d8f8 Update etcher-sdk to ^2.0.7
Changelog-entry: win32: fix running diskpart when the tmp file path contains spaces
Change-type: patch
2019-05-09 15:58:40 +02:00
Resin CI
1145cbc75c v1.5.33 2019-04-30 22:17:08 +03:00
Alexis Svinartchouk
e669b81072 Merge pull request #2759 from balena-io/fix-gzip-progress
Update etcher-sdk to ^2.0.5
2019-04-30 21:14:26 +02:00
Alexis Svinartchouk
9d78da941b Update etcher-sdk to ^2.0.5
Changelog-entry: Fix gzipped files verification percentage and dmg verification.
Change-type: patch
2019-04-30 18:38:35 +02:00
Resin CI
63d0f5e2c6 v1.5.32 2019-04-30 19:05:05 +03:00
Alexis Svinartchouk
dae047eff1 Merge pull request #2758 from balena-io/makefile-npm-version
Export NPM_VERSION variable in Makefile
2019-04-30 18:03:21 +02:00
Lorenzo Alberto Maria Ambrosi
8a2db8bced Add CODEOWNERS file to repository
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzothunder.ambrosi@gmail.com>
2019-04-30 16:56:44 +02:00
Lorenzo Alberto Maria Ambrosi
792fab20e6 Export NPM_VERSION variable in Makefile
Change-type: patch
Changelog-entry: Export NPM_VERSION variable in Makefile
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzothunder.ambrosi@gmail.com>
2019-04-30 16:14:26 +02:00
Resin CI
f40c0f6bd3 v1.5.31 2019-04-30 13:55:10 +03:00
Alexis Svinartchouk
ccf11b9861 Merge pull request #2753 from balena-io/electron-4
Update electron to 4.1.5
2019-04-30 12:52:46 +02:00
Alexis Svinartchouk
1fcde5a17c Update etcher-sdk to ^2.0.3
Changelog-entry: Update etcher-sdk to ^2.0.3
Change-type: patch
2019-04-29 12:52:52 +02:00
Alexis Svinartchouk
88f543dd25 Update electron to 4.1.5
Changelog-entry: Update electron to 4.1.5
Change-type: patch
2019-04-25 16:12:03 +02:00
Resin CI
8b6f3f6022 v1.5.30 2019-04-24 15:00:52 +03:00
Alexis Svinartchouk
294ef8045a Merge pull request #2749 from balena-io/remove-double-error-message
Remove double error message
2019-04-24 13:58:38 +02:00
Alexis Svinartchouk
1f7e4c886b Don't show a dialog when the write fails.
There is already an error modal and the error detail will be shown in the console.

Changelog-entry: Don't show a dialog when the write fails.
2019-04-22 18:25:26 +02:00
Alexis Svinartchouk
63c047009f Remove useless returns and unused parameter
Change-type: patch
2019-04-22 18:24:50 +02:00
Resin CI
2c5f5004cc v1.5.29 2019-04-22 10:10:53 +03:00
Lorenzo Alberto Maria Ambrosi
2fa5426cf5 Merge pull request #2736 from balena-io/electron-updater-2
Add electron autoupdater
2019-04-22 09:08:08 +02:00
Alexis Svinartchouk
428c777402 Fix npm-shrinkwrap.json
Change-type: patch
2019-04-19 19:56:30 +02:00
Lorenzo Alberto Maria Ambrosi
7e2c62c520 Fix mixpanel events sampling rate
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzothunder.ambrosi@gmail.com>
2019-04-19 17:26:38 +02:00
Giovanni Garufi
3d3b4f4a46 Add electron autoupdater
Change-type: patch
Changelog-entry: Add support for auto-updating feature
Signed-off-by: Giovanni Garufi <giovanni@balena.io>
2019-04-19 17:13:37 +02:00
Resin CI
a543dcf166 v1.5.28 2019-04-19 14:46:55 +03:00
Alexis Svinartchouk
5de54bb6bf Merge pull request #2741 from balena-io/update-etcher-sdk-2
Update etcher sdk to ^2.0.1
2019-04-19 13:44:52 +02:00
Alexis Svinartchouk
d95401e614 Update electron-builder to ^20.40.2
Changelog-entry: Update electron-builder to ^20.40.2
Change-type: patch
2019-04-18 18:40:59 +02:00
Alexis Svinartchouk
2c835437e9 Update etcher-sdk to ^2.0.1
Changelog-entry: Update etcher-sdk to ^2.0.1
Change-type: patch
2019-04-18 18:40:46 +02:00
Resin CI
498e70ed2b v1.5.27 2019-04-16 17:30:43 +03:00
Alexis Svinartchouk
fce5b500bf Merge pull request #2734 from balena-io/fix-wmic-tmp-spaces
Fix reading images from network drives on windows when the tmp dir has spaces
2019-04-16 16:28:39 +02:00
Alexis Svinartchouk
11def54adb Fix reading images from network drives on windows when the tmp dir has spaces
Changelog-entry: (Windows): Fix reading images from network drives when the tmp dir has spaces
Change-type: patch
2019-04-16 13:44:25 +02:00
Resin CI
9da9e73f7a v1.5.26 2019-04-12 20:44:41 +03:00
Alexis Svinartchouk
f90cd49a6d Merge pull request #2729 from balena-io/fix-wmic-output-encoding
Fix reading images from network drives containing non ascii characters
2019-04-12 19:42:13 +02:00
Alexis Svinartchouk
6e72c07190 Fix reading images from network drives containing non ascii characters
Changelog-entry: (Windows): Fix reading images from network drives containing non ascii characters
Change-type: patch
2019-04-12 18:56:12 +02:00
Resin CI
1997e1faeb v1.5.25 2019-04-10 14:27:04 +03:00
Lorenzo Alberto Maria Ambrosi
b33b34bd71 Merge pull request #2698 from balena-io/filter-analytics
New parameter in webview for opt-out analytics
2019-04-10 13:24:57 +02:00
Lorenzo Alberto Maria Ambrosi
6a9b739541 New parameter in webview for opt-out analytics
Change-type: patch
Changelog-entry: New parameter in webview for opt-out analytics
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2019-04-09 19:10:29 +02:00
Resin CI
6cb0bdd1a4 v1.5.24 2019-04-08 16:28:04 +03:00
Lorenzo Alberto Maria Ambrosi
b73ebb6f92 Merge pull request #2726 from balena-io/analytics-version-weight
Add sample property to Mixpanel events
2019-04-08 15:25:39 +02:00
Lorenzo Alberto Maria Ambrosi
24a83260ca Update building scripts to latest master
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2019-04-05 20:01:44 +02:00
Lorenzo Alberto Maria Ambrosi
fc1c1b402b Add sample property to Mixpanel events
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2019-04-05 17:02:04 +02:00
Alexis Svinartchouk
af462b3486 Merge pull request #2725 from balena-io/update-resin-corvus
Update resin-corvus to ^2.0.3
2019-04-03 18:09:20 +02:00
Alexis Svinartchouk
3e236996c8 Update resin-corvus to ^2.0.3
Changelog-entry: Update resin-corvus to ^2.0.3
Change-type: patch
2019-04-03 16:16:06 +02:00
Resin CI
c4e84483df v1.5.23 2019-04-03 13:19:19 +03:00
Giovanni Garufi
e9532f2158 Merge pull request #2720 from balena-io/publish-gh-pages
Set publishMetadata in repo.yml
2019-04-03 03:17:17 -07:00
Giovanni Garufi
15fc8ab2e7 Set publishMetadata in repo.yml
This will cause VB to publish metadata about the repo to its gh-pages
branch on merge

Change-type: patch
Changelog-entry: Configure versionbot to publish repo metadata to github pages
Signed-off-by: Giovanni Garufi <giovanni@balena.io>
2019-04-03 11:22:31 +02:00
Resin CI
b39dbeb25e v1.5.22 2019-04-02 19:54:16 +03:00
Alexis Svinartchouk
e181c21f85 Merge pull request #2724 from balena-io/fix-wmic-not-in-path
Use full path to wmic as some systems don't have it in their PATH
2019-04-02 18:51:38 +02:00
Alexis Svinartchouk
db771bc2cc Use full path to wmic as some systems don't have it in their PATH
Changelog-entry: (Windows): Use full path to wmic as some systems don't have it in their PATH
Change-type: patch
2019-04-02 17:32:49 +02:00
Resin CI
0695cfb3c0 v1.5.21 2019-04-02 17:43:58 +03:00
Alexis Svinartchouk
ff3982efa4 Merge pull request #2721 from balena-io/fix-getMixpanelConfig
Fix error when config.analytics was undefined
2019-04-02 16:42:00 +02:00
Alexis Svinartchouk
40de7f5d54 Fix error when config.analytics was undefined
Changelog-entry: Fix error when config.analytics was undefined
Change-type: patch
2019-04-01 18:16:56 +02:00
Resin CI
18a848696f v1.5.20 2019-04-01 19:04:20 +03:00
Alexis Svinartchouk
58de7375a2 Merge pull request #2717 from balena-io/1.5.20
1.5.20
2019-04-01 18:00:27 +02:00
Alexis Svinartchouk
b61109a269 Fix reading images from network drives on windows
Change-type: patch
2019-04-01 15:40:30 +02:00
Alexis Svinartchouk
164fd8f022 Don't try to flash when no device is selected
Changelog-entry: Don't try to flash when no device is selected
Change-type: patch
2019-03-29 17:24:34 +01:00
Giovanni Garufi
cafaa9ff22 Delete versionist.conf
Versionist will now look at repo.yml and inject the versionist config
corresponding to the type

Change-type: patch
Changelog-Entry: Reformat changelog
Signed-off-by: Giovanni Garufi <giovanni@balena.io>
2019-03-29 17:24:34 +01:00
Alexis Svinartchouk
34c98d1dcd Use async/await in flash.js
Avoid a rare race condition leading to "Error: There is already a flash in progress" messages

Changelog-entry: Avoid "Error: There is already a flash in progress" errors
Change-type: patch
2019-03-29 17:24:34 +01:00
Alexis Svinartchouk
ec015da795 Avoid "Invalid state percentage: null" errors
Change-type: patch
2019-03-29 17:24:34 +01:00
Resin CI
a21a82c64e v1.5.19 2019-03-28 16:49:12 +02:00
Alexis Svinartchouk
1aca669c62 Merge pull request #2714 from balena-io/report-unhandled-rejections
Better reporting of unhandled rejections to sentry
2019-03-28 15:47:02 +01:00
Alexis Svinartchouk
39573ada54 Update resin-corvus to ^2.0.2
Changelog-entry: Update resin-corvus to ^2.0.2
Change-type: patch
2019-03-28 13:47:30 +01:00
Alexis Svinartchouk
bceb7c77d1 Better reporting of unhandled rejections to sentry
Changelog-entry: Better reporting of unhandled rejections to sentry
Change-type: patch
2019-03-27 19:54:28 +01:00
Resin CI
68fa771905 v1.5.18 2019-03-27 01:42:35 +02:00
Lorenzo Alberto Maria Ambrosi
8a85968ec4 Merge pull request #2709 from balena-io/fix-appimage-build
Recreate zipped appImage
2019-03-27 00:40:22 +01:00
Giovanni Garufi
03b1a2dcff Update scripts
Change-type: patch
Changelog-entry: Update build scripts
Signed-off-by: Giovanni Garufi <giovanni@balena.io>
2019-03-26 23:29:17 +01:00
Resin CI
5cb231e427 v1.5.17 2019-03-26 10:48:08 +02:00
Giovanni Garufi
e90f6764f5 Merge pull request #2705 from balena-io/publish-github
Set publish: github in repo.yml
2019-03-26 01:45:28 -07:00
Giovanni Garufi
d078055e40 Set publish: github in repo.yml
Change-type: patch
Signed-off-by: Giovanni Garufi <giovanni@balena.io>
Changelog-entry: Automatically publish github release from CI
2019-03-25 17:48:21 +01:00
Resin CI
98134eb612 v1.5.16 2019-03-25 18:38:34 +02:00
Giovanni Garufi
b0f2dfc4fb Merge pull request #2696 from balena-io/test-pipeline
Add repo.yml
2019-03-25 09:31:05 -07:00
Giovanni Garufi
195f07c09f Update scripts
Change-type: patch
Signed-off-by: Giovanni Garufi <giovanni@balena.io>
2019-03-22 18:23:16 +01:00
Giovanni Garufi
15f87edc96 Update .gitattributes to always use LF for EOL in json files 2019-03-22 12:12:36 +01:00
Giovanni Garufi
52caae8f05 Add repo.yml
Change-type: patch
Signed-off-by: Giovanni Garufi <giovanni@balena.io>
Changelog-Entry: Add repo.yml for CI
2019-03-22 12:11:02 +01:00
Resin CI
99f7fc99da v1.5.15 2019-03-21 02:21:49 +02:00
Alexis Svinartchouk
89fc98c6f6 Merge pull request #2701 from balena-io/upgrade-etcher-sdk
etcher-sdk: Upgrade to 1.3.11
2019-03-21 01:19:14 +01:00
Juan Cruz Viotti
0c2eb1caab etcher-sdk: Upgrade to 1.3.11
Change-type: patch
Changelog-entry: Show the correct logo on usbboot devices on Ubuntu
Signed-off-by: Juan Cruz Viotti <juan@balena.io>
2019-03-20 21:18:30 +00:00
Resin CI
303969bdbf v1.5.14 2019-03-20 19:14:54 +02:00
Alexis Svinartchouk
8b7266a435 Merge pull request #2692 from balena-io/1.5.13
1.5.14
2019-03-20 18:09:34 +01:00
Alexis Svinartchouk
fc9282fff7 Remove versionist from dev dependencies
Change-type: patch
2019-03-20 16:13:38 +01:00
Alexis Svinartchouk
33fb79e0de Update etcher-sdk to ^1.3.10
Changelog-entry: Update etcher-sdk to ^1.3.10
Change-type: patch
2019-03-20 16:13:38 +01:00
Resin CI
b4418660df v1.5.13 2019-03-18 20:07:14 +02:00
Giovanni Garufi
3560a22a77 Merge pull request #2694 from balena-io/update-scripts
Update scripts
2019-03-18 19:02:30 +01:00
Giovanni Garufi
818b466687 Update scripts
Change-type: patch
Signed-off-by: Giovanni Garufi <giovanni@balena.io>
Changelog-Entry: Update build scripts
2019-03-18 17:44:44 +01:00
Resin CI
91d29c1e2c v1.5.12 2019-03-15 19:18:17 +02:00
Alexis Svinartchouk
e06fe72131 Merge pull request #2691 from balena-io/local-node-gyp-electron-builder
Update electron-builder scripts
2019-03-15 18:12:01 +01:00
Alexis Svinartchouk
7d715fdca0 Disable node gyp rebuild while running electron-builder
Change-type: patch
2019-03-15 17:33:19 +01:00
Lorenzo Alberto Maria Ambrosi
3cfa6988ab Update build scripts
Changelog-entry: Update build scripts
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2019-03-15 17:33:19 +01:00
Resin CI
1c707b2d37 v1.5.11 2019-03-12 20:07:34 +02:00
Alexis Svinartchouk
2ed4c76abf Merge pull request #2689 from balena-io/1.5.11
1.5.11
2019-03-12 19:00:51 +01:00
David Lozano Jarque
94e91723f4 Update PUBLISHING.md
Fixed broken Hombrew cask link for etcher

Changelog-entry: Fixed broken Hombrew cask link for etcher
Change-type: patch
2019-03-12 17:35:19 +01:00
Alexis Svinartchouk
091bddbad8 Remove no longer used travis and appveyor configs
Changelog-entry: Remove no longer used travis and appveyor configs
Change-type: patch
2019-03-12 17:35:19 +01:00
Resin CI
b3f68c2638 v1.5.10 2019-03-12 18:01:29 +02:00
Alexis Svinartchouk
00c94c8efd Merge pull request #2688 from balena-io/fix-appimage
Use APPDIR from env in the child writer
2019-03-12 16:29:00 +01:00
Alexis Svinartchouk
66b19677bf Use APPDIR from env in the child writer
Change-type: patch
2019-03-12 13:30:26 +01:00
Alexis Svinartchouk
2d4170e0d7 Merge pull request #2683 from balena-io/fix-makefile
Fix Makefile
2019-03-07 17:54:00 +01:00
Alexis Svinartchouk
7f8f38ddf1 Update resin-scripts
Changelog-entry: Update resin-scripts
Change-type: patch
2019-03-07 16:29:20 +01:00
Alexis Svinartchouk
2e1763f19a Fix Makefile
Change-type: patch
2019-03-07 15:20:07 +01:00
Resin CI
a5f8b3c164 v1.5.9 2019-03-06 18:00:26 +02:00
Alexis Svinartchouk
a802087009 Merge pull request #2677 from balena-io/1.5.9
1.5.9
2019-03-06 16:56:45 +01:00
Alexis Svinartchouk
3b16c06f70 upgrade(scripts): Use master branch of resin-scripts
Change-type: patch
2019-03-05 17:04:06 +01:00
Alexis Svinartchouk
a979ae3ced upgrade(etcher-sdk): Update etcher-sdk to 1.3.0
Changelog-entry: Update etcher-sdk to 1.3.0
Change-type: patch
2019-03-05 17:04:06 +01:00
Resin CI
02e0f40702 v1.5.8 2019-03-01 20:04:48 +01:00
Alexis Svinartchouk
a4d7853bb2 Merge pull request #2675 from balena-io/update-node-ext2fs
upgrade(ext2fs): Update ext2fs to 1.0.27
2019-03-01 20:00:24 +01:00
Alexis Svinartchouk
ac463e0f65 upgrade(ext2fs): Update ext2fs to 1.0.27
Changelog-entry: Update ext2fs to 1.0.27
Change-type: patch
2019-03-01 19:06:13 +01:00
Resin CI
c187aa46b7 v1.5.7 2019-03-01 17:10:08 +01:00
Alexis Svinartchouk
e65fa9dcae Merge pull request #2674 from balena-io/1.5.7
1.5.7
2019-03-01 17:05:33 +01:00
Robert Vojta
fea230cfab fix(docs): Update macOS contributing info
Changelog-entry: Update docs
Change-type: patch
Signed-off-by: Robert Vojta <robert@balena.io>
2019-03-01 15:10:50 +01:00
Lorenzo Alberto Maria Ambrosi
90838c99fc Add missing line for supporting flashing CM3+
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2019-03-01 15:10:50 +01:00
Robert Vojta
8e96adeda9 Fix copyright year
Change-type: patch
Signed-off-by: Robert Vojta <robert@balena.io>
2019-03-01 15:10:50 +01:00
Robert Vojta
3cdb0f840e Fix electron links
Change-type: patch
Signed-off-by: Robert Vojta <robert@balena.io>
2019-03-01 15:10:50 +01:00
Robert Vojta
b6ad6e0a85 Fix macOS version requirements
Change-type: patch
Signed-off-by: Robert Vojta <robert@balena.io>
2019-03-01 15:10:50 +01:00
Robert Vojta
e73a577452 Fix electron links
Change-type: patch
Signed-off-by: Robert Vojta <robert@balena.io>
2019-03-01 15:10:50 +01:00
Robert Vojta
16e8aa2447 Fix AppImages link
Change-type: patch
Signed-off-by: Robert Vojta <robert@balena.io>
2019-03-01 15:10:50 +01:00
Robert Vojta
1d6958a67e fix(osx installer): Fix blurred background image
Changelog-entry: Fix blurred background image
Change-type: patch
Signed-off-by: Robert Vojta <robert@balena.io>
2019-03-01 15:10:05 +01:00
Robert Vojta
136ca282eb fix(gui): Fix disappearing modal window
Changelog-entry: Fix disappearing modal window
Change-type: patch
Signed-off-by: Robert Vojta <robert@balena.io>
2019-03-01 15:09:19 +01:00
Lorenzo Alberto Maria Ambrosi
388fc2f7d9 Remove screenshot
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2019-03-01 13:49:26 +01:00
Resin CI
72fdb7127a v1.5.6 2019-03-01 12:16:33 +01:00
Alexis Svinartchouk
f67832644f Merge pull request #2673 from balena-io/babel-target-electron-3
Target electron 3 runtime in babel options
2019-03-01 11:44:46 +01:00
Alexis Svinartchouk
2614f3261c Target electron 3 runtime in babel options
This saves around 40KiB in generated/gui.js

Changelog-entry: Target electron 3 runtime in babel options
Change-type: patch
2019-02-28 15:04:00 +01:00
Resin CI
e84204b49a v1.5.5 2019-02-28 13:13:02 +01:00
Alexis Svinartchouk
86aaa725d5 Merge pull request #2663 from balena-io/1.5-fixes
1.5.x fixes
2019-02-28 13:10:25 +01:00
Alexis Svinartchouk
dd583a176f Don't pass undefined sockets to ipc.server.emit()
Changelog-entry: Don't pass undefined sockets to ipc.server.emit()
Change-type: patch
2019-02-28 11:16:12 +01:00
Alexis Svinartchouk
5299d958f2 Fix error when event.dataTransfer.files is empty
Changelog-entry: Fix error when event.dataTransfer.files is empty
Change-type: patch
2019-02-28 11:16:12 +01:00
Alexis Svinartchouk
f0374cf9d9 Fix error message not showing when an unsupported image is selected
Changelog-entry: Fix error message not showing when an unsupported image is selected
Change-type: patch
2019-02-28 11:16:12 +01:00
Alexis Svinartchouk
6b6a0d7b4f Avoid Invalid percentage exceptions
Changelog-entry: Avoid `Invalid percentage` exceptions
Change-type: patch
2019-02-28 11:16:12 +01:00
Alexis Svinartchouk
4317892421 Update etcher-sdk to 1.1.0
Changelog-entry: Update etcher-sdk to 1.1.0
Change-type: patch
2019-02-28 11:16:12 +01:00
Resin CI
8052b2adfa v1.5.4 2019-02-28 11:03:17 +01:00
Lorenzo Alberto Maria Ambrosi
d44927447a Merge pull request #2668 from balena-io/add-missing-contributing-step
Add missing step for submodule init & update
2019-02-28 11:01:02 +01:00
Lorenzo Alberto Maria Ambrosi
09e6c6422d Add missing step for submodule init & update
Change-type: patch
Changelog-entry: Add missing step for submodule cloning in README
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2019-02-27 22:24:47 +01:00
Resin CI
df85ffb254 v1.5.3 2019-02-27 22:11:45 +01:00
Lorenzo Alberto Maria Ambrosi
752ba4405c Merge pull request #2669 from balena-io/fix-versionist-conf
Fix versionist conf
2019-02-27 22:09:02 +01:00
Lorenzo Alberto Maria Ambrosi
1f3a02b83d Bump version in npm-shrinkwrap.json
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2019-02-27 19:48:20 +01:00
Giovanni Garufi
8e372f1e93 Fix changelog 2019-02-27 16:25:10 +01:00
Giovanni Garufi
caeb84f58b Throw error if no commit is annotated with a changelog entry
Change-type: patch
Signed-off-by: Giovanni Garufi <giovanni@balena.io>
Changelog-entry: Throw error if no commit is annotated with a changelog entry
2019-02-27 16:23:55 +01:00
Resin CI
759722bf7d v1.5.2 2019-02-26 15:21:12 +01:00
Lorenzo Alberto Maria Ambrosi
cefdc95c9b Merge pull request #2664 from balena-io/enable-edit-version-versionist
Enable versionist editVersion
2019-02-26 15:17:26 +01:00
Lorenzo Alberto Maria Ambrosi
3be7029078 Enable versionist editVersion
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2019-02-26 13:10:50 +01:00
Resin CI
3f16858a93 v1.5.1 2019-02-25 12:11:04 +01:00
Giovanni Garufi
c61c6deaa8 Merge pull request #2634 from balena-io/versioning
[WIP] Remove lodash use from versionist.conf.js
2019-02-25 11:04:33 +00:00
Giovanni Garufi
90c8483df8 Remove lodash dependency in versionist.conf.js
Changelog-entry: Removed lodash dependency in versionist.conf.js
Change-type: patch
Signed-off-by: Giovanni Garufi <giovanni@balena.io>
2019-02-22 13:30:49 +00:00
Lorenzo Alberto Maria Ambrosi
d70b189cec Merge pull request #2635 from balena-io/release-v1.5.0
Release v1.5.0
2019-02-21 17:13:26 +01:00
Lorenzo Alberto Maria Ambrosi
41a7fc4de5 Release v1.5.0
Change-type: minor
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2019-02-20 17:00:31 +01:00
Alexis Svinartchouk
db119d5230 Update npm-shrinkwrap.json to update drivelist
Change-type: patch
2019-02-20 17:00:31 +01:00
Alexis Svinartchouk
c88245954d Wait 100ms before disconnecting if a message is being sent
Change-Type: patch
2019-02-19 14:18:22 +01:00
Alexis Svinartchouk
b1ab3834b6 Merge pull request #2631 from balena-io/dont-use-drivelist-directly
Dont use drivelist directly
2019-02-15 14:16:41 +01:00
Alexis Svinartchouk
34b7c1be81 Update etcher-sdk to ^1.0.7
Change-type: patch
2019-02-14 19:19:19 +01:00
Alexis Svinartchouk
082c77586f Don't use drivelist directly
Use etcher-sdk's drive scanner instead.

Change-Type: patch
2019-02-14 19:19:19 +01:00
Alexis Svinartchouk
3b6fe7b548 Merge pull request #2630 from balena-io/drop-cli
Remove etcher-cli
2019-02-14 19:09:30 +01:00
Alexis Svinartchouk
da072e7621 Remove etcher-cli
Change-type: major
2019-02-14 18:22:40 +01:00
Alexis Svinartchouk
4568404a70 Merge pull request #2616 from balena-io/electron-3.0
Bump electron to v3.1.3
2019-02-14 17:12:39 +01:00
Alexis Svinartchouk
43319853ef Workaround a bug when 2 webviews are loaded at the same time.
In some cases the spectron tests time out in app:start. This should
prevent it.

Change-type: patch
2019-02-14 15:41:03 +01:00
Lorenzo Alberto Maria Ambrosi
ce9f142621 Bump electron to v3.1.3
Change-type: major
Changelog-entry: Upgrade to Electron v3
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2019-02-12 15:42:05 +01:00
Alexis Svinartchouk
8ef3add183 Merge pull request #2615 from balena-io/npm6-3
Npm6 replaces #2577
2019-02-11 17:15:18 +01:00
Alexis Svinartchouk
ef45696015 Double app:start test timeout
Change-type: patch
2019-02-11 14:46:05 +01:00
Alexis Svinartchouk
a8f8c2cd85 Increase svg icon test timeout
Change-type: patch
2019-02-11 14:08:13 +01:00
Alexis Svinartchouk
6d79a8e23a Rebuild node-sass before using it
It avoids an error for x86 win32 builds on x64 platforms:
`Node Sass could not find a binding for your current environment: Windows 64-bit with Node.js 6.x`

Change-type: patch
2019-02-11 12:06:27 +01:00
Alexis Svinartchouk
d65dc6ccac Use npx branch of resin-scripts
Change-type: patch
2019-02-08 15:37:45 +01:00
Alexis Svinartchouk
ccc9076a80 Use npx to force npm version
Change-type: patch
2019-02-01 15:32:06 +01:00
Alexis Svinartchouk
3c007cea34 Specify npm_version in .resinci.json
Change-type: patch
2019-02-01 13:07:13 +01:00
Alexis Svinartchouk
bf29312ecf npm6, electron 1.8.8
Change-type: patch
2019-01-30 16:24:01 +01:00
Alexis Svinartchouk
a53095b29e Merge pull request #2403 from balena-io/etcher-sdk
refactor: use etcher-sdk
2019-01-29 14:37:05 +01:00
Alexis Svinartchouk
d5c9e6b054 Move patches back to patches folder
Change-type: patch
2019-01-28 14:53:29 +01:00
Alexis Svinartchouk
d4f29bd2af Hardcode electron_version in node-pre-gyp patch
Because it is not available in electron when running with
ELECTRON_RUN_AS_NODE=1

Change-type: patch
2019-01-28 13:07:38 +01:00
Alexis Svinartchouk
a6661ac759 Update node-ext2fs to 1.0.25
Change-type: patch
2019-01-25 18:05:51 +01:00
Alexis Svinartchouk
6aa83819d1 Remove napi-build-utils from npm-shrinkwrap
Change-type: patch
2019-01-24 18:51:30 +01:00
Alexis Svinartchouk
8ff4c8a4a5 Fix npm-shrinkwrap.json and remove versionist
versionist is causing ci issues with the shrinkwrap file on windows.
You'll need to manually install versionist before running `make changelog`

Change-type: patch
2019-01-24 13:21:27 +01:00
Alexis Svinartchouk
1d77b8dae7 Update node-pre-gyp patch and move it to another folder
To prevent the apply-patches script from doing stuff

Change-type: patch
2019-01-24 13:21:27 +01:00
Alexis Svinartchouk
3e0062621b Update build scripts for electron-builder unresolved dependencies
Change-type: patch
2019-01-24 13:21:27 +01:00
Alexis Svinartchouk
b20e220910 Update styled-system to 3.1.11 (it was lost in a rebase)
Change-type: patch
2019-01-24 13:21:27 +01:00
Alexis Svinartchouk
0259572ded Update etcher-sdk to ^1.0.2 and update npm-shrinkwrap.json
Change-type: patch
2019-01-24 13:21:27 +01:00
Alexis Svinartchouk
a78866069b Update webpack to 4.27.0 and babel to 7.2.0
Change-type: patch
2019-01-24 13:21:27 +01:00
Alexis Svinartchouk
b8fc83577c Remove asar from devDependencies, update versionist
Change-Type: patch
2019-01-24 13:21:27 +01:00
Alexis Svinartchouk
c21969ab4e Remove etcher-sdk folder filtering from webpack config
This folder has been removed

Change-type: patch
2019-01-24 13:21:27 +01:00
Alexis Svinartchouk
e02cfc4529 update(etcher-sdk): Update etcher-sdk and shrinkwrap.json
Change-type: patch
2019-01-24 13:21:27 +01:00
Alexis Svinartchouk
ac07c63631 update(etcher-sdk): Update etcher-sdk and shrinkwrap.json
Also update the node-pre-gyp patch (the directory has changed)

Change-type: patch
2019-01-24 13:21:27 +01:00
Alexis Svinartchouk
1054bc995b fix(ci): Set node target to 6.14.4
Change-type: patch
2019-01-24 13:21:27 +01:00
Alexis Svinartchouk
3560ab6387 update(package): Update etcher-sdk and npm-shrinkwrap.json
Change-type: patch
2019-01-24 13:21:27 +01:00
Alexis Svinartchouk
e50274b962 Remove no longer used bluebird-retry
Change-type: patch
2019-01-24 13:21:27 +01:00
Alexis Svinartchouk
bb1773a1a1 Remove styled-system from package.json
Change-type: patch
2019-01-24 13:21:27 +01:00
Alexis Svinartchouk
941dc3b1b4 update(package): Update shrinkwrap.json
Change-type: patch
2019-01-24 13:21:27 +01:00
Alexis Svinartchouk
92d08d24ab fix(build): Update resin scripts to build modules from source
Change-type: patch
2019-01-24 13:21:27 +01:00
Alexis Svinartchouk
7f6ffe0f73 fix(package): Fix shrinkwrap file
Change-type: patch
Signed-off-by: Alexis Svinartchouk <alexis@balena.io>
2019-01-24 13:21:27 +01:00
Alexis Svinartchouk
66457ca0c7 upgrade(package): Update to etcher-sdk@0.1.28
Change-type: patch
Signed-off-by: Alexis Svinartchouk <alexis@resin.io>
2019-01-24 13:21:27 +01:00
Alexis Svinartchouk
3344f1fd88 upgrade(package): Update to etcher-sdk@0.1.27
Change-type: patch
Signed-off-by: Alexis Svinartchouk <alexis@resin.io>
2019-01-24 13:21:27 +01:00
Alexis Svinartchouk
c4b636f80a upgrade(package): Update to etcher-sdk@0.1.26 and fix npm-shrinkwrap
Change-type: patch
Signed-off-by: Alexis Svinartchouk <alexis@resin.io>
2019-01-24 13:21:27 +01:00
Alexis Svinartchouk
0ea0975bd4 upgrade(package): Update to etcher-sdk@0.1.23
Change-type: patch
Signed-off-by: Alexis Svinartchouk <alexis@resin.io>
2019-01-24 13:21:27 +01:00
Alexis Svinartchouk
534f3a7469 fix(gui): Always show the "success" screen
Change-type: patch
Signed-off-by: Alexis Svinartchouk <alexis@resin.io>
2019-01-24 13:21:27 +01:00
Alexis Svinartchouk
f3110ba018 upgrade(package): Update to etcher-sdk@0.1.16
Change-type: patch
Signed-off-by: Alexis Svinartchouk <alexis@resin.io>
2019-01-24 13:21:27 +01:00
Alexis Svinartchouk
e76cc81fe1 upgrade(package): Update to etcher-sdk@0.1.15
Change-type: patch
Signed-off-by: Alexis Svinartchouk <alexis@resin.io>
2019-01-24 13:21:27 +01:00
Alexis Svinartchouk
adcc3343ec fix(gui): Disable compute modules selection during preparation
Change-type: patch
Signed-off-by: Alexis Svinartchouk <alexis@resin.io>
2019-01-24 13:21:27 +01:00
Alexis Svinartchouk
645e114a1f fix(gui): Allow drives to be objects
This fixes an error when plugging usbboot devices.

Change-type: patch
Signed-off-by: Alexis Svinartchouk <alexis@resin.io>
2019-01-24 13:21:27 +01:00
Alexis Svinartchouk
65d86460cb fix(shared): Fix getDriveImageCompatibilityStatuses() and tests
Change-type: patch
Signed-off-by: Alexis Svinartchouk <alexis@resin.io>
2019-01-24 13:21:27 +01:00
Alexis Svinartchouk
aaccd10c2a fix(gui): Allow undefined eta
Change-type: patch
Signed-off-by: Alexis Svinartchouk <alexis@resin.io>
2019-01-24 13:21:27 +01:00
Alexis Svinartchouk
a237bfd930 upgrade(package): Update to etcher-sdk@0.1.13
Change-type: patch
Signed-off-by: Alexis Svinartchouk <alexis@resin.io>
2019-01-24 13:21:27 +01:00
Alexis Svinartchouk
73f64d93b1 upgrade(package): Update to etcher-sdk@0.1.9
Change-type: patch
Signed-off-by: Alexis Svinartchouk <alexis@resin.io>
2019-01-24 13:21:26 +01:00
Alexis Svinartchouk
871db09447 fix(tests): Fix gui tests
Change-type: patch
Signed-off-by: Alexis Svinartchouk <alexis@resin.io>
2019-01-24 13:21:26 +01:00
Alexis Svinartchouk
8d79103392 upgrade(package): Update to etcher-sdk@0.1.7
Also update the shrinkwrap file

Change-type: patch
Signed-off-by: Alexis Svinartchouk <alexis@resin.io>
2019-01-24 13:21:26 +01:00
Jonas Hermsmeier
fd765443e4 fix(image-selection): Only trigger digest loop after setting image
Change-type: patch
Signed-off-by: Jonas Hermsmeier <jhermsmeier@gmail.com>
2019-01-24 13:21:26 +01:00
Alexis Svinartchouk
63967d1558 fix(tests): Remove throw if no percentage or eta test
Since 25916200f2864a9b137325f919c0f8ef5d62fa60 we can handle a progress
state with no percentage or eta.
2019-01-24 13:21:26 +01:00
Alexis Svinartchouk
6b270885bf feat(driverless) show driverless devices 2019-01-24 13:21:26 +01:00
Alexis Svinartchouk
47937d6aaa fix(package): remove diskpart helper, it is in the sdk now 2019-01-24 13:21:26 +01:00
Alexis Svinartchouk
7d2ba45620 fix(store): Lowercase extensions before comparing 2019-01-24 13:21:26 +01:00
Jonas Hermsmeier
b270d819a8 fix(store): Restore drive object validity check 2019-01-24 13:21:26 +01:00
Jonas Hermsmeier
c50553fbf6 upgrade(package): Update etcher-sdk git ref 2019-01-24 13:21:26 +01:00
Jonas Hermsmeier
a541c863be fix(test): Sort compressed extensions before comparing 2019-01-24 13:21:26 +01:00
Jonas Hermsmeier
254b482651 upgrade(package): Update mime-types 2.1.15 -> 2.1.18
This update includes a previously missing mapping for gzip
(`application/gzip`), which contributes to fixing gzip compressed
image detection in the new SDK

Change-type: patch
2019-01-24 13:21:26 +01:00
Jonas Hermsmeier
d3c2cd4215 fix(test): Sort supported extensions to fix order mismatch
Change-type: patch
2019-01-24 13:21:26 +01:00
Jonas Hermsmeier
4f7cc7dd6b fix(lib): Fix MIME type exclusion condition
As `mime.extension()` returns `false`, instead of `null` or `undefined`,
this condition simply needs to check for truthyness.

Change-type: patch
2019-01-24 13:21:26 +01:00
Jonas Hermsmeier
21f1f4e503 fix(test): Turn SDK integration tests for the GUI back on
Change-type: patch
2019-01-24 13:21:26 +01:00
Jonas Hermsmeier
47f2336673 fix(lib): Fix use of non-existent dependency
Change-Type: patch
2019-01-24 13:21:26 +01:00
Alexis Svinartchouk
5ae93bf6d0 Update etcher-sdk and load DriverlessDeviceAdapter on windows 2019-01-24 13:21:26 +01:00
Alexis Svinartchouk
caf5f10326 lint 2019-01-24 13:21:26 +01:00
Alexis Svinartchouk
e68dbcf4ee Remove lib/sdk and its tests 2019-01-24 13:21:26 +01:00
Alexis Svinartchouk
a42e81cf8c Replace imageStream with etcher-sdk in the react file selector 2019-01-24 13:21:21 +01:00
Alexis Svinartchouk
98a8588c1b Update etcher-sdk and use it in the cli 2019-01-24 13:21:21 +01:00
Alexis Svinartchouk
8630af7646 Remove usage of old sdk in supported-formats 2019-01-24 13:21:21 +01:00
Alexis Svinartchouk
268c5302e8 Handle the last fail as an error if all devices failed 2019-01-24 13:21:21 +01:00
Alexis Svinartchouk
d07d535993 Show raspberry pi usbboot update progress in devices list 2019-01-24 13:21:21 +01:00
Alexis Svinartchouk
a8a75f22b2 Allow flashing from sources for which we don't know the compressed size
* don't show any percentage or eta, show the bytes written instead
2019-01-24 13:21:21 +01:00
Alexis Svinartchouk
6143023502 Integrate etcher-sdk 2019-01-24 13:21:21 +01:00
Alexis Svinartchouk
ca6aa5d4aa Merge pull request #2611 from balena-io/update-node-gyp
Update node-gyp to 3.8.0
2019-01-24 08:52:52 +01:00
Alexis Svinartchouk
bc028ed41f Add napi-build-utils to platformSpecificDependencies
Change-type: patch
2019-01-23 17:25:42 +01:00
Alexis Svinartchouk
911d3a9188 Update node-gyp to 3.8.0
Change-type: patch
2019-01-23 16:26:26 +01:00
Alexis Svinartchouk
b88e715fc5 Merge pull request #2610 from balena-io/update-winusb
Update winusb-driver-generator to 1.2.4
2019-01-23 13:22:17 +01:00
Alexis Svinartchouk
a4dfa5f281 Update winusb-driver-generator to 1.2.4
Change-type: patch
2019-01-22 18:29:20 +01:00
Lorenzo Alberto Maria Ambrosi
05fc1711b9 Merge pull request #2606 from balena-io/bump-dependencies
Bump dependencies
2019-01-18 19:13:32 +01:00
Lorenzo Alberto Maria Ambrosi
c16fbb5b47 Rename resin-io modules to balena-io
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2019-01-18 17:05:06 +01:00
Lorenzo Alberto Maria Ambrosi
7ca3e2b519 Update build scripts for electron-builder unresolved dependencies
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2019-01-18 16:51:20 +01:00
Lorenzo Alberto Maria Ambrosi
8c8a0bf8eb Fix linting error for winusb-driver-generator
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2019-01-18 14:48:10 +01:00
Lorenzo Alberto Maria Ambrosi
e85251d2e3 Bump drivelist to v6.4.6
Change-type: patch
Changelog-entry: Fix incorrect drives list on Linux
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2019-01-17 10:57:46 +01:00
Lorenzo Alberto Maria Ambrosi
73e4827249 Bump mountutils to v1.3.16 for XCode build fix
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2019-01-17 10:54:29 +01:00
Lorenzo Alberto Maria Ambrosi
c37270ea08 Switch to fork of xxhash with XCode build fix
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2019-01-17 10:52:34 +01:00
Lorenzo Alberto Maria Ambrosi
8cc33b46bb Make winusb-driver-generator optional (win only)
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2019-01-17 10:51:11 +01:00
Lorenzo Alberto Maria Ambrosi
700341f9cc Fix error with OSX XCode build
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2019-01-17 10:49:38 +01:00
Lorenzo Alberto Maria Ambrosi
ca85ad5995 Merge pull request #2460 from balena-io/contribution-file-fix
docs: Add info about required npm version
2019-01-14 19:59:16 +01:00
Lorenzo Alberto Maria Ambrosi
1c8c36a224 Update nodejs req to 6.11 (fixes package build)
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2019-01-14 18:36:25 +01:00
Agnieszka Domanska
25b814e796 docs: Add info about required npm version
Npm 3.10 version is required to install dev tools correctly on Linux.

Change-type: patch
Signed-off-by: amdomanska <aga@resin.io>
2019-01-14 17:22:40 +01:00
Lorenzo Alberto Maria Ambrosi
e89566e04a Merge pull request #2580 from balena-io/progress-button-disabled-prop-is-a-boolean
ProgressBar.disabled prop is a boolean
2019-01-09 14:04:55 +01:00
Alexis Svinartchouk
e946f388c0 ProgressBar.disabled prop is a boolean
Change-type: patch
2019-01-08 12:42:39 +01:00
Lorenzo Alberto Maria Ambrosi
7616e8dab7 Merge pull request #2582 from balena-io/2281-drive-mountpoint-contains-image
Change "Drive Contains Image" label.
2019-01-08 11:53:47 +01:00
Lorenzo Alberto Maria Ambrosi
2dc4fef4d3 Update scripts to build on other Linux distros
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2019-01-07 17:01:18 +01:00
Alexis Svinartchouk
f2ca997195 Change "Drive Contains Image" label.
Use "Drive Mountpoint Contains Image" instead as the image may not be on
this drive but on a drive mounted in one of the mountpoins of this
drive.
We still don't want to allow flashing this drive in that situation.

Changelog-entry: Changed “Drive Contains Image” to “Drive Mountpoint Contains Image”
Change-type: patch
2019-01-07 15:35:21 +01:00
Lorenzo Alberto Maria Ambrosi
7445004abf Merge pull request #2589 from balena-io/fix-offline-success-banner
Restored offline success-banner style
2019-01-07 15:34:23 +01:00
Lorenzo Alberto Maria Ambrosi
9b76abe2ed Restored offline success-banner style
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2019-01-07 14:06:05 +01:00
Lorenzo Alberto Maria Ambrosi
a97205c9fc Merge pull request #2595 from Jacalz/fix-solus-install
Refinements to the README
2019-01-07 09:56:39 +01:00
Jacalz
bf3d069aad Refinements to the README
This started out with the intention to fix a typo in the uninstall 
section of Solus, but developed in to a couple improvements to the 
README.
2019-01-05 16:44:49 +01:00
Lorenzo Alberto Maria Ambrosi
27ea74722c Merge pull request #2592 from balena-io/fix-readme
Fix readme
2019-01-04 17:38:53 +01:00
Lorenzo Alberto Maria Ambrosi
2525456d8b Update balena-etcher .deb and .rpm install steps
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2019-01-04 16:08:10 +01:00
Lorenzo Alberto Maria Ambrosi
9fa32df3a6 Remove travis-ci and appveyor badges
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2019-01-04 15:39:23 +01:00
Lorenzo Alberto Maria Ambrosi
5bdd5da13b Merge pull request #2587 from balena-io/fix-dmg-assets
New dmg package background assets
2018-12-23 15:54:06 +01:00
Lorenzo Alberto Maria Ambrosi
b8756edd29 New dmg package background assets
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2018-12-22 01:41:18 +01:00
Lorenzo Alberto Maria Ambrosi
c93910e858 Merge pull request #2586 from balena-io/release-v1.4.9
v1.4.9
2018-12-21 16:07:29 +01:00
Lorenzo Alberto Maria Ambrosi
ad4226ace7 Invert analytics event probability
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2018-12-21 15:12:08 +01:00
Lorenzo Alberto Maria Ambrosi
d71b3fe1bc v1.4.9
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2018-12-19 22:10:26 +01:00
Lorenzo Alberto Maria Ambrosi
07858eecac Merge pull request #2571 from balena-io/restyle-success-screen
Restyle success screen and enlarge UI elements
2018-12-19 19:36:49 +01:00
Lorenzo Alberto Maria Ambrosi
64ec6d0e58 Convert flash results component to React
Change-type: minor
Changelog-entry: Added React component for the Flash Results button
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2018-12-19 16:02:38 +01:00
Lorenzo Alberto Maria Ambrosi
cf722427ab Restyle success screen and enlarge UI elements
Change-type: patch
Changelog-entry: Added React component for the Flash Another button
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2018-12-19 13:20:02 +01:00
Lorenzo Alberto Maria Ambrosi
1b7ff07efc Merge pull request #2584 from balena-io/remove-webview-console-messages
Remove forwarding of SafeWebview console messages
2018-12-19 13:09:21 +01:00
Lorenzo Alberto Maria Ambrosi
87533f4417 Remove forwarding of SafeWebview console messages
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2018-12-19 12:19:42 +01:00
Lorenzo Alberto Maria Ambrosi
9077c95cdd Merge pull request #2583 from balena-io/add-mixpanel-configs
Customize Mixpanel configs
2018-12-18 15:13:16 +01:00
Lorenzo Alberto Maria Ambrosi
22acc5ae96 Customize Mixpanel configs
Change-type: minor
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2018-12-18 11:32:07 +01:00
Lorenzo Alberto Maria Ambrosi
cf596a88ab Merge pull request #2557 from balena-io/explicit-safe-webview-events
Use explicit names for safe-webview events
2018-11-28 21:11:10 +01:00
Lorenzo Alberto Maria Ambrosi
7354fa3050 Use explicit names for safe-webview events
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2018-11-28 15:57:58 +01:00
Lorenzo Alberto Maria Ambrosi
978497b287 Merge pull request #2539 from Jacalz/gitmodule-https
Use https for fetching sub modules
2018-11-28 15:35:33 +01:00
Lorenzo Alberto Maria Ambrosi
a52d745250 Merge branch 'master' into gitmodule-https 2018-11-28 14:14:13 +01:00
Chris Crocker-White
aae71f8105 Merge pull request #2562 from balena-io/chrisys-patch
Update URLs in GUI to balena
2018-11-27 15:51:23 -08:00
Jacob
5419b4b732 Use https for fetching sub modules
This switches over the sub module to using https instead of ssh. It simplifies a lot for people packaging the application and you won't need to have ssh configured correctly.
2018-11-27 18:19:02 +01:00
Chris Crocker-White
caf5a8917c Merge branch 'master' into chrisys-patch 2018-11-27 08:22:15 -08:00
Lorenzo Alberto Maria Ambrosi
beec00dcb3 Merge pull request #2560 from OSSystems/add-wic-support
Add `.wic` image extension as supported format
2018-11-27 14:31:42 +01:00
Otavio Salvador
7565e809b0 Add .wic image extension as supported format
The `.wic` is a widely used image format in the OpenEmbedded / Yocto
Project ecosystem and is straightforward to be supported.

Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
2018-11-27 10:01:05 -02:00
Lorenzo Alberto Maria Ambrosi
5c9a646bc1 Merge pull request #2561 from rhwood/patch-1
Update MacOS installation instructions.
2018-11-27 10:26:19 +01:00
Chris Crocker-White
dd8ef288f7 Update URLs in GUI to balena
Change-type: patch
Signed-off-by: Chris Crocker-White <chriscw@balena.io>
2018-11-26 17:38:06 -08:00
Randall Wood
db8d2953cb Update MacOS installation instructions.
Homebrew/homebrew-cask#55358 changed the name used for installation.
2018-11-26 17:23:38 -08:00
Lorenzo Alberto Maria Ambrosi
b75ca26db2 Merge pull request #2558 from Eate/patch-1
Updated Chocolatey section of Readme
2018-11-26 20:05:54 +01:00
Eate
948a04122a Updated Chocolatey section
Previously, the section header was a "###" header, and I changed it to a "####" header like all the other install variants so it is the same level header. I also added uninstall instructions like the other sections had.
2018-11-26 08:09:47 -08:00
Lorenzo Alberto Maria Ambrosi
b7c4562b85 Merge pull request #2556 from balena-io/fix-update-notification
fix(GUI): Fix update notification error
2018-11-26 17:08:49 +01:00
Lorenzo Alberto Maria Ambrosi
6d0fea1983 fix(GUI): Fix update notification error
Remove "this" and use "exports" instead

Change-type: patch
Changelog-entry: Fix update notifier error popping up on v1.4.1->1.4.8
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2018-11-26 15:53:55 +01:00
Lorenzo Alberto Maria Ambrosi
1a158a919a Merge pull request #2553 from balena-io/v1.4.8
v1.4.8
2018-11-23 18:52:18 +01:00
Lorenzo Alberto Maria Ambrosi
9a83bd4267 v1.4.8
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2018-11-23 17:51:41 +01:00
Lorenzo Alberto Maria Ambrosi
7e3f516b04 Merge pull request #2551 from balena-io/add-potm-webview
feat(GUI): Add featured-project component
2018-11-23 17:44:49 +01:00
Lorenzo Alberto Maria Ambrosi
afd888e14d fix(GUI): Fix styling issues with buttons
Change-type: patch
Changelog-entry: Moved back the write cancel button
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2018-11-23 16:28:06 +01:00
Lorenzo Alberto Maria Ambrosi
76af6e975e Add flashing info while showing webview
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2018-11-23 13:19:47 +01:00
Lorenzo Alberto Maria Ambrosi
2017df9ec6 feat(GUI): Add featured-project component
Change-type: patch
Changelog-entry: Added featured-project while flashing
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2018-11-22 22:05:11 +01:00
Lorenzo Alberto Maria Ambrosi
aa1e83dc24 Merge pull request #2552 from balena-io/reject-drives-null-size
fix(GUI): Reject drives with null size
2018-11-22 20:50:56 +01:00
Lorenzo Alberto Maria Ambrosi
20996b153d fix(GUI): Reject drives with null size
Change-type: patch
Changelog-entry: Reject drives with null size (fixes pretty-bytes error)
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2018-11-22 19:57:45 +01:00
Alexis Svinartchouk
b298e53fc4 Merge pull request #2544 from balena-io/usbboot-limit-transfer-size
Usbboot limit transfer size
2018-11-13 15:49:42 +01:00
Alexis Svinartchouk
7fb382bee0 fix(usbboot): Limit usbboot transfers to 1MiB
Change-type: patch
2018-11-13 14:57:42 +01:00
Alexis Svinartchouk
2158772e3b lint: don't run codespell on svg files
Change-type: patch
2018-11-13 14:55:45 +01:00
Lorenzo Alberto Maria Ambrosi
333298e6c3 Merge pull request #2542 from balena-io/release-1.4.7
v1.4.7
2018-11-12 11:47:34 +01:00
Lorenzo Alberto Maria Ambrosi
6e9deeba5b v1.4.7
Change-type: major
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2018-11-11 16:23:13 +01:00
apostolism
15951509a7 Merge pull request #2535 from balena-io/fix-versionist
fix(versionist): Adapt versionist.conf.js to new guidelines
2018-11-09 18:22:02 +02:00
Lorenzo Alberto Maria Ambrosi
dd8b7e42d6 fix(versionist): Adapt versionist.conf.js to new guidelines
Change-type: patch
Changelog-entry: Modify versionist.conf.js to match new internal commit guidelines
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2018-11-08 01:40:24 +01:00
Lorenzo Alberto Maria Ambrosi
2655c86be3 Merge pull request #2534 from balena-io/add-balena-icons
Add balena iconset & osx installer background
2018-11-07 18:10:01 +01:00
Lorenzo Alberto Maria Ambrosi
c4c4d347cf Update application name & copyright
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2018-11-05 15:58:09 +01:00
Lorenzo Alberto Maria Ambrosi
a3f7239c1b Add balena iconset & osx installer background
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
2018-11-02 12:14:52 +01:00
Lorenzo Alberto Maria Ambrosi
f90c2ad74e Merge pull request #2477 from balena-io/select-image-button
refactor(GUI): Image Selector Button
2018-11-02 10:54:15 +01:00
amdomanska
2907cd173b refactor(GUI): Convert Select Image button to Rendition
Convert Select Image button to Rendition component

Change-type: minor
Signed-off-by: amdomanska <aga@resin.io>
2018-11-01 19:21:39 +01:00
Lucian Buzzo
779ee8294f Merge pull request #2494 from balena-io/docs-typo
docs: fix typo in contributing guidelines
2018-11-01 10:37:42 +00:00
Lucian Buzzo
a229c9e10e docs: Fix typo in contributing guidelines
Change-type: patch
Signed-off-by: Lucian Buzzo <lucian.buzzo@gmail.com>
2018-11-01 09:51:29 +00:00
Petros Angelatos
3f8d2e4242 Merge pull request #2525 from resin-io/release-1.4.6
v1.4.6
2018-10-29 15:29:23 -07:00
Lorenzo Alberto Maria Ambrosi
c1a8b0c303 v1.4.6
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzothunder.ambrosi@gmail.com>
2018-10-28 22:00:27 +01:00
Lorenzo Alberto Maria Ambrosi
8e92c5b844 Merge pull request #2522 from resin-io/fix-progress-button
Put flash cancel button in foreground
2018-10-28 21:53:17 +01:00
Lorenzo Alberto Maria Ambrosi
c366fbde22 Put flash cancel button in foreground
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzothunder.ambrosi@gmail.com>
2018-10-28 21:15:30 +01:00
Lorenzo Alberto Maria Ambrosi
890e866ae2 Merge pull request #2513 from resin-io/balena
Add new logos
2018-10-28 21:13:54 +01:00
Lorenzo Alberto Maria Ambrosi
8eb11a8957 Change resin.io to balena.io
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzothunder.ambrosi@gmail.com>
2018-10-25 17:32:37 +02:00
Lorenzo Alberto Maria Ambrosi
9cc65a386b Add new logos
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzothunder.ambrosi@gmail.com>
2018-10-25 15:57:44 +02:00
Lorenzo Alberto Maria Ambrosi
e4d4af1587 Merge pull request #2475 from resin-io/progressBar
refactor(GUI): convert Progress Button to Rendition
2018-10-24 03:06:25 +02:00
amdomanska
b3aab5116a refactor(GUI): Convert Progress Button to Rendition
Convert progress-button component to Rendition

Change-type: minor
Signed-off-by: amdomanska <aga@resin.io>
2018-10-24 02:07:49 +02:00
Lorenzo Alberto Maria Ambrosi
7227c76538 Merge pull request #2507 from resin-io/react-lint-rules
Enable React lint rules
2018-10-24 01:47:12 +02:00
Lorenzo Alberto Maria Ambrosi
c2c59f4a9e Enable React lint rules
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzothunder.ambrosi@gmail.com>
2018-10-23 21:56:02 +02:00
Lorenzo Alberto Maria Ambrosi
eeede318fd Merge pull request #2488 from resin-io/refactor-build-system
Use Resin CI scripts to build Etcher
2018-10-23 00:02:35 +02:00
Juan Cruz Viotti
3855bb4d56 Use Resin CI scripts to build Etcher
Change-type: patch
Signed-off-by: Juan Cruz Viotti <juan@resin.io>
2018-10-22 14:58:15 +02:00
Lorenzo Alberto Maria Ambrosi
89fa682721 Merge pull request #2510 from resin-io/fix-file-selector-constraint-path
Fix incorrect file constraint path
2018-10-17 16:42:46 +02:00
Lorenzo Alberto Maria Ambrosi
cb701a7bbc Change spectron port
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzothunder.ambrosi@gmail.com>
2018-10-17 15:50:51 +02:00
Lorenzo Alberto Maria Ambrosi
407325b8ce Fix incorrect file constraint path
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzothunder.ambrosi@gmail.com>
2018-10-17 15:20:08 +02:00
Lorenzo Alberto Maria Ambrosi
161debb35a Merge pull request #2506 from resin-io/fix-64-bit-detection
fix: Fix 64 bit detection on arm
2018-10-12 19:00:13 +02:00
Alexis Svinartchouk
fd5385b127 fix: Fix 64 bit detection on arm
Signed-off-by: Alexis Svinartchouk <alexis@resin.io>
2018-10-12 16:11:13 +02:00
Alexis Svinartchouk
e85e1410aa Merge pull request #2505 from resin-io/fix-xxhash-digest-read
fix: Provide a Buffer to xxhash.Stream
2018-10-12 16:08:06 +02:00
Alexis Svinartchouk
ac068f353a fix: Provide a Buffer to xxhash.Stream
This fixes the digest being a number instead of a buffer.

Signed-off-by: Alexis Svinartchouk <alexis@resin.io>
2018-10-12 15:24:00 +02:00
Lorenzo Alberto Maria Ambrosi
fe7c6d0d57 Merge pull request #2503 from resin-io/fix-changelog
fix: Correct 1.4.5 release date & remove checklist
2018-10-11 18:16:08 +02:00
Lorenzo Alberto Maria Ambrosi
abf1e4a8ac fix: Correct 1.4.5 release date & remove checklist
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzothunder.ambrosi@gmail.com>
2018-10-11 16:15:08 +02:00
Lorenzo Alberto Maria Ambrosi
f9dfb2d0c7 Merge pull request #2441 from resin-io/release-1.4.5
Release v1.4.5
2018-10-11 16:10:54 +02:00
Lorenzo Alberto Maria Ambrosi
da23740f17 v1.4.5
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@resin.io>
2018-10-10 21:29:34 +02:00
Lorenzo Alberto Maria Ambrosi
47f81251d7 Merge pull request #2496 from resin-io/remove-libudev-dependency
Use fork of node-usb to disable libudev
2018-10-09 11:42:17 +02:00
Lorenzo Alberto Maria Ambrosi
7e01eca7f5 Use fork of node-usb to disable libudev
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@resin.io>
2018-10-05 18:43:29 +02:00
Lorenzo Alberto Maria Ambrosi
941b5c9e45 Merge pull request #2495 from resin-io/fix-analytics-in-sdk
Add 'debug' in place of 'logException'
2018-10-04 23:21:35 +02:00
Lorenzo Alberto Maria Ambrosi
207c0d612d Add 'debug' in place of 'logException'
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@resin.io>
2018-10-04 21:20:39 +02:00
Lorenzo Alberto Maria Ambrosi
4035176d88 Merge pull request #2491 from resin-io/warn-if-cant-require-usb
fix(GUI): Warn when requiring usb fails
2018-10-02 17:23:35 +02:00
Alexis Svinartchouk
b9f9968f84 fix(GUI): Warn when requiring usb fails
Change-type: patch
Signed-off-by: Alexis Svinartchouk <alexis@resin.io>
2018-10-02 16:17:58 +02:00
Lorenzo Alberto Maria Ambrosi
7a2dac8d5b Merge pull request #2443 from resin-io/2442-update-package-repo-info
2442 update package repo info
2018-09-28 08:37:16 +02:00
Lorenzo Alberto Maria Ambrosi
2fb8ad146f Change spectron port to run tests
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@resin.io>
2018-09-27 19:21:54 +02:00
Michael Angelos Simos
2f4a7352d9 makefile: Update etcher deb/rpm publishing
Change-type: patch
Signed-off-by: Michael Angelos Simos <michalis@resin.io>
2018-09-27 16:19:25 +02:00
Michael Angelos Simos
c3ff030542 doc: Update etcher package repo installation and publishing info
Change-type: patch
Signed-off-by: Michael Angelos Simos <michalis@resin.io>
2018-09-27 16:19:25 +02:00
Lorenzo Alberto Maria Ambrosi
aa05cd1449 Merge pull request #2467 from resin-io/add-missing-store-require
fix(GUI): Add missing 'store' require
2018-09-27 13:52:51 +02:00
Alexis Svinartchouk
31cd33f86c fix(GUI): Add missing 'store' require
Change-type: patch
Signed-off-by: Alexis Svinartchouk <alexis@resin.io>
2018-09-27 12:51:32 +02:00
Lorenzo Alberto Maria Ambrosi
9abca204e3 Merge pull request #2469 from resin-io/fix-double-flash
fix(sudo-prompt): Use a fork of sudo-prompt
2018-09-27 12:49:58 +02:00
Alexis Svinartchouk
e9760c2100 update(sudo-prompt): Update sudo-prompt to 8.2.3
This is to avoid running the child-writer twice when the hostname isn't
set in /etc/hosts. See https://github.com/jorangreef/sudo-prompt/pull/76

Change-type: patch
Signed-off-by: Alexis Svinartchouk <alexis@resin.io>
2018-09-27 11:37:50 +02:00
Alexis Svinartchouk
1c5bab63a5 Merge pull request #2470 from resin-io/fix-blacklist-setting
gui: Also blacklist match against device & raw path
2018-09-26 10:41:49 +02:00
Jonas Hermsmeier
0d80957639 gui: Also blacklist match against device & raw path
This fixes device blacklist handling to also match against
`drive.device` and `drive.raw`, in order to be able to specify devices
lacking a `devicePath`.

Change-type: patch
Signed-off-by: Jonas Hermsmeier <jhermsmeier@gmail.com>
2018-09-25 23:59:55 +02:00
Lorenzo Alberto Maria Ambrosi
6c73ddcaca Merge pull request #2466 from resin-io/update-drivelist-6.4.2
chore: Update drivelist to v6.4.2
2018-09-25 19:58:53 +02:00
Lorenzo Alberto Maria Ambrosi
1bb86fe4a8 Update drivelist to v6.4.2
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@resin.io>
2018-09-25 18:47:03 +02:00
Lorenzo Alberto Maria Ambrosi
6b7be7a82d Merge pull request #2489 from resin-io/dont-use-tilde-in-rpm
Makefile: Don't use tilde in rpm versions
2018-09-25 17:27:25 +02:00
Lorenzo Alberto Maria Ambrosi
37b25d8422 Change port so not to overlap with other builds
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@resin.io>
Signed-off-by: Juan Cruz Viotti <juan@resin.io>
2018-09-25 15:22:42 +01:00
Juan Cruz Viotti
49edd1a6dc Makefile: Don't use tilde in rpm versions
The tilde is not a valid version character in RPM packages, according to
the RPM source code.

Change-type: patch
Signed-off-by: Juan Cruz Viotti <juan@resin.io>
2018-09-24 16:42:14 +01:00
Jonas Hermsmeier
a338c6e60a Merge branch 'salvozappa-fix-travis-build' 2018-09-10 16:45:53 +02:00
Salvatore Zappalà
f9805f3bc7 minifix: add "make webpack" to travis-ci build script
Currently, the Travis CI build is failing due to the fact that
the folder 'generated/etcher' is empty.

The folder is missing because the "make webpack" step is missing
from the travis CI build.

This commit amends that by adding the "make webpack" build step
after linting.

Change-type: patch
Signed-off-by: Salvatore Zappalà <salvatore@salvatorezappala.info>
2018-08-22 10:21:23 +01:00
Lorenzo Alberto Maria Ambrosi
b24c4ea030 Merge pull request #2448 from resin-io/fix-flash-cancel
fix(GUI): Remove results data from cancel event
2018-08-14 23:35:34 +02:00
Lorenzo Alberto Maria Ambrosi
0cabac1eed fix(GUI): Remove results data from cancel event
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@resin.io>
2018-08-14 21:20:00 +02:00
Lorenzo Alberto Maria Ambrosi
7c08dbfbd2 Merge pull request #2445 from resin-io/fix-webpack-electron-main
fix(webpack): Add etcher.js to webpack build
2018-08-14 20:37:35 +02:00
Lorenzo Alberto Maria Ambrosi
c0ec74bbb7 fix(webpack): Add etcher.js to webpack build
Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@resin.io>
2018-08-14 19:04:13 +02:00
Lorenzo Alberto Maria Ambrosi
ea834f6778 Merge pull request #2420 from resin-io/better-analytics
fix(GUI): Additional data on events
2018-08-07 19:40:53 +02:00
Lorenzo Alberto Maria Ambrosi
2271f32140 fix(GUI): Add data on events
Application session UUID for global app events
Flashing workflow UUID for every flashing session
Flash instance UUID for every flashing session

Change-type: patch
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzothunder.ambrosi@gmail.com>
2018-08-07 18:56:14 +02:00
Lorenzo Alberto Maria Ambrosi
93906b9b17 Merge pull request #2433 from resin-io/fix-cli-settings
fix(cli): Don't use electron to get USER_DATA_DIR in CLI
2018-08-07 18:42:04 +02:00
Jonas Hermsmeier
40d84b7a82 fix(cli): Don't use electron to get USER_DATA_DIR in CLI
A previous change erronously relied solely on `electron` to determine
the user's data directory, which of course, isn't available when
running in the CLI. So this adds a fallback to the same mechanic
for CLI should this code not be loaded in Electron.

Change-type: patch
Signed-off-by: Jonas Hermsmeier <jhermsmeier@gmail.com>
2018-08-07 17:14:53 +02:00
Alexis Svinartchouk
d0ee569989 Merge pull request #2439 from resin-io/fix-shared-tests
fix(test): Move available-drives, flash-state and selection-state tests to gui tests
2018-08-07 13:51:47 +02:00
Alexis Svinartchouk
92d969b075 fix(test): Move tests to correct scope
Move available-drives, flash-state and selection-state tests to gui
tests. These files only test gui code and make `make test-cli` fail.

Change-type: patch
Signed-off-by: Alexis Svinartchouk <alexis@resin.io>
2018-08-07 09:22:29 +02:00
Lorenzo Alberto Maria Ambrosi
49b70d0efd Merge pull request #2296 from resin-io/fix-usbboot-on-linux
fix(sdk): load usbboot adapter on start
2018-08-07 04:36:39 +02:00
Alexis Svinartchouk
26779ef1fb fix(sdk): Load usbboot adapter on start
Change-type: patch
Changelog-entry: Load usbboot adapter on start on GNU/Linux if running as root.
Signed-off-by: Alexis Svinartchouk <alexis@resin.io>
2018-08-07 04:01:13 +02:00
Lorenzo Alberto Maria Ambrosi
fd19af23a6 Merge pull request #2436 from resin-io/update-mountutils-1.3.15
upgrade(package): Bump mountutils to v1.3.15
2018-08-07 03:59:54 +02:00
Jonas Hermsmeier
f798fef212 upgrade(package): Bump mountutils to v1.3.15
Change-type: patch
Signed-off-by: Jonas Hermsmeier <jhermsmeier@gmail.com>
2018-08-07 03:11:10 +02:00
Lorenzo Alberto Maria Ambrosi
c74eab4fb5 Merge pull request #2435 from resin-io/update-drivelist-6.4.0
upgrade(package): Bump drivelist to v6.4.0
2018-08-07 01:53:29 +02:00
Lorenzo Alberto Maria Ambrosi
6a0198639f Merge branch 'master' into update-drivelist-6.4.0 2018-08-06 18:04:51 +02:00
Lorenzo Alberto Maria Ambrosi
8c870f2db8 Merge pull request #2430 from resin-io/fix-blockmap-checksum-error
fix(writer): Set EVALIDATION on blockmap checksum errors
2018-08-06 17:58:42 +02:00
Jonas Hermsmeier
73d287e7ee upgrade(package): Bump drivelist to v6.4.0
Change-type: patch
Signed-off-by: Jonas Hermsmeier <jhermsmeier@gmail.com>
2018-08-02 22:40:25 +02:00
Jonas Hermsmeier
9eb3eea3f1 fix(writer): Set EVALIDATION on blockmap checksum errors
This patches validation errors coming form the `blockmap` module to have
the `EVALIDATION` error code, in order to trigger the appropriate code
paths and analytics.

Change-type: patch
Signed-off-by: Jonas Hermsmeier <jhermsmeier@gmail.com>
2018-08-01 20:54:08 +02:00
Jonas Hermsmeier
df769396b1 Merge pull request #2422 from Jacalz/solus-instructions
doc(README): add install and uninstall instructions for Solus
2018-07-31 21:30:33 +02:00
Jacob
c2e47ca9dc doc(README): add install and uninstall instructions for Solus
This adds the required steps to installing and uninstalling Etcher on Solus Linux.

Change-Type: patch
Changelog-Entry: Add instructions for installing and uninstalling on Solus.
2018-07-21 15:30:53 +02:00
Jonas Hermsmeier
b348159e0e Merge pull request #2418 from resin-io/private-module
resinci: Set private: true in package.json to avoid running npm builds
2018-07-18 17:54:37 +02:00
John (Jack) Brown
45b62f0e77 resinci: Set private: true in package.json to avoid running npm builds
Change-type: patch
Signed-off-by: Jack Brown <jack@resin.io>
2018-07-18 07:25:33 -07:00
Jonas Hermsmeier
1fb420c2fc Merge pull request #2416 from resin-io/enable-production-react
chore(webpack): Set NODE_ENV to production for React / WebPack
2018-07-10 17:08:12 +02:00
Jonas Hermsmeier
b4f2bc1cb3 chore(webpack): Set NODE_ENV to production
This enables production builds for React

Change-Type: patch
2018-07-09 17:34:03 +02:00
Jonas Hermsmeier
d6cc182da2 Merge pull request #2412 from resin-io/update-winusb-driver
upgrade(package): Update winusb-driver-generator
2018-07-09 17:30:13 +02:00
Jonas Hermsmeier
9d7baa86aa Merge pull request #2413 from resin-io/fix-fs-promisify
fix(gui): Fix missing promisify in file picker model
2018-07-05 20:14:36 +02:00
Jonas Hermsmeier
872cd90dc6 fix(gui): Fix missing promisify in file picker model
Change-Type: patch
2018-07-05 18:52:04 +02:00
Jonas Hermsmeier
00ab816791 upgrade(package): Update winusb-driver-generator
This updates `winusb-driver-generator` to the latest version,
which supports building under VS 2015 and running under Electron 2.0+

Change-Type: patch
2018-07-04 15:12:45 +02:00
Jonas Hermsmeier
2a9e9962e8 Merge pull request #2405 from resin-io/file-selection-constraint
feat(gui): Enable device specific constraints for file selection
2018-07-03 17:08:39 +02:00
Jonas Hermsmeier
ed25dd931e feat(gui): Enable device specific constraints for file selection
This adds the ability to restrict the file selection to a given device,
only making its mountpoints accessible.

Change-Type: patch
2018-07-03 15:39:49 +02:00
Jonas Hermsmeier
66031f1bc2 Merge pull request #2402 from resin-io/fix-missing-settings
fix(app): Fix settings being unavailable when packaged
2018-06-20 20:46:30 +02:00
Jonas Hermsmeier
a902872880 fix(app): Fix settings being unavailable when packaged
This fixes an issue where the settings model would be missing
from Etcher when packaged, as it's used in two different contexts;
namely the webpack bundle and the main process.

Change-Type: patch
2018-06-20 20:05:56 +02:00
Jonas Hermsmeier
4c2d440871 Merge pull request #2401 from resin-io/file-picker-separators
refactor(gui): Add separating borders to file selector
2018-06-20 20:01:07 +02:00
Jonas Hermsmeier
0da17de422 refactor(gui): Add separating borders to file selector
This adds thin gray borders to the control surfaces in
the file selector for better visual distinction

Change-Type: patch
2018-06-20 19:03:40 +02:00
Jonas Hermsmeier
07025ae76b Merge pull request #2400 from resin-io/file-picker-path
feat(gui): Add full filename to file selector
2018-06-20 19:01:38 +02:00
Jonas Hermsmeier
d99fe944f3 feat(gui): Add full filename to file selector
This adds the display of the full filename to the file selector.

Change-Type: minor
2018-06-20 18:31:09 +02:00
Jonas Hermsmeier
408b2a473e Merge pull request #2388 from resin-io/refactor-file-picker
refactor(gui): Refactor file picker fs I/O
2018-06-12 21:15:07 +02:00
Jonas Hermsmeier
fc22e9e28a refactor(gui): Refactor file picker fs I/O
This refactors the experimental file picker to avoid fs i/o
in as many places as possible to improve performance.
Further, rendering performance is improved by avoiding unnecessary
element state changes invalidating components.
Also, recent files & favorites have been temporarily disabled
due to lack of need for Etcher Pro.

Change-Type: patch
2018-06-12 18:51:58 +02:00
Jonas Hermsmeier
d1c44ab7b1 Merge pull request #2383 from resin-io/webpack-exclude-node
fix(webpack): Exclude all node externals / node_modules
2018-06-08 17:36:29 +02:00
Jonas Hermsmeier
4ddac50d9b fix(webpack): Exclude all node externals / node_modules
This adds `webpack-node-externals` to exclude node_modules,
immensely reducing bundle size and avoiding complex exclusion rules
for the etcher-sdk

Change-Type: patch
2018-06-08 16:56:21 +02:00
Jonas Hermsmeier
7208ad67f1 Merge pull request #2376 from resin-io/fix-infinite-digest
fix(gui): Fix an inifinite digest loop trigger
2018-05-31 15:01:27 +02:00
Jonas Hermsmeier
fffdeb1320 fix(gui): Fix an inifinite digest loop trigger
This fixes a guard against infinite digest loop triggering
that was erronously dropped during a rebase.

Change-Type: patch
2018-05-30 20:34:38 +02:00
Jonas Hermsmeier
e8fa7d8812 Merge pull request #2375 from resin-io/update-lodash
upgrade(package): Update lodash to 4.17.10
2018-05-30 16:49:36 +02:00
Jonas Hermsmeier
dfdb92957e Merge pull request #2362 from resin-io/file-picker-performance
fix(GUI): file-picker performance and design improvements
2018-05-30 14:18:17 +02:00
Jonas Hermsmeier
441069f04b Merge pull request #2373 from resin-io/fix-drive-blacklist
fix(gui): Fix error with empty drive blacklist
2018-05-30 13:37:45 +02:00
Jonas Hermsmeier
201995eb90 upgrade(package): Update lodash to 4.17.10
This updates `lodash` to mitigate a prototype pollution vulnerability.
See https://nodesecurity.io/advisories/577

Change-Type: patch
2018-05-30 13:17:20 +02:00
Benedict Aas
5863319c0b fix(GUI): file-picker performance and design improvements
- Replace onClick arrow functions in all components that use them for
  efficiency reasons: 300-500% speed-up
- Sort by folders and ignore case for better UX
- Remove use of `rendition.Button` in files, leading to a 10-20%
  performance increase when browsing files
- Proper sidebar width and spacing
- Recents and favorites are now filtered by existence async for a tiny
  performance improvement
- Make Breadcrumbs and Icon pure components to stop frequent re-rendering
- Initial support for array constraints
- Use first constraint as initial path instead of homedir if a
  constraint is set
- Use correct design height on modal, `calc(100vh - 20px)`
- Reset scroll position when browsing a new folder
- Fuse Bluebird `.map()` and `.reduce()` in
  `files.getAllFilesMetadataAsync`.
- Use `localeCompare`'s own case-insensitive option instead of calling
  `.toLowerCase()` twice on `n-2` files compared.
- Use 16px font sizes in sidebar and files to match design.
- Disable `$locationProvider.html5Mode.rewriteLinks`, which seemed to
  take 50ms of the directory changing time.
- Leave file extension as-is in `files.getFileMetadataSync` and the
  async counterpart for a very minor performance improvement.

Change-Type: patch
2018-05-30 12:39:59 +02:00
Jonas Hermsmeier
2986d85b26 fix(gui): Fix error with empty drive blacklist
This fixes an error occuring if the drive blacklist
is empty, and not split correctly

Change-Type: patch
2018-05-30 12:33:12 +02:00
Jonas Hermsmeier
f312457f35 Merge pull request #2372 from resin-io/file-picker-drag-fix
fix(GUI): restrict webkit drag to header
2018-05-30 12:12:45 +02:00
Jonas Hermsmeier
de501f5ba3 Merge pull request #2369 from resin-io/feature-settings
feat: Use settings for feature control
2018-05-29 23:47:58 +02:00
Jonas Hermsmeier
c5e5141b21 refactor(local-settings): Log JSON parse errors 2018-05-29 22:06:41 +02:00
Jonas Hermsmeier
c08cf61d0c chore(app): Use settings instead of env vars
Change-Type: patch
2018-05-29 22:06:41 +02:00
Jonas Hermsmeier
6728382141 feat: Use settings for feature control
Change-Type: minor
2018-05-29 22:06:40 +02:00
Jonas Hermsmeier
7c3f104d1b Merge pull request #2368 from resin-io/refactor-settings
feat(gui): Persist local settings to config file
2018-05-29 22:06:02 +02:00
Jonas Hermsmeier
ad6be11bbc refactor(store): Return unsubscribe directly 2018-05-29 17:36:51 +02:00
Benedict Aas
f09faf6645 minifix(GUI): move success banner back down (#2367)
Change-Type: patch
2018-05-29 12:56:54 +01:00
Benedict Aas
117a7762e1 fix(GUI): restrict webkit drag to header
We ensure that the `-webkit-app-region` attribute is only set to `drag`
on the header element and we explicitly disable it on modals, as this
has unintended behaviour on a non-draggable window with touch-screens.

Change-Type: patch
2018-05-29 11:23:54 +01:00
Jonas Hermsmeier
3d47f494a8 fix(app): Fix config path on Windows, typos 2018-05-28 17:25:22 +02:00
Jonas Hermsmeier
e0ebdc9045 fix(test): Fix lint errors & tests 2018-05-25 20:35:59 +02:00
Jonas Hermsmeier
53f8e9328d feat(app): Make store change-observable
This adds true change observability to the store,
as the `.subscribe()` callback triggers with every dispatch,
even if the data didn't change.

Now `store.observe(onChange)` can be used to only be notified
once the state data actually changes

Change-Type: minor
2018-05-25 20:35:59 +02:00
Jonas Hermsmeier
687e0b563b refactor(gui): Move shared models to app/models 2018-05-25 20:35:59 +02:00
Jonas Hermsmeier
6232cc7d49 test(settings): Update test specs accordingly
Change-Type: patch
2018-05-25 20:35:59 +02:00
Jonas Hermsmeier
2a6670a404 refactor: Remove use of localStorage for local settings
Change-Type: minor
2018-05-23 21:20:51 +02:00
Jonas Hermsmeier
447efc7096 refactor: Move shared/store.js -> gui/app/models/store.js 2018-05-23 21:20:50 +02:00
Benedict Aas
c47878202d feat(GUI): center content independent to window resolution (#2299)
We pave way for different sizes of Etcher windows by dynamically
centering the content with flexbox.

Connects-To: #2263
Closes: #2241
Change-Type: patch
Changelog-Entry: Center content independent to window resolution.
2018-05-23 20:10:02 +01:00
Jonas Hermsmeier
349076bf34 Merge pull request #2353 from resin-io/webber-packer
chore(package): Add npm run script for webpack
2018-05-23 19:43:22 +02:00
Jonas Hermsmeier
1748bf2e2a chore(package): Add npm run script for webpack
Make life simpler

Change-Type: patch
2018-05-22 18:44:59 +02:00
Jonas Hermsmeier
d9a7730511 test(eslint): Fix JSX not being linted (#2358)
Change-Type: patch
2018-05-21 11:28:22 +01:00
Jonas Hermsmeier
4a239cc217 upgrade(package): Update React to v16 (#2355)
Change-Type: patch
2018-05-21 11:23:42 +01:00
Benedict Aas
ce2534c5b7 minifix(GUI): resolve react missing key field warning (#2354)
We attach key fields where necessary to make the warnings go away.

Change-Type: patch
2018-05-21 11:23:20 +01:00
Jonas Hermsmeier
3083f5fd55 Merge pull request #2351 from resin-io/fix-username-spaces-diskpart
fix(diskpart): Fix diskpart argv when tmpdir contains spaces
2018-05-18 17:46:42 +02:00
Jonas Hermsmeier
2045066b16 fix(diskpart): Fix diskpart argv when tmpdir contains spaces
This escapes the diskpart script filename when shelling out,
to avoid failure when the username and thus the `os.tmpdir()` path
contains spaces.

Change-Type: patch
2018-05-17 18:03:41 +02:00
Jonas Hermsmeier
995177498f Merge pull request #2349 from resin-io/add-files-module
fix: add missing files module
2018-05-17 18:02:55 +02:00
Benedict Aas
c00b7b62d6 fix: add missing files module
We add a convenience module for file and path operations.
Tests included.

Change-Type: patch
2018-05-17 15:34:34 +01:00
Benedict Aas
93b772f197 fix: ensure file-picker is slicing arrays (#2350)
We ensure the file-picker is slicing arrays when the localStorage values
aren't available.

Change-Type: patch
2018-05-17 10:40:19 +01:00
Benedict Aas
7782f94daa feat(GUI): add electron-native file-picker component (#2333)
We add a file-picker written with Rendition/React. It is activated with
the `ETCHER_EXPERIMENTAL_FILE_PICKER` environment variable. Further
customisation can be done with the `ETCHER_FILE_BROWSER_CONSTRAIN_FOLDER`
variable that takes a path and allows one to constrain the file-picker to
a folder.

Related: https://github.com/resin-io/etcher/issues/2238
Related: https://github.com/resin-io/etcher/issues/2285
Change-Type: patch
Changelog-Entry: Add electron-native file-picker component.
2018-05-16 20:34:04 +01:00
Jonas Hermsmeier
7c97dc8004 Merge pull request #2346 from CherryDT/master
Fix devtools key binding for Windows in SUPPORT.md
2018-05-16 21:10:25 +02:00
Benedict Aas
34ce00e2d5 feat(GUI): hide unsafe mode option with env var (#2347)
We hide the unsafe mode option toggle with an env var
`ETCHER_HIDE_UNSAFE_MODE` that also enables unsafe mode.

Closes: https://github.com/resin-io/etcher/issues/2243
Change-Type: patch
Changelog-Entry: Hide unsafe mode option toggle with an env var.
2018-05-16 19:52:55 +01:00
CherryDT
702658cca5 Fix devtools key binding for Windows in SUPPORT.md 2018-05-16 16:39:33 +02:00
Benedict Aas
e472fe0276 feat: blacklist devices by device path (#2345)
We use `devicePath` instead of `device` to blacklist drives using the
`ETCHER_BLACKLISTED_DRIVES` environment variable.

Closes: https://github.com/resin-io/etcher/issues/2264
Change-Type: patch
2018-05-16 15:28:10 +01:00
Jonas Hermsmeier
fb1c381ab7 Merge pull request #2343 from resin-io/disable-notifications
feat(gui): Add desktop notification setting
Close #2254
2018-05-16 00:51:49 +02:00
Jonas Hermsmeier
03c7998c11 feat(gui): Add desktop notification setting
This adds a setting to disable desktop notifications, to be controlled
via configuration file

Change-Type: feat
2018-05-15 18:58:10 +02:00
Benedict Aas
35729fc36b feat(GUI): use design background and drive size ordering (#2341)
We use the new design background color, and order the drive step size in
accordance with the new design as well.

Related: https://github.com/resin-io/etcher/issues/2310
Change-Type: patch
Changelog-Entry: Use new design background color and drive step size
ordering.
2018-05-15 14:23:33 +01:00
Benedict Aas
f6ce603e45 feat(GUI): add convenience localstorage class (#2276)
* feat(GUI): add convenience localstorage class

We add a class `Storage` and accompanying helper methods that makes
localStorage usage easier.

Change-Type: patch
Changelog-Entry: Add a convenience Storage class on top of localStorage.
2018-05-15 11:59:36 +01:00
Benedict Aas
81a75ca955 feat(GUI): use new design blue and spacing (#2327)
We use the new design blue, spacing, and order of step buttons.

Closes: https://github.com/resin-io/etcher/issues/2310
Change-Type: patch
2018-05-14 15:58:45 +01:00
Jonas Hermsmeier
b57c9a51f8 Merge pull request #2331 from resin-io/env-analytics
feat(gui): Add ability to set analytics tokens via env
Close #2329
2018-05-11 20:04:21 +02:00
Jonas Hermsmeier
df396966b0 Merge pull request #2332 from resin-io/disable-update-notify
minifix(gui): Don't check for updates when in resin
2018-05-11 20:03:45 +02:00
Jonas Hermsmeier
b8897e0193 minifix(gui): Don't check for updates when in resin
This disabled Etcher checking for updates & showing update notifications
if running under resinOS with update locks enabled

Change-Type: patch
2018-05-11 16:36:14 +02:00
Jonas Hermsmeier
150e8112ea feat(gui): Add ability to set analytics tokens via env
This adds the ability to set the Sentry & Mixpanel API tokens
via environment variables.

Change-Type: patch
2018-05-11 16:25:11 +02:00
Jonas Hermsmeier
196f16b941 Merge pull request #2326 from resin-io/resin-update-lock
feat(gui): Add resin update lock based on inactivity
2018-05-10 21:07:01 +02:00
Benedict Aas
21cb7a4847 feat(GUI): env var toggle autoselecting all valid drives (#2306)
We introduce an environment variable
`ETCHER_DISABLE_EXPLICIT_DRIVE_SELECTION` that both enables
autoselection of drives and disables explicit drive selection by hiding
the buttons allowing this. All valid drives are autoselected, i.e. any
drive-image pair that does not result in an error, however warnings are
accepted.

Closes: https://github.com/resin-io/etcher/issues/2262
Change-Type: patch
Changelog-Entry: Introduce env var to toggle autoselection of all
drives.
2018-05-10 18:53:53 +01:00
Jonas Hermsmeier
bb2dac7504 feat(gui): Add resin update lock based on inactivity
This adds functionality to acquire & release the update lock
when running under resinOS, re-using the `ELECTRON_RESIN_UPDATE_LOCK`
environment variable from `resin-electronjs`.

Further this adds the `ETCHER_INTERACTION_TIMEOUT_MS` env var, to
facilitate adjusting the inactivity period required to release the lock.

Change-Type: minor
2018-05-10 19:15:31 +02:00
Jonas Hermsmeier
f5fd2f2be3 Merge pull request #2325 from resin-io/update-drivelist
upgrade(package): Bump drivelist 6.1.7 -> 6.2.2
Close #2235
2018-05-10 14:20:38 +02:00
Jonas Hermsmeier
e6ea3879c3 upgrade(package): Bump drivelist 6.1.7 -> 6.2.2
This will enable use of unique device paths on Linux

Change-Type: patch
2018-05-10 13:33:50 +02:00
Jonas Hermsmeier
c07895d418 Merge pull request #2319 from resin-io/update-keyserver
doc(README): Use ubuntu keyserver for apt-key
2018-05-09 21:04:49 +02:00
Jonas Hermsmeier
58fb1cf4c3 Merge pull request #2318 from resin-io/kiosk
minifix(gui): Only enable Kiosk Mode when FULLSCREEN is set
2018-05-09 20:09:29 +02:00
Jonas Hermsmeier
52cc8cb8fc doc(README): Use ubuntu keyserver for apt-key
As pgp.mit.edu has become extremely unreliable, this switches to
keyserver.ubuntu.com for retrieval of package keys

Change-Type: patch
2018-05-09 17:30:40 +02:00
Benedict Aas
1b30dab8eb fix(webpack): don't rewrite import paths inside node_modules (#2195)
We ensure that paths inside node_modules files are kept untouched, as
currently the RegExp can match 'shared' folders inside those and rewrite
paths, breaking them.

Change-Type: patch
2018-05-09 16:09:17 +01:00
Jonas Hermsmeier
40df4a94a7 minifix(gui): Only enable Kiosk Mode when FULLSCREEN is set
This fixes the `kiosk` setting always being true, and causing
the operating system's desktop to disappear.

Change-Type: patch
2018-05-09 17:04:38 +02:00
Jonas Hermsmeier
262d06f035 Merge pull request #2311 from resin-io/config-file
feat(gui): Add ability to read settings from a config file
Close #1356
2018-05-09 17:00:36 +02:00
Jonas Hermsmeier
408ab99774 Merge pull request #1921 from resin-io/link-to-windows-usbboot-drivers
feat(GUI): link to drivers when clicking a driverless usbboot device
2018-05-09 16:48:00 +02:00
Jonas Hermsmeier
28cb21db13 Merge pull request #2292 from resin-io/bench-verify
feat(writer): Use xxHash instead of SHA512 for verification
2018-05-09 16:46:02 +02:00
Benedict Aas
7f37f4ca41 feat(GUI): add font-awesome (#2177)
We add font-awesome icons as this is more in-line with the designs.

Change-Type: patch
Changelog-Entry: Add font-awesome.
2018-05-09 15:44:03 +01:00
Jonas Hermsmeier
5f85258e84 feat(gui): Add ability to read settings from a config file
This adds the capability to configure settings via a `.etcher.json` file,
either in the user's home directory, or the current working directory.
In the case of the home directory, the config file is `$HOME/.config/etcher/config.json`,
while on Windows `$HOME/.etcher.json` is used.
The defined settings are merged with localStorage settings, and preceding
configuration files.
If both are present, the current working directory takes precedence.

Change-Type: minor
Changelog-Entry: Add support for configuration files
2018-05-09 16:22:07 +02:00
Benedict Aas
cde1776a2d feat(GUI): use gtk3 dark theme mode (#2314)
We enable the `darkTheme` mode for GTK-3 applications (mainly Linux)
that suits Etcher's dark theme better, making the window title bar dark.

Change-Type: patch
Changelog-Entry: Use GTK-3 darkTheme mode.
2018-05-09 11:13:14 +01:00
Benedict Aas
7f6303391a feat(GUI): add env var to toggle fullscreen (#2313)
We add an environment variable to toggle Etcher in fullscreen.

Closes: https://github.com/resin-io/etcher/issues/2307
Change-Type: patch
Changelog-Entry: Add environment variable to toggle fullscreen.
2018-05-09 11:08:15 +01:00
Benedict Aas
66c7806cfa feat(GUI): blacklist drives with an env var (#2315)
We add an environment variable `ETCHER_BLACKLISTED_DRIVES` that allows
us to filter certain drives from ever showing up in Etcher with comma
separated device paths, e.g. `/dev/sda,/dev/sdb,/dev/mmcblk0`.

Closes: https://github.com/resin-io/etcher/issues/2264
Change-Type: patch
Changelog-Entry: Allow blacklisting of drives through and environment
variable ETCHER_BLACKLISTED_DRIVES.
2018-05-09 11:06:18 +01:00
Benedict Aas
2cdb6945ba feat(GUI): show selected drives below drive step (#2309)
We add a list of selected drives below the drive selection step, able to
accommodate four lines of drives before scrolling occurs.

Closes: https://github.com/resin-io/etcher/issues/2263
Change-Type: patch
Changelog-Entry: Show selected drives below drive selection step.
2018-05-08 17:45:27 +01:00
Benedict Aas
ca45855ed7 feat(GUI): add drive quantity to flash analytics (#2298)
We add a field `driveCount` to the flash analytics events in the image
writer.

Change-Type: patch
2018-05-08 10:56:15 +01:00
Benedict Aas
07ed90ed11 minifix: add jsx files to gitattributes and attribute jviotti (#2302)
Change-Type: patch
2018-05-04 14:46:27 +01:00
Benedict Aas
c1b97b1b44 minifix(GUI): negate predicate to show help icon (#2300)
Change-Type: patch
2018-05-03 11:00:37 +01:00
Benedict Aas
674019ea75 feat(GUI): add button to cancel flash process (#2301)
We add a cancel button next to the flash progress bar that gracefully
aborts the flash process.

Closes: https://github.com/resin-io/etcher/issues/1791
Closes: https://github.com/resin-io/etcher/issues/2234
Closes: https://github.com/resin-io/etcher/issues/2245
Change-Type: patch
Changelog-Entry: Add a button to cancel the flash process.
2018-05-03 10:58:15 +01:00
Jonas Hermsmeier
8f762484f2 feat(gui): Add CTA in drivelist, update drive download modal 2018-05-02 23:37:15 +02:00
Jonas Hermsmeier
4174991345 feat(gui): Add simple confirmation modal 2018-05-02 23:21:02 +02:00
Benedict Aas
71064cc760 fix(GUI): fix multi-writes analytics (#2295)
We make the analytics block into a function `handleErrorLogging` and
use it in the fail event that happens during multi-writes. Previously
error events would be handled when single drives were flashed on Promise
rejection, instead we now only handle the Promise rejection when all
devices fail as a special event.

Change-Type: patch
Changelog-Entry: Fix multi-writes analytics by reusing existing logic in
multi-write events.
2018-05-02 22:02:31 +01:00
Juan Cruz Viotti
4c40c8ff30 feat(GUI): link to drivers when clicking a driverless usbboot device
Step 2 until we support installing the drivers from within Etcher. This
also introduces an "Open drive link" Mixpanel event.

See: https://www.raspberrypi.org/documentation/hardware/computemodule/cm-emmc-flashing.md
See: https://github.com/resin-io/etcher/pull/1892
Change-Type: patch
Changelog-Entry: Download usbboot drivers installer when clicking a driverless usbboot device on Windows.
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
2018-05-02 22:10:49 +02:00
Benedict Aas
d7211b130b feat(GUI): allow disabling links and hiding help link (#2290)
We allow users to pass an env var `ETCHER_DISABLE_EXTERNAL_LINKS` to
disable external links and hide links rendered useless by the change
such as the help icon.

Closes: https://github.com/resin-io/etcher/issues/2246
Closes: https://github.com/resin-io/etcher/issues/2247
Change-Type: patch
Changelog-Entry: Allow disabling links and hiding help link with an env var.
2018-05-02 17:29:08 +01:00
Jonas Hermsmeier
e40d5a0a5d Merge pull request #2291 from resin-io/publish-symantec
doc: Update MAINTAINERS.md with Symantec Whitelisting
2018-04-28 00:27:34 +02:00
Jonas Hermsmeier
553fbf1a77 minifix(writer): Increase HWM for verification readstream
Change-Type: patch
2018-04-27 22:29:03 +02:00
Jonas Hermsmeier
d3a4753b79 feat(writer): Use xxHash instead of SHA512 for verification
This switches from SHA512 to xxHash for verification hashing,
as xxHash provides more throughput.

Change-Type: patch
2018-04-27 21:51:05 +02:00
Jonas Hermsmeier
12cc0de571 doc: Update MAINTAINERS.md with Symantec Whitelisting
This adds instructions for submitting Etcher for false positive detection
to Symantec Endpoint Protection.

Change-Type: patch
2018-04-27 21:09:28 +02:00
Jonas Hermsmeier
cbd531e161 Merge pull request #2269 from resin-io/release-1.4.4
Release v1.4.4
2018-04-26 19:06:43 +02:00
Jonas Hermsmeier
a8bbe02e21 v1.4.4 2018-04-25 20:58:17 +02:00
Jonas Hermsmeier
6605d5ee63 Merge pull request #2275 from resin-io/revert-image-data
fix(tests): Revert unintended change to raspberrypi-raw.dmg
2018-04-25 17:36:36 +02:00
Jonas Hermsmeier
df8bacd82e fix(tests): Revert unintended change to raspberrypi-raw.dmg
This file was accidentally changed due to a globally executed search & replace

Change-Type: patch
2018-04-25 16:34:12 +02:00
Benedict Aas
ee831da52d minifix: replace succeeded with successful in messages (#2273)
Change-Type: patch
2018-04-25 15:08:46 +01:00
Jonas Hermsmeier
8f969374c7 Merge pull request #2272 from resin-io/fix-store-warning-deselect
fix(store): keep single warning-drives selected
2018-04-25 14:39:58 +02:00
Benedict Aas
5a788b04b5 fix(store): keep single warning-drives selected
We ensure that drive-image pairs with warnings don't get deselected when
there is only one drive available. This happenened because there was no
check for any previous selected devices. Comes with a test case.

Fixes: https://github.com/resin-io/etcher/issues/2267
Change-Type: patch
Changelog-Entry: Keep single warning-drive-image pairs selected.
2018-04-25 00:49:42 +01:00
Benedict Aas
b88a45aa79 refactor(GUI): make the finish notification message concise (#2268)
We make the finish notification message print the device name as usual
when there's one target, and instead list quantity of successful and
failed devices when there are multiple. Previously it would list all
device names, and wouldn't specify how many were successful or failures.

Change-Type: patch
2018-04-24 22:04:36 +01:00
Jonas Hermsmeier
3c20a056e6 Merge pull request #2228 from resin-io/change-succeeded-successful
refactor: use word successful instead of succeeded
2018-04-24 18:24:05 +02:00
Benedict Aas
82a57d34b8 fix(GUI): remove success screen dots with a quantity of zero (#2227)
We remove success screen dots that are zero, which mainly means that the
error dot disappears as it shouldn't currently be possible to end up
with zero successful devices on that screen.

Change-Type: patch
2018-04-23 18:33:31 +01:00
Benedict Aas
c4d7076fe8 refactor: use word successful instead of succeeded
We replace 'succeeded' with 'successful' throughout the codebase.

Change-Type: patch
2018-04-23 18:31:44 +01:00
Jonas Hermsmeier
00b11157b2 Merge pull request #2217 from resin-io/release-1.4.3
Release v1.4.3
2018-04-20 21:22:11 +02:00
Jonas Hermsmeier
b63bb1ac0c v1.4.3 2018-04-20 15:46:38 +02:00
Jonas Hermsmeier
882d0ecba8 Merge pull request #2219 from resin-io/fix-zero-zero
fix(gui): Fix zero-zero devices when verify is disabled
2018-04-20 15:45:47 +02:00
Jonas Hermsmeier
963f1a11eb fix(gui): Fix zero-zero devices when verify is disabled
This fixes a state where the success screen would display
zero succeeded and zero failed devices if verification was
turned off. This could occur due to the "done" event being
emitted before the next progress event could set the relevant data.

Change-Type: patch
2018-04-20 01:04:30 +02:00
Jonas Hermsmeier
ba8acb40ec Merge pull request #2218 from resin-io/fix-flash-result-errors
fix(gui): De-serialize errors from flashResults
2018-04-19 22:56:34 +02:00
Jonas Hermsmeier
1d4ea2164f fix(gui): De-serialize errors from flashResults
Change-Type: patch
2018-04-19 21:46:03 +02:00
Jonas Hermsmeier
0199243ce9 Merge pull request #2216 from resin-io/fix-usbboot-blobs
fix(usbboot): Move blob handling to SDK
2018-04-19 17:46:35 +02:00
Jonas Hermsmeier
4c8b97afb3 fix(usbboot): Move blob handling to SDK
This moves the usbboot blob handling into the SDK to avoid
root dirname conflicts through shimmed __dirname in bundled UI
and different contexts of execution.

Change-Type: patch
2018-04-19 16:54:23 +02:00
Jonas Hermsmeier
3bac0225e5 refactor(usbboot): Move lib/blobs/usbboot/ -> lib/sdk/adapters/usbboot/blobs 2018-04-19 15:48:59 +02:00
344 changed files with 24004 additions and 22861 deletions

View File

@@ -14,3 +14,6 @@ trim_trailing_whitespace = false
[Makefile]
indent_style = tab
[*.ts]
indent_style = tab

View File

@@ -8,9 +8,12 @@ plugins:
- lodash
- jsdoc
- node
- react
extends: 'standard'
parserOptions:
sourceType: 'script'
ecmaFeatures:
jsx: true
settings:
jsdoc:
additionalTagNames:
@@ -286,7 +289,7 @@ rules:
- error
- anonymous: always
named: always
asyncArrow: never
asyncArrow: always
template-tag-spacing:
- error
- always
@@ -295,9 +298,6 @@ rules:
# ECMAScript 6
arrow-body-style:
- error
- always
arrow-parens:
- error
- always
@@ -318,8 +318,6 @@ rules:
- always
prefer-const:
- error
prefer-reflect:
- error
prefer-spread:
- error
prefer-numeric-literals:
@@ -444,3 +442,13 @@ rules:
node/no-extraneous-import:
- error
# React
react/jsx-uses-vars:
- error
overrides:
files: ['*.jsx']
rules:
require-jsdoc:
- off

12
.gitattributes vendored
View File

@@ -1,5 +1,7 @@
# Javascript files must retain LF line-endings (to keep eslint happy)
*.ts text eol=lf
*.js text eol=lf
*.jsx text eol=lf
# CSS and SCSS files must retain LF line-endings (to keep ensure-staged-sass.sh happy)
*.css text eol=lf
*.scss text eol=lf
@@ -11,7 +13,7 @@ Dockerfile* text
etcher text
.git* text
*.html text
*.json text
*.json text eol=lf
*.cpp text
*.h text
*.gyp text
@@ -24,6 +26,7 @@ Makefile text
*.yml text
*.patch text
*.txt text
CODEOWNERS text
# Binary files (no line-ending conversions)
*.bz2 binary diff=hex
@@ -44,5 +47,12 @@ Makefile text
*.bin binary diff=hex
*.dmg binary diff=hex
*.rpi-sdcard binary diff=hex
*.wic binary diff=hex
*.foo binary diff=hex
*.eot binary diff=hex
*.otf binary diff=hex
*.woff binary diff=hex
*.woff2 binary diff=hex
*.ttf binary diff=hex
xz-without-extension binary diff=hex
wmic-output.txt binary diff=hex

4
.gitignore vendored
View File

@@ -43,3 +43,7 @@ node_modules
*.cer
*.crt
*.pem
# OSX files
.DS_Store

4
.gitmodules vendored Normal file
View File

@@ -0,0 +1,4 @@
[submodule "scripts/resin"]
path = scripts/resin
url = https://github.com/balena-io/scripts.git
branch = master

View File

@@ -1,31 +1,82 @@
{
"node-cli": {
"node": "6.1.0",
"main": "lib/cli/etcher.js",
"dependencies": {
"linux": [
"libudev-dev",
"libusb-1.0-0-dev"
]
}
},
"electron": {
"npm_version": "6.7.0",
"dependencies": {
"linux": [
"libudev-dev",
"libusb-1.0-0-dev",
"libyaml-dev"
"libyaml-dev",
"libgtk-3-0",
"libatk-bridge2.0-0",
"libdbus-1-3",
"libc6"
]
},
"builder": {
"appId": "io.resin.etcher",
"copyright": "Copyright 2016-2018 Resinio Ltd",
"productName": "Etcher",
"appId": "io.balena.etcher",
"copyright": "Copyright 2016-2019 Balena Ltd",
"productName": "balenaEtcher",
"nodeGypRebuild": true,
"files": [
"!node_modules/**/*.js.map",
"!node_modules/**/*.h",
"!node_modules/**/*.hpp",
"!node_modules/**/*.cpp",
"!node_modules/**/*.md",
"!node_modules/**/*.ts",
"!node_modules/**/*.coffee",
"!node_modules/**/*.scss",
"!node_modules/**/*.less",
"!node_modules/**/*.hbs",
"!node_modules/**/*.mkd",
"!node_modules/**/LICENSE",
"!node_modules/**/LICENCE",
"!node_modules/**/license",
"!node_modules/**/License",
"!node_modules/**/LICENSE.txt",
"!node_modules/**/Makefile",
"!node_modules/**/.editorconfig",
"!node_modules/**/.babelrc",
"!node_modules/**/.prettierrc",
"!node_modules/**/.prettierrc-*",
"!node_modules/**/.eslintrc.yml",
"!node_modules/**/.eslintignore",
"!node_modules/**/.publishrc",
"!lib/gui/app",
"lib/gui/app/index.html",
"generated"
"generated",
"!node_modules/chart.js/dist/docs",
"!node_modules/ext2fs/config",
"!node_modules/ext2fs/deps",
"!node_modules/ext2fs/LICENSE",
"!node_modules/ext2fs/src",
"!node_modules/winusb-driver-generator/src",
"!node_modules/winusb-driver-generator/deps",
"!node_modules/winusb-driver-generator/ci",
"!node_modules/rendition/__screenshots__",
"!node_modules/polished/docs",
"!node_modules/mermaid/src",
"!node_modules/mermaid/dist",
"node_modules/mermaid/dist/mermaid.core.js",
"!node_modules/raven-js/src",
"!node_modules/raven-js/dist",
"node_modules/raven-js/dist/raven.js",
"!node_modules/raven-js/plugins",
"!node_modules/react-jsonschema-form/dist",
"!node_modules/xxhash/deps",
"!node_modules/xxhash/src",
"!node_modules/unzip-stream/testData*",
"!node_modules/usb",
"node_modules/usb/usb.js",
"node_modules/usb/package.json",
"node_modules/usb/build",
"node_modules/usb/src/binding",
"!node_modules/roboto-fontface/fonts",
"node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.woff",
"node_modules/roboto-fontface/fonts/roboto/Roboto-Light.woff",
"node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.woff",
"node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.woff",
"node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.woff"
],
"mac": {
"category": "public.app-category.developer-tools"
@@ -35,24 +86,24 @@
"contents": [
{
"x": 140,
"y": 225
"y": 245
},
{
"x": 415,
"y": 225,
"y": 245,
"type": "link",
"path": "/Applications"
}
],
"window": {
"width": 540,
"height": 405
"width": 544,
"height": 407
}
},
"linux": {
"category": "Utility",
"packageCategory": "utils",
"synopsis": "Etcher is a powerful OS image flasher built with web technologies to ensure flashing an SDCard or USB drive is a pleasant and safe experience. It protects you from accidentally writing to your hard-drives, ensures every byte of data was written correctly and much more."
"synopsis": "balenaEtcher is a powerful OS image flasher built with web technologies to ensure flashing an SDCard or USB drive is a pleasant and safe experience. It protects you from accidentally writing to your hard-drives, ensures every byte of data was written correctly and much more."
},
"deb": {
"priority": "optional",

View File

@@ -1,69 +0,0 @@
language: node_js
sudo: false
node_js:
- "6.10.3"
# Remove wine from cache
before_cache:
- rm -rf $HOME/.cache/electron-builder/wine
cache:
ccache: true
directories:
- $HOME/.cache/electron
- $HOME/.cache/electron-builder
- $HOME/.npm/_prebuilds
- $HOME/Library/Caches/electron
- $HOME/Library/Caches/electron-builder
- $HOME/.pkg-cache
- node_modules
services:
- docker
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- libstdc++-6-dev
env:
global:
- CCACHE_TEMPDIR=/tmp/.ccache-temp
- CCACHE_COMPRESS=1
- CC="clang"
- CXX="clang++"
- HOMEBREW_NO_AUTO_UPDATE=1
matrix:
- TARGET_ARCH=x64
- TARGET_ARCH=x86
matrix:
fast_finish: true
exclude:
- os: osx
env: TARGET_ARCH=x86
os:
- linux
before_install:
- export HOST_OS="$TRAVIS_OS_NAME";
install:
- ./scripts/ci/install.sh -o $HOST_OS -r $TARGET_ARCH
script:
- ./scripts/ci/test.sh -o $HOST_OS -r $TARGET_ARCH
- ./scripts/ci/build-installers.sh -o $HOST_OS -r $TARGET_ARCH
deploy:
provider: script
skip_cleanup: true
script: scripts/ci/deploy.sh -o $HOST_OS -r $TARGET_ARCH
on:
branch: master
notifications:
email: false

View File

@@ -3,6 +3,411 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
# v1.5.51
## (2019-06-28)
* Update sudo-prompt to ^9.0.0 [Alexis Svinartchouk]
# v1.5.50
## (2019-06-13)
* Option for trimming ext partitions on raw images [Alexis Svinartchouk]
# v1.5.49
## (2019-06-13)
* Make window size configurable [Alexis Svinartchouk]
# v1.5.48
## (2019-06-13)
* Don't use sudo-prompt when already elevated [Alexis Svinartchouk]
# v1.5.47
## (2019-06-10)
* Rework drive-selector with react + rendition [Lorenzo Alberto Maria Ambrosi]
* Use rendition theme property for step buttons [Lorenzo Alberto Maria Ambrosi]
* Upgrade styled-system to v4.1.0 [Lorenzo Alberto Maria Ambrosi]
* Upgrade rendition to v8.7.2 [Lorenzo Alberto Maria Ambrosi]
# v1.5.46
## (2019-06-09)
* Update ext2fs to 1.0.29 [Alexis Svinartchouk]
# v1.5.45
## (2019-06-04)
* Empty commit to trigger build [Alexis Svinartchouk]
# v1.5.44
## (2019-06-03)
* Fix elevation on windows when the path contains "&" or "'" [Alexis Svinartchouk]
# v1.5.43
## (2019-05-28)
* Revert "Include sass in webpack configs" [Lorenzo Alberto Maria Ambrosi]
# v1.5.42
## (2019-05-28)
* Include sass in webpack configs [Lorenzo Alberto Maria Ambrosi]
# v1.5.41
## (2019-05-27)
* waffle.io removal and adding a link to the license [Mateusz Hajder]
# v1.5.40
## (2019-05-24)
* windows installer and portable version support both ia32 and x64 [Alexis Svinartchouk]
# v1.5.39
## (2019-05-14)
* Add clean-shrinkwrap script to postshrinkwrap step [Lorenzo Alberto Maria Ambrosi]
# v1.5.38
## (2019-05-13)
* Add mention to usbboot compatibility [Carlo Maria Curinga]
# v1.5.37
## (2019-05-13)
* Bump react dependency to v16.8.5 [Lorenzo Alberto Maria Ambrosi]
# v1.5.36
## (2019-05-13)
* Update etcher-sdk to ^2.0.9 [Alexis Svinartchouk]
# v1.5.35
## (2019-05-10)
* Downgrade electron 4.1.5 -> 3.1.9 [Alexis Svinartchouk]
# v1.5.34
## (2019-05-09)
* Use https url for fetching config, avoid redirection [Alexis Svinartchouk]
* win32: fix running diskpart when the tmp file path contains spaces [Alexis Svinartchouk]
# v1.5.33
## (2019-04-30)
* Fix gzipped files verification percentage and dmg verification. [Alexis Svinartchouk]
# v1.5.32
## (2019-04-30)
* Export NPM_VERSION variable in Makefile [Lorenzo Alberto Maria Ambrosi]
# v1.5.31
## (2019-04-29)
* Update etcher-sdk to ^2.0.3 [Alexis Svinartchouk]
* Update electron to 4.1.5 [Alexis Svinartchouk]
# v1.5.30
## (2019-04-24)
* Don't show a dialog when the write fails. [Alexis Svinartchouk]
# v1.5.29
## (2019-04-19)
* Add support for auto-updating feature [Giovanni Garufi]
# v1.5.28
## (2019-04-18)
* Update electron-builder to ^20.40.2 [Alexis Svinartchouk]
* Update etcher-sdk to ^2.0.1 [Alexis Svinartchouk]
# v1.5.27
## (2019-04-16)
* (Windows): Fix reading images from network drives when the tmp dir has spaces [Alexis Svinartchouk]
# v1.5.26
## (2019-04-12)
* (Windows): Fix reading images from network drives containing non ascii characters [Alexis Svinartchouk]
# v1.5.25
## (2019-04-09)
* New parameter in webview for opt-out analytics [Lorenzo Alberto Maria Ambrosi]
# v1.5.24
## (2019-04-05)
* Update resin-corvus to ^2.0.3 [Alexis Svinartchouk]
# v1.5.23
## (2019-04-03)
* Configure versionbot to publish repo metadata to github pages [Giovanni Garufi]
# v1.5.22
## (2019-04-02)
* (Windows): Use full path to wmic as some systems don't have it in their PATH [Alexis Svinartchouk]
# v1.5.21
## (2019-04-02)
* Fix error when config.analytics was undefined [Alexis Svinartchouk]
# v1.5.20
## (2019-04-01)
* Don't try to flash when no device is selected [Alexis Svinartchouk]
* Reformat changelog [Giovanni Garufi]
* Avoid "Error: There is already a flash in progress" errors [Alexis Svinartchouk]
# v1.5.19
## (2019-03-28)
* Update resin-corvus to ^2.0.2 [Alexis Svinartchouk]
* Better reporting of unhandled rejections to sentry [Alexis Svinartchouk]
# v1.5.18
## (2019-03-26)
* Update build scripts [Giovanni Garufi]
## v1.5.17 - 2019-03-25
### Misc
- Automatically publish github release from CI
## v1.5.16 - 2019-03-25
### Misc
- Add repo.yml
## v1.5.15 - 2019-03-20
### Misc
- Show the correct logo on usbboot devices on Ubuntu
## v1.5.14 - 2019-03-20
### Misc
- Update etcher-sdk to ^1.3.10
## v1.5.13 - 2019-03-18
### Misc
- Update build scripts
## v1.5.12 - 2019-03-15
### Misc
- Update build scripts
## v1.5.11 - 2019-03-12
### Misc
- Fixed broken Hombrew cask link for etcher
- Remove no longer used travis and appveyor configs
## v1.5.10 - 2019-03-12
### Misc
- Update resin-scripts
## v1.5.9 - 2019-03-05
### Misc
- Update etcher-sdk to 1.3.0
## v1.5.8 - 2019-03-01
### Misc
- Update ext2fs to 1.0.27
## v1.5.7 - 2019-03-01
### Fixes
- Update docs
- Fix disappearing modal window
### Misc
- Fix blurred background image
## v1.5.6 - 2019-02-28
### Misc
- Target electron 3 runtime in babel options
## v1.5.5 - 2019-02-28
### Misc
- Don't pass undefined sockets to ipc.server.emit()
- Fix error when event.dataTransfer.files is empty
- Fix error message not showing when an unsupported image is selected
- Avoid `Invalid percentage` exceptions
- Update etcher-sdk to 1.1.0
## v1.5.4 - 2019-02-27
### Misc
- Add missing step for submodule cloning in README
## v1.5.3 - 2019-02-27
### Misc
- Throw error if no commit is annotated with a changelog entry
## v1.5.2 - 2019-02-26
- Enable versionist editVersion
## v1.5.1 - 2019-02-22
### Misc
- Removed lodash dependency in versionist.conf.js
## v1.5.0 - 2019-02-16
### Misc
- Reworked flashing logic with etcher-sdk
- Add support for flashing Raspberry Pi CM3+
- Upgrade to Electron v3.
- Upgrade to NPM 6.7.0
- Fix incorrect drives list on Linux
- Changed “Drive Contains Image” to “Drive Mountpoint Contains Image”
- Removed etcher-cli
## v1.4.9 - 2018-12-19
### Fixes
- Fix update notifier error popping up on v1.4.1->1.4.8
### Misc
- Added React component for the Flash Results button
- Added React component for the Flash Another button
- Restyle success screen and enlarge UI elements
- Use https for fetching sub modules
- Add `.wic` image extension as supported format
## v1.4.8 - 2018-11-23
### Features
- Added featured-project while flashing
### Fixes
- Moved back the write cancel button
- Reject drives with null size (fixes pretty-bytes error)
## v1.4.7 - 2018-11-12
### Fixes
- Fix typo in contributing guidelines
- Modify versionist.conf.js to match new internal commit guidelines
### Misc
- Rename etcher to balena-etcher
- Convert Select Image button to Rendition
## v1.4.6 - 2018-10-28
### Fixes
- Provide a Buffer to xxhash.Stream
- Fix 64 bit detection on arm
- Fix incorrect file constraint path
- Fix flash cancel button interaction
### Misc
- Add new balena.io logos
- Use Resin CI scripts to build Etcher
- Enable React lint rules
- Convert Progress Button to Rendition
## v1.4.5 - 2018-10-11
### Features
- Center content independent to window resolution.
- Add electron-native file-picker component.
- Hide unsafe mode option toggle with an env var.
- Use new design background color and drive step size ordering.
- Add a convenience Storage class on top of localStorage.
- Introduce env var to toggle autoselection of all drives.
- Add font-awesome.
- Add support for configuration files
- Use GTK-3 darkTheme mode.
- Add environment variable to toggle fullscreen.
- Allow blacklisting of drives through and environment variable ETCHER_BLACKLISTED_DRIVES.
- Show selected drives below drive selection step.
- Add a button to cancel the flash process.
- Download usbboot drivers installer when clicking a driverless usbboot device on Windows.
- Allow disabling links and hiding help link with an env var.
### Fixes
- Add "make webpack" to travis-ci build script
- Makefile: Don't use tilde in rpm versions
- Change Spectron port so not to overlap with other builds
- Fix multi-writes analytics by reusing existing logic in multi-write events.
- Load usbboot adapter on start on GNU/Linux if running as root.
### Misc
- Update drivelist to v6.4.2
- Add instructions for installing and uninstalling on Solus.
## v1.4.4 - 2018-04-24
### Fixes
- Don't display status dots with a quantity of zero on success screen
- Correct wording of flash status to use "successful" instead of "succeeded"
- Keep single drive-image pairs with warnings selected
### Misc
- Improve notification messages
## v1.4.3 - 2018-04-19
### Fixes
- Fix blob handling for usbboot
## v1.4.2 - 2018-04-18
### Features

2
CODEOWNERS Normal file
View File

@@ -0,0 +1,2 @@
* @thundron @zvin @jviotti
/scripts @nazrhom

483
Makefile
View File

@@ -2,9 +2,9 @@
# Build configuration
# ---------------------------------------------------------------------
# A non-existing target to force rules to rebuild
# See https://stackoverflow.com/a/816416
.FORCE:
RESIN_SCRIPTS ?= ./scripts/resin
export NPM_VERSION ?= 6.7.0
S3_BUCKET = artifacts.ci.balena-cloud.com
# This directory will be completely deleted by the `clean` rule
BUILD_DIRECTORY ?= dist
@@ -17,8 +17,11 @@ endif
BUILD_TEMPORARY_DIRECTORY = $(BUILD_DIRECTORY)/.tmp
# See https://github.com/electron/spectron/issues/127
ETCHER_SPECTRON_ENTRYPOINT ?= $(shell node -e 'console.log(require("electron"))')
$(BUILD_DIRECTORY):
mkdir $@
$(BUILD_TEMPORARY_DIRECTORY): | $(BUILD_DIRECTORY)
mkdir $@
# See https://stackoverflow.com/a/13468229/1641422
SHELL := /bin/bash
@@ -75,10 +78,10 @@ else
endif
ifndef PLATFORM
$(error We couldn't detect your host platform)
$(error We could not detect your host platform)
endif
ifndef HOST_ARCH
$(error We couldn't detect your host architecture)
$(error We could not detect your host architecture)
endif
# Default to host architecture. You can override by doing:
@@ -87,289 +90,32 @@ endif
#
TARGET_ARCH ?= $(HOST_ARCH)
# Support x86 builds from x64 in GNU/Linux
# See https://github.com/addaleax/lzma-native/issues/27
ifeq ($(PLATFORM),linux)
ifneq ($(HOST_ARCH),$(TARGET_ARCH))
ifeq ($(TARGET_ARCH),x86)
export CFLAGS += -m32
else
$(error Can't build $(TARGET_ARCH) binaries on a $(HOST_ARCH) host)
endif
endif
endif
# ---------------------------------------------------------------------
# Application configuration
# Electron
# ---------------------------------------------------------------------
electron-develop: | $(BUILD_TEMPORARY_DIRECTORY)
$(RESIN_SCRIPTS)/electron/install.sh \
-b $(shell pwd) \
-r $(TARGET_ARCH) \
-s $(PLATFORM) \
-m $(NPM_VERSION)
ELECTRON_VERSION = $(shell jq -r '.devDependencies["electron"]' package.json)
NODE_VERSION = 6.1.0
COMPANY_NAME = Resinio Ltd
APPLICATION_NAME = $(shell jq -r '.displayName' package.json)
APPLICATION_DESCRIPTION = $(shell jq -r '.description' package.json)
APPLICATION_COPYRIGHT = $(shell cat electron-builder.yml | shyaml get-value copyright)
BINTRAY_ORGANIZATION = resin-io
BINTRAY_REPOSITORY_DEBIAN = debian
BINTRAY_REPOSITORY_REDHAT = redhat
# ---------------------------------------------------------------------
# Extra variables
# ---------------------------------------------------------------------
TARGET_ARCH_DEBIAN = $(shell ./scripts/build/architecture-convert.sh -r $(TARGET_ARCH) -t debian)
TARGET_ARCH_REDHAT = $(shell ./scripts/build/architecture-convert.sh -r $(TARGET_ARCH) -t redhat)
TARGET_ARCH_APPIMAGE = $(shell ./scripts/build/architecture-convert.sh -r $(TARGET_ARCH) -t appimage)
TARGET_ARCH_ELECTRON_BUILDER = $(shell ./scripts/build/architecture-convert.sh -r $(TARGET_ARCH) -t electron-builder)
PLATFORM_PKG = $(shell ./scripts/build/platform-convert.sh -r $(PLATFORM) -t pkg)
ENTRY_POINT_CLI = lib/cli/etcher.js
ETCHER_CLI_BINARY = $(APPLICATION_NAME_LOWERCASE)
ifeq ($(PLATFORM),win32)
ETCHER_CLI_BINARY = $(APPLICATION_NAME_LOWERCASE).exe
endif
APPLICATION_NAME_LOWERCASE = $(shell echo $(APPLICATION_NAME) | tr A-Z a-z)
APPLICATION_VERSION_DEBIAN = $(shell echo $(APPLICATION_VERSION) | tr "-" "~")
APPLICATION_VERSION_REDHAT = $(shell echo $(APPLICATION_VERSION) | tr "-" "~")
# ---------------------------------------------------------------------
# Release type
# ---------------------------------------------------------------------
# Add the current commit to the version if release type is "snapshot"
RELEASE_TYPE ?= snapshot
PACKAGE_JSON_VERSION = $(shell jq -r '.version' package.json)
ifeq ($(RELEASE_TYPE),production)
APPLICATION_VERSION = $(PACKAGE_JSON_VERSION)
S3_BUCKET = resin-production-downloads
BINTRAY_COMPONENT = $(APPLICATION_NAME_LOWERCASE)
endif
ifeq ($(RELEASE_TYPE),snapshot)
CURRENT_COMMIT_HASH = $(shell git log -1 --format="%h")
APPLICATION_VERSION = $(PACKAGE_JSON_VERSION)+$(CURRENT_COMMIT_HASH)
S3_BUCKET = resin-nightly-downloads
BINTRAY_COMPONENT = $(APPLICATION_NAME_LOWERCASE)-devel
endif
ifndef APPLICATION_VERSION
$(error Invalid release type: $(RELEASE_TYPE))
endif
# ---------------------------------------------------------------------
# Code signing
# ---------------------------------------------------------------------
ifeq ($(PLATFORM),darwin)
ifndef CSC_NAME
$(warning No code-sign identity found (CSC_NAME is not set))
endif
endif
ifeq ($(PLATFORM),win32)
ifndef CSC_LINK
$(warning No code-sign certificate found (CSC_LINK is not set))
ifndef CSC_KEY_PASSWORD
$(warning No code-sign certificate password found (CSC_KEY_PASSWORD is not set))
endif
endif
endif
# ---------------------------------------------------------------------
# Electron Builder
# ---------------------------------------------------------------------
ELECTRON_BUILDER_OPTIONS = --$(TARGET_ARCH_ELECTRON_BUILDER)
# ---------------------------------------------------------------------
# Analytics
# ---------------------------------------------------------------------
ifndef ANALYTICS_SENTRY_TOKEN
$(warning No Sentry token found (ANALYTICS_SENTRY_TOKEN is not set))
else
ELECTRON_BUILDER_OPTIONS += --extraMetadata.analytics.sentry.token=$(ANALYTICS_SENTRY_TOKEN)
endif
ifndef ANALYTICS_MIXPANEL_TOKEN
$(warning No Mixpanel token found (ANALYTICS_MIXPANEL_TOKEN is not set))
else
ELECTRON_BUILDER_OPTIONS += --extraMetadata.analytics.mixpanel.token=$(ANALYTICS_MIXPANEL_TOKEN)
endif
# ---------------------------------------------------------------------
# Rules
# ---------------------------------------------------------------------
# See http://stackoverflow.com/a/12528721
# Note that the blank line before 'endef' is actually important - don't delete it
define execute-command
$(1)
endef
$(BUILD_DIRECTORY):
mkdir $@
$(BUILD_TEMPORARY_DIRECTORY): | $(BUILD_DIRECTORY)
mkdir $@
# ---------------------------------------------------------------------
# CLI
# ---------------------------------------------------------------------
$(BUILD_DIRECTORY)/$(APPLICATION_NAME)-cli-$(APPLICATION_VERSION)-$(PLATFORM)-$(TARGET_ARCH)-app: \
package.json npm-shrinkwrap.json \
| $(BUILD_DIRECTORY)
mkdir -p $@
./scripts/build/dependencies-npm.sh -p \
-r "$(TARGET_ARCH)" \
-v "$(NODE_VERSION)" \
-x $@ \
-t node \
-s "$(PLATFORM)"
patch --directory=$@ --force --strip=1 --ignore-whitespace < patches/lzma-native-index-static-addon-require.patch
cp -r lib $@
cp package.json $@
$(BUILD_DIRECTORY)/$(APPLICATION_NAME)-cli-$(APPLICATION_VERSION)-$(PLATFORM)-$(TARGET_ARCH): \
$(BUILD_DIRECTORY)/$(APPLICATION_NAME)-cli-$(APPLICATION_VERSION)-$(PLATFORM)-$(TARGET_ARCH)-app \
| $(BUILD_DIRECTORY)
mkdir $@
cd $< && pkg --output ../../$@/$(ETCHER_CLI_BINARY) -t node6-$(PLATFORM_PKG)-$(TARGET_ARCH) $(ENTRY_POINT_CLI)
./scripts/build/dependencies-npm-extract-addons.sh \
-d $</node_modules \
-o $@/node_modules
# pkg currently has a bug where darwin executables
# can't be code-signed
# See https://github.com/zeit/pkg/issues/128
# ifeq ($(PLATFORM),darwin)
# ifdef CSC_NAME
# ./scripts/build/electron-sign-file-darwin.sh -f $@/$(ETCHER_CLI_BINARY) -i "$(CSC_NAME)"
# endif
# endif
# pkg currently has a bug where Windows executables
# can't be branded
# See https://github.com/zeit/pkg/issues/149
# ifeq ($(PLATFORM),win32)
# ./scripts/build/electron-brand-exe.sh \
# -f $@/$(ETCHER_CLI_BINARY) \
# -n $(APPLICATION_NAME) \
# -d "$(APPLICATION_DESCRIPTION)" \
# -v "$(APPLICATION_VERSION)" \
# -c "$(APPLICATION_COPYRIGHT)" \
# -m "$(COMPANY_NAME)" \
# -i assets/icon.ico \
# -w $(BUILD_TEMPORARY_DIRECTORY)
# endif
ifeq ($(PLATFORM),win32)
ifdef CSC_LINK
ifdef CSC_KEY_PASSWORD
./scripts/build/electron-sign-exe-win32.sh -f $@/$(ETCHER_CLI_BINARY) \
-d "$(APPLICATION_NAME) - $(APPLICATION_VERSION)" \
-c $(CSC_LINK) \
-p $(CSC_KEY_PASSWORD)
endif
endif
endif
$(BUILD_DIRECTORY)/$(APPLICATION_NAME)-cli-$(APPLICATION_VERSION)-$(PLATFORM)-$(TARGET_ARCH).zip: \
$(BUILD_DIRECTORY)/$(APPLICATION_NAME)-cli-$(APPLICATION_VERSION)-$(PLATFORM)-$(TARGET_ARCH)
./scripts/build/zip-file.sh -f $< -s $(PLATFORM) -o $@
$(BUILD_DIRECTORY)/$(APPLICATION_NAME)-cli-$(APPLICATION_VERSION)-$(PLATFORM)-$(TARGET_ARCH).tar.gz: \
$(BUILD_DIRECTORY)/$(APPLICATION_NAME)-cli-$(APPLICATION_VERSION)-$(PLATFORM)-$(TARGET_ARCH)
./scripts/build/tar-gz-file.sh -f $< -o $@
# ---------------------------------------------------------------------
# GUI
# ---------------------------------------------------------------------
electron-test:
$(RESIN_SCRIPTS)/electron/test.sh \
-b $(shell pwd) \
-s $(PLATFORM)
assets/dmg/background.tiff: assets/dmg/background.png assets/dmg/background@2x.png
tiffutil -cathidpicheck $^ -out $@
build/js/gui.js: .FORCE
webpack
$(BUILD_DIRECTORY)/$(APPLICATION_NAME)-$(APPLICATION_VERSION).dmg: assets/dmg/background.tiff build/js/gui.js \
| $(BUILD_DIRECTORY)
TARGET_ARCH=$(TARGET_ARCH) build --mac dmg $(ELECTRON_BUILDER_OPTIONS) \
--extraMetadata.version=$(APPLICATION_VERSION) \
--extraMetadata.packageType=dmg
$(BUILD_DIRECTORY)/$(APPLICATION_NAME)-$(APPLICATION_VERSION)-mac.zip: assets/dmg/background.tiff build/js/gui.js \
| $(BUILD_DIRECTORY)
TARGET_ARCH=$(TARGET_ARCH) build --mac zip $(ELECTRON_BUILDER_OPTIONS) \
--extraMetadata.version=$(APPLICATION_VERSION) \
--extraMetadata.packageType=zip
APPLICATION_NAME_ELECTRON = $(APPLICATION_NAME_LOWERCASE)-electron
$(BUILD_DIRECTORY)/$(APPLICATION_NAME_ELECTRON)-$(APPLICATION_VERSION_REDHAT).$(TARGET_ARCH_REDHAT).rpm: build/js/gui.js \
| $(BUILD_DIRECTORY)
build --linux rpm $(ELECTRON_BUILDER_OPTIONS) \
--extraMetadata.name=$(APPLICATION_NAME_ELECTRON) \
--extraMetadata.version=$(APPLICATION_VERSION_REDHAT) \
--extraMetadata.packageType=rpm
$(BUILD_DIRECTORY)/$(APPLICATION_NAME_ELECTRON)_$(APPLICATION_VERSION_DEBIAN)_$(TARGET_ARCH_DEBIAN).deb: build/js/gui.js \
| $(BUILD_DIRECTORY)
build --linux deb $(ELECTRON_BUILDER_OPTIONS) \
--extraMetadata.name=$(APPLICATION_NAME_ELECTRON) \
--extraMetadata.version=$(APPLICATION_VERSION_DEBIAN) \
--extraMetadata.packageType=deb
ifeq ($(TARGET_ARCH),x64)
ELECTRON_BUILDER_LINUX_UNPACKED_DIRECTORY = linux-unpacked
else
ELECTRON_BUILDER_LINUX_UNPACKED_DIRECTORY = linux-$(TARGET_ARCH_ELECTRON_BUILDER)-unpacked
endif
$(BUILD_DIRECTORY)/$(ELECTRON_BUILDER_LINUX_UNPACKED_DIRECTORY)/$(APPLICATION_NAME_ELECTRON): build/js/gui.js | $(BUILD_DIRECTORY)
build --dir --linux $(ELECTRON_BUILDER_OPTIONS) \
--extraMetadata.name=$(APPLICATION_NAME_ELECTRON) \
--extraMetadata.version=$(APPLICATION_VERSION) \
--extraMetadata.packageType=AppImage
touch $@
$(BUILD_DIRECTORY)/$(APPLICATION_NAME_LOWERCASE)-$(APPLICATION_VERSION)-$(PLATFORM).AppDir: \
$(BUILD_DIRECTORY)/$(ELECTRON_BUILDER_LINUX_UNPACKED_DIRECTORY)/$(APPLICATION_NAME_ELECTRON) \
| $(BUILD_DIRECTORY)
./scripts/build/electron-create-appdir.sh \
-n $(APPLICATION_NAME) \
-d "$(APPLICATION_DESCRIPTION)" \
-p $(dir $<) \
electron-build: assets/dmg/background.tiff | $(BUILD_TEMPORARY_DIRECTORY)
$(RESIN_SCRIPTS)/electron/build.sh \
-b $(shell pwd) \
-r $(TARGET_ARCH) \
-b $(APPLICATION_NAME_ELECTRON) \
-i assets/icon.png \
-o $@
$(BUILD_DIRECTORY)/$(APPLICATION_NAME_LOWERCASE)-$(APPLICATION_VERSION)-$(TARGET_ARCH_APPIMAGE).AppImage: \
$(BUILD_DIRECTORY)/$(APPLICATION_NAME_LOWERCASE)-$(APPLICATION_VERSION)-$(PLATFORM).AppDir \
| $(BUILD_DIRECTORY) $(BUILD_TEMPORARY_DIRECTORY)
./scripts/build/electron-create-appimage-linux.sh \
-d $< \
-r $(TARGET_ARCH) \
-w $(BUILD_TEMPORARY_DIRECTORY) \
-o $@
$(BUILD_DIRECTORY)/$(APPLICATION_NAME_LOWERCASE)-$(APPLICATION_VERSION)-$(PLATFORM)-$(TARGET_ARCH_APPIMAGE).zip: \
$(BUILD_DIRECTORY)/$(APPLICATION_NAME_LOWERCASE)-$(APPLICATION_VERSION)-$(TARGET_ARCH_APPIMAGE).AppImage \
| $(BUILD_DIRECTORY)
./scripts/build/zip-file.sh -f $< -s $(PLATFORM) -o $@
$(BUILD_DIRECTORY)/$(APPLICATION_NAME)-Portable-$(APPLICATION_VERSION)-$(TARGET_ARCH).exe: build/js/gui.js \
| $(BUILD_DIRECTORY)
TARGET_ARCH=$(TARGET_ARCH) build --win portable $(ELECTRON_BUILDER_OPTIONS) \
--extraMetadata.version=$(APPLICATION_VERSION) \
--extraMetadata.packageType=portable
$(BUILD_DIRECTORY)/$(APPLICATION_NAME)-Setup-$(APPLICATION_VERSION)-$(TARGET_ARCH).exe: build/js/gui.js \
| $(BUILD_DIRECTORY)
TARGET_ARCH=$(TARGET_ARCH) build --win nsis $(ELECTRON_BUILDER_OPTIONS) \
--extraMetadata.version=$(APPLICATION_VERSION) \
--extraMetadata.packageType=nsis
-s $(PLATFORM) \
-v production \
-n $(BUILD_TEMPORARY_DIRECTORY)/npm \
-w $(BUILD_TEMPORARY_DIRECTORY)
# ---------------------------------------------------------------------
# Phony targets
@@ -386,159 +132,29 @@ TARGETS = \
lint-spell \
test-spectron \
test-gui \
test-sdk \
test-cli \
test \
sanity-checks \
clean \
distclean \
changelog \
webpack \
package-electron \
package-cli \
cli-develop \
installers-all \
publish-all \
electron-develop
electron-develop \
electron-test \
electron-build
changelog:
versionist
webpack: build/js/gui.js
package-electron:
TARGET_ARCH=$(TARGET_ARCH) build --dir $(ELECTRON_BUILDER_OPTIONS)
package-cli: $(BUILD_DIRECTORY)/$(APPLICATION_NAME)-cli-$(APPLICATION_VERSION)-$(PLATFORM)-$(TARGET_ARCH)
ifeq ($(PLATFORM),darwin)
electron-installer-app-zip: $(BUILD_DIRECTORY)/$(APPLICATION_NAME)-$(APPLICATION_VERSION)-mac.zip
electron-installer-dmg: $(BUILD_DIRECTORY)/$(APPLICATION_NAME)-$(APPLICATION_VERSION).dmg
cli-installer-tar-gz: $(BUILD_DIRECTORY)/$(APPLICATION_NAME)-cli-$(APPLICATION_VERSION)-$(PLATFORM)-$(TARGET_ARCH).tar.gz
TARGETS += \
electron-installer-dmg \
electron-installer-app-zip \
cli-installer-tar-gz
PUBLISH_AWS_S3 += \
$(BUILD_DIRECTORY)/$(APPLICATION_NAME)-$(APPLICATION_VERSION)-mac.zip \
$(BUILD_DIRECTORY)/$(APPLICATION_NAME)-$(APPLICATION_VERSION).dmg \
$(BUILD_DIRECTORY)/$(APPLICATION_NAME)-cli-$(APPLICATION_VERSION)-$(PLATFORM)-$(TARGET_ARCH).tar.gz
endif
ifeq ($(PLATFORM),linux)
electron-installer-appimage: $(BUILD_DIRECTORY)/$(APPLICATION_NAME_LOWERCASE)-$(APPLICATION_VERSION)-$(PLATFORM)-$(TARGET_ARCH_APPIMAGE).zip
electron-installer-debian: $(BUILD_DIRECTORY)/$(APPLICATION_NAME_ELECTRON)_$(APPLICATION_VERSION_DEBIAN)_$(TARGET_ARCH_DEBIAN).deb
electron-installer-redhat: $(BUILD_DIRECTORY)/$(APPLICATION_NAME_ELECTRON)-$(APPLICATION_VERSION_REDHAT).$(TARGET_ARCH_REDHAT).rpm
cli-installer-tar-gz: $(BUILD_DIRECTORY)/$(APPLICATION_NAME)-cli-$(APPLICATION_VERSION)-$(PLATFORM)-$(TARGET_ARCH).tar.gz
TARGETS += \
electron-installer-appimage \
electron-installer-debian \
electron-installer-redhat \
cli-installer-tar-gz
PUBLISH_AWS_S3 += \
$(BUILD_DIRECTORY)/$(APPLICATION_NAME_LOWERCASE)-$(APPLICATION_VERSION)-$(PLATFORM)-$(TARGET_ARCH_APPIMAGE).zip \
$(BUILD_DIRECTORY)/$(APPLICATION_NAME)-cli-$(APPLICATION_VERSION)-$(PLATFORM)-$(TARGET_ARCH).tar.gz
PUBLISH_BINTRAY_DEBIAN += \
$(BUILD_DIRECTORY)/$(APPLICATION_NAME_ELECTRON)_$(APPLICATION_VERSION_DEBIAN)_$(TARGET_ARCH_DEBIAN).deb
PUBLISH_BINTRAY_REDHAT += \
$(BUILD_DIRECTORY)/$(APPLICATION_NAME_ELECTRON)-$(APPLICATION_VERSION_REDHAT).$(TARGET_ARCH_REDHAT).rpm
endif
ifeq ($(PLATFORM),win32)
electron-installer-portable: $(BUILD_DIRECTORY)/$(APPLICATION_NAME)-Portable-$(APPLICATION_VERSION)-$(TARGET_ARCH).exe
electron-installer-nsis: $(BUILD_DIRECTORY)/$(APPLICATION_NAME)-Setup-$(APPLICATION_VERSION)-$(TARGET_ARCH).exe
cli-installer-zip: $(BUILD_DIRECTORY)/$(APPLICATION_NAME)-cli-$(APPLICATION_VERSION)-$(PLATFORM)-$(TARGET_ARCH).zip
TARGETS += \
electron-installer-portable \
electron-installer-nsis \
cli-installer-zip
PUBLISH_AWS_S3 += \
$(BUILD_DIRECTORY)/$(APPLICATION_NAME)-Portable-$(APPLICATION_VERSION)-$(TARGET_ARCH).exe \
$(BUILD_DIRECTORY)/$(APPLICATION_NAME)-Setup-$(APPLICATION_VERSION)-$(TARGET_ARCH).exe \
$(BUILD_DIRECTORY)/$(APPLICATION_NAME)-cli-$(APPLICATION_VERSION)-$(PLATFORM)-$(TARGET_ARCH).zip
endif
installers-all: $(PUBLISH_AWS_S3) $(PUBLISH_BINTRAY_DEBIAN) $(PUBLISH_BINTRAY_REDHAT)
ifdef PUBLISH_AWS_S3
publish-aws-s3: $(PUBLISH_AWS_S3)
ifeq ($(RELEASE_TYPE),production)
$(foreach publishable,$^,$(call execute-command,./scripts/publish/aws-s3.sh \
-f $(publishable) \
-b $(S3_BUCKET) \
-v $(APPLICATION_VERSION) \
-p $(APPLICATION_NAME_LOWERCASE)))
endif
ifeq ($(RELEASE_TYPE),snapshot)
$(foreach publishable,$^,$(call execute-command,./scripts/publish/aws-s3.sh \
-f $(publishable) \
-b $(S3_BUCKET) \
-v $(APPLICATION_VERSION) \
-p $(APPLICATION_NAME_LOWERCASE) \
-k $(shell date +"%Y-%m-%d")))
endif
PUBLISHABLES += publish-aws-s3
TARGETS += publish-aws-s3
endif
ifeq ($(RELEASE_TYPE),production)
ifdef PUBLISH_BINTRAY_DEBIAN
publish-bintray-debian: $(PUBLISH_BINTRAY_DEBIAN)
$(foreach publishable,$^,$(call execute-command,./scripts/publish/bintray.sh \
-f $(publishable) \
-v $(APPLICATION_VERSION_DEBIAN) \
-r $(TARGET_ARCH) \
-t $(RELEASE_TYPE) \
-o $(BINTRAY_ORGANIZATION) \
-p $(BINTRAY_REPOSITORY_DEBIAN) \
-c $(BINTRAY_COMPONENT) \
-y debian))
PUBLISHABLES += publish-bintray-debian
TARGETS += publish-bintray-debian
endif
ifdef PUBLISH_BINTRAY_REDHAT
publish-bintray-redhat: $(PUBLISH_BINTRAY_REDHAT)
$(foreach publishable,$^,$(call execute-command,./scripts/publish/bintray.sh \
-f $(publishable) \
-v $(APPLICATION_VERSION_REDHAT) \
-r $(TARGET_ARCH) \
-t $(RELEASE_TYPE) \
-o $(BINTRAY_ORGANIZATION) \
-p $(BINTRAY_REPOSITORY_REDHAT) \
-c $(BINTRAY_COMPONENT) \
-y redhat))
PUBLISHABLES += publish-bintray-redhat
TARGETS += publish-bintray-redhat
endif
endif
publish-all: $(PUBLISHABLES)
webpack:
./node_modules/.bin/webpack
.PHONY: $(TARGETS)
cli-develop:
./scripts/build/dependencies-npm.sh \
-r "$(TARGET_ARCH)" \
-v "$(NODE_VERSION)" \
-t node \
-s "$(PLATFORM)"
electron-develop:
./scripts/build/dependencies-npm.sh \
-r "$(TARGET_ARCH)" \
-v "$(ELECTRON_VERSION)" \
-t electron \
-s "$(PLATFORM)"
sass:
npm rebuild node-sass
node-sass lib/gui/app/scss/main.scss > lib/gui/css/main.css
lint-ts:
resin-lint --typescript lib
lint-js:
eslint lib tests scripts bin versionist.conf.js webpack.config.js
eslint --ignore-pattern scripts/resin/**/*.js lib tests scripts bin webpack.config.js
lint-sass:
sass-lint lib/gui/scss
@@ -553,13 +169,15 @@ lint-spell:
codespell \
--dictionary - \
--dictionary dictionary.txt \
--skip *.gz,*.bz2,*.xz,*.zip,*.img,*.dmg,*.iso,*.rpi-sdcard,.DS_Store,*.dtb,*.dtbo,*.dat,*.elf,*.bin,*.foo,xz-without-extension \
--skip *.svg *.gz,*.bz2,*.xz,*.zip,*.img,*.dmg,*.iso,*.rpi-sdcard,*.wic,.DS_Store,*.dtb,*.dtbo,*.dat,*.elf,*.bin,*.foo,xz-without-extension \
lib tests docs scripts Makefile *.md LICENSE
lint: lint-js lint-sass lint-cpp lint-html lint-spell
lint: lint-ts lint-js lint-sass lint-cpp lint-html lint-spell
MOCHA_OPTIONS=--recursive --reporter spec
MOCHA_OPTIONS=--recursive --reporter spec --require ts-node/register
# See https://github.com/electron/spectron/issues/127
ETCHER_SPECTRON_ENTRYPOINT ?= $(shell node -e 'console.log(require("electron"))')
test-spectron:
ETCHER_SPECTRON_ENTRYPOINT="$(ETCHER_SPECTRON_ENTRYPOINT)" mocha $(MOCHA_OPTIONS) tests/spectron
@@ -568,13 +186,7 @@ test-gui:
test-sdk:
electron-mocha $(MOCHA_OPTIONS) \
tests/shared \
tests/image-stream
test-cli:
mocha $(MOCHA_OPTIONS) \
tests/shared \
tests/image-stream
tests/shared
test: test-gui test-sdk test-spectron
@@ -582,18 +194,13 @@ help:
@echo "Available targets: $(TARGETS)"
info:
@echo "Application version : $(APPLICATION_VERSION)"
@echo "Release type : $(RELEASE_TYPE)"
@echo "Platform : $(PLATFORM)"
@echo "Host arch : $(HOST_ARCH)"
@echo "Target arch : $(TARGET_ARCH)"
sanity-checks:
./scripts/ci/ensure-staged-sass.sh
./scripts/ci/ensure-staged-shrinkwrap.sh
./scripts/ci/ensure-npm-dependencies-compatibility.sh
./scripts/ci/ensure-npm-valid-dependencies.sh
./scripts/ci/ensure-npm-shrinkwrap-versions.sh
./scripts/ci/ensure-all-file-extensions-in-gitattributes.sh
clean:
@@ -602,6 +209,8 @@ clean:
distclean: clean
rm -rf node_modules
rm -rf build
rm -rf dist
rm -rf generated
rm -rf $(BUILD_TEMPORARY_DIRECTORY)
.DEFAULT_GOAL = help

109
README.md
View File

@@ -1,40 +1,32 @@
Etcher
======
# Etcher
> Flash OS images to SD cards & USB drives, safely and easily.
Etcher is a powerful OS image flasher built with web technologies to ensure
flashing an SDCard or USB drive is a pleasant and safe experience. It protects
you from accidentally writing to your hard-drives, ensures every byte of data
was written correctly and much more.
was written correctly and much more. It can also flash directly Raspberry Pi devices that support the usbboot protocol
[![Current Release](https://img.shields.io/github/release/resin-io/etcher.svg?style=flat-square)](https://etcher.io)
![License](https://img.shields.io/github/license/resin-io/etcher.svg?style=flat-square)
[![Travis CI status](https://img.shields.io/travis/resin-io/etcher/master.svg?style=flat-square&label=linux)](https://travis-ci.org/resin-io/etcher/branches)
[![AppVeyor status](https://img.shields.io/appveyor/ci/resin-io/etcher/master.svg?style=flat-square&label=windows)](https://ci.appveyor.com/project/resin-io/etcher/branch/master)
[![Dependency status](https://img.shields.io/david/resin-io/etcher.svg?style=flat-square)](https://david-dm.org/resin-io/etcher)
[![Resin.io Forums](https://img.shields.io/discourse/https/forums.resin.io/topics.svg?style=flat-square&label=resin.io%20forums)](https://forums.resin.io/c/etcher)
[![Stories in Progress](https://img.shields.io/waffle/label/resin-io/etcher/in%20progress.svg?style=flat-square)](https://waffle.io/resin-io/etcher)
[![Current Release](https://img.shields.io/github/release/balena-io/etcher.svg?style=flat-square)](https://balena.io/etcher)
[![License](https://img.shields.io/github/license/balena-io/etcher.svg?style=flat-square)](https://github.com/balena-io/etcher/blob/master/LICENSE)
[![Dependency status](https://img.shields.io/david/balena-io/etcher.svg?style=flat-square)](https://david-dm.org/balena-io/etcher)
[![Balena.io Forums](https://img.shields.io/discourse/https/forums.balena.io/topics.svg?style=flat-square&label=balena.io%20forums)](https://forums.balena.io/c/etcher)
***
[**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/resin-io/etcher/master/screenshot.png)
Supported Operating Systems
---------------------------
## Supported Operating Systems
- Linux (most distros)
- macOS 10.9 and later
- macOS 10.10 (Yosemite) and later
- Microsoft Windows 7 and later
Note that Etcher will run on any platform officially supported by
[Electron][electron]. Read more in their
[documentation][electron-supported-platforms].
Installers
----------
## Installers
Refer to the [downloads page][etcher] for the latest pre-made
installers for all supported operating systems.
@@ -43,28 +35,28 @@ installers for all supported operating systems.
1. Add Etcher debian repository:
```
echo "deb https://dl.bintray.com/resin-io/debian stable etcher" | sudo tee /etc/apt/sources.list.d/etcher.list
```sh
echo "deb https://deb.etcher.io stable etcher" | sudo tee /etc/apt/sources.list.d/balena-etcher.list
```
2. Trust Bintray.com's GPG key:
```sh
sudo apt-key adv --keyserver hkp://pgp.mit.edu:80 --recv-keys 379CE192D401AB61
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 379CE192D401AB61
```
3. Update and install:
```sh
sudo apt-get update
sudo apt-get install etcher-electron
sudo apt-get install balena-etcher-electron
```
##### Uninstall
```sh
sudo apt-get remove etcher-electron
sudo rm /etc/apt/sources.list.d/etcher.list
sudo apt-get remove balena-etcher-electron
sudo rm /etc/apt/sources.list.d/balena-etcher.list
sudo apt-get update
```
#### Redhat (RHEL) and Fedora based Package Repository (GNU/Linux x86/x64)
@@ -72,35 +64,47 @@ sudo apt-get update
1. Add Etcher rpm repository:
```sh
sudo wget https://bintray.com/resin-io/redhat/rpm -O /etc/yum.repos.d/bintray-resin-io-redhat.repo
sudo wget https://balena.io/etcher/static/etcher-rpm.repo -O /etc/yum.repos.d/etcher-rpm.repo
```
2. Update and install:
```sh
sudo yum install -y etcher-electron
sudo yum install -y balena-etcher-electron
```
or
```sh
sudo dnf install -y etcher-electron
sudo dnf install -y balena-etcher-electron
```
##### Uninstall
```
sudo yum remove -y etcher-electron
sudo rm /etc/yum.repos.d/bintray-resin-io-redhat.repo
```sh
sudo yum remove -y balena-etcher-electron
sudo rm /etc/yum.repos.d/etcher-rpm.repo
sudo yum clean all
sudo yum makecache fast
```
or
```
sudo dnf remove -y etcher-electron
sudo rm /etc/yum.repos.d/bintray-resin-io-redhat.repo
```sh
sudo dnf remove -y balena-etcher-electron
sudo rm /etc/yum.repos.d/etcher-rpm.repo
sudo dnf clean all
sudo dnf makecache
```
#### Solus (GNU/Linux x64)
```sh
sudo eopkg it etcher
```
##### Uninstall
```sh
sudo eopkg rm etcher
```
#### Brew Cask (macOS)
Note that the Etcher Cask has to be updated manually to point to new versions,
@@ -108,16 +112,16 @@ so it might not refer to the latest version immediately after an Etcher
release.
```sh
brew cask install etcher
brew cask install balenaetcher
```
##### Uninstall
```sh
brew cask uninstall etcher
brew cask uninstall balenaetcher
```
### Chocolatey (Windows)
#### Chocolatey (Windows)
This package is maintained by [@majkinetor](https://github.com/majkinetor), and
is kept up to date automatically.
@@ -126,25 +130,28 @@ is kept up to date automatically.
choco install etcher
```
Support
-------
##### Uninstall
```sh
choco uninstall etcher
```
## Support
If you're having any problem, please [raise an issue][newissue] on GitHub and
the resin.io team will be happy to help.
the balena.io team will be happy to help.
License
-------
## License
Etcher is free software, and may be redistributed under the terms specified in
the [license].
[etcher]: https://etcher.io
[electron]: http://electron.atom.io
[electron-supported-platforms]: http://electron.atom.io/docs/tutorial/supported-platforms/
[SUPPORT]: https://github.com/resin-io/etcher/blob/master/SUPPORT.md
[CONTRIBUTING]: https://github.com/resin-io/etcher/blob/master/docs/CONTRIBUTING.md
[CLI]: https://github.com/resin-io/etcher/blob/master/docs/CLI.md
[USER-DOCUMENTATION]: https://github.com/resin-io/etcher/blob/master/docs/USER-DOCUMENTATION.md
[milestones]: https://github.com/resin-io/etcher/milestones
[newissue]: https://github.com/resin-io/etcher/issues/new
[license]: https://github.com/resin-io/etcher/blob/master/LICENSE
[etcher]: https://balena.io/etcher
[electron]: https://electronjs.org/
[electron-supported-platforms]: https://electronjs.org/docs/tutorial/support#supported-platforms
[SUPPORT]: https://github.com/balena-io/etcher/blob/master/SUPPORT.md
[CONTRIBUTING]: https://github.com/balena-io/etcher/blob/master/docs/CONTRIBUTING.md
[USER-DOCUMENTATION]: https://github.com/balena-io/etcher/blob/master/docs/USER-DOCUMENTATION.md
[milestones]: https://github.com/balena-io/etcher/milestones
[newissue]: https://github.com/balena-io/etcher/issues/new
[license]: https://github.com/balena-io/etcher/blob/master/LICENSE

View File

@@ -8,7 +8,7 @@ Forums
------
We have a [Discourse forum][discourse] which is open to everyone, so please
come join us :). Drop us a line there and the resin.io staff and community
come join us :). Drop us a line there and the balena.io staff and community
users will be happy to assist. Your question might already be answered, so take
a look at the existing threads before opening a new one!
@@ -20,7 +20,7 @@ support:
- The operating system you're running Etcher in.
- Relevant logging output, if any, from DevTools, which you can open by
pressing `Ctrl+Alt+I` or `Cmd+Alt+I` depending on your platform.
pressing `Ctrl+Shift+I` or `Cmd+Alt+I` depending on your platform.
GitHub
------
@@ -29,6 +29,6 @@ If you encounter an issue or have a suggestion, head on over to Etcher's [issue
tracker][issues] and if there isn't a ticket covering it, [create
one][new-issue].
[discourse]: https://forums.resin.io/c/etcher
[issues]: https://github.com/resin-io/etcher/issues
[new-issue]: https://github.com/resin-io/etcher/issues/new
[discourse]: https://forums.balena.io/c/etcher
[issues]: https://github.com/balena-io/etcher/issues
[new-issue]: https://github.com/balena-io/etcher/issues/new

View File

@@ -1,50 +0,0 @@
# appveyor file
# http://www.appveyor.com/docs/appveyor-yml
image: Visual Studio 2015
# See https://github.com/electron/spectron#on-appveyor
os: unstable
cache:
- C:\Users\appveyor\.node-gyp
- '%LOCALAPPDATA%\electron\Cache'
- '%LOCALAPPDATA%\electron-builder\cache'
- '%AppData%\npm-cache'
- '%USERPROFILE%\.pkg-cache'
- node_modules -> npm-shrinkwrap.json
- C:\ProgramData\chocolatey\bin -> appveyor.yml
- C:\ProgramData\chocolatey\lib -> appveyor.yml
- C:\Users\appveyor\AppData\Local\Temp\chocolatey -> appveyor.yml
# what combinations to test
environment:
global:
ELECTRON_NO_ATTACH_CONSOLE: true
nodejs_version: "6.10.3"
platform:
- x86
- x64
matrix:
fast_finish: true
install:
- ps: Update-NodeJsInstallation $env:nodejs_version $env:Platform
- set PATH=C:\Program Files (x86)\Windows Kits\8.1\bin\x86;%PATH%
- set PATH=C:\Program Files (x86)\NSIS;%PATH%
- set PATH=C:\MinGW\bin;%PATH%
- set PATH=C:\MinGW\msys\1.0\bin;%PATH%
- bash .\scripts\ci\install.sh -o win32 -r %Platform%
build: off
test_script:
- node --version
- npm --version
- bash .\scripts\ci\test.sh -o win32 -r %Platform%
- bash .\scripts\ci\build-installers.sh -o win32 -r %Platform%
deploy_script:
- if %APPVEYOR_REPO_BRANCH%==master (bash .\scripts\ci\deploy.sh -o win32 -r %Platform%)

BIN
assets/dmg/background.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 38 KiB

BIN
assets/dmg/background.tiff Normal file → Executable file

Binary file not shown.

BIN
assets/dmg/background@2x.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 49 KiB

BIN
assets/icon.icns Normal file → Executable file

Binary file not shown.

BIN
assets/icon.ico Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 361 KiB

After

Width:  |  Height:  |  Size: 361 KiB

BIN
assets/icon.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

BIN
assets/iconset/128x128.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

BIN
assets/iconset/16x16.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 881 B

After

Width:  |  Height:  |  Size: 479 B

BIN
assets/iconset/256x256.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

BIN
assets/iconset/32x32.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 802 B

BIN
assets/iconset/48x48.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
assets/iconset/512x512.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 146 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

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

View File

@@ -17,8 +17,18 @@
"libraries": [
"-lShell32.lib",
],
} ]
} ],
[ 'OS=="mac"', {
"xcode_settings": {
"OTHER_CPLUSPLUSFLAGS": [
"-stdlib=libc++"
],
"OTHER_LDFLAGS": [
"-stdlib=libc++"
]
}
} ]
],
}
],

4
dev-app-update.yml Normal file
View File

@@ -0,0 +1,4 @@
owner: balena-io
repo: etcher
provider: github
updaterCacheDirName: balena-etcher-updater

View File

@@ -40,62 +40,18 @@ to submit their work or bug reports.
These are the main Etcher components, in a nutshell:
- [Etcher Image Write][etcher-image-write]
This is the repository that implements the actual procedures to write an image
to a raw device and the place where image validation resides. Its main purpose
is to abstract the messy details of interacting with raw devices in all major
operating systems.
- [Etcher Image Stream](../lib/image-stream)
> (Moved from a separate repository into the main Etcher codebase)
This module converts any kind of input into a readable stream
representing the image so it can be plugged to [etcher-image-write]. Inputs
that this module might handle could be, for example: a simple image file, a URL
to an image, a compressed image, an image inside a ZIP archive, etc. Together
with [etcher-image-write], these modules are the building blocks needed to take
an image representation to the user's device, the "Etcher's backend".
- [Drivelist](https://github.com/resin-io-modules/drivelist)
- [Drivelist](https://github.com/balena-io-modules/drivelist)
As the name implies, this module's duty is to detect the connected drives
uniformly in all major operating systems, along with valuable metadata, like if
a drive is removable or not, to prevent users from trying to write an image to
a system drive.
- [Etcher](https://github.com/resin-io/etcher)
- [Etcher](https://github.com/balena-io/etcher)
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.
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
-------
@@ -106,10 +62,8 @@ since fresh eyes could help unveil things that we take for granted, but should
be documented instead!
[lego-blocks]: https://github.com/sindresorhus/ama/issues/10#issuecomment-117766328
[etcher-image-write]: https://github.com/resin-io-modules/etcher-image-write
[exit-codes]: https://github.com/resin-io/etcher/blob/master/lib/shared/exit-codes.js
[cli-dir]: https://github.com/resin-io/etcher/tree/master/lib/cli
[gui-dir]: https://github.com/resin-io/etcher/tree/master/lib/gui
[exit-codes]: https://github.com/balena-io/etcher/blob/master/lib/gui/app/modules/exit-codes.js
[gui-dir]: https://github.com/balena-io/etcher/tree/master/lib/gui
[electron]: http://electron.atom.io
[nodejs]: https://nodejs.org
[angularjs]: https://angularjs.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
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
-------
@@ -122,8 +117,8 @@ A commit can include multiple instances of this tag.
Examples:
```
Closes: https://github.com/resin-io/etcher/issues/XXX
Fixes: https://github.com/resin-io/etcher/issues/XXX
Closes: https://github.com/balena-io/etcher/issues/XXX
Fixes: https://github.com/balena-io/etcher/issues/XXX
```
### `Change-Type: <type>`
@@ -198,7 +193,7 @@ first non compressed extension.
Change-Type: patch
Changelog-Entry: Don't interpret image file name information between dots as image extensions.
Fixes: https://github.com/resin-io/etcher/issues/492
Fixes: https://github.com/balena-io/etcher/issues/492
```
***
@@ -212,8 +207,8 @@ the operating system still thinks the drive has a file system.
Change-Type: patch
Changelog-Entry: Upgrade `etcher-image-write` to v5.0.2.
Link: https://github.com/resin-io-modules/etcher-image-write/blob/master/CHANGELOG.md#502---2016-06-27
Fixes: https://github.com/resin-io/etcher/issues/531
Link: https://github.com/balena-io-modules/etcher-image-write/blob/master/CHANGELOG.md#502---2016-06-27
Fixes: https://github.com/balena-io/etcher/issues/531
```
***
@@ -243,7 +238,7 @@ re-used by other services.
Change-Type: minor
Changelog-Entry: Check for updates and show a modal prompting the user to download the latest version.
Closes: https://github.com/resin-io/etcher/issues/396
Closes: https://github.com/balena-io/etcher/issues/396
```
[angular-commit-guidelines]: https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#commit

View File

@@ -17,10 +17,11 @@ Developing
#### Common
- [NodeJS](https://nodejs.org) (at least v6)
- [NodeJS](https://nodejs.org) (at least v6.11)
- [Python 2.7](https://www.python.org)
- [jq](https://stedolan.github.io/jq/)
- [curl](https://curl.haxx.se/)
- [npm](https://www.npmjs.com/) (version 6.7)
```sh
pip install -r requirements.txt
@@ -51,10 +52,12 @@ The following MinGW packages are required:
- `msys-bash`
- `msys-coreutils`
#### OS X
#### macOS
- [XCode](https://developer.apple.com/xcode/) or [XCode Command Line Tools],
which can be installed by running `xcode-select --install`.
- [Xcode](https://developer.apple.com/xcode/)
It's not enough to have [Xcode Command Line Tools] installed. Xcode must be installed
as well.
#### Linux
@@ -63,7 +66,7 @@ which can be installed by running `xcode-select --install`.
### Cloning the project
```sh
git clone https://github.com/resin-io/etcher
git clone --recursive https://github.com/balena-io/etcher
cd etcher
```
@@ -93,12 +96,6 @@ make webpack
npm start
```
#### CLI
```sh
node bin/etcher
```
Testing
-------
@@ -204,7 +201,7 @@ Before your pull request can be merged, the following conditions must hold:
- The linter doesn't throw any warning.
- All the tests passes.
- All the tests pass.
- The coding style aligns with the project's convention.
@@ -213,9 +210,9 @@ systems we support.
Don't hesitate to get in touch if you have any questions or need any help!
[ARCHITECTURE]: https://github.com/resin-io/etcher/blob/master/docs/ARCHITECTURE.md
[COMMIT-GUIDELINES]: https://github.com/resin-io/etcher/blob/master/docs/COMMIT-GUIDELINES.md
[ARCHITECTURE]: https://github.com/balena-io/etcher/blob/master/docs/ARCHITECTURE.md
[COMMIT-GUIDELINES]: https://github.com/balena-io/etcher/blob/master/docs/COMMIT-GUIDELINES.md
[EditorConfig]: http://editorconfig.org
[shrinkwrap]: https://docs.npmjs.com/cli/shrinkwrap
[hxd]: https://github.com/jhermsmeier/hxd
[XCode Command Line Tools]: https://developer.apple.com/library/content/technotes/tn2339/_index.html
[Xcode Command Line Tools]: https://developer.apple.com/library/content/technotes/tn2339/_index.html

View File

@@ -17,7 +17,7 @@ Releasing
- [Prepare the new version](#preparing-a-new-version)
- [Generate build artifacts](#generating-binaries) (binaries, archives, etc.)
- [Draft a release on GitHub](https://github.com/resin-io/etcher/releases)
- [Draft a release on GitHub](https://github.com/balena-io/etcher/releases)
- Upload build artifacts to GitHub release draft
#### Testing
@@ -27,9 +27,10 @@ Releasing
#### Publishing
- [Publish release draft on GitHub](https://github.com/resin-io/etcher/releases)
- [Post release note to forums](https://forums.resin.io/c/etcher)
- [Update the website](https://github.com/resin-io/etcher-homepage)
- [Publish release draft on GitHub](https://github.com/balena-io/etcher/releases)
- [Post release note to forums](https://forums.balena.io/c/etcher)
- [Submit Windows binaries to Symantec for whitelisting](#submitting-binaries-to-symantec)
- [Update the website](https://github.com/balena-io/etcher-homepage)
- Wait 2-3 hours for analytics (Sentry, Mixpanel) to trickle in and check for elevated error rates, or regressions
- If regressions arise; pull the release, and release a patched version, else:
- [Upload deb & rpm packages to Bintray](#uploading-packages-to-bintray)
@@ -39,39 +40,6 @@ Releasing
- Write a blog post about it, and / or
- Write about it to the Etcher mailing list
### Preparing a New Version
- Create & hop onto a new release branch, i.e. `release-1.0.0`
- Bump the version number in the `package.json`'s `version` property.
- Bump the version number in the `npm-shrinkwrap.json`'s `version` property
- Add a new entry to `CHANGELOG.md` by running `make changelog`
- Manually revise the `CHANGELOG.md` versionist output
- Update `screenshot.png` so it displays the latest version in the bottom
right corner
- Revise the `updates.semverRange` version in `package.json`
- Commit the changes with the version number as the commit title, including the `v` prefix, to `master`. For example:
**NOTE:** The version **MUST** be prefixed with a "v"
```bash
git commit -m "v1.0.0" # not 1.0.0
```
- Create an annotated tag for the new version. The commit title should equal the annotated tag name. For example:
```bash
git tag -a v1.0.0 -m "v1.0.0"
```
- Push the commit and the annotated tag.
```bash
git push
git push --tags
```
- Open a pull request against `master` titled "Release v1.0.0"
### Generating binaries
**Environment**
@@ -104,8 +72,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"
# Build AppImages
./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
@@ -115,8 +81,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"
# Build AppImages
./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
@@ -124,13 +88,9 @@ export ANALYTICS_MIXPANEL_TOKEN="xxxxxx"
**ATTENTION:** For production releases you'll need the code-signing key,
and set `CSC_NAME` to generate signed binaries on Mac OS.
**NOTE:** The CLI is not code-signed for either at this time.
```bash
make electron-develop
# Build the CLI
make RELEASE_TYPE=production cli-installer-tar-gz
# Build the zip
make RELEASE_TYPE=production electron-installer-app-zip
# Build the dmg
@@ -143,14 +103,11 @@ make RELEASE_TYPE=production electron-installer-dmg
and set `CSC_LINK`, and `CSC_KEY_PASSWORD` to generate signed binaries on Windows.
**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`.
```bash
make electron-develop
# Build the CLI
make RELEASE_TYPE=production cli-installer-zip
# Build the Portable version
make RELEASE_TYPE=production electron-installer-portable
# Build the Installer
@@ -165,10 +122,10 @@ export BINTRAY_API_KEY="youruserapikey"
```
```bash
./scripts/publish/bintray.sh -c "etcher" -t "production" -v "1.2.1" -o "resin-io" -p "debian" -y "debian" -r "x64" -f "dist/etcher-electron_1.2.1_amd64.deb"
./scripts/publish/bintray.sh -c "etcher" -t "production" -v "1.2.1" -o "resin-io" -p "debian" -y "debian" -r "x86" -f "dist/etcher-electron_1.2.1_i386.deb"
./scripts/publish/bintray.sh -c "etcher" -t "production" -v "1.2.1" -o "resin-io" -p "redhat" -y "redhat" -r "x64" -f "dist/etcher-electron-1.2.1.x86_64.rpm"
./scripts/publish/bintray.sh -c "etcher" -t "production" -v "1.2.1" -o "resin-io" -p "redhat" -y "redhat" -r "x86" -f "dist/etcher-electron-1.2.1.i686.rpm"
./scripts/publish/bintray.sh -c "etcher" -t "production" -v "1.2.1" -o "etcher" -p "debian" -y "debian" -r "x64" -f "dist/etcher-electron_1.2.1_amd64.deb"
./scripts/publish/bintray.sh -c "etcher" -t "production" -v "1.2.1" -o "etcher" -p "debian" -y "debian" -r "x86" -f "dist/etcher-electron_1.2.1_i386.deb"
./scripts/publish/bintray.sh -c "etcher" -t "production" -v "1.2.1" -o "etcher" -p "redhat" -y "redhat" -r "x64" -f "dist/etcher-electron-1.2.1.x86_64.rpm"
./scripts/publish/bintray.sh -c "etcher" -t "production" -v "1.2.1" -o "etcher" -p "redhat" -y "redhat" -r "x86" -f "dist/etcher-electron-1.2.1.i686.rpm"
```
### Uploading binaries to Amazon S3
@@ -178,7 +135,7 @@ export S3_KEY="..."
```
```bash
./scripts/publish/aws-s3.sh -b "resin-production-downloads" -v "1.2.1" -p "etcher" -f "dist/<filename>"
./scripts/publish/aws-s3.sh -b "balena-production-downloads" -v "1.2.1" -p "etcher" -f "dist/<filename>"
```
### Dealing with a Problematic Release
@@ -189,7 +146,7 @@ revert the problematic release as soon as possible, until the bugs are fixed.
You can revert a version by deleting its builds from the S3 bucket and Bintray.
Refer to the `Makefile` for the up to date information about the S3 bucket
where we push builds to, and get in touch with the resin.io operations team to
where we push builds to, and get in touch with the balena.io operations team to
get write access to it.
The Etcher update notifier dialog and the website only show the a certain
@@ -203,3 +160,15 @@ aws s3api delete-object --bucket <bucket name> --key <file name>
```
The Bintray dashboard provides an easy way to delete a version's files.
### Submitting binaries to Symantec
- [Report a Suspected Erroneous Detection](https://submit.symantec.com/false_positive/standard/)
- Fill out form:
- **Select Submission Type:** "Provide a direct download URL"
- **Name of the software being detected:** Etcher
- **Name of detection given by Symantec product:** WS.Reputation.1
- **Contact name:** Balena.io Ltd
- **E-mail address:** hello@etcher.io
- **Are you the creator or distributor of the software in question?** Yes

View File

@@ -52,7 +52,7 @@ Signing
### OS X
1. Get our Apple Developer ID certificate for signing applications distributed
outside the Mac App Store from the resin.io Apple account.
outside the Mac App Store from the balena.io Apple account.
2. Install the Developer ID certificate to your Mac's Keychain by double
clicking on the certificate file.
@@ -62,7 +62,7 @@ packaging for OS X.
### Windows
1. Get access to our code signing certificate and decryption key as a resin.io
1. Get access to our code signing certificate and decryption key as a balena.io
employee by asking for it from the relevant people.
2. Place the certificate in the root of the Etcher repository naming it
@@ -118,7 +118,7 @@ Publishing to S3
- [AWS CLI][aws-cli]
Make sure you have the [AWS CLI tool][aws-cli] installed and configured to
access resin.io's production or snapshot S3 bucket.
access balena.io's production or snapshot S3 bucket.
Run the following command to publish all files for the current combination of
_platform_ and _arch_ (building them if necessary):
@@ -128,7 +128,7 @@ make publish-aws-s3
```
Also add links to each AWS S3 file in [GitHub Releases][github-releases]. See
[`v1.0.0-beta.17`](https://github.com/resin-io/etcher/releases/tag/v1.0.0-beta.17)
[`v1.0.0-beta.17`](https://github.com/balena-io/etcher/releases/tag/v1.0.0-beta.17)
as an example.
Publishing to Homebrew Cask
@@ -143,12 +143,12 @@ Publishing to Homebrew Cask
Announcing
----------
Post messages to the [Etcher forum][resin-forum-etcher] announcing the new version
Post messages to the [Etcher forum][balena-forum-etcher] announcing the new version
of Etcher, and including the relevant section of the Changelog.
[aws-cli]: https://aws.amazon.com/cli
[bintray]: https://bintray.com
[etcher-cask-file]: https://github.com/caskroom/homebrew-cask/blob/master/Casks/etcher.rb
[etcher-cask-file]: https://github.com/caskroom/homebrew-cask/blob/master/Casks/balenaetcher.rb
[homebrew-cask]: https://github.com/caskroom/homebrew-cask
[resin-forum-etcher]: https://forums.resin.io/c/etcher
[github-releases]: https://github.com/resin-io/etcher/releases
[balena-forum-etcher]: https://forums.balena.io/c/etcher
[github-releases]: https://github.com/balena-io/etcher/releases

View File

@@ -30,7 +30,7 @@ if you require this functionality, we advise to fallback to
Deactivate desktop shortcut prompt on GNU/Linux
-----------------------------------------------
This is a feature provided by [AppImages](appimage), where the applications
This is a feature provided by [AppImages][appimage], where the applications
prompts the user to automatically register a desktop shortcut to easily access
the application.
@@ -206,20 +206,16 @@ Running in older macOS versions
-------------------------------
Etcher GUI is based on the [Electron][electron] framework, [which only supports
macOS 10.9 and newer versions][electron-supported-platforms].
macOS 10.10 (Yosemite) and newer versions][electron-supported-platforms].
You can however, run the [Etcher CLI][etcher-cli], which should work in older
platforms.
[resin.io]: https://resin.io
[balena.io]: https://balena.io
[appimage]: http://appimage.org
[xwayland]: https://wayland.freedesktop.org/xserver.html
[weston.ini]: http://manpages.ubuntu.com/manpages/wily/man5/weston.ini.5.html
[diskpart]: https://technet.microsoft.com/en-us/library/cc770877(v=ws.11).aspx
[electron]: http://electron.atom.io
[electron-supported-platforms]: https://github.com/electron/electron/blob/master/docs/tutorial/supported-platforms.md
[etcher-cli]: https://github.com/resin-io/etcher/blob/master/docs/CLI.md
[publishing]: https://github.com/resin-io/etcher/blob/master/docs/PUBLISHING.md
[electron]: https://electronjs.org/
[electron-supported-platforms]: https://electronjs.org/docs/tutorial/support#supported-platforms
[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
[rufus]: https://rufus.akeo.ie
[unetbootin]: https://unetbootin.github.io

View File

@@ -1,12 +1,11 @@
appId: io.resin.etcher
copyright: Copyright 2016-2018 Resinio Ltd
productName: Etcher
npmRebuild: false
nodeGypRebuild: false
appId: io.balena.etcher
copyright: Copyright 2016-2019 Balena Ltd
productName: balenaEtcher
npmRebuild: true
nodeGypRebuild: true
publish: null
files:
- lib
- "!lib/gui/app"
- lib/gui/app/index.html
- generated
- build/**/*.node
@@ -38,15 +37,15 @@ nsis:
uninstallerIcon: assets/icon.ico
deleteAppDataOnUninstall: true
license: LICENSE
artifactName: "${productName}-Setup-${version}-${env.TARGET_ARCH}.${ext}"
artifactName: "${productName}-Setup-${version}.${ext}"
portable:
artifactName: "${productName}-Portable-${version}-${env.TARGET_ARCH}.${ext}"
artifactName: "${productName}-Portable-${version}.${ext}"
requestExecutionLevel: user
linux:
category: Utility
packageCategory: utils
executableName: etcher-electron
synopsis: Etcher is a powerful OS image flasher built with web technologies to ensure flashing an SDCard or USB drive is a pleasant and safe experience. It protects you from accidentally writing to your hard-drives, ensures every byte of data was written correctly and much more.
executableName: balena-etcher-electron
synopsis: balenaEtcher is a powerful OS image flasher built with web technologies to ensure flashing an SDCard or USB drive is a pleasant and safe experience. It protects you from accidentally writing to your hard-drives, ensures every byte of data was written correctly and much more.
icon: assets/iconset
deb:
priority: optional
@@ -67,7 +66,7 @@ deb:
- libgconf-2-4
- libgdk-pixbuf2.0-0
- libglib2.0-0
- libgtk2.0-0
- libgtk-3-0
- liblzma5
- libnotify4
- libnspr4

View File

@@ -1,339 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

Binary file not shown.

Binary file not shown.

View File

@@ -1,4 +0,0 @@
gpu_mem=16
dtoverlay=dwc2,dr_mode=peripheral
dtparam=act_led_trigger=none
dtparam=act_led_activelow=off

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,30 +0,0 @@
Copyright (c) 2006, Broadcom Corporation.
Copyright (c) 2015, Raspberry Pi (Trading) Ltd
All rights reserved.
Redistribution. Redistribution and use in binary form, without
modification, are permitted provided that the following conditions are
met:
* This software may only be used for the purposes of developing for,
running or using a Raspberry Pi device.
* Redistributions must reproduce the above copyright notice and the
following disclaimer in the documentation and/or other materials
provided with the distribution.
* Neither the name of Broadcom Corporation nor the names of its suppliers
may be used to endorse or promote products derived from this software
without specific prior written permission.
DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

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/resin-io/etcher/blob/master/lib/shared/exit-codes.js

View File

@@ -1,124 +0,0 @@
/*
* Copyright 2017 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 os = require('os')
const fs = require('fs')
const path = require('path')
const crypto = require('crypto')
const childProcess = require('child_process')
const debug = require('debug')('etcher:cli:diskpart')
const Promise = require('bluebird')
const retry = require('bluebird-retry')
const TMP_RANDOM_BYTES = 6
const DISKPART_DELAY = 2000
const DISKPART_RETRIES = 5
/**
* @summary Generate a tmp filename with full path of OS' tmp dir
* @function
* @private
*
* @param {String} extension - temporary file extension
* @returns {String} filename
*
* @example
* const filename = tmpFilename('.sh');
*/
const tmpFilename = (extension) => {
const random = crypto.randomBytes(TMP_RANDOM_BYTES).toString('hex')
const filename = `etcher-diskpart-${random}${extension}`
return path.join(os.tmpdir(), filename)
}
/**
* @summary Run a diskpart script
* @param {Array<String>} commands - list of commands to run
* @param {Function} callback - callback(error)
* @example
* runDiskpart(['rescan'], (error) => {
* ...
* })
*/
const runDiskpart = (commands, callback) => {
if (os.platform() !== 'win32') {
callback()
return
}
const filename = tmpFilename('')
const script = commands.join('\r\n')
fs.writeFile(filename, script, {
mode: 0o755
}, (writeError) => {
debug('write %s:', filename, writeError || 'OK')
childProcess.exec(`diskpart /s ${filename}`, (execError, stdout, stderr) => {
debug('stdout:', stdout)
debug('stderr:', stderr)
fs.unlink(filename, (unlinkError) => {
debug('unlink %s:', filename, unlinkError || 'OK')
callback(execError)
})
})
})
}
module.exports = {
/**
* @summary Clean a device's partition tables
* @param {String} device - device path
* @example
* diskpart.clean('\\\\.\\PhysicalDrive2')
* .then(...)
* .catch(...)
* @returns {Promise}
*/
clean (device) {
if (os.platform() !== 'win32') {
return Promise.resolve()
}
debug('clean', device)
const pattern = /PHYSICALDRIVE(\d+)/i
if (pattern.test(device)) {
const deviceId = device.match(pattern).pop()
return retry(() => {
return new Promise((resolve, reject) => {
runDiskpart([ `select disk ${deviceId}`, 'clean', 'rescan' ], (error) => {
return error ? reject(error) : resolve()
})
}).delay(DISKPART_DELAY)
}, {
/* eslint-disable camelcase */
max_tries: DISKPART_RETRIES
/* eslint-enable camelcase */
}).catch((error) => {
throw new Error(`Couldn't clean the drive, ${error.failure.message} (code ${error.failure.code})`)
})
}
return Promise.reject(new Error(`Invalid device: "${device}"`))
}
}

View File

@@ -1,153 +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 ImageWriter = require('../sdk/writer')
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 = {
write: new visuals.Progress('Flashing'),
check: new visuals.Progress('Validating')
}
return new Bluebird((resolve, reject) => {
/**
* @summary Progress update handler
* @param {Object} state - progress state
* @private
* @example
* writer.on('progress', onProgress)
*/
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 === 'write' ? 'Flashing' : 'Validating'}: ${state.message}`
// Update progress bar
progressBars[state.type].update(state)
}
const writer = new ImageWriter({
verify: options.check,
unmountOnSuccess: options.unmount,
checksumAlgorithms: options.check ? [ 'sha512' ] : []
})
/**
* @summary Finish handler
* @private
* @example
* writer.on('finish', onFinish)
*/
const onFinish = function () {
resolve(Array.from(writer.destinations.values()))
}
writer.on('progress', onProgress)
writer.on('error', reject)
writer.on('finish', onFinish)
// NOTE: Drive can be (String|Array)
const destinations = [].concat(answers.drive)
writer.write(imagePath, destinations)
})
}).then((results) => {
let exitCode = EXIT_CODES.SUCCESS
if (options.check) {
console.log('')
console.log('Checksums:')
_.forEach(results, (result) => {
if (result.error) {
exitCode = EXIT_CODES.GENERAL_ERROR
console.log(` - ${result.device.device}: ${result.error.message}`)
} else {
console.log(` - ${result.device.device}: ${result.checksum.sha512}`)
}
})
}
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/resin-io/etcher/issues/new',
' Forums: https://forums.resin.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

@@ -27,25 +27,29 @@ var angular = require('angular')
/* eslint-enable no-var */
const electron = require('electron')
const Bluebird = require('bluebird')
const semver = require('semver')
const EXIT_CODES = require('../../shared/exit-codes')
const messages = require('../../shared/messages')
const s3Packages = require('../../shared/s3-packages')
const release = require('../../shared/release')
const store = require('../../shared/store')
const errors = require('../../shared/errors')
const sdk = require('etcher-sdk')
const _ = require('lodash')
const uuidV4 = require('uuid/v4')
const EXIT_CODES = require('../../gui/app/modules/exit-codes')
const messages = require('../../gui/app/modules/messages')
const store = require('./models/store')
const packageJSON = require('../../../package.json')
const flashState = require('../../shared/models/flash-state')
const flashState = require('./models/flash-state')
// eslint-disable-next-line node/no-missing-require
const settings = require('./models/settings')
const windowProgress = require('./os/window-progress')
const analytics = require('./modules/analytics')
const updateNotifier = require('./components/update-notifier')
const availableDrives = require('../../shared/models/available-drives')
const selectionState = require('../../shared/models/selection-state')
const availableDrives = require('./models/available-drives')
const selectionState = require('./models/selection-state')
const driveScanner = require('./modules/drive-scanner')
const osDialog = require('./os/dialog')
const exceptionReporter = require('./modules/exception-reporter')
const updateLock = require('./modules/update-lock')
// eslint-disable-next-line node/no-missing-require
const screensaver = require('./modules/screensaver')
/* eslint-disable lodash/prefer-lodash-method,lodash/prefer-get */
// Enable debug information from all modules that use `debug`
// See https://github.com/visionmedia/debug#browser-support
@@ -55,6 +59,30 @@ const exceptionReporter = require('./modules/exception-reporter')
process.env.DRIVELIST_DEBUG = /drivelist|^\*$/i.test(process.env.DEBUG) ? '1' : ''
window.localStorage.debug = process.env.DEBUG
window.addEventListener('unhandledrejection', (event) => {
// Promise: event.reason
// Bluebird: event.detail.reason
// Anything else: event
const error = event.reason || (event.detail && event.detail.reason) || event
analytics.logException(error)
event.preventDefault()
})
// Set application session UUID
store.dispatch({
type: store.Actions.SET_APPLICATION_SESSION_UUID,
data: uuidV4()
})
// Set first flashing workflow UUID
store.dispatch({
type: store.Actions.SET_FLASHING_WORKFLOW_UUID,
data: uuidV4()
})
const applicationSessionUuid = store.getState().toJS().applicationSessionUuid
const flashingWorkflowUuid = store.getState().toJS().flashingWorkflowUuid
const app = angular.module('Etcher', [
require('angular-ui-router'),
require('angular-ui-bootstrap'),
@@ -64,6 +92,7 @@ const app = angular.module('Etcher', [
require('./components/svg-icon'),
require('./components/warning-modal/warning-modal'),
require('./components/safe-webview'),
require('./components/file-selector'),
// Pages
require('./pages/main/main'),
@@ -88,7 +117,7 @@ app.run(() => {
'\\____/ \\__\\___|_| |_|\\___|_|',
'',
'Interested in joining the Etcher team?',
'Drop us a line at join+etcher@resin.io',
'Drop us a line at join+etcher@balena.io',
'',
`Version = ${packageJSON.version}, Type = ${packageJSON.packageType}`
].join('\n'))
@@ -99,84 +128,13 @@ app.run(() => {
analytics.logEvent('Application start', {
packageType: packageJSON.packageType,
version: currentVersion
version: currentVersion,
applicationSessionUuid
})
const shouldCheckForUpdates = updateNotifier.shouldCheckForUpdates({
currentVersion,
lastSleptUpdateNotifier: settings.get('lastSleptUpdateNotifier'),
lastSleptUpdateNotifierVersion: settings.get('lastSleptUpdateNotifierVersion')
})
const isStableRelease = release.isStableRelease(currentVersion)
const updatesEnabled = settings.get('updatesEnabled')
if (!shouldCheckForUpdates || !updatesEnabled) {
analytics.logEvent('Not checking for updates', {
shouldCheckForUpdates,
updatesEnabled,
stable: isStableRelease
})
return Bluebird.resolve()
}
const updateSemverRange = packageJSON.updates.semverRange
const includeUnstableChannel = settings.get('includeUnstableUpdateChannel')
analytics.logEvent('Checking for updates', {
currentVersion,
stable: isStableRelease,
updateSemverRange,
includeUnstableChannel
})
return s3Packages.getLatestVersion(release.getReleaseType(currentVersion), {
range: updateSemverRange,
includeUnstableChannel
}).then((latestVersion) => {
if (semver.gte(currentVersion, latestVersion || '0.0.0')) {
analytics.logEvent('Update notification skipped', {
reason: 'Latest version'
})
return Bluebird.resolve()
}
// In case the internet connection is not good and checking the
// latest published version takes too long, only show notify
// the user about the new version if he didn't start the flash
// process (e.g: selected an image), otherwise such interruption
// might be annoying.
if (selectionState.hasImage()) {
analytics.logEvent('Update notification skipped', {
reason: 'Image selected'
})
return Bluebird.resolve()
}
analytics.logEvent('Notifying update', {
latestVersion
})
return updateNotifier.notify(latestVersion, {
allowSleepUpdateCheck: isStableRelease
})
// If the error is an update user error, then we don't want
// to bother users each time they open the app.
// See: https://github.com/resin-io/etcher/issues/1525
}).catch((error) => {
return errors.isUserError(error) && error.code === 'UPDATE_USER_ERROR'
}, (error) => {
analytics.logEvent('Update check user error', {
title: errors.getTitle(error),
description: errors.getDescription(error)
})
}).catch(exceptionReporter.report)
})
app.run(() => {
store.subscribe(() => {
store.observe(() => {
if (!flashState.isFlashing()) {
return
}
@@ -202,16 +160,160 @@ app.run(() => {
})
})
/**
* @summary The radix used by USB ID numbers
* @type {Number}
* @constant
*/
const USB_ID_RADIX = 16
/**
* @summary The expected length of a USB ID number
* @type {Number}
* @constant
*/
const USB_ID_LENGTH = 4
/**
* @summary Convert a USB id (e.g. product/vendor) to a string
* @function
* @private
*
* @param {Number} id - USB id
* @returns {String} string id
*
* @example
* console.log(usbIdToString(2652))
* > '0x0a5c'
*/
const usbIdToString = (id) => {
return `0x${_.padStart(id.toString(USB_ID_RADIX), USB_ID_LENGTH, '0')}`
}
/**
* @summary Product ID of BCM2708
* @type {Number}
* @constant
*/
const USB_PRODUCT_ID_BCM2708_BOOT = 0x2763
/**
* @summary Product ID of BCM2710
* @type {Number}
* @constant
*/
const USB_PRODUCT_ID_BCM2710_BOOT = 0x2764
/**
* @summary Compute module descriptions
* @type {Object}
* @constant
*/
const COMPUTE_MODULE_DESCRIPTIONS = {
[USB_PRODUCT_ID_BCM2708_BOOT]: 'Compute Module 1',
[USB_PRODUCT_ID_BCM2710_BOOT]: 'Compute Module 3'
}
app.run(($timeout) => {
driveScanner.on('devices', (drives) => {
const BLACKLISTED_DRIVES = settings.has('driveBlacklist')
? settings.get('driveBlacklist').split(',')
: []
// eslint-disable-next-line require-jsdoc
const driveIsAllowed = (drive) => {
return !(
BLACKLISTED_DRIVES.includes(drive.devicePath) ||
BLACKLISTED_DRIVES.includes(drive.device) ||
BLACKLISTED_DRIVES.includes(drive.raw)
)
}
// eslint-disable-next-line require-jsdoc,consistent-return
const prepareDrive = (drive) => {
if (drive instanceof sdk.sourceDestination.BlockDevice) {
return drive.drive
} else if (drive instanceof sdk.sourceDestination.UsbbootDrive) {
// This is a workaround etcher expecting a device string and a size
drive.device = drive.usbDevice.portId
drive.size = null
drive.progress = 0
drive.disabled = true
drive.on('progress', (progress) => {
updateDriveProgress(drive, progress)
})
return drive
} else if (drive instanceof sdk.sourceDestination.DriverlessDevice) {
const description = COMPUTE_MODULE_DESCRIPTIONS[drive.deviceDescriptor.idProduct] || 'Compute Module'
return {
device: `${usbIdToString(drive.deviceDescriptor.idVendor)}:${usbIdToString(drive.deviceDescriptor.idProduct)}`,
displayName: 'Missing drivers',
description,
mountpoints: [],
isReadOnly: false,
isSystem: false,
disabled: true,
icon: 'warning',
size: null,
link: 'https://www.raspberrypi.org/documentation/hardware/computemodule/cm-emmc-flashing.md',
linkCTA: 'Install',
linkTitle: 'Install missing drivers',
linkMessage: [
'Would you like to download the necessary drivers from the Raspberry Pi Foundation?',
'This will open your browser.\n\n',
'Once opened, download and run the installer from the "Windows Installer" section to install the drivers.'
].join(' ')
}
}
}
// eslint-disable-next-line require-jsdoc
const setDrives = (drives) => {
availableDrives.setDrives(_.values(drives))
// Safely trigger a digest cycle.
// In some cases, AngularJS doesn't acknowledge that the
// available drives list has changed, and incorrectly
// keeps asking the user to "Connect a drive".
$timeout(() => {
availableDrives.setDrives(drives)
})
})
$timeout()
}
// eslint-disable-next-line require-jsdoc
const getDrives = () => {
return _.keyBy(availableDrives.getDrives() || [], 'device')
}
// eslint-disable-next-line require-jsdoc
const addDrive = (drive) => {
const preparedDrive = prepareDrive(drive)
if (!driveIsAllowed(preparedDrive)) {
return
}
const drives = getDrives()
drives[preparedDrive.device] = preparedDrive
setDrives(drives)
}
// eslint-disable-next-line require-jsdoc
const removeDrive = (drive) => {
const preparedDrive = prepareDrive(drive)
const drives = getDrives()
// eslint-disable-next-line prefer-reflect
delete drives[preparedDrive.device]
setDrives(drives)
}
// eslint-disable-next-line require-jsdoc
const updateDriveProgress = (drive, progress) => {
const drives = getDrives()
const driveInMap = drives[drive.device]
if (driveInMap) {
driveInMap.progress = progress
setDrives(drives)
}
}
driveScanner.on('attach', addDrive)
driveScanner.on('detach', removeDrive)
driveScanner.on('error', (error) => {
// Stop the drive scanning loop in case of errors,
@@ -232,7 +334,8 @@ app.run(($window) => {
$window.addEventListener('beforeunload', (event) => {
if (!flashState.isFlashing() || popupExists) {
analytics.logEvent('Close application', {
isFlashing: flashState.isFlashing()
isFlashing: flashState.isFlashing(),
applicationSessionUuid
})
return
}
@@ -243,7 +346,7 @@ app.run(($window) => {
// Don't open any more popups
popupExists = true
analytics.logEvent('Close attempt while flashing')
analytics.logEvent('Close attempt while flashing', { applicationSessionUuid, flashingWorkflowUuid })
osDialog.showWarning({
confirmationLabel: 'Yes, quit',
@@ -253,7 +356,9 @@ app.run(($window) => {
}).then((confirmed) => {
if (confirmed) {
analytics.logEvent('Close confirmed while flashing', {
uuid: flashState.getFlashUuid()
flashInstanceUuid: flashState.getFlashUuid(),
applicationSessionUuid,
flashingWorkflowUuid
})
// This circumvents the 'beforeunload' event unlike
@@ -261,10 +366,27 @@ app.run(($window) => {
electron.remote.process.exit(EXIT_CODES.SUCCESS)
}
analytics.logEvent('Close rejected while flashing')
analytics.logEvent('Close rejected while flashing', { applicationSessionUuid, flashingWorkflowUuid })
popupExists = false
}).catch(exceptionReporter.report)
})
/**
* @summary Helper fn for events
* @function
* @private
* @example
* window.addEventListener('click', extendLock)
*/
const extendLock = () => {
updateLock.extend()
}
$window.addEventListener('click', extendLock)
$window.addEventListener('touchstart', extendLock)
// Initial update lock acquisition
extendLock()
})
app.run(($rootScope) => {
@@ -276,7 +398,8 @@ app.run(($rootScope) => {
analytics.logEvent('Navigate', {
to: toState.name,
from: fromState.name
from: fromState.name,
applicationSessionUuid
})
})
})
@@ -294,6 +417,13 @@ app.config(($provide) => {
})
})
app.config(($locationProvider) => {
// NOTE(Shou): this seems to invoke a minor perf decrease when set to true
$locationProvider.html5Mode({
rewriteLinks: false
})
})
app.controller('HeaderController', function (OSOpenExternalService) {
/**
* @summary Open help page
@@ -312,6 +442,46 @@ app.controller('HeaderController', function (OSOpenExternalService) {
const supportUrl = selectionState.getImageSupportUrl() || DEFAULT_SUPPORT_URL
OSOpenExternalService.open(supportUrl)
}
/**
* @summary Whether to show the help link
* @function
* @public
*
* @returns {Boolean}
*
* @example
* HeaderController.shouldShowHelp()
*/
this.shouldShowHelp = () => {
return !settings.get('disableExternalLinks')
}
/**
* @summary Whether to show the sleep button
* @function
* @public
*
* @returns {Boolean}
*
* @example
* HeaderController.shouldShowSleep()
*/
this.shouldShowSleep = () => {
return settings.get('showScreensaverDelay')
}
/**
* @summary Enables the screensaver
* @function
* @public
*
* @example
* HeaderController.sleep()
*/
this.sleep = () => {
screensaver.off()
}
})
app.controller('StateController', function ($rootScope, $scope) {
@@ -365,3 +535,5 @@ angular.element(document).ready(() => {
angular.bootstrap(document, [ 'Etcher' ])
}).catch(exceptionReporter.report)
})
screensaver.init()

View File

@@ -0,0 +1,32 @@
/*
* Copyright 2018 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'
/**
* @module Etcher.Components.ConfirmModal
*/
const angular = require('angular')
const MODULE_NAME = 'Etcher.Components.ConfirmModal'
const ConfirmModal = angular.module(MODULE_NAME, [
require('../modal/modal')
])
ConfirmModal.controller('ConfirmModalController', require('./controllers/confirm-modal'))
ConfirmModal.service('ConfirmModalService', require('./services/confirm-modal'))
module.exports = MODULE_NAME

View File

@@ -0,0 +1,50 @@
/*
* Copyright 2018 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'
module.exports = function ($uibModalInstance, options) {
/**
* @summary Modal options
* @type {Object}
* @public
*/
this.options = options
/**
* @summary Reject the warning prompt
* @function
* @public
*
* @example
* WarningModalController.reject();
*/
this.reject = () => {
$uibModalInstance.close(false)
}
/**
* @summary Accept the warning prompt
* @function
* @public
*
* @example
* WarningModalController.accept();
*/
this.accept = () => {
$uibModalInstance.close(true)
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright 2018 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')
module.exports = function ($sce, ModalService) {
/**
* @summary show the confirm modal
* @function
* @public
*
* @param {Object} options - options
* @param {String} options.description - danger message
* @param {String} options.confirmationLabel - confirmation button text
* @param {String} options.rejectionLabel - rejection button text
* @fulfil {Boolean} - whether the user accepted or rejected the confirm
* @returns {Promise}
*
* @example
* ConfirmModalService.show({
* description: 'Don\'t do this!',
* confirmationLabel: 'Yes, continue!'
* });
*/
this.show = (options = {}) => {
options.description = $sce.trustAsHtml(options.description)
return ModalService.open({
name: 'confirm',
template: require('../templates/confirm-modal.tpl.html'),
controller: 'ConfirmModalController as modal',
size: 'confirm-modal',
resolve: {
options: _.constant(options)
}
}).result
}
}

View File

@@ -0,0 +1,28 @@
/*
* 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.
*/
.modal-confirm-modal .modal-content {
width: 350px;
}
.modal-confirm-modal .modal-title .glyphicon {
color: $palette-theme-danger-background;
}
.modal-confirm-modal .modal-body {
max-height: 200px;
overflow-y: auto;
}

View File

@@ -0,0 +1,36 @@
<div class="modal-header">
<h4 class="modal-title">
<span>{{ ::modal.options.title }}</span>
</h4>
<button class="close"
tabindex="11"
ng-click="modal.reject()">&times;</button>
</div>
<div class="modal-body">
<p>{{ ::modal.options.message }}</p>
</div>
<div class="modal-footer">
<div class="modal-menu">
<button ng-if="modal.options.rejectionLabel" class="button button-block"
tabindex="12"
ng-class="{
'button-default': modal.options.cancelButton === 'default',
'button-primary': modal.options.cancelButton === 'primary',
'button-warning': modal.options.cancelButton === 'warning',
'button-danger': modal.options.cancelButton === 'danger',
}"
ng-click="modal.reject()">{{ ::modal.options.rejectionLabel }}</button>
<button class="button button-block"
tabindex="13"
ng-class="{
'button-default': modal.options.confirmButton === 'default',
'button-primary': modal.options.confirmButton === 'primary',
'button-warning': modal.options.confirmButton === 'warning',
'button-danger': modal.options.confirmButton === 'danger',
}"
ng-click="modal.accept()">{{ ::modal.options.confirmationLabel }}</button>
</div>
</div>

View File

@@ -18,15 +18,20 @@
const angular = require('angular')
const _ = require('lodash')
const constraints = require('../../../../../shared/drive-constraints')
const Bluebird = require('bluebird')
const constraints = require('../../../../../gui/app/modules/drive-constraints')
const store = require('../../../models/store')
const analytics = require('../../../modules/analytics')
const availableDrives = require('../../../../../shared/models/available-drives')
const selectionState = require('../../../../../shared/models/selection-state')
const utils = require('../../../../../shared/utils')
const availableDrives = require('../../../models/available-drives')
const selectionState = require('../../../models/selection-state')
// eslint-disable-next-line node/no-missing-require
const utils = require('../../../../../gui/app/modules/utils')
module.exports = function (
$q,
$uibModalInstance
$uibModalInstance,
ConfirmModalService,
OSOpenExternalService
) {
/**
* @summary The drive selector state
@@ -93,14 +98,60 @@ module.exports = function (
if (canChangeDriveSelectionState) {
analytics.logEvent('Toggle drive', {
drive,
previouslySelected: selectionState.isCurrentDrive(drive.device)
previouslySelected: selectionState.isCurrentDrive(drive.device),
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
})
selectionState.toggleDrive(drive.device)
}
return Bluebird.resolve()
})
}
/**
* @summary Prompt the user to install missing usbboot drivers
* @function
* @public
*
* @param {Object} drive - drive
* @returns {Promise} - resolved promise
*
* @example
* DriveSelectorController.installMissingDrivers({
* linkTitle: 'Go to example.com',
* linkMessage: 'Examples are great, right?',
* linkCTA: 'Call To Action',
* link: 'https://example.com'
* });
*/
this.installMissingDrivers = (drive) => {
if (drive.link) {
analytics.logEvent('Open driver link modal', {
url: drive.link,
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
})
return ConfirmModalService.show({
confirmationLabel: 'Yes, continue',
rejectionLabel: 'Cancel',
title: drive.linkTitle,
confirmButton: 'primary',
message: drive.linkMessage || `Etcher will open ${drive.link} in your browser`
}).then((shouldContinue) => {
if (shouldContinue) {
OSOpenExternalService.open(drive.link)
}
}).catch((error) => {
analytics.logException(error)
})
}
return Bluebird.resolve()
}
/**
* @summary Close the modal and resolve the selected drive
* @function
@@ -142,7 +193,10 @@ module.exports = function (
if (canChangeDriveSelectionState) {
selectionState.selectDrive(drive.device)
analytics.logEvent('Drive selected (double click)')
analytics.logEvent('Drive selected (double click)', {
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
})
this.closeModal()
}

View File

@@ -24,7 +24,9 @@ const angular = require('angular')
const MODULE_NAME = 'Etcher.Components.DriveSelector'
const DriveSelector = angular.module(MODULE_NAME, [
require('../modal/modal'),
require('../../utils/byte-size/byte-size')
require('../confirm-modal/confirm-modal'),
require('../../utils/byte-size/byte-size'),
require('../../os/open-external/open-external')
])
DriveSelector.controller('DriveSelectorController', require('./controllers/drive-selector'))

View File

@@ -0,0 +1,32 @@
/*
* Copyright 2019 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.
*/
/**
* @module Etcher.Components.TargetSelector
*/
import * as angular from 'angular';
import { react2angular } from 'react2angular';
const MODULE_NAME = 'Etcher.Components.TargetSelector';
const SelectTargetButton = angular.module(MODULE_NAME, []);
SelectTargetButton.component(
'targetSelector',
react2angular(require('./target-selector.jsx')),
);
export = MODULE_NAME;

View File

@@ -0,0 +1,166 @@
/*
* Copyright 2019 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.
*/
/* eslint-disable no-magic-numbers */
'use strict'
// eslint-disable-next-line no-unused-vars
const React = require('react')
const propTypes = require('prop-types')
const { default: styled } = require('styled-components')
const {
ChangeButton,
DetailsText,
StepButton,
StepNameButton,
ThemedProvider
} = require('./../../styled-components')
const { Txt } = require('rendition')
const middleEllipsis = require('./../../utils/middle-ellipsis')
const { bytesToClosestUnit } = require('./../../../../gui/app/modules/units')
const TargetDetail = styled((props) => (
<Txt.span {...props}>
</Txt.span>
)) `
float: ${({ float }) => float}
`
const TargetDisplayText = ({
description,
size,
...props
}) => {
return (
<Txt.span {...props}>
<TargetDetail
float='left'>
{description}
</TargetDetail>
<TargetDetail
float='right'
>
{size}
</TargetDetail>
</Txt.span>
)
}
const TargetSelector = (props) => {
const targets = props.selection.getSelectedDrives()
if (targets.length === 1) {
const target = targets[0]
return (
<ThemedProvider>
<StepNameButton
plain
tooltip={props.tooltip}
>
{/* eslint-disable no-magic-numbers */}
{ middleEllipsis(target.description, 20) }
</StepNameButton>
{ !props.flashing &&
<ChangeButton
plain
mb={14}
onClick={props.reselectDrive}
>
Change
</ChangeButton>
}
<DetailsText>
{ props.constraints.hasListDriveImageCompatibilityStatus(targets, props.image) &&
<Txt.span className='glyphicon glyphicon-exclamation-sign'
ml={2}
tooltip={
props.constraints.getListDriveImageCompatibilityStatuses(targets, props.image)[0].message
}
/>
}
{ bytesToClosestUnit(target.size) }
</DetailsText>
</ThemedProvider>
)
}
if (targets.length > 1) {
const targetsTemplate = []
for (const target of targets) {
targetsTemplate.push((
<DetailsText
key={target.device}
tooltip={
`${target.description} ${target.displayName} ${bytesToClosestUnit(target.size)}`
}
px={21}
>
<TargetDisplayText
description={middleEllipsis(target.description, 14)}
size={bytesToClosestUnit(target.size)}
>
</TargetDisplayText>
</DetailsText>
))
}
return (
<ThemedProvider>
<StepNameButton
plain
tooltip={props.tooltip}
>
{targets.length} Targets
</StepNameButton>
{ !props.flashing &&
<ChangeButton
plain
onClick={props.reselectDrive}
mb={14}
>
Change
</ChangeButton>
}
{targetsTemplate}
</ThemedProvider>
)
}
return (
<ThemedProvider>
<StepButton
tabindex={(targets.length > 0) ? -1 : 2 }
disabled={props.disabled}
onClick={props.openDriveSelector}
>
Select target
</StepButton>
</ThemedProvider>
)
}
TargetSelector.propTypes = {
disabled: propTypes.bool,
openDriveSelector: propTypes.func,
selection: propTypes.object,
reselectDrive: propTypes.func,
flashing: propTypes.bool,
constraints: propTypes.object,
show: propTypes.bool,
tooltip: propTypes.string
}
module.exports = TargetSelector

View File

@@ -23,7 +23,8 @@
<span class="word-keep"
ng-show="drive.size"> - {{ drive.size | closestUnit }}</span>
</h4>
<p class="list-group-item-text">{{ drive.displayName }}</p>
<p class="list-group-item-text" ng-if="!drive.link">{{ drive.displayName }}</p>
<p class="list-group-item-text" ng-if="drive.link">{{ drive.displayName }} - <b><a ng-click="modal.installMissingDrivers(drive)">{{ drive.linkCTA }}</a></b></p>
<footer class="list-group-item-footer">
@@ -51,7 +52,7 @@
</div>
<div class="modal-footer">
<button class="button button-primary button-block"
<button class="button button-primary"
tabindex="{{ 15 + modal.getDrives().length }}"
ng-class="{
'button-warning': modal.constraints.hasListDriveImageCompatibilityStatus(modal.state.getSelectedDrives(), modal.state.getImage())

View File

@@ -0,0 +1,264 @@
/*
* Copyright 2019 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.
*/
import { Meter } from 'grommet';
import { sortBy } from 'lodash';
import * as React from 'react';
import { Badge, Modal, Table } from 'rendition';
import { getDrives } from '../../models/available-drives';
import { COMPATIBILITY_STATUS_TYPES } from '../../modules/drive-constraints';
import { subscribe } from '../../models/store';
import { ThemedProvider } from '../../styled-components';
import { bytesToClosestUnit } from '../../modules/units';
interface Drive {
description: string;
device: string;
isSystem: boolean;
isReadOnly: boolean;
progress?: number;
size?: number;
link?: string;
linkCTA?: string;
displayName: string;
}
interface CompatibilityStatus {
type: number;
message: string;
}
interface DriveSelectorProps {
title: string;
close: () => void;
setSelectedDrives: (drives: Drive[]) => void;
isDriveSelected: (drive: Drive) => boolean;
isDriveValid: (drive: Drive) => boolean;
getDriveBadges: (drive: Drive) => CompatibilityStatus[];
}
interface DriveSelectorState {
drives: Drive[];
selected: Drive[];
disabledDrives: string[];
}
const modalStyle = {
width: '800px',
height: '600px',
paddingTop: '20px',
paddingLeft: '30px',
paddingRight: '30px',
paddingBottom: '11px',
};
const titleStyle = {
color: '#2a506f',
};
const subtitleStyle = {
marginLeft: '10px',
fontSize: '11px',
color: '#5b82a7',
};
const wrapperStyle = {
height: '250px',
overflowX: 'hidden' as 'hidden',
overflowY: 'auto' as 'auto',
};
export class DriveSelector2 extends React.Component<
DriveSelectorProps,
DriveSelectorState
> {
private table: Table<Drive> | null = null;
private columns: {
field: keyof Drive;
label: string;
render?: (value: any, row: Drive) => string | number | JSX.Element | null;
}[];
private unsubscribe?: () => void;
constructor(props: DriveSelectorProps) {
super(props);
this.columns = [
{
field: 'description',
label: 'Name',
} as const,
{
field: 'size',
label: 'Size',
render: this.renderSize.bind(this),
} as const,
{
field: 'displayName',
label: 'Location',
render: this.renderLocation.bind(this),
} as const,
{
field: 'isReadOnly', // We don't use this, but a valid field that is not used in another column is required
label: ' ',
render: this.renderBadges.bind(this),
} as const,
];
this.state = this.getNewState();
}
public componentDidMount() {
this.update();
if (this.unsubscribe === undefined) {
this.unsubscribe = subscribe(this.update.bind(this));
}
}
public componentWillUnmount() {
if (this.unsubscribe !== undefined) {
this.unsubscribe();
this.unsubscribe = undefined;
}
}
private getNewState() {
let drives: Drive[] = getDrives();
for (let i = 0; i < drives.length; i++) {
drives[i] = { ...drives[i] };
}
drives = sortBy(drives, 'device');
const selected = drives.filter(d => this.props.isDriveSelected(d));
const disabledDrives = drives
.filter(d => !this.props.isDriveValid(d))
.map(d => d.device);
return { drives, disabledDrives, selected };
}
private update() {
this.setState(this.getNewState());
this.updateTableSelection();
}
private updateTableSelection() {
if (this.table !== null) {
this.table.setRowSelection(this.state.selected);
}
}
private renderSize(size: number) {
if (size) {
return bytesToClosestUnit(size);
} else {
return null;
}
}
private renderLocation(displayName: string, drive: Drive) {
const result: Array<string | JSX.Element> = [displayName];
if (drive.link && drive.linkCTA) {
result.push(<a href={drive.link}>{drive.linkCTA}</a>);
}
return <React.Fragment>{result}</React.Fragment>;
}
private renderBadges(_value: any, row: Drive) {
const result = [];
if (row.progress !== undefined) {
result.push(
<Meter
size="small"
thickness="xxsmall"
values={[
{
value: row.progress,
label: row.progress + '%',
color: '#2297de',
},
]}
/>,
);
}
result.push(
...this.props.getDriveBadges(row).map((status: CompatibilityStatus) => {
const props: {
key: string;
xsmall: true;
danger?: boolean;
warning?: boolean;
} = { xsmall: true, key: status.message };
if (status.type === COMPATIBILITY_STATUS_TYPES.ERROR) {
props.danger = true;
} else if (status.type === COMPATIBILITY_STATUS_TYPES.WARNING) {
props.warning = true;
}
return <Badge {...props}>{status.message}</Badge>;
}),
);
return <React.Fragment>{result}</React.Fragment>;
}
private renderTbodyPrefix() {
if (this.state.drives.length === 0) {
return (
<tr>
<td colSpan={this.columns.length} style={{ textAlign: 'center' }}>
<b>Connect a drive</b>
<div>No removable drive detected.</div>
</td>
</tr>
);
}
}
public render() {
return (
<ThemedProvider>
<Modal
titleElement={
<div style={titleStyle}>
{this.props.title}
<span style={subtitleStyle}>
{this.state.drives.length} found
</span>
</div>
}
action={`Select (${this.state.selected.length})`}
style={modalStyle}
done={this.props.close}
>
<div style={wrapperStyle}>
<Table<Drive>
ref={t => {
this.table = t;
this.updateTableSelection();
}}
rowKey="device"
onCheck={this.onCheck.bind(this)}
columns={this.columns}
data={this.state.drives}
disabledRows={this.state.disabledDrives}
tbodyPrefix={this.renderTbodyPrefix()}
/>
</div>
</Modal>
</ThemedProvider>
);
}
private onCheck(checkedDrives: Drive[]): void {
this.props.setSelectedDrives(checkedDrives);
}
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright 2019 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.
*/
import * as angular from 'angular';
import { react2angular } from 'react2angular';
import { DriveSelector2 } from './drive-selector.tsx';
const MODULE_NAME = 'Etcher.Components.DriveSelector2';
angular
.module(MODULE_NAME, [])
.component(
'driveSelector2',
react2angular(DriveSelector2, [
'close',
'getDriveBadges',
'isDriveSelected',
'isDriveValid',
'setSelectedDrives',
'title',
]),
);
export = MODULE_NAME;

View File

@@ -0,0 +1,57 @@
/*
* 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 React = require('react')
const propTypes = require('prop-types')
const SafeWebview = require('../safe-webview/safe-webview.jsx')
const settings = require('../../models/settings')
const analytics = require('../../modules/analytics')
class FeaturedProject extends React.Component {
constructor (props) {
super(props)
this.state = {
endpoint: null
}
}
componentDidMount () {
return settings.load()
.then(() => {
const endpoint = settings.get('featuredProjectEndpoint') || 'https://assets.balena.io/etcher-featured/index.html'
this.setState({ endpoint })
})
.catch(analytics.logException)
}
render () {
return (this.state.endpoint) ? (
<SafeWebview
src={this.state.endpoint}
{...this.props}>
</SafeWebview>
) : null
}
}
FeaturedProject.propTypes = {
onWebviewShow: propTypes.func
}
module.exports = FeaturedProject

View File

@@ -17,28 +17,18 @@
'use strict'
/**
* @summary ProgressButton directive
* @function
* @public
*
* @description
* This directive provides a button containing a progress bar inside.
* The button is styled by default as a primary button.
*
* @returns {Object} directive
*
* @example
* <progress-button percentage="{{ 40 }}" striped>My Progress Button</progress-button>
* @module Etcher.Components.FeaturedProject
*/
module.exports = () => {
return {
template: require('../templates/progress-button.tpl.html'),
restrict: 'E',
replace: true,
transclude: true,
scope: {
percentage: '=',
striped: '@'
}
}
}
const angular = require('angular')
const { react2angular } = require('react2angular')
const MODULE_NAME = 'Etcher.Components.FeaturedProject'
const FeaturedProject = angular.module(MODULE_NAME, [])
FeaturedProject.component(
'featuredProject',
react2angular(require('./featured-project.jsx'))
)
module.exports = MODULE_NAME

View File

@@ -0,0 +1,74 @@
/*
* Copyright 2018 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 os = require('os')
// eslint-disable-next-line node/no-missing-require
const settings = require('../../../models/settings')
// eslint-disable-next-line node/no-missing-require
const utils = require('../../../../../gui/app/modules/utils')
const angular = require('angular')
/* eslint-disable lodash/prefer-lodash-method */
module.exports = function (
$uibModalInstance
) {
/**
* @summary Close the modal
* @function
* @public
*
* @example
* FileSelectorController.close();
*/
this.close = () => {
$uibModalInstance.close()
}
/**
* @summary Folder to constrain the file picker to
* @function
* @public
*
* @returns {String} - folder to constrain by
*
* @example
* FileSelectorController.getFolderConstraint()
*/
this.getFolderConstraint = utils.memoize(() => {
return settings.has('fileBrowserConstraintPath')
? settings.get('fileBrowserConstraintPath')
: ''
}, angular.equals)
/**
* @summary Get initial path
* @function
* @public
*
* @returns {String} - path
*
* @example
* <file-selector path="FileSelectorController.getPath()"></file-selector>
*/
this.getPath = () => {
const constraintFolderPath = this.getFolderConstraint()
return _.isEmpty(constraintFolderPath) ? os.homedir() : constraintFolderPath
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017 resin.io
* Copyright 2018 resin.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,32 +16,30 @@
'use strict'
const SDK = module.exports
/**
* @summary Initialised adapters
* @type {Object<String,Adapter>}
* @summary Color scheme
* @constant
* @private
*/
SDK.adapters = require('./adapters')
/**
* Adapter Scanner
* @see scanner.js
* @ignore
*/
SDK.Scanner = require('./scanner')
/**
* @summary Create a new Scanner
* @param {Object} [options] - options
* @returns {SDK.Scanner}
* @example
* SDK.createScanner({
* blockdevice: { ... },
* usbboot: { ... }
* })
*/
SDK.createScanner = (options) => {
return new SDK.Scanner(options)
const colors = {
primary: {
color: '#3a3c41',
background: '#ffffff',
subColor: '#ababab',
faded: '#c3c4c6'
},
secondary: {
color: '#1c1d1e',
background: '#ebeff4',
title: '#b3b6b9'
},
highlight: {
color: 'white',
background: '#2297de'
},
soft: {
color: '#4d5056'
}
}
module.exports = colors

View File

@@ -0,0 +1,321 @@
/*
* Copyright 2018 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 React = require('react')
const propTypes = require('prop-types')
const styled = require('styled-components').default
const rendition = require('rendition')
const colors = require('./colors')
const prettyBytes = require('pretty-bytes')
const files = require('../../../models/files')
const middleEllipsis = require('../../../utils/middle-ellipsis')
const supportedFormats = require('../../../../../gui/app/modules/supported-formats')
const debug = require('debug')('etcher:gui:file-selector')
/**
* @summary Character limit of a filename before a middle-ellipsis is added
* @constant
* @private
*/
const FILENAME_CHAR_LIMIT = 20
/**
* @summary Pattern to match all supported formats for highlighting
* @constant
* @private
*/
const SUPPORTED_FORMATS_PATTERN = new RegExp(`^\\.(${supportedFormats.getAllExtensions().join('|')})$`, 'i')
/**
* @summary Flex styled component
* @function
* @type {ReactElement}
*/
const Flex = styled.div`
display: flex;
flex: ${ props => props.flex };
flex-direction: ${ props => props.direction };
justify-content: ${ props => props.justifyContent };
align-items: ${ props => props.alignItems };
flex-wrap: ${ props => props.wrap };
flex-grow: ${ props => props.grow };
`
/**
* @summary Anchor flex styled component
* @function
* @type {ReactElement}
*/
const ClickableFlex = styled.a`
display: flex;
flex: ${ props => props.flex };
flex-direction: ${ props => props.direction };
justify-content: ${ props => props.justifyContent };
align-items: ${ props => props.alignItems };
flex-wrap: ${ props => props.wrap };
flex-grow: ${ props => props.grow };
`
/**
* @summary FileList scroll wrapper element
* @class
* @type {ReactElement}
*/
class UnstyledFileListWrap extends React.PureComponent {
constructor (props) {
super(props)
this.scrollElem = null
}
render () {
return (
<Flex className={ this.props.className }
ref={ ::this.setScrollElem }
wrap="wrap">
{ this.props.children }
</Flex>
)
}
setScrollElem (element) {
this.scrollElem = element
}
componentDidUpdate (prevProps) {
if (this.scrollElem) {
this.scrollElem.scrollTop = 0
}
}
}
/**
* @summary FileList scroll wrapper element
* @class
* @type {StyledComponent}
*/
const FileListWrap = styled(UnstyledFileListWrap)`
overflow-x: hidden;
overflow-y: auto;
padding: 0 20px;
`
/**
* @summary File element
* @class
* @type {ReactElement}
*/
class UnstyledFile extends React.PureComponent {
static getFileIconClass (file) {
return file.isDirectory
? 'fas fa-folder'
: 'fas fa-file-alt'
}
onHighlight (event) {
event.preventDefault()
this.props.onHighlight(this.props.file)
}
onSelect (event) {
event.preventDefault()
this.props.onSelect(this.props.file)
}
render () {
const file = this.props.file
return (
<ClickableFlex
data-path={ file.path }
href={ `file://${file.path}` }
direction="column"
alignItems="stretch"
className={ this.props.className }
onClick={ ::this.onHighlight }
onDoubleClick={ ::this.onSelect }>
<span className={ UnstyledFile.getFileIconClass(file) } />
<span>{ middleEllipsis(file.basename, FILENAME_CHAR_LIMIT) }</span>
<div>{ file.isDirectory ? '' : prettyBytes(file.size || 0) }</div>
</ClickableFlex>
)
}
}
/**
* @summary File element
* @class
* @type {StyledComponent}
*/
const File = styled(UnstyledFile)`
width: 100px;
min-height: 100px;
max-height: 128px;
margin: 5px 10px;
padding: 5px;
background-color: none;
transition: 0.05s background-color ease-out;
color: ${ colors.primary.color };
cursor: pointer;
border-radius: 5px;
word-break: break-word;
> span:first-of-type {
align-self: center;
line-height: 1;
margin-bottom: 6px;
font-size: 48px;
color: ${ props => props.disabled ? colors.primary.faded : colors.soft.color };
}
> span:last-of-type {
display: flex;
justify-content: center;
text-align: center;
font-size: 14px;
}
> div:last-child {
background-color: none;
color: ${ colors.primary.subColor };
text-align: center;
font-size: 12px;
}
:hover, :visited {
color: ${ colors.primary.color };
}
:focus,
:active {
color: ${ colors.highlight.color };
background-color: ${ colors.highlight.background };
}
:focus > span:first-of-type,
:active > span:first-of-type {
color: ${ colors.highlight.color };
}
:focus > div:last-child,
:active > div:last-child {
color: ${ colors.highlight.color };
}
`
/**
* @summary FileList element
* @class
* @type {ReactElement}
*/
class FileList extends React.Component {
constructor (props) {
super(props)
this.state = {
path: props.path,
highlighted: null,
files: [],
}
debug('FileList', props)
}
readdir (dirname) {
debug('FileList:readdir', dirname)
if (this.props.constraintPath && dirname === '/') {
if (this.props.constraint) {
const mountpoints = this.props.constraint.mountpoints.map(( mount ) => {
const entry = new files.FileEntry(mount.path, {
size: 0,
isFile: () => false,
isDirectory: () => true
})
entry.name = mount.label
return entry
})
debug('FileList:readdir', mountpoints)
window.requestAnimationFrame(() => {
this.setState({ files: mountpoints })
})
}
return
}
files.readdirAsync(dirname).then((files) => {
window.requestAnimationFrame(() => {
this.setState({ files: files })
})
})
}
componentDidMount () {
process.nextTick(() => {
this.readdir(this.state.path)
})
}
onHighlight (file) {
debug('FileList:onHighlight', file)
this.props.onHighlight(file)
}
onSelect (file) {
debug('FileList:onSelect', file.path, file.isDirectory)
this.props.onSelect(file)
}
shouldComponentUpdate (nextProps, nextState) {
const shouldUpdate = (this.state.files !== nextState.files)
debug('FileList:shouldComponentUpdate', shouldUpdate)
if (this.props.path !== nextProps.path || this.props.constraint !== nextProps.constraint) {
process.nextTick(() => {
this.readdir(nextProps.path)
})
}
return shouldUpdate
}
static isSelectable (file) {
return file.isDirectory || !file.ext ||
SUPPORTED_FORMATS_PATTERN.test(file.ext)
}
render () {
return (
<FileListWrap wrap="wrap">
{
this.state.files.map((file) => {
return (
<File key={ file.path }
file={ file }
disabled={ !FileList.isSelectable(file) }
onSelect={ ::this.onSelect }
onHighlight={ ::this.onHighlight }/>
)
})
}
</FileListWrap>
)
}
}
module.exports = FileList

View File

@@ -0,0 +1,358 @@
/*
* Copyright 2018 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 path = require('path')
const sdk = require('etcher-sdk')
const Bluebird = require('bluebird')
const React = require('react')
const propTypes = require('prop-types')
const styled = require('styled-components').default
const rendition = require('rendition')
const colors = require('./colors')
const Breadcrumbs = require('./path-breadcrumbs')
const FileList = require('./file-list')
const RecentFiles = require('./recent-files')
const files = require('../../../models/files')
const selectionState = require('../../../models/selection-state')
const store = require('../../../models/store')
const osDialog = require('../../../os/dialog')
const exceptionReporter = require('../../../modules/exception-reporter')
const messages = require('../../../../../gui/app/modules/messages')
const errors = require('../../../../../gui/app/modules/errors')
const supportedFormats = require('../../../../../gui/app/modules/supported-formats')
const analytics = require('../../../modules/analytics')
const debug = require('debug')('etcher:gui:file-selector')
/**
* @summary Flex styled component
* @function
* @type {ReactElement}
*/
const Flex = styled.div`
display: flex;
flex: ${ props => props.flex };
flex-direction: ${ props => props.direction };
justify-content: ${ props => props.justifyContent };
align-items: ${ props => props.alignItems };
flex-wrap: ${ props => props.wrap };
flex-grow: ${ props => props.grow };
overflow: ${ props => props.overflow };
`
const Header = styled(Flex) `
padding: 10px 15px 0;
border-bottom: 1px solid ${ colors.primary.faded };
> * {
margin: 5px;
}
`
const Main = styled(Flex) ``
const Footer = styled(Flex) `
padding: 10px;
flex: 0 0 auto;
border-top: 1px solid ${ colors.primary.faded };
> * {
margin: 0 10px;
}
> button {
flex-grow: 0;
flex-shrink: 0;
}
`
class UnstyledFilePath extends React.PureComponent {
render () {
return (
<div className={ this.props.className }>
<span>{
this.props.file && !this.props.file.isDirectory
? this.props.file.basename
: ''
}</span>
</div>
)
}
}
const FilePath = styled(UnstyledFilePath)`
display: flex;
flex-grow: 1;
align-items: center;
overflow: hidden;
> span {
font-size: 16px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
`
class FileSelector extends React.PureComponent {
constructor (props) {
super(props)
this.state = {
path: props.path,
highlighted: null,
constraint: null,
files: [],
}
}
componentDidMount() {
if (this.props.constraintpath) {
const device = files.getConstraintDevice(this.props.constraintpath)
debug('FileSelector:getConstraintDevice', device)
if (device !== undefined) {
this.setState({ constraint: device.drive })
}
}
}
confirmSelection () {
if (this.state.highlighted) {
this.selectFile(this.state.highlighted)
}
}
close () {
this.props.close()
}
componentDidUpdate () {
debug('FileSelector:componentDidUpdate')
}
containPath (newPath) {
if (this.state.constraint) {
const isContained = this.state.constraint.mountpoints.some((mount) => {
return !path.relative(mount.path, newPath).startsWith('..')
})
if (!isContained) {
return '/'
}
}
return newPath
}
navigate (newPath) {
debug('FileSelector:navigate', newPath)
this.setState({ path: this.containPath(newPath) })
}
navigateUp () {
let newPath = this.containPath(path.join(this.state.path, '..'))
debug('FileSelector:navigateUp', this.state.path, '->', newPath)
this.setState({ path: newPath })
}
selectImage (image) {
debug('FileSelector:selectImage', image)
if (!supportedFormats.isSupportedImage(image.path)) {
const invalidImageError = errors.createUserError({
title: 'Invalid image',
description: messages.error.invalidImage(image.path)
})
osDialog.showError(invalidImageError)
analytics.logEvent('Invalid image', {
image,
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
})
return Bluebird.resolve()
}
return Bluebird.try(() => {
let message = null
if (supportedFormats.looksLikeWindowsImage(image.path)) {
analytics.logEvent('Possibly Windows image', {
image,
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
})
message = messages.warning.looksLikeWindowsImage()
} else if (!image.hasMBR) {
analytics.logEvent('Missing partition table', {
image,
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
})
message = messages.warning.missingPartitionTable()
}
if (message) {
// TODO: `Continue` should be on a red background (dangerous action) instead of `Change`.
// We want `X` to act as `Continue`, that's why `Continue` is the `rejectionLabel`
return osDialog.showWarning({
confirmationLabel: 'Change',
rejectionLabel: 'Continue',
title: 'Warning',
description: message
})
}
return false
}).then((shouldChange) => {
if (shouldChange) {
return
}
selectionState.selectImage(image)
this.close()
// An easy way so we can quickly identify if we're making use of
// certain features without printing pages of text to DevTools.
image.logo = Boolean(image.logo)
image.blockMap = Boolean(image.blockMap)
analytics.logEvent('Select image', {
image,
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
})
}).catch(exceptionReporter.report)
}
selectFile (file) {
debug('FileSelector:selectFile', file)
if (file.isDirectory) {
this.navigate(file.path)
return
}
if (!supportedFormats.isSupportedImage(file.path)) {
const invalidImageError = errors.createUserError({
title: 'Invalid image',
description: messages.error.invalidImage(file.path)
})
osDialog.showError(invalidImageError)
analytics.logEvent('Invalid image', { path: file.path })
return
}
debug('FileSelector:getImageMetadata', file)
const source = new sdk.sourceDestination.File(file.path, sdk.sourceDestination.File.OpenFlags.Read)
source.getInnerSource()
.then((innerSource) => {
return innerSource.getMetadata()
.then((imageMetadata) => {
debug('FileSelector:getImageMetadata', imageMetadata)
imageMetadata.path = file.path
imageMetadata.extension = path.extname(file.path).slice(1)
return innerSource.getPartitionTable()
.then((partitionTable) => {
if (partitionTable !== undefined) {
imageMetadata.hasMBR = true
imageMetadata.partitions = partitionTable.partitions
}
return this.selectImage(imageMetadata)
})
})
})
.catch((error) => {
debug('FileSelector:getImageMetadata', error)
const imageError = errors.createUserError({
title: 'Error opening image',
description: messages.error.openImage(path.basename(file.path), error.message)
})
osDialog.showError(imageError)
analytics.logException(error)
})
}
onHighlight (file) {
this.setState({ highlighted: file })
}
render () {
const styles = {
display: 'flex',
height: 'calc(100vh - 20px)',
}
return (
<rendition.Provider style={ styles }>
{/*<RecentFiles flex="0 0 auto"
selectFile={ ::this.selectFile }
navigate={ ::this.navigate } />*/}
<Flex direction="column" grow="1" overflow="auto">
<Header flex="0 0 auto" alignItems="baseline">
<rendition.Button
bg={ colors.secondary.background }
color={ colors.primary.color }
onClick={ ::this.navigateUp }>
<span className="fas fa-angle-left" />
&nbsp;Back
</rendition.Button>
<span className="fas fa-hdd" />
<Breadcrumbs
path={ this.state.path }
navigate={ ::this.navigate }
constraintPath={ this.props.constraintpath }
constraint={ this.state.constraint }
/>
</Header>
<Main flex="1">
<Flex direction="column" grow="1">
<FileList path={ this.state.path }
constraintPath={ this.props.constraintpath }
constraint={ this.state.constraint }
onHighlight={ ::this.onHighlight }
onSelect={ ::this.selectFile }></FileList>
</Flex>
</Main>
<Footer justifyContent="flex-end">
<FilePath file={ this.state.highlighted }></FilePath>
<rendition.Button onClick={ ::this.close }>Cancel</rendition.Button>
<rendition.Button
primary
onClick={ ::this.confirmSelection }>
Select file
</rendition.Button>
</Footer>
</Flex>
</rendition.Provider>
)
}
}
FileSelector.propTypes = {
path: propTypes.string,
close: propTypes.func,
constraintpath: propTypes.string,
}
module.exports = FileSelector

View File

@@ -0,0 +1,119 @@
/*
* Copyright 2018 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 path = require('path')
const React = require('react')
const propTypes = require('prop-types')
const styled = require('styled-components').default
const rendition = require('rendition')
const middleEllipsis = require('../../../utils/middle-ellipsis')
/**
* @summary How many directories to show with the breadcrumbs
* @type {Number}
* @constant
* @private
*/
const MAX_DIR_CRUMBS = 3
/**
* @summary Character limit of a filename before a middle-ellipsis is added
* @constant
* @private
*/
const FILENAME_CHAR_LIMIT_SHORT = 15
function splitComponents(dirname, root) {
const components = []
let basename = null
root = root || path.parse(dirname).root
while( dirname !== root ) {
basename = path.basename(dirname)
components.unshift({
path: dirname,
basename: basename,
name: basename
})
dirname = path.join( dirname, '..' )
}
if (components.length < MAX_DIR_CRUMBS) {
components.unshift({
path: root,
basename: root,
name: 'Root'
})
}
return components
}
class Crumb extends React.PureComponent {
constructor (props) {
super(props)
}
render () {
return (
<rendition.Button
onClick={ ::this.navigate }
plain={ true }>
<rendition.Txt bold={ this.props.bold }>
{ middleEllipsis(this.props.dir.name, FILENAME_CHAR_LIMIT_SHORT) }
</rendition.Txt>
</rendition.Button>
)
}
navigate () {
this.props.navigate(this.props.dir.path)
}
}
class UnstyledBreadcrumbs extends React.PureComponent {
render () {
const components = splitComponents(this.props.path).slice(-MAX_DIR_CRUMBS)
return (
<div className={ this.props.className }>
{
components.map((dir, index) => {
return (
<Crumb
key={ dir.path }
bold={ index === components.length - 1 }
dir={ dir }
navigate={ ::this.props.navigate }
/>
)
})
}
</div>
)
}
}
const Breadcrumbs = styled(UnstyledBreadcrumbs)`
font-size: 18px;
& > button:not(:last-child)::after {
content: '/';
margin: 9px;
}
`
module.exports = Breadcrumbs

View File

@@ -0,0 +1,125 @@
/*
* Copyright 2018 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 React = require('react')
const propTypes = require('prop-types')
const styled = require('styled-components').default
const rendition = require('rendition')
const colors = require('./colors')
const middleEllipsis = require('../../../utils/middle-ellipsis')
/**
* @summary Flex styled component
* @function
* @type {ReactElement}
*/
const Flex = styled.div`
display: flex;
flex: ${ props => props.flex };
flex-direction: ${ props => props.direction };
justify-content: ${ props => props.justifyContent };
align-items: ${ props => props.alignItems };
flex-wrap: ${ props => props.wrap };
flex-grow: ${ props => props.grow };
`
class RecentFileLink extends React.PureComponent {
constructor (props) {
super(props)
}
render () {
const file = this.props.file
return (
<rendition.Button
onClick={ ::this.select }
plain={ true }>
{ middleEllipsis(file.name, FILENAME_CHAR_LIMIT_SHORT) }
</rendition.Button>
)
}
select () {
this.props.onSelect(this.props.file)
}
}
class UnstyledRecentFiles extends React.PureComponent {
constructor(props) {
super(props)
this.state = {
recent: [],
favorites: []
}
}
render () {
return (
<Flex className={ this.props.className }>
<h5>Recent</h5>
{
this.state.recent.map((file) => {
<RecentFileLink key={ file.path }
file={ file }
onSelect={ this.props.selectFile }/>
})
}
<h5>Favorite</h5>
{
this.state.favorites.map((file) => {
<RecentFileLink key={ file.path }
file={ file }
onSelect={ this.props.navigate }/>
})
}
</Flex>
)
}
}
const RecentFiles = styled(UnstyledRecentFiles)`
display: flex;
flex: 0 0 auto;
flex-direction: column;
align-items: flex-start;
width: 130px;
background-color: ${ colors.secondary.background };
padding: 20px;
color: ${ colors.secondary.color };
> h5 {
color: ${ colors.secondary.title };
font-size: 11px;
font-weight: 500;
text-transform: uppercase;
margin-bottom: 15px;
}
> h5:last-of-type {
margin-top: 20px;
}
> button {
margin-bottom: 10px;
text-align: start;
font-size: 16px;
}
`
module.exports = RecentFiles

View File

@@ -0,0 +1,37 @@
/*
* Copyright 2018 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'
/* eslint-disable jsdoc/require-example */
/**
* @module Etcher.Components.SVGIcon
*/
const angular = require('angular')
const react2angular = require('react2angular').react2angular
const MODULE_NAME = 'Etcher.Components.FileSelector'
const angularFileSelector = angular.module(MODULE_NAME, [
require('../modal/modal')
])
angularFileSelector.component('fileSelector', react2angular(require('./file-selector/file-selector.jsx')))
angularFileSelector.controller('FileSelectorController', require('./controllers/file-selector'))
angularFileSelector.service('FileSelectorService', require('./services/file-selector'))
module.exports = MODULE_NAME

View File

@@ -0,0 +1,53 @@
/*
* Copyright 2018 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'
module.exports = function (ModalService, $q) {
let modal = null
/**
* @summary Open the file selector widget
* @function
* @public
*
* @example
* DriveSelectorService.open()
*/
this.open = () => {
modal = ModalService.open({
name: 'file-selector',
template: require('../templates/file-selector-modal.tpl.html'),
controller: 'FileSelectorController as selector',
size: 'file-selector-modal'
})
}
/**
* @summary Close the file selector widget
* @function
* @public
*
* @example
* DriveSelectorService.close()
*/
this.close = () => {
if (modal) {
modal.close()
}
modal = null
}
}

View File

@@ -0,0 +1,23 @@
/*
* Copyright 2018 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.
*/
.modal-file-selector-modal {
width: calc(100vw - 10px);
> .modal-content {
height: calc(100vh - 20px);
}
}

View File

@@ -0,0 +1,4 @@
<file-selector
constraintpath="selector.getFolderConstraint()"
path="selector.getPath()"
close="selector.close"></file-selector>

View File

@@ -0,0 +1,49 @@
/*
* Copyright 2018 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'
// eslint-disable-next-line no-unused-vars
const React = require('react')
const PropTypes = require('prop-types')
const styled = require('styled-components').default
const { position, right } = require('styled-system')
const { BaseButton, ThemedProvider } = require('../../styled-components')
const Div = styled.div `
${position}
${right}
`
const FlashAnother = (props) => {
return (
<ThemedProvider>
<Div position='absolute' right='152px'>
<BaseButton
primary
onClick={props.onClick.bind(null, { preserveImage: true })}>
Flash Another
</BaseButton>
</Div>
</ThemedProvider>
)
}
FlashAnother.propTypes = {
onClick: PropTypes.func
}
module.exports = FlashAnother

View File

@@ -0,0 +1,34 @@
/*
* Copyright 2018 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'
/**
* @module Etcher.Components.FlashAnother
*/
const angular = require('angular')
const { react2angular } = require('react2angular')
const MODULE_NAME = 'Etcher.Components.FlashAnother'
const FlashAnother = angular.module(MODULE_NAME, [])
FlashAnother.component(
'flashAnother',
react2angular(require('./flash-another.jsx'))
)
module.exports = MODULE_NAME

View File

@@ -16,8 +16,9 @@
'use strict'
const flashState = require('../../../../../shared/models/flash-state')
const selectionState = require('../../../../../shared/models/selection-state')
const flashState = require('../../../models/flash-state')
const selectionState = require('../../../models/selection-state')
const store = require('../../../models/store')
const analytics = require('../../../modules/analytics')
module.exports = function (WarningModalService) {
@@ -40,7 +41,10 @@ module.exports = function (WarningModalService) {
flashState.resetState()
if (confirmed) {
analytics.logEvent('Restart after failure')
analytics.logEvent('Restart after failure', {
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
})
} else {
selectionState.clear()
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright 2018 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 React = require('react')
const PropTypes = require('prop-types')
const _ = require('lodash')
const styled = require('styled-components').default
const { position, left, top, space } = require('styled-system')
const { Underline } = require('./../../styled-components')
const Div = styled.div `
${position}
${top}
${left}
${space}
`
/* eslint-disable no-inline-comments */
const FlashResults = (props) => {
return (
<Div position='absolute' left='153px' top='66px'>
<div className="inline-flex title">
<span className="tick tick--success space-right-medium"></span>
<h3>Flash Complete!</h3>
</div>
<Div className="results" mt='11px' mr='0' mb='0' ml='40px'>
<Underline
tooltip={props.errors()}>
{_.map(props.results.devices, (quantity, type) => {
return (quantity) ? (
<div key={type} className={`target-status-line target-status-${type}`}>
<span className="target-status-dot"></span>
<span className="target-status-quantity">{ quantity }</span>
<span className="target-status-message">{ props.message[type](quantity) }</span>
</div>
) : null
})}
</Underline>
</Div>
</Div>
)
}
FlashResults.propTypes = {
results: PropTypes.object,
message: PropTypes.object,
errors: PropTypes.func
}
module.exports = FlashResults

View File

@@ -0,0 +1,34 @@
/*
* Copyright 2018 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'
/**
* @module Etcher.Components.FlashResults
*/
const angular = require('angular')
const { react2angular } = require('react2angular')
const MODULE_NAME = 'Etcher.Components.FlashResults'
const FlashResults = angular.module(MODULE_NAME, [])
FlashResults.component(
'flashResults',
react2angular(require('./flash-results.jsx'))
)
module.exports = MODULE_NAME

View File

@@ -0,0 +1,128 @@
/*
* 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'
/* eslint-disable no-unused-vars */
const React = require('react')
const propTypes = require('prop-types')
const { Badge, DropDownButton, Select } = require('rendition')
const { default: styled } = require('styled-components')
const middleEllipsis = require('./../../utils/middle-ellipsis')
const shared = require('./../../../../gui/app/modules/units')
const {
StepButton,
StepNameButton,
StepSelection,
Footer,
Underline,
DetailsText,
ChangeButton,
ThemedProvider
} = require('./../../styled-components')
const DropdownItem = styled.p`
padding-top: 10px;
text-align: left;
width: 150px;
cursor: pointer;
`
const DropdownItemIcon = styled.i`
padding-right: 10px;
`
const SelectImageButton = (props) => {
if (props.hasImage) {
return (
<ThemedProvider>
<StepNameButton
plain
onClick={props.showSelectedImageDetails}
tooltip={props.imageBasename}
>
{/* eslint-disable no-magic-numbers */}
{ middleEllipsis(props.imageName || props.imageBasename, 20) }
</StepNameButton>
{ !props.flashing &&
<ChangeButton
plain
mb={14}
onClick={props.deselectImage}
>
Remove
</ChangeButton>
}
<DetailsText>
{shared.bytesToClosestUnit(props.imageSize)}
</DetailsText>
</ThemedProvider>
)
}
return (
<ThemedProvider>
<StepSelection>
<DropDownButton
primary
label={
<div onClick={props.openImageSelector}>Select image</div>
}
style={{height: '48px'}}
>
<DropdownItem
onClick={props.openImageSelector}
>
<DropdownItemIcon className="far fa-file"/>
Select image file
</DropdownItem>
<DropdownItem
onClick={props.openDriveSelector}
>
<DropdownItemIcon className="far fa-copy"/>
Duplicate drive
</DropdownItem>
</DropDownButton>
<Footer>
{ props.mainSupportedExtensions.join(', ') }, and{' '}
<Underline
tooltip={ props.extraSupportedExtensions.join(', ') }
>
many more
</Underline>
</Footer>
</StepSelection>
</ThemedProvider>
)
}
SelectImageButton.propTypes = {
openImageSelector: propTypes.func,
openDriveSelector: propTypes.func,
mainSupportedExtensions: propTypes.array,
extraSupportedExtensions: propTypes.array,
hasImage: propTypes.bool,
showSelectedImageDetails: propTypes.func,
imageName: propTypes.string,
imageBasename: propTypes.string,
deselectImage: propTypes.func,
flashing: propTypes.bool,
imageSize: propTypes.number,
sourceType: propTypes.string
}
module.exports = SelectImageButton

View File

@@ -0,0 +1,34 @@
/*
* Copyright 2018 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'
/**
* @module Etcher.Components.ImageSelector
*/
const angular = require('angular')
const { react2angular } = require('react2angular')
const MODULE_NAME = 'Etcher.Components.ImageSelector'
const SelectImageButton = angular.module(MODULE_NAME, [])
SelectImageButton.component(
'imageSelector',
react2angular(require('./image-selector.jsx'))
)
module.exports = MODULE_NAME

View File

@@ -17,6 +17,7 @@
'use strict'
const _ = require('lodash')
const store = require('../../../models/store')
const analytics = require('../../../modules/analytics')
module.exports = function ($uibModal, $q) {
@@ -45,7 +46,9 @@ module.exports = function ($uibModal, $q) {
})
analytics.logEvent('Open modal', {
name: options.name
name: options.name,
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
})
const modal = $uibModal.open({
@@ -53,7 +56,8 @@ module.exports = function ($uibModal, $q) {
template: options.template,
controller: options.controller,
size: options.size,
resolve: options.resolve
resolve: options.resolve,
backdrop: 'static'
})
return {
@@ -62,16 +66,20 @@ module.exports = function ($uibModal, $q) {
modal.result.then((value) => {
analytics.logEvent('Modal accepted', {
name: options.name,
value
value,
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
})
resolve(value)
}).catch((error) => {
// Bootstrap doesn't 'resolve' these but cancels the dialog
if (error === 'escape key press' || error === 'backdrop click') {
if (error === 'escape key press') {
analytics.logEvent('Modal rejected', {
name: options.name,
method: error
method: error,
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
})
return resolve()
@@ -79,7 +87,9 @@ module.exports = function ($uibModal, $q) {
analytics.logEvent('Modal rejected', {
name: options.name,
value: error
value: error,
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
})
return reject(error)

View File

@@ -20,6 +20,7 @@
flex-direction: column;
margin: 0 auto;
height: auto;
overflow: hidden;
}
.modal-header {
@@ -82,6 +83,7 @@
.modal-footer {
flex-grow: 0;
border: 0;
text-align: center;
}
.modal {
@@ -101,5 +103,4 @@
.modal-dialog {
margin: 0;
position: initial;
max-width: 50%;
}

View File

@@ -21,8 +21,14 @@
*/
const angular = require('angular')
const { react2angular } = require('react2angular')
const MODULE_NAME = 'Etcher.Components.ProgressButton'
const ProgressButton = angular.module(MODULE_NAME, [])
ProgressButton.directive('progressButton', require('./directives/progress-button'))
ProgressButton.component(
'progressButton',
react2angular(require('./progress-button.jsx'))
)
module.exports = MODULE_NAME

View File

@@ -0,0 +1,161 @@
/*
* 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 React = require('react')
const propTypes = require('prop-types')
const Color = require('color')
const {
default: styled,
css,
keyframes
} = require('styled-components')
const { ProgressBar, Provider } = require('rendition')
const { colors } = require('./../../theme')
const { StepButton, StepSelection } = require('./../../styled-components')
const darkenForegroundStripes = 0.18
const desaturateForegroundStripes = 0.2
const progressButtonStripesForegroundColor = Color(colors.primary.background)
.darken(darkenForegroundStripes)
.desaturate(desaturateForegroundStripes)
.string()
const desaturateBackgroundStripes = 0.05
const progressButtonStripesBackgroundColor = Color(colors.primary.background)
.desaturate(desaturateBackgroundStripes)
.string()
const ProgressButtonStripes = keyframes `
0% {
background-position: 0 0;
}
100% {
background-position: 20px 20px;
}
`
const ProgressButtonStripesRule = css `
${ProgressButtonStripes} 1s linear infinite;
`
const FlashProgressBar = styled(ProgressBar) `
> div {
width: 200px;
height: 48px;
color: white !important;
text-shadow: none !important;
}
width: 200px;
height: 48px;
font-size: 16px;
line-height: 48px;
background: ${Color(colors.warning.background).darken(darkenForegroundStripes).string()};
`
const FlashProgressBarValidating = styled(FlashProgressBar) `
// Notice that we add 0.01 to certain gradient stop positions.
// That workarounds a Chrome rendering issue where diagonal
// lines look spiky.
// See https://github.com/resin-io/etcher/issues/472
background-image: -webkit-gradient(linear, 0 0, 100% 100%,
color-stop(0.25, ${progressButtonStripesForegroundColor}),
color-stop(0.26, ${progressButtonStripesBackgroundColor}),
color-stop(0.50, ${progressButtonStripesBackgroundColor}),
color-stop(0.51, ${progressButtonStripesForegroundColor}),
color-stop(0.75, ${progressButtonStripesForegroundColor}),
color-stop(0.76 , ${progressButtonStripesBackgroundColor}),
to(${progressButtonStripesBackgroundColor}));
background-color: white;
animation: ${ProgressButtonStripesRule};
overflow: hidden;
background-size: 20px 20px;
`
/**
* Progress Button component
*/
class ProgressButton extends React.Component {
render () {
if (this.props.active) {
if (this.props.striped) {
return (
<Provider>
<StepSelection>
<FlashProgressBarValidating
primary
emphasized
value= { this.props.percentage }
>
{ this.props.label }
</FlashProgressBarValidating>
</StepSelection>
</Provider>
)
}
return (
<Provider>
<StepSelection>
<FlashProgressBar
warning
emphasized
value= { this.props.percentage }
>
{ this.props.label }
</FlashProgressBar>
</StepSelection>
</Provider>
)
}
return (
<Provider>
<StepSelection>
<StepButton
onClick= { this.props.callback }
disabled= { this.props.disabled }
>
{this.props.label}
</StepButton>
</StepSelection>
</Provider>
)
}
}
ProgressButton.propTypes = {
striped: propTypes.bool,
active: propTypes.bool,
percentage: propTypes.number,
label: propTypes.string,
disabled: propTypes.bool,
callback: propTypes.func
}
module.exports = ProgressButton

View File

@@ -1,126 +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.
*/
/**
* A button with a progress bar inside.
*
* From http://tympanus.net/Development/ProgressButtonStyles/
*
* The state of the progress bar is controller by the width, in percentage,
* of `.progress-button__bar`.
*
* If there is an action in place, the `active` attribute must be set to `true`.
* This is useful to determine if the progress bar is paused from the point of view
* of the styling.
*
* You can optionally pass the `.progress-button--striped` modified to get a striped
* progress bar.
*
* The stripe implementation idea was taken from:
*
* https://css-tricks.com/css3-progress-bars/
*
* Usage:
*
* <button class="progress-button" active="true">
* <span class="progress-button__content">Button text</span>
* <span class="progress-button__bar" style="width: 50%;"></span>
* </button>
*/
$progress-button-stripes-width: 20px;
$progress-button-stripes-animation-duration: 1s;
.progress-button {
@extend .button;
@extend .button-primary;
overflow: hidden;
&[active="true"] {
background-color: $palette-theme-warning-background;
}
.progress-button__bar {
background-color: lighten($palette-theme-warning-background, 5%);
}
&.progress-button--striped {
$progress-button-stripes-background-color: desaturate($palette-theme-primary-background, 5%);
$progress-button-stripes-foreground-color: desaturate(darken($palette-theme-primary-background, 18%), 20%);
// Notice that we add `0.01` to certain gradient stop positions.
// That workarounds a Chrome rendering issue where diagonal
// lines look spiky.
// See https://github.com/resin-io/etcher/issues/472
background-image: -webkit-gradient(linear, 0 0, 100% 100%,
color-stop(0.25, $progress-button-stripes-foreground-color),
color-stop(0.25 + 0.01, $progress-button-stripes-background-color),
color-stop(0.50, $progress-button-stripes-background-color),
color-stop(0.50 + 0.01, $progress-button-stripes-foreground-color),
color-stop(0.75, $progress-button-stripes-foreground-color),
color-stop(0.75 + 0.01, $progress-button-stripes-background-color),
to($progress-button-stripes-background-color));
.progress-button__bar {
background-color: lighten($palette-theme-primary-background, 5%);
}
}
}
// Prevent the button from being clickable
// when it has an active progress bar.
.progress-button[active="true"] {
@extend .button-no-hover;
}
.progress-button__content {
position: relative;
z-index: 10;
}
.progress-button__bar {
position: absolute;
left: 0;
top: 0;
width: 0;
height: 100%;
// Subtle progress bar animation
transition: width 0.3s;
}
.progress-button--striped {
background-size: $progress-button-stripes-width $progress-button-stripes-width;
animation: progress-button-stripes $progress-button-stripes-animation-duration linear infinite;
overflow: hidden;
}
@keyframes progress-button-stripes {
0% {
background-position: 0 0;
}
100% {
background-position: $progress-button-stripes-width $progress-button-stripes-width;
}
}

View File

@@ -1,7 +0,0 @@
<button class="progress-button"
ng-class="{
'progress-button--striped': striped && striped != 'false'
}">
<span class="progress-button__content" ng-transclude></span>
<span class="progress-button__bar" ng-style="{ width: (percentage > 100 ? 100 : percentage) + '%' }"></span>
</button>

View File

@@ -16,32 +16,19 @@
'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!'));
* @module Etcher.Components.ReducedFlashingInfos
*/
exports.printError = (error) => {
const title = errors.getTitle(error)
const description = errors.getDescription(error, {
userFriendlyDescriptionsOnly: true
})
console.error(chalk.red(title))
const angular = require('angular')
const { react2angular } = require('react2angular')
if (description) {
console.error(`\n${chalk.red(description)}`)
}
const MODULE_NAME = 'Etcher.Components.ReducedFlashingInfos'
const ReducedFlashingInfos = angular.module(MODULE_NAME, [])
if (process.env.ETCHER_CLI_DEBUG && error.stack) {
console.error(`\n${chalk.red(error.stack)}`)
}
}
ReducedFlashingInfos.component(
'reducedFlashingInfos',
react2angular(require('./reduced-flashing-infos.jsx'))
)
module.exports = MODULE_NAME

View File

@@ -0,0 +1,81 @@
/*
* 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 React = require('react')
const propTypes = require('prop-types')
const styled = require('styled-components').default
const { color } = require('styled-system')
const SvgIcon = require('../svg-icon/svg-icon.jsx')
const Div = styled.div `
position: absolute;
top: 45px;
left: 545px;
> span.step-name {
justify-content: flex-start;
> span {
margin-left: 10px;
}
> span:nth-child(2) {
font-weight: 500;
}
> span:nth-child(3) {
font-weight: 400;
font-style: italic;
}
}
.svg-icon[disabled] {
opacity: 0.4;
}
`
const Span = styled.span `
${color}
`
const ReducedFlashingInfos = (props) => {
return (props.shouldShow) ? (
<Div>
<Span className="step-name">
<SvgIcon disabled contents={[ props.imageLogo ]} paths={[ '../../assets/image.svg' ]} width='20px'></SvgIcon>
<Span>{ props.imageName }</Span>
<Span color='#7e8085'>{ props.imageSize }</Span>
</Span>
<Span className="step-name">
<SvgIcon disabled paths={[ '../../assets/drive.svg' ]} width='20px'></SvgIcon>
<Span>{ props.driveTitle }</Span>
</Span>
</Div>
) : null
}
ReducedFlashingInfos.propTypes = {
imageLogo: propTypes.string,
imageName: propTypes.string,
imageSize: propTypes.string,
driveTitle: propTypes.string,
shouldShow: propTypes.bool
}
module.exports = ReducedFlashingInfos

View File

@@ -0,0 +1,34 @@
/*
* Copyright 2018 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'
/**
* @module Etcher.Components.SafeWebview
*/
const angular = require('angular')
const { react2angular } = require('react2angular')
const MODULE_NAME = 'Etcher.Components.SafeWebview'
const SafeWebview = angular.module(MODULE_NAME, [])
SafeWebview.component(
'safeWebview',
react2angular(require('./safe-webview.jsx'))
)
module.exports = MODULE_NAME

View File

@@ -20,15 +20,12 @@
const _ = require('lodash')
const electron = require('electron')
const angular = require('angular')
const react = require('react')
const propTypes = require('prop-types')
const { react2angular } = require('react2angular')
const analytics = require('../modules/analytics')
const packageJSON = require('../../../../package.json')
const MODULE_NAME = 'Etcher.Components.SafeWebview'
const angularSafeWebview = angular.module(MODULE_NAME, [])
const analytics = require('../../modules/analytics')
const store = require('../../models/store')
const settings = require('../../models/settings')
const packageJSON = require('../../../../../package.json')
/**
* @summary Electron session identifier
@@ -54,6 +51,14 @@ const ETCHER_VERSION_PARAM = 'etcher-version'
*/
const API_VERSION_PARAM = 'api-version'
/**
* @summary Opt-out analytics search-parameter key
* @constant
* @private
* @type {String}
*/
const OPT_OUT_ANALYTICS_PARAM = 'optOutAnalytics'
/**
* @summary Webview API version
* @constant
@@ -65,8 +70,10 @@ const API_VERSION_PARAM = 'api-version'
* should only be changed when truly necessary as it introduces breaking changes.
* This version number is exposed to the banner such that it can determine what
* features are safe to utilize.
*
* See `git blame -L n` where n is the line below for the history of version changes.
*/
const API_VERSION = 1
const API_VERSION = 2
/**
* @summary Webviews that hide/show depending on the HTTP status returned
@@ -92,6 +99,7 @@ class SafeWebview extends react.PureComponent {
// We set the version GET parameters here.
url.searchParams.set(ETCHER_VERSION_PARAM, packageJSON.version)
url.searchParams.set(API_VERSION_PARAM, API_VERSION)
url.searchParams.set(OPT_OUT_ANALYTICS_PARAM, !settings.get('errorReporting'))
this.entryHref = url.href
@@ -101,13 +109,11 @@ class SafeWebview extends react.PureComponent {
this.eventTuples = [
[ 'did-fail-load', this.didFailLoad ],
[ 'did-get-response-details', this.didGetResponseDetails ],
[ 'new-window', this.constructor.newWindow ],
[ 'console-message', this.constructor.consoleMessage ]
[ 'new-window', this.constructor.newWindow ]
]
// Make a persistent electron session for the webview
electron.remote.session.fromPartition(ELECTRON_SESSION, {
this.session = electron.remote.session.fromPartition(ELECTRON_SESSION, {
// Disable the cache for the session such that new content shows up when refreshing
cache: false
@@ -120,6 +126,7 @@ class SafeWebview extends react.PureComponent {
render () {
return react.createElement('webview', {
ref: 'webview',
partition: ELECTRON_SESSION,
style: {
flex: this.state.shouldShow ? null : '0 1',
width: this.state.shouldShow ? null : '0',
@@ -137,8 +144,7 @@ class SafeWebview extends react.PureComponent {
this.refs.webview.addEventListener(...tuple)
})
// Use the 'success-banner' session
this.refs.webview.partition = ELECTRON_SESSION
this.session.webRequest.onCompleted(this.didGetResponseDetails)
// It's important that this comes after the partition setting, otherwise it will
// use another session and we can't change it without destroying the element again
@@ -153,6 +159,7 @@ class SafeWebview extends react.PureComponent {
_.map(this.eventTuples, (tuple) => {
this.refs.webview.removeEventListener(...tuple)
})
this.session.webRequest.onCompleted(null)
}
/**
@@ -195,11 +202,18 @@ class SafeWebview extends react.PureComponent {
if (event.resourceType === 'mainFrame') {
const HTTP_OK = 200
analytics.logEvent(event)
analytics.logEvent('SafeWebview loaded', {
event,
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
})
this.setState({
shouldShow: event.httpResponseCode === HTTP_OK
shouldShow: event.statusCode === HTTP_OK
})
if (this.props.onWebviewShow) {
this.props.onWebviewShow(event.statusCode === HTTP_OK)
}
}
}
@@ -212,39 +226,14 @@ class SafeWebview extends react.PureComponent {
if (_.every([
url.protocol === 'http:' || url.protocol === 'https:',
event.disposition === 'foreground-tab'
event.disposition === 'foreground-tab',
// Don't open links if they're disabled by the env var
!settings.get('disableExternalLinks')
])) {
electron.shell.openExternal(url.href)
}
}
/**
* @summary Forward specially-formatted console messages from the webview
* @param {Event} event - event object
*
* @example
*
* // In the webview
* console.log('Good night!')
*/
static consoleMessage (event) {
if (_.isNil(event.message)) {
return
}
let message = event.message
try {
message = JSON.parse(event.message)
} catch (error) {
// Ignore
}
if (message.command === 'error') {
analytics.logException(message.data)
} else {
analytics.logEvent(message.data || message)
}
}
}
SafeWebview.propTypes = {
@@ -257,10 +246,13 @@ SafeWebview.propTypes = {
/**
* @summary Refresh the webview
*/
refreshNow: propTypes.bool
refreshNow: propTypes.bool,
/**
* @summary Webview lifecycle event
*/
onWebviewShow: propTypes.func
}
angularSafeWebview.component('safeWebview', react2angular(SafeWebview))
module.exports = MODULE_NAME
module.exports = SafeWebview

View File

@@ -0,0 +1,32 @@
/*
* 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'
/* eslint-disable jsdoc/require-example */
/**
* @module Etcher.Components.SVGIcon
*/
const angular = require('angular')
const react2angular = require('react2angular').react2angular
const MODULE_NAME = 'Etcher.Components.SVGIcon'
const angularSVGIcon = angular.module(MODULE_NAME, [])
angularSVGIcon.component('svgIcon', react2angular(require('./svg-icon.jsx')))
module.exports = MODULE_NAME

Some files were not shown because too many files have changed in this diff Show More