mirror of
https://github.com/balena-io/etcher.git
synced 2025-07-25 12:16:37 +00:00
Merge pull request #3202 from balena-io/add-custom-protocol-2
Add custom protocol 2
This commit is contained in:
commit
b7ad7bd729
@ -62,6 +62,12 @@
|
|||||||
"depends": [
|
"depends": [
|
||||||
"polkit-1-auth-agent | policykit-1-gnome | polkit-kde-1"
|
"polkit-1-auth-agent | policykit-1-gnome | polkit-kde-1"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"protocols": {
|
||||||
|
"name": "etcher",
|
||||||
|
"schemes": [
|
||||||
|
"etcher"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
4
Makefile
4
Makefile
@ -164,10 +164,8 @@ lint: lint-ts lint-sass lint-cpp lint-spell
|
|||||||
|
|
||||||
MOCHA_OPTIONS=--recursive --reporter spec --require ts-node/register --require-main "tests/gui/allow-renderer-process-reuse.ts"
|
MOCHA_OPTIONS=--recursive --reporter spec --require ts-node/register --require-main "tests/gui/allow-renderer-process-reuse.ts"
|
||||||
|
|
||||||
# See https://github.com/electron/spectron/issues/127
|
|
||||||
ETCHER_SPECTRON_ENTRYPOINT ?= $(shell node -e 'console.log(require("electron"))')
|
|
||||||
test-spectron:
|
test-spectron:
|
||||||
ETCHER_SPECTRON_ENTRYPOINT="$(ETCHER_SPECTRON_ENTRYPOINT)" mocha $(MOCHA_OPTIONS) tests/spectron/runner.spec.ts
|
mocha $(MOCHA_OPTIONS) tests/spectron/runner.spec.ts
|
||||||
|
|
||||||
test-gui:
|
test-gui:
|
||||||
electron-mocha $(MOCHA_OPTIONS) --full-trace --no-sandbox --renderer tests/gui/**/*.ts
|
electron-mocha $(MOCHA_OPTIONS) --full-trace --no-sandbox --renderer tests/gui/**/*.ts
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
const { notarize } = require('electron-notarize')
|
const { notarize } = require('electron-notarize')
|
||||||
|
const { ELECTRON_SKIP_NOTARIZATION } = process.env
|
||||||
|
|
||||||
async function main(context) {
|
async function main(context) {
|
||||||
const { electronPlatformName, appOutDir } = context
|
const { electronPlatformName, appOutDir } = context
|
||||||
if (electronPlatformName !== 'darwin') {
|
if (electronPlatformName !== 'darwin' || ELECTRON_SKIP_NOTARIZATION === 'true') {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,17 +1,26 @@
|
|||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
const cp = require('child_process')
|
const cp = require('child_process');
|
||||||
|
const rimraf = require('rimraf');
|
||||||
|
const process = require('process');
|
||||||
|
|
||||||
// Rebuild native modules for ia32 and run webpack again for the ia32 part of windows packages
|
// Rebuild native modules for ia32 and run webpack again for the ia32 part of windows packages
|
||||||
exports.default = function(context) {
|
exports.default = function(context) {
|
||||||
if (context.platform.name === 'windows') {
|
if (context.platform.name === 'windows') {
|
||||||
cp.execFileSync(
|
cp.execFileSync(
|
||||||
'bash',
|
'bash',
|
||||||
['./node_modules/.bin/electron-rebuild', '--types', 'dev', '--arch', context.arch]
|
['./node_modules/.bin/electron-rebuild', '--types', 'dev', '--arch', context.arch],
|
||||||
);
|
);
|
||||||
|
rimraf.sync('generated');
|
||||||
cp.execFileSync(
|
cp.execFileSync(
|
||||||
'bash',
|
'bash',
|
||||||
['./node_modules/.bin/webpack']
|
['./node_modules/.bin/webpack'],
|
||||||
|
{
|
||||||
|
env: {
|
||||||
|
...process.env,
|
||||||
|
npm_config_target_arch: context.arch,
|
||||||
|
},
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,3 +91,7 @@ deb:
|
|||||||
rpm:
|
rpm:
|
||||||
depends:
|
depends:
|
||||||
- util-linux
|
- util-linux
|
||||||
|
protocols:
|
||||||
|
name: etcher
|
||||||
|
schemes:
|
||||||
|
- etcher
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
import { faFile, faLink } from '@fortawesome/free-solid-svg-icons';
|
import { faFile, faLink } from '@fortawesome/free-solid-svg-icons';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import { sourceDestination } from 'etcher-sdk';
|
import { sourceDestination } from 'etcher-sdk';
|
||||||
|
import { ipcRenderer, IpcRendererEvent } from 'electron';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import { GPTPartition, MBRPartition } from 'partitioninfo';
|
import { GPTPartition, MBRPartition } from 'partitioninfo';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
@ -237,6 +238,7 @@ export class SourceSelector extends React.Component<
|
|||||||
this.openImageSelector = this.openImageSelector.bind(this);
|
this.openImageSelector = this.openImageSelector.bind(this);
|
||||||
this.openURLSelector = this.openURLSelector.bind(this);
|
this.openURLSelector = this.openURLSelector.bind(this);
|
||||||
this.reselectImage = this.reselectImage.bind(this);
|
this.reselectImage = this.reselectImage.bind(this);
|
||||||
|
this.onSelectImage = this.onSelectImage.bind(this);
|
||||||
this.onDrop = this.onDrop.bind(this);
|
this.onDrop = this.onDrop.bind(this);
|
||||||
this.showSelectedImageDetails = this.showSelectedImageDetails.bind(this);
|
this.showSelectedImageDetails = this.showSelectedImageDetails.bind(this);
|
||||||
this.afterSelected = props.afterSelected.bind(this);
|
this.afterSelected = props.afterSelected.bind(this);
|
||||||
@ -246,10 +248,22 @@ export class SourceSelector extends React.Component<
|
|||||||
this.unsubscribe = observe(() => {
|
this.unsubscribe = observe(() => {
|
||||||
this.setState(getState());
|
this.setState(getState());
|
||||||
});
|
});
|
||||||
|
ipcRenderer.on('select-image', this.onSelectImage);
|
||||||
|
ipcRenderer.send('source-selector-ready');
|
||||||
}
|
}
|
||||||
|
|
||||||
public componentWillUnmount() {
|
public componentWillUnmount() {
|
||||||
this.unsubscribe();
|
this.unsubscribe();
|
||||||
|
ipcRenderer.removeListener('select-image', this.onSelectImage);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async onSelectImage(_event: IpcRendererEvent, imagePath: string) {
|
||||||
|
const isURL =
|
||||||
|
_.startsWith(imagePath, 'https://') || _.startsWith(imagePath, 'http://');
|
||||||
|
await this.selectImageByPath({
|
||||||
|
imagePath,
|
||||||
|
SourceType: isURL ? sourceDestination.Http : sourceDestination.File,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private reselectImage() {
|
private reselectImage() {
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
import { delay } from 'bluebird';
|
import { delay } from 'bluebird';
|
||||||
import * as electron from 'electron';
|
import * as electron from 'electron';
|
||||||
import { autoUpdater } from 'electron-updater';
|
import { autoUpdater } from 'electron-updater';
|
||||||
|
import { platform } from 'os';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as semver from 'semver';
|
import * as semver from 'semver';
|
||||||
@ -28,6 +29,8 @@ import * as settings from './app/models/settings';
|
|||||||
import * as analytics from './app/modules/analytics';
|
import * as analytics from './app/modules/analytics';
|
||||||
import { buildWindowMenu } from './menu';
|
import { buildWindowMenu } from './menu';
|
||||||
|
|
||||||
|
const customProtocol = 'etcher';
|
||||||
|
const scheme = `${customProtocol}://`;
|
||||||
const updatablePackageTypes = ['appimage', 'nsis', 'dmg'];
|
const updatablePackageTypes = ['appimage', 'nsis', 'dmg'];
|
||||||
const packageUpdatable = _.includes(updatablePackageTypes, packageType);
|
const packageUpdatable = _.includes(updatablePackageTypes, packageType);
|
||||||
let packageUpdated = false;
|
let packageUpdated = false;
|
||||||
@ -54,6 +57,44 @@ async function checkForUpdates(interval: number) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getCommandLineURL(argv: string[]): string | undefined {
|
||||||
|
argv = argv.slice(electron.app.isPackaged ? 1 : 2);
|
||||||
|
if (argv.length) {
|
||||||
|
const value = argv[argv.length - 1];
|
||||||
|
// Take into account electron arguments
|
||||||
|
if (value.startsWith('--')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// https://stackoverflow.com/questions/10242115/os-x-strange-psn-command-line-parameter-when-launched-from-finder
|
||||||
|
if (platform() === 'darwin' && value.startsWith('-psn_')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const sourceSelectorReady = new Promise((resolve) => {
|
||||||
|
electron.ipcMain.on('source-selector-ready', resolve);
|
||||||
|
});
|
||||||
|
|
||||||
|
async function selectImageURL(url?: string) {
|
||||||
|
// 'data:,' is the default chromedriver url that is passed as last argument when running spectron tests
|
||||||
|
if (url !== undefined && url !== 'data:,') {
|
||||||
|
url = url.startsWith(scheme) ? url.slice(scheme.length) : url;
|
||||||
|
await sourceSelectorReady;
|
||||||
|
electron.BrowserWindow.getAllWindows().forEach((window) => {
|
||||||
|
window.webContents.send('select-image', url);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This will catch clicks on links such as <a href="etcher://...">Open in Etcher</a>
|
||||||
|
// We need to listen to the event before everything else otherwise the event won't be fired
|
||||||
|
electron.app.on('open-url', async (event, data) => {
|
||||||
|
event.preventDefault();
|
||||||
|
await selectImageURL(data);
|
||||||
|
});
|
||||||
|
|
||||||
async function createMainWindow() {
|
async function createMainWindow() {
|
||||||
const fullscreen = Boolean(await settings.get('fullscreen'));
|
const fullscreen = Boolean(await settings.get('fullscreen'));
|
||||||
const defaultWidth = 800;
|
const defaultWidth = 800;
|
||||||
@ -87,6 +128,8 @@ async function createMainWindow() {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
electron.app.setAsDefaultProtocolClient(customProtocol);
|
||||||
|
|
||||||
buildWindowMenu(mainWindow);
|
buildWindowMenu(mainWindow);
|
||||||
mainWindow.setFullScreen(true);
|
mainWindow.setFullScreen(true);
|
||||||
|
|
||||||
@ -133,6 +176,7 @@ async function createMainWindow() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
return mainWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
electron.app.allowRendererProcessReuse = false;
|
electron.app.allowRendererProcessReuse = false;
|
||||||
@ -145,14 +189,24 @@ electron.app.on('window-all-closed', electron.app.quit);
|
|||||||
// make use of it to ensure the browser window is completely destroyed.
|
// make use of it to ensure the browser window is completely destroyed.
|
||||||
// See https://github.com/electron/electron/issues/5273
|
// See https://github.com/electron/electron/issues/5273
|
||||||
electron.app.on('before-quit', () => {
|
electron.app.on('before-quit', () => {
|
||||||
|
electron.app.releaseSingleInstanceLock();
|
||||||
process.exit(EXIT_CODES.SUCCESS);
|
process.exit(EXIT_CODES.SUCCESS);
|
||||||
});
|
});
|
||||||
|
|
||||||
async function main(): Promise<void> {
|
async function main(): Promise<void> {
|
||||||
if (electron.app.isReady()) {
|
if (!electron.app.requestSingleInstanceLock()) {
|
||||||
await createMainWindow();
|
electron.app.quit();
|
||||||
} else {
|
} else {
|
||||||
electron.app.on('ready', createMainWindow);
|
await electron.app.whenReady();
|
||||||
|
const window = await createMainWindow();
|
||||||
|
electron.app.on('second-instance', async (_event, argv) => {
|
||||||
|
if (window.isMinimized()) {
|
||||||
|
window.restore();
|
||||||
|
}
|
||||||
|
window.focus();
|
||||||
|
await selectImageURL(getCommandLineURL(argv));
|
||||||
|
});
|
||||||
|
await selectImageURL(getCommandLineURL(process.argv));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,7 +246,7 @@ ipc.connectTo(IPC_SERVER_ID, () => {
|
|||||||
path: options.imagePath,
|
path: options.imagePath,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
source = new Http({ url: options.imagePath });
|
source = new Http({ url: options.imagePath, avoidRandomAccess: true });
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const results = await writeAndValidate({
|
const results = await writeAndValidate({
|
||||||
|
@ -29,7 +29,10 @@ import { tmpFileDisposer } from './utils';
|
|||||||
|
|
||||||
const execAsync = promisify(childProcess.exec);
|
const execAsync = promisify(childProcess.exec);
|
||||||
const execFileAsync = promisify(childProcess.execFile);
|
const execFileAsync = promisify(childProcess.execFile);
|
||||||
const sudoExecAsync = promisify(sudoPrompt.exec);
|
// sudo-prompt's exec callback is function(error, stdout, stderr) so we need multiArgs
|
||||||
|
const sudoExecAsync = Bluebird.promisify(sudoPrompt.exec, {
|
||||||
|
multiArgs: true,
|
||||||
|
}) as (cmd: string, options: any) => Bluebird<[string, string]>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @summary The user id of the UNIX "superuser"
|
* @summary The user id of the UNIX "superuser"
|
||||||
@ -123,10 +126,7 @@ async function elevateScriptUnix(
|
|||||||
name: string,
|
name: string,
|
||||||
): Promise<{ cancelled: boolean }> {
|
): Promise<{ cancelled: boolean }> {
|
||||||
const cmd = ['bash', escapeSh(path)].join(' ');
|
const cmd = ['bash', escapeSh(path)].join(' ');
|
||||||
const [, stderr] = await sudoExecAsync(cmd, { name });
|
await sudoExecAsync(cmd, { name });
|
||||||
if (!_.isEmpty(stderr)) {
|
|
||||||
throw errors.createError({ title: stderr });
|
|
||||||
}
|
|
||||||
return { cancelled: false };
|
return { cancelled: false };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
159
npm-shrinkwrap.json
generated
159
npm-shrinkwrap.json
generated
@ -677,6 +677,16 @@
|
|||||||
"integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==",
|
"integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@types/copy-webpack-plugin": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/copy-webpack-plugin/-/copy-webpack-plugin-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-Ousy+sNap1j44eG+C9FZvTUybpp9lFmKjBRF7L0NDs/+SDA9OXKo2OpsHJfD/LMWflz+uvfTCBXH1CgdL6AW/g==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/node": "*",
|
||||||
|
"@types/webpack": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@types/debug": {
|
"@types/debug": {
|
||||||
"version": "4.1.5",
|
"version": "4.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.5.tgz",
|
||||||
@ -965,13 +975,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@types/terser-webpack-plugin": {
|
"@types/terser-webpack-plugin": {
|
||||||
"version": "2.2.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/terser-webpack-plugin/-/terser-webpack-plugin-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/terser-webpack-plugin/-/terser-webpack-plugin-3.0.0.tgz",
|
||||||
"integrity": "sha512-ywqEfTm7KdKoX9aYx0zYtiFU1z6IHrIYW9FJqeay2Ea58rTPML1J0hvoztGal2Jow3bkgGKcAmEZNL+8LqUVrA==",
|
"integrity": "sha512-K5C7izOT8rR4qiE2vfXcQNEJN4lT9cq/2qJgpMUWR2HsjDW/KVrHx2CaHuaXvaqDNsRmdELPLaxeJHiI4GjVrA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/webpack": "*",
|
"@types/webpack": "*",
|
||||||
"terser": "^4.3.9"
|
"terser": "^4.6.13"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@types/tmp": {
|
"@types/tmp": {
|
||||||
@ -4325,9 +4335,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"drivelist": {
|
"drivelist": {
|
||||||
"version": "9.0.0",
|
"version": "9.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/drivelist/-/drivelist-9.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/drivelist/-/drivelist-9.0.2.tgz",
|
||||||
"integrity": "sha512-DNQ1oFAv5p1+UKVkQHCYQFHolFbItxSnjcJchxrhlEkW4RSuLfC0xOnq87uM8dcMzOuPfA37SKX7HsUIpw14uA==",
|
"integrity": "sha512-B68AttNDXsew8M2viM99I4sNMJ2T5/lZ2fDlVsEAAzaJ1pyZN2Ibhhd37LAqsNRPhhPtpyrCi9+C6AfJ2kwo4g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"bindings": "^1.3.0",
|
"bindings": "^1.3.0",
|
||||||
@ -4402,9 +4412,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"electron": {
|
"electron": {
|
||||||
"version": "9.0.0",
|
"version": "9.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/electron/-/electron-9.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/electron/-/electron-9.0.2.tgz",
|
||||||
"integrity": "sha512-JsaSQNPh+XDYkLj8APtVKTtvpb86KIG57W5OOss4TNrn8L3isC9LsCITwfnVmGIXHhvX6oY/weCtN5hAAytjVg==",
|
"integrity": "sha512-+a3KegLvQXVjC3b6yBWwZmtWp3tHf9ut27yORAWHO9JRFtKfNf88fi1UvTPJSW8R0sUH7ZEdzN6A95T22KGtlA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@electron/get": "^1.0.1",
|
"@electron/get": "^1.0.1",
|
||||||
@ -4756,6 +4766,25 @@
|
|||||||
"path-exists": "^3.0.0"
|
"path-exists": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node-gyp": {
|
||||||
|
"version": "6.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-6.1.0.tgz",
|
||||||
|
"integrity": "sha512-h4A2zDlOujeeaaTx06r4Vy+8MZ1679lU+wbCKDS4ZtvY2A37DESo37oejIw0mtmR3+rvNwts5B6Kpt1KrNYdNw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"env-paths": "^2.2.0",
|
||||||
|
"glob": "^7.1.4",
|
||||||
|
"graceful-fs": "^4.2.2",
|
||||||
|
"mkdirp": "^0.5.1",
|
||||||
|
"nopt": "^4.0.1",
|
||||||
|
"npmlog": "^4.1.2",
|
||||||
|
"request": "^2.88.0",
|
||||||
|
"rimraf": "^2.6.3",
|
||||||
|
"semver": "^5.7.1",
|
||||||
|
"tar": "^4.4.12",
|
||||||
|
"which": "^1.3.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"p-locate": {
|
"p-locate": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
|
||||||
@ -4771,6 +4800,12 @@
|
|||||||
"integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
|
"integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"semver": {
|
||||||
|
"version": "5.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||||
|
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"string-width": {
|
"string-width": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
|
||||||
@ -5320,9 +5355,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"etcher-sdk": {
|
"etcher-sdk": {
|
||||||
"version": "4.1.4",
|
"version": "4.1.8",
|
||||||
"resolved": "https://registry.npmjs.org/etcher-sdk/-/etcher-sdk-4.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/etcher-sdk/-/etcher-sdk-4.1.8.tgz",
|
||||||
"integrity": "sha512-s9KXeLOtwrOxZs6F2VpGdS2VARwgJzmQp7/Xh4DG0yTAIR58djzZ2+cmUQQN16ztFMiQdCgTWWnOUJV1eVtO4g==",
|
"integrity": "sha512-fSNwpqeCdc75xNIKwf+At8+r/EQ+/X/IV7gUYFa/wKXtnFHHxYJor6VfPdELUbtDDBWWa2cneJvtwGmcDPBAvA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ronomon/direct-io": "^3.0.1",
|
"@ronomon/direct-io": "^3.0.1",
|
||||||
@ -9454,9 +9489,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node-addon-api": {
|
"node-addon-api": {
|
||||||
"version": "1.7.1",
|
"version": "1.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz",
|
||||||
"integrity": "sha512-2+DuKodWvwRTrCfKOeR24KIc5unKjOh8mz17NCzVnHWfjAdDqbfbjqh7gUT+BkXBRQM52+xCHciKWonJ3CbJMQ==",
|
"integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node-environment-flags": {
|
"node-environment-flags": {
|
||||||
@ -9488,28 +9523,90 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node-gyp": {
|
"node-gyp": {
|
||||||
"version": "6.1.0",
|
"version": "7.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-6.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.0.0.tgz",
|
||||||
"integrity": "sha512-h4A2zDlOujeeaaTx06r4Vy+8MZ1679lU+wbCKDS4ZtvY2A37DESo37oejIw0mtmR3+rvNwts5B6Kpt1KrNYdNw==",
|
"integrity": "sha512-ZW34qA3CJSPKDz2SJBHKRvyNQN0yWO5EGKKksJc+jElu9VA468gwJTyTArC1iOXU7rN3Wtfg/CMt/dBAOFIjvg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"env-paths": "^2.2.0",
|
"env-paths": "^2.2.0",
|
||||||
"glob": "^7.1.4",
|
"glob": "^7.1.4",
|
||||||
"graceful-fs": "^4.2.2",
|
"graceful-fs": "^4.2.3",
|
||||||
"mkdirp": "^0.5.1",
|
"nopt": "^4.0.3",
|
||||||
"nopt": "^4.0.1",
|
|
||||||
"npmlog": "^4.1.2",
|
"npmlog": "^4.1.2",
|
||||||
"request": "^2.88.0",
|
"request": "^2.88.2",
|
||||||
"rimraf": "^2.6.3",
|
"rimraf": "^2.6.3",
|
||||||
"semver": "^5.7.1",
|
"semver": "^7.3.2",
|
||||||
"tar": "^4.4.12",
|
"tar": "^6.0.1",
|
||||||
"which": "^1.3.1"
|
"which": "^2.0.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"semver": {
|
"chownr": {
|
||||||
"version": "5.7.1",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
|
||||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
|
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"fs-minipass": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"minipass": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"minipass": {
|
||||||
|
"version": "3.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz",
|
||||||
|
"integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"yallist": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"minizlib": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-EzTZN/fjSvifSX0SlqUERCN39o6T40AMarPbv0MrarSFtIITCBh7bi+dU8nxGFHuqs9jdIAeoYoKuQAAASsPPA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"minipass": "^3.0.0",
|
||||||
|
"yallist": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mkdirp": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
|
||||||
|
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"tar": {
|
||||||
|
"version": "6.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/tar/-/tar-6.0.2.tgz",
|
||||||
|
"integrity": "sha512-Glo3jkRtPcvpDlAs/0+hozav78yoXKFr+c4wgw62NNMO3oo4AaJdCo21Uu7lcwr55h39W2XD1LMERc64wtbItg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"chownr": "^2.0.0",
|
||||||
|
"fs-minipass": "^2.0.0",
|
||||||
|
"minipass": "^3.0.0",
|
||||||
|
"minizlib": "^2.1.0",
|
||||||
|
"mkdirp": "^1.0.3",
|
||||||
|
"yallist": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"which": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"isexe": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"yallist": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||||
"dev": true
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -14963,4 +15060,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -51,6 +51,7 @@
|
|||||||
"@fortawesome/react-fontawesome": "^0.1.7",
|
"@fortawesome/react-fontawesome": "^0.1.7",
|
||||||
"@types/bluebird": "^3.5.30",
|
"@types/bluebird": "^3.5.30",
|
||||||
"@types/chai": "^4.2.7",
|
"@types/chai": "^4.2.7",
|
||||||
|
"@types/copy-webpack-plugin": "^6.0.0",
|
||||||
"@types/mime-types": "^2.1.0",
|
"@types/mime-types": "^2.1.0",
|
||||||
"@types/mini-css-extract-plugin": "^0.9.1",
|
"@types/mini-css-extract-plugin": "^0.9.1",
|
||||||
"@types/mocha": "^7.0.2",
|
"@types/mocha": "^7.0.2",
|
||||||
@ -60,7 +61,7 @@
|
|||||||
"@types/request": "^2.48.4",
|
"@types/request": "^2.48.4",
|
||||||
"@types/semver": "^7.1.0",
|
"@types/semver": "^7.1.0",
|
||||||
"@types/sinon": "^9.0.0",
|
"@types/sinon": "^9.0.0",
|
||||||
"@types/terser-webpack-plugin": "^2.2.0",
|
"@types/terser-webpack-plugin": "^3.0.0",
|
||||||
"@types/tmp": "^0.2.0",
|
"@types/tmp": "^0.2.0",
|
||||||
"@types/webpack-node-externals": "^1.7.0",
|
"@types/webpack-node-externals": "^1.7.0",
|
||||||
"bluebird": "^3.7.2",
|
"bluebird": "^3.7.2",
|
||||||
@ -70,13 +71,13 @@
|
|||||||
"css-loader": "^3.5.3",
|
"css-loader": "^3.5.3",
|
||||||
"d3": "^4.13.0",
|
"d3": "^4.13.0",
|
||||||
"debug": "^4.2.0",
|
"debug": "^4.2.0",
|
||||||
"electron": "9.0.0",
|
"electron": "9.0.2",
|
||||||
"electron-builder": "^22.7.0",
|
"electron-builder": "^22.7.0",
|
||||||
"electron-mocha": "^8.2.0",
|
"electron-mocha": "^8.2.0",
|
||||||
"electron-notarize": "^0.3.0",
|
"electron-notarize": "^0.3.0",
|
||||||
"electron-rebuild": "^1.11.0",
|
"electron-rebuild": "^1.11.0",
|
||||||
"electron-updater": "^4.3.2",
|
"electron-updater": "^4.3.2",
|
||||||
"etcher-sdk": "^4.1.4",
|
"etcher-sdk": "^4.1.8",
|
||||||
"file-loader": "^6.0.0",
|
"file-loader": "^6.0.0",
|
||||||
"flexboxgrid": "^6.3.0",
|
"flexboxgrid": "^6.3.0",
|
||||||
"husky": "^4.2.5",
|
"husky": "^4.2.5",
|
||||||
@ -89,7 +90,7 @@
|
|||||||
"mocha": "^7.0.1",
|
"mocha": "^7.0.1",
|
||||||
"nan": "^2.14.0",
|
"nan": "^2.14.0",
|
||||||
"native-addon-loader": "^2.0.1",
|
"native-addon-loader": "^2.0.1",
|
||||||
"node-gyp": "^6.1.0",
|
"node-gyp": "^7.0.0",
|
||||||
"node-ipc": "^9.1.1",
|
"node-ipc": "^9.1.1",
|
||||||
"omit-deep-lodash": "1.1.4",
|
"omit-deep-lodash": "1.1.4",
|
||||||
"path-is-inside": "^1.0.2",
|
"path-is-inside": "^1.0.2",
|
||||||
|
@ -16,41 +16,29 @@
|
|||||||
|
|
||||||
import { expect } from 'chai';
|
import { expect } from 'chai';
|
||||||
import { Application } from 'spectron';
|
import { Application } from 'spectron';
|
||||||
|
import * as electronPath from 'electron';
|
||||||
import * as EXIT_CODES from '../../lib/shared/exit-codes';
|
|
||||||
|
|
||||||
const entrypoint = process.env.ETCHER_SPECTRON_ENTRYPOINT;
|
|
||||||
|
|
||||||
if (!entrypoint) {
|
|
||||||
console.error('You need to properly configure ETCHER_SPECTRON_ENTRYPOINT');
|
|
||||||
process.exit(EXIT_CODES.GENERAL_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('Spectron', function () {
|
describe('Spectron', function () {
|
||||||
// Mainly for CI jobs
|
// Mainly for CI jobs
|
||||||
this.timeout(40000);
|
this.timeout(40000);
|
||||||
|
|
||||||
let app: Application;
|
const app = new Application({
|
||||||
|
path: (electronPath as unknown) as string,
|
||||||
before('app:start', function () {
|
args: ['--no-sandbox', '.'],
|
||||||
app = new Application({
|
|
||||||
path: entrypoint,
|
|
||||||
args: ['--no-sandbox', '.'],
|
|
||||||
});
|
|
||||||
|
|
||||||
return app.start();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
after('app:stop', function () {
|
before('app:start', async () => {
|
||||||
|
await app.start();
|
||||||
|
});
|
||||||
|
|
||||||
|
after('app:stop', async () => {
|
||||||
if (app && app.isRunning()) {
|
if (app && app.isRunning()) {
|
||||||
return app.stop();
|
await app.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.resolve();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Browser Window', function () {
|
describe('Browser Window', () => {
|
||||||
it('should open a browser window', async function () {
|
it('should open a browser window', async () => {
|
||||||
// We can't use `isVisible()` here as it won't work inside
|
// We can't use `isVisible()` here as it won't work inside
|
||||||
// a Windows Docker container, but we can approximate it
|
// a Windows Docker container, but we can approximate it
|
||||||
// with these set of checks:
|
// with these set of checks:
|
||||||
@ -61,7 +49,7 @@ describe('Spectron', function () {
|
|||||||
expect(await app.browserWindow.isFocused()).to.be.true;
|
expect(await app.browserWindow.isFocused()).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set a proper title', async function () {
|
it('should set a proper title', async () => {
|
||||||
// @ts-ignore (SpectronClient.getTitle exists)
|
// @ts-ignore (SpectronClient.getTitle exists)
|
||||||
return expect(await app.client.getTitle()).to.equal('Etcher');
|
return expect(await app.client.getTitle()).to.equal('Etcher');
|
||||||
});
|
});
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// @ts-ignore @types for copy-webpack-plugin@6.0.1 not released yet
|
|
||||||
import * as CopyPlugin from 'copy-webpack-plugin';
|
import * as CopyPlugin from 'copy-webpack-plugin';
|
||||||
import { readdirSync } from 'fs';
|
import { readdirSync } from 'fs';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
@ -22,6 +21,7 @@ import * as MiniCssExtractPlugin from 'mini-css-extract-plugin';
|
|||||||
import * as os from 'os';
|
import * as os from 'os';
|
||||||
import outdent from 'outdent';
|
import outdent from 'outdent';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
import { env } from 'process';
|
||||||
import * as SimpleProgressWebpackPlugin from 'simple-progress-webpack-plugin';
|
import * as SimpleProgressWebpackPlugin from 'simple-progress-webpack-plugin';
|
||||||
import * as TerserPlugin from 'terser-webpack-plugin';
|
import * as TerserPlugin from 'terser-webpack-plugin';
|
||||||
import { BannerPlugin, NormalModuleReplacementPlugin } from 'webpack';
|
import { BannerPlugin, NormalModuleReplacementPlugin } from 'webpack';
|
||||||
@ -77,7 +77,11 @@ function renameNodeModules(resourcePath: string) {
|
|||||||
|
|
||||||
function findLzmaNativeBindingsFolder(): string {
|
function findLzmaNativeBindingsFolder(): string {
|
||||||
const files = readdirSync(path.join('node_modules', 'lzma-native'));
|
const files = readdirSync(path.join('node_modules', 'lzma-native'));
|
||||||
const bindingsFolder = files.find((f) => f.startsWith('binding-'));
|
const bindingsFolder = files.find(
|
||||||
|
(f) =>
|
||||||
|
f.startsWith('binding-') &&
|
||||||
|
f.endsWith(env.npm_config_target_arch || os.arch()),
|
||||||
|
);
|
||||||
if (bindingsFolder === undefined) {
|
if (bindingsFolder === undefined) {
|
||||||
throw new Error('Could not find lzma_native binding');
|
throw new Error('Could not find lzma_native binding');
|
||||||
}
|
}
|
||||||
@ -91,11 +95,15 @@ interface ReplacementRule {
|
|||||||
replace: string | (() => string);
|
replace: string | (() => string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function slashOrAntislash(pattern: RegExp): RegExp {
|
||||||
|
return new RegExp(pattern.source.replace(/\\\//g, '(\\/|\\\\)'));
|
||||||
|
}
|
||||||
|
|
||||||
function replace(test: RegExp, ...replacements: ReplacementRule[]) {
|
function replace(test: RegExp, ...replacements: ReplacementRule[]) {
|
||||||
return {
|
return {
|
||||||
loader: 'string-replace-loader',
|
loader: 'string-replace-loader',
|
||||||
// Handle windows path separators
|
// Handle windows path separators
|
||||||
test: new RegExp(test.source.replace(/\\\//g, '(\\/|\\\\)')),
|
test: slashOrAntislash(test),
|
||||||
options: { multiple: replacements.map((r) => ({ ...r, strict: true })) },
|
options: { multiple: replacements.map((r) => ({ ...r, strict: true })) },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -218,7 +226,7 @@ const commonConfig = {
|
|||||||
// Force axios to use http.js, not xhr.js as we need stream support
|
// Force axios to use http.js, not xhr.js as we need stream support
|
||||||
// (it's package.json file replaces http with xhr for browser targets).
|
// (it's package.json file replaces http with xhr for browser targets).
|
||||||
new NormalModuleReplacementPlugin(
|
new NormalModuleReplacementPlugin(
|
||||||
/node_modules\/axios\/lib\/adapters\/xhr\.js/,
|
slashOrAntislash(/node_modules\/axios\/lib\/adapters\/xhr\.js/),
|
||||||
'./http.js',
|
'./http.js',
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user