mirror of
https://github.com/balena-io/etcher.git
synced 2025-04-24 07:17:18 +00:00
commit
3ece1fd841
@ -91,8 +91,6 @@ zypper rr balena-etcher-source
|
||||
|
||||
```sh
|
||||
sudo dnf install -y balena-etcher-electron
|
||||
rm /etc/yum.repos.d/balena-etcher.repo
|
||||
rm /etc/yum.repos.d/balena-etcher-source.repo
|
||||
```
|
||||
|
||||
###### Uninstall
|
||||
|
@ -1,5 +1,5 @@
|
||||
Getting help with Etcher
|
||||
========================
|
||||
Getting help with BalenaEtcher
|
||||
===============================
|
||||
|
||||
There are various ways to get support for Etcher if you experience an issue or
|
||||
have an idea you'd like to share with us.
|
||||
@ -22,7 +22,7 @@ a look at the existing threads before opening a new one!
|
||||
Make sure to mention the following information to help us provide better
|
||||
support:
|
||||
|
||||
- The Etcher version you're running.
|
||||
- The BalenaEtcher version you're running.
|
||||
|
||||
- The operating system you're running Etcher in.
|
||||
|
||||
@ -32,7 +32,7 @@ support:
|
||||
GitHub
|
||||
------
|
||||
|
||||
If you encounter an issue or have a suggestion, head on over to Etcher's [issue
|
||||
If you encounter an issue or have a suggestion, head on over to BalenaEtcher's [issue
|
||||
tracker][issues] and if there isn't a ticket covering it, [create
|
||||
one][new-issue].
|
||||
|
||||
|
@ -91,7 +91,7 @@ make electron-develop
|
||||
|
||||
```sh
|
||||
# Build the GUI
|
||||
make webpack
|
||||
npm run webpack
|
||||
# Start Electron
|
||||
npm start
|
||||
```
|
||||
|
@ -159,6 +159,18 @@ pre-installed in all modern Windows versions.
|
||||
|
||||
- Run `clean`. This command will completely clean your drive by erasing any
|
||||
existent filesystem.
|
||||
|
||||
- Run `create partition primary`. This command will create a new partition.
|
||||
|
||||
- Run `active`. This command will active the partition.
|
||||
|
||||
- Run `list partition`. This command will show available partition.
|
||||
|
||||
- Run `select partition N`, where `N` corresponds to the id of the newly available partition.
|
||||
|
||||
- Run `format override quick`. This command will format the partition. You can choose a specific formatting by adding `FS=xx` where `xx` could be `NTFS or FAT or FAT32` after `format`. Example : `format FS=NTFS override quick`
|
||||
|
||||
- Run `exit` to quit diskpart.
|
||||
|
||||
### OS X
|
||||
|
||||
|
@ -61,6 +61,7 @@ import ImageSvg from '../../../assets/image.svg';
|
||||
import SrcSvg from '../../../assets/src.svg';
|
||||
import { DriveSelector } from '../drive-selector/drive-selector';
|
||||
import { DrivelistDrive } from '../../../../shared/drive-constraints';
|
||||
import axios, { AxiosRequestConfig } from 'axios';
|
||||
|
||||
const recentUrlImagesKey = 'recentUrlImages';
|
||||
|
||||
@ -279,6 +280,7 @@ interface SourceSelectorState {
|
||||
showDriveSelector: boolean;
|
||||
defaultFlowActive: boolean;
|
||||
imageSelectorOpen: boolean;
|
||||
imageLoading: boolean;
|
||||
}
|
||||
|
||||
export class SourceSelector extends React.Component<
|
||||
@ -297,6 +299,7 @@ export class SourceSelector extends React.Component<
|
||||
showDriveSelector: false,
|
||||
defaultFlowActive: true,
|
||||
imageSelectorOpen: false,
|
||||
imageLoading: false,
|
||||
};
|
||||
|
||||
// Bind `this` since it's used in an event's callback
|
||||
@ -317,10 +320,12 @@ export class SourceSelector extends React.Component<
|
||||
}
|
||||
|
||||
private async onSelectImage(_event: IpcRendererEvent, imagePath: string) {
|
||||
this.setState({ imageLoading: true });
|
||||
await this.selectSource(
|
||||
imagePath,
|
||||
isURL(imagePath) ? sourceDestination.Http : sourceDestination.File,
|
||||
).promise;
|
||||
this.setState({ imageLoading: false });
|
||||
}
|
||||
|
||||
private async createSource(selected: string, SourceType: Source) {
|
||||
@ -330,14 +335,34 @@ export class SourceSelector extends React.Component<
|
||||
analytics.logException(error);
|
||||
}
|
||||
|
||||
if (this.isJson(decodeURIComponent(selected))) {
|
||||
const config: AxiosRequestConfig = JSON.parse(
|
||||
decodeURIComponent(selected),
|
||||
);
|
||||
return new sourceDestination.Http({
|
||||
url: config.url!,
|
||||
axiosInstance: axios.create(_.omit(config, ['url'])),
|
||||
});
|
||||
}
|
||||
|
||||
if (SourceType === sourceDestination.File) {
|
||||
return new sourceDestination.File({
|
||||
path: selected,
|
||||
});
|
||||
}
|
||||
|
||||
return new sourceDestination.Http({ url: selected });
|
||||
}
|
||||
|
||||
public isJson(jsonString: string) {
|
||||
try {
|
||||
JSON.parse(jsonString);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private reselectSource() {
|
||||
analytics.logEvent('Reselect image', {
|
||||
previousImage: selectionState.getImage(),
|
||||
@ -395,7 +420,7 @@ export class SourceSelector extends React.Component<
|
||||
}
|
||||
metadata.SourceType = SourceType;
|
||||
|
||||
if (!metadata.hasMBR) {
|
||||
if (!metadata.hasMBR && this.state.warning === null) {
|
||||
analytics.logEvent('Missing partition table', { metadata });
|
||||
this.setState({
|
||||
warning: {
|
||||
@ -567,7 +592,12 @@ export class SourceSelector extends React.Component<
|
||||
// TODO add a visual change when dragging a file over the selector
|
||||
public render() {
|
||||
const { flashing } = this.props;
|
||||
const { showImageDetails, showURLSelector, showDriveSelector } = this.state;
|
||||
const {
|
||||
showImageDetails,
|
||||
showURLSelector,
|
||||
showDriveSelector,
|
||||
imageLoading,
|
||||
} = this.state;
|
||||
const selectionImage = selectionState.getImage();
|
||||
let image: SourceMetadata | DrivelistDrive =
|
||||
selectionImage !== undefined ? selectionImage : ({} as SourceMetadata);
|
||||
@ -605,16 +635,18 @@ export class SourceSelector extends React.Component<
|
||||
}}
|
||||
/>
|
||||
|
||||
{selectionImage !== undefined ? (
|
||||
{selectionImage !== undefined || imageLoading ? (
|
||||
<>
|
||||
<StepNameButton
|
||||
plain
|
||||
onClick={() => this.showSelectedImageDetails()}
|
||||
tooltip={imageName || imageBasename}
|
||||
>
|
||||
{middleEllipsis(imageName || imageBasename, 20)}
|
||||
<Spinner show={imageLoading}>
|
||||
{middleEllipsis(imageName || imageBasename, 20)}
|
||||
</Spinner>
|
||||
</StepNameButton>
|
||||
{!flashing && (
|
||||
{!flashing && !imageLoading && (
|
||||
<ChangeButton
|
||||
plain
|
||||
mb={14}
|
||||
@ -623,7 +655,7 @@ export class SourceSelector extends React.Component<
|
||||
Remove
|
||||
</ChangeButton>
|
||||
)}
|
||||
{!_.isNil(imageSize) && (
|
||||
{!_.isNil(imageSize) && !imageLoading && (
|
||||
<DetailsText>{prettyBytes(imageSize)}</DetailsText>
|
||||
)}
|
||||
</>
|
||||
|
@ -17,21 +17,24 @@
|
||||
import * as _ from 'lodash';
|
||||
import { Animator, AnimationFunction, Color, RGBLed } from 'sys-class-rgb-led';
|
||||
|
||||
import { DrivelistDrive } from '../../../shared/drive-constraints';
|
||||
import {
|
||||
DrivelistDrive,
|
||||
isSourceDrive,
|
||||
} from '../../../shared/drive-constraints';
|
||||
import { getDrives } from './available-drives';
|
||||
import { getImage, getSelectedDrives } from './selection-state';
|
||||
import { getSelectedDrives } from './selection-state';
|
||||
import * as settings from './settings';
|
||||
import { observe, store } from './store';
|
||||
|
||||
const leds: Map<string, RGBLed> = new Map();
|
||||
const animator = new Animator([], 10);
|
||||
|
||||
const red: Color = [0.59, 0, 0];
|
||||
const green: Color = [0, 0.59, 0];
|
||||
const blue: Color = [0, 0, 0.59];
|
||||
const white: Color = [0.04, 0.04, 0.04];
|
||||
const red: Color = [0.78, 0, 0];
|
||||
const green: Color = [0, 0.58, 0];
|
||||
const blue: Color = [0, 0, 0.1];
|
||||
const purple: Color = [0.7, 0, 0.78];
|
||||
const white: Color = [0.7, 0.7, 0.7];
|
||||
const black: Color = [0, 0, 0];
|
||||
const purple: Color = [0.117, 0, 0.196];
|
||||
|
||||
function createAnimationFunction(
|
||||
intensityFunction: (t: number) => number,
|
||||
@ -172,7 +175,9 @@ function stateObserver() {
|
||||
const availableDrives = getDrives().filter(
|
||||
(d: DrivelistDrive) => d.devicePath,
|
||||
);
|
||||
const sourceDrivePath = getImage()?.drive?.devicePath;
|
||||
const sourceDrivePath = availableDrives.filter((d: DrivelistDrive) =>
|
||||
isSourceDrive(d, s.selection.image),
|
||||
)[0]?.devicePath;
|
||||
const availableDrivesPaths = availableDrives.map(
|
||||
(d: DrivelistDrive) => d.devicePath,
|
||||
);
|
||||
|
21
npm-shrinkwrap.json
generated
21
npm-shrinkwrap.json
generated
@ -3535,11 +3535,11 @@
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
|
||||
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"base64-js": "^1.3.1",
|
||||
"ieee754": "^1.1.13"
|
||||
}
|
||||
},
|
||||
"dev": true
|
||||
},
|
||||
"buffer-alloc": {
|
||||
"version": "1.2.0",
|
||||
@ -11635,6 +11635,15 @@
|
||||
"semver-compare": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"pnp-webpack-plugin": {
|
||||
"version": "1.6.4",
|
||||
"resolved": "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz",
|
||||
"integrity": "sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ts-pnp": "^1.1.6"
|
||||
}
|
||||
},
|
||||
"polished": {
|
||||
"version": "3.7.0",
|
||||
"resolved": "https://registry.npmjs.org/polished/-/polished-3.7.0.tgz",
|
||||
@ -14818,6 +14827,12 @@
|
||||
"yn": "3.1.1"
|
||||
}
|
||||
},
|
||||
"ts-pnp": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.2.0.tgz",
|
||||
"integrity": "sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==",
|
||||
"dev": true
|
||||
},
|
||||
"tslib": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz",
|
||||
@ -16828,4 +16843,4 @@
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -15,8 +15,7 @@
|
||||
"scripts": {
|
||||
"lint-ts": "balena-lint --fix --typescript typings lib tests scripts/clean-shrinkwrap.ts webpack.config.ts",
|
||||
"lint-css": "prettier --write lib/**/*.css",
|
||||
"lint-spell": "codespell --dictionary - --dictionary dictionary.txt --skip *.ttf *.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 Makefile *.md LICENSE",
|
||||
"lint": "npm run lint-ts && npm run lint-css && npm run lint-spell",
|
||||
"lint": "npm run lint-ts && npm run lint-css",
|
||||
"test-spectron": "mocha --recursive --reporter spec --require ts-node/register --require-main tests/gui/allow-renderer-process-reuse.ts tests/spectron/runner.spec.ts",
|
||||
"test-gui": "electron-mocha --recursive --reporter spec --require ts-node/register --require-main tests/gui/allow-renderer-process-reuse.ts --full-trace --no-sandbox --renderer tests/gui/**/*.ts",
|
||||
"test-shared": "electron-mocha --recursive --reporter spec --require ts-node/register --require-main tests/gui/allow-renderer-process-reuse.ts --full-trace --no-sandbox tests/shared/**/*.ts",
|
||||
@ -99,6 +98,7 @@
|
||||
"omit-deep-lodash": "1.1.4",
|
||||
"outdent": "^0.7.1",
|
||||
"path-is-inside": "^1.0.2",
|
||||
"pnp-webpack-plugin": "^1.6.4",
|
||||
"pretty-bytes": "^5.3.0",
|
||||
"react": "^16.8.5",
|
||||
"react-dom": "^16.8.5",
|
||||
|
@ -1,3 +1,2 @@
|
||||
codespell==1.12.0
|
||||
awscli==1.11.87
|
||||
shyaml==0.5.0
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit d1b05ad312e65ea82b1c16b31f5af3c0b5fa2777
|
||||
Subproject commit 8dfa21cfc23b1dbc0eaa22b5dbdf1f5c796b0c2c
|
1
typings/pnp-webpack-plugin/index.d.ts
vendored
Normal file
1
typings/pnp-webpack-plugin/index.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
declare module 'pnp-webpack-plugin';
|
@ -24,6 +24,7 @@ import { env } from 'process';
|
||||
import * as SimpleProgressWebpackPlugin from 'simple-progress-webpack-plugin';
|
||||
import * as TerserPlugin from 'terser-webpack-plugin';
|
||||
import { BannerPlugin, NormalModuleReplacementPlugin } from 'webpack';
|
||||
import * as PnpWebpackPlugin from 'pnp-webpack-plugin';
|
||||
|
||||
/**
|
||||
* Don't webpack package.json as mixpanel & sentry tokens
|
||||
@ -293,6 +294,7 @@ const commonConfig = {
|
||||
extensions: ['.node', '.js', '.json', '.ts', '.tsx'],
|
||||
},
|
||||
plugins: [
|
||||
PnpWebpackPlugin,
|
||||
new SimpleProgressWebpackPlugin({
|
||||
format: process.env.WEBPACK_PROGRESS || 'verbose',
|
||||
}),
|
||||
@ -303,6 +305,9 @@ const commonConfig = {
|
||||
'./http.js',
|
||||
),
|
||||
],
|
||||
resolveLoader: {
|
||||
plugins: [PnpWebpackPlugin.moduleLoader(module)],
|
||||
},
|
||||
output: {
|
||||
path: path.join(__dirname, 'generated'),
|
||||
filename: '[name].js',
|
||||
|
Loading…
x
Reference in New Issue
Block a user