Remove bluebird from main process, reduce lodash usage

Changelog-entry: Remove bluebird from main process, reduce lodash usage
Change-type: patch
This commit is contained in:
Alexis Svinartchouk 2020-07-16 14:56:32 +02:00
parent 963fc574c3
commit 512785e0a9
7 changed files with 63 additions and 83 deletions

View File

@ -18,7 +18,7 @@ import * as _ from 'lodash';
import * as resinCorvus from 'resin-corvus/browser';
import * as packageJSON from '../../../../package.json';
import { getConfig, hasProps } from '../../../shared/utils';
import { getConfig } from '../../../shared/utils';
import * as settings from '../models/settings';
import { store } from '../models/store';
@ -55,7 +55,8 @@ async function initConfig() {
await installCorvus();
let validatedConfig = null;
try {
const config = await getConfig();
const configUrl = await settings.get('configUrl');
const config = await getConfig(configUrl);
const mixpanel = _.get(config, ['analytics', 'mixpanel'], {});
mixpanelSample = mixpanel.probability || DEFAULT_PROBABILITY;
if (isClientEligible(mixpanelSample)) {
@ -88,7 +89,7 @@ function validateMixpanelConfig(config: {
const mixpanelConfig = {
api_host: 'https://api.mixpanel.com',
};
if (hasProps(config, ['HTTP_PROTOCOL', 'api_host'])) {
if (config.HTTP_PROTOCOL !== undefined && config.api_host !== undefined) {
mixpanelConfig.api_host = `${config.HTTP_PROTOCOL}://${config.api_host}`;
}
return mixpanelConfig;

View File

@ -23,7 +23,7 @@ import { join } from 'path';
import { env } from 'process';
import { promisify } from 'util';
import { tmpFileDisposer } from '../../../shared/utils';
import { tmpFileDisposer } from '../../../shared/tmp';
const readFileAsync = promisify(readFile);

View File

@ -14,26 +14,24 @@
* limitations under the License.
*/
import { delay } from 'bluebird';
import * as electron from 'electron';
import { autoUpdater } from 'electron-updater';
import { promises as fs } from 'fs';
import { platform } from 'os';
import * as _ from 'lodash';
import * as path from 'path';
import * as semver from 'semver';
import { packageType, version } from '../../package.json';
import * as EXIT_CODES from '../shared/exit-codes';
import { getConfig } from '../shared/utils';
import { delay, getConfig } from '../shared/utils';
import * as settings from './app/models/settings';
import * as analytics from './app/modules/analytics';
import { logException } from './app/modules/analytics';
import { buildWindowMenu } from './menu';
const customProtocol = 'etcher';
const scheme = `${customProtocol}://`;
const updatablePackageTypes = ['appimage', 'nsis', 'dmg'];
const packageUpdatable = _.includes(updatablePackageTypes, packageType);
const packageUpdatable = updatablePackageTypes.includes(packageType);
let packageUpdated = false;
async function checkForUpdates(interval: number) {
@ -51,7 +49,7 @@ async function checkForUpdates(interval: number) {
packageUpdated = true;
}
} catch (err) {
analytics.logException(err);
logException(err);
}
}
await delay(interval);
@ -114,6 +112,14 @@ electron.app.on('open-url', async (event, data) => {
await selectImageURL(data);
});
interface AutoUpdaterConfig {
autoDownload?: boolean;
autoInstallOnAppQuit?: boolean;
allowPrerelease?: boolean;
fullChangelog?: boolean;
allowDowngrade?: boolean;
}
async function createMainWindow() {
const fullscreen = Boolean(await settings.get('fullscreen'));
const defaultWidth = 800;
@ -171,27 +177,24 @@ async function createMainWindow() {
page.once('did-frame-finish-load', async () => {
autoUpdater.on('error', (err) => {
analytics.logException(err);
logException(err);
});
if (packageUpdatable) {
try {
const onlineConfig = await getConfig();
const autoUpdaterConfig = _.get(
onlineConfig,
['autoUpdates', 'autoUpdaterConfig'],
{
autoDownload: false,
},
);
_.merge(autoUpdater, autoUpdaterConfig);
const checkForUpdatesTimer = _.get(
onlineConfig,
['autoUpdates', 'checkForUpdatesTimer'],
300000,
);
const configUrl = await settings.get('configUrl');
const onlineConfig = await getConfig(configUrl);
const autoUpdaterConfig: AutoUpdaterConfig = onlineConfig?.autoUpdates
?.autoUpdaterConfig ?? {
autoDownload: false,
};
for (const [key, value] of Object.entries(autoUpdaterConfig)) {
autoUpdater[key as keyof AutoUpdaterConfig] = value;
}
const checkForUpdatesTimer =
onlineConfig?.autoUpdates?.checkForUpdatesTimer ?? 300000;
checkForUpdates(checkForUpdatesTimer);
} catch (err) {
analytics.logException(err);
logException(err);
}
}
});

View File

@ -14,7 +14,6 @@
* limitations under the License.
*/
import { delay } from 'bluebird';
import { Drive as DrivelistDrive } from 'drivelist';
import * as sdk from 'etcher-sdk';
import { cleanupTmpFiles } from 'etcher-sdk/build/tmp';
@ -23,6 +22,7 @@ import * as ipc from 'node-ipc';
import { toJSON } from '../../shared/errors';
import { GENERAL_ERROR, SUCCESS } from '../../shared/exit-codes';
import { delay } from '../../shared/utils';
import { SourceOptions } from '../app/components/source-selector/source-selector';
ipc.config.id = process.env.IPC_CLIENT_ID as string;

View File

@ -25,7 +25,7 @@ import { promisify } from 'util';
import { sudo as catalinaSudo } from './catalina-sudo/sudo';
import * as errors from './errors';
import { tmpFileDisposer } from './utils';
import { tmpFileDisposer } from './tmp';
const execAsync = promisify(childProcess.exec);
const execFileAsync = promisify(childProcess.execFile);

24
lib/shared/tmp.ts Normal file
View File

@ -0,0 +1,24 @@
import * as Bluebird from 'bluebird';
import * as tmp from 'tmp';
function tmpFileAsync(
options: tmp.FileOptions,
): Promise<{ path: string; cleanup: () => void }> {
return new Promise((resolve, reject) => {
tmp.file(options, (error, path, _fd, cleanup) => {
if (error) {
reject(error);
} else {
resolve({ path, cleanup });
}
});
});
}
export function tmpFileDisposer(
options: tmp.FileOptions,
): Bluebird.Disposer<{ path: string; cleanup: () => void }> {
return Bluebird.resolve(tmpFileAsync(options)).disposer(({ cleanup }) => {
cleanup();
});
}

View File

@ -15,15 +15,12 @@
*/
import axios from 'axios';
import * as Bluebird from 'bluebird';
import * as _ from 'lodash';
import * as tmp from 'tmp';
import { Dictionary } from 'lodash';
import * as errors from './errors';
import * as settings from '../gui/app/models/settings';
export function isValidPercentage(percentage: any): boolean {
return _.every([_.isNumber(percentage), percentage >= 0, percentage <= 100]);
return typeof percentage === 'number' && percentage >= 0 && percentage <= 100;
}
export function percentageToFloat(percentage: any) {
@ -35,63 +32,18 @@ export function percentageToFloat(percentage: any) {
return percentage / 100;
}
/**
* @summary Check if obj has one or many specific props
*/
export function hasProps(obj: _.Dictionary<any>, props: string[]): boolean {
return _.every(props, (prop) => {
return _.has(obj, prop);
});
}
/**
* @summary Get etcher configs stored online
* @param {String} - url where config.json is stored
*/
export async function getConfig(): Promise<_.Dictionary<any>> {
const configUrl =
(await settings.get('configUrl')) ||
'https://balena.io/etcher/static/config.json';
export async function getConfig(configUrl?: string): Promise<Dictionary<any>> {
configUrl = configUrl ?? 'https://balena.io/etcher/static/config.json';
const response = await axios.get(configUrl, { responseType: 'json' });
return response.data;
}
/**
* @summary returns { path: String, cleanup: Function }
*
* @example
* const {path, cleanup } = await tmpFileAsync()
* console.log(path)
* cleanup()
*/
function tmpFileAsync(
options: tmp.FileOptions,
): Promise<{ path: string; cleanup: () => void }> {
return new Promise((resolve, reject) => {
tmp.file(options, (error, path, _fd, cleanup) => {
if (error) {
reject(error);
} else {
resolve({ path, cleanup });
}
});
});
}
/**
* @summary Disposer for tmpFileAsync, calls cleanup()
*
* @returns {Disposer<{ path: String, cleanup: Function }>}
*
* @example
* await Bluebird.using(tmpFileDisposer(), ({ path }) => {
* console.log(path);
* })
*/
export function tmpFileDisposer(
options: tmp.FileOptions,
): Bluebird.Disposer<{ path: string; cleanup: () => void }> {
return Bluebird.resolve(tmpFileAsync(options)).disposer(({ cleanup }) => {
cleanup();
export async function delay(duration: number): Promise<void> {
await new Promise((resolve) => {
setTimeout(resolve, duration);
});
}