mirror of
https://github.com/balena-io/etcher.git
synced 2025-04-24 23:37:18 +00:00
Convert child-writer.js to typescript
Change-type: patch
This commit is contained in:
parent
1c46ee2988
commit
97aff2eb4c
@ -1,244 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2017 balena.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 Bluebird = require('bluebird')
|
|
||||||
const _ = require('lodash')
|
|
||||||
const ipc = require('node-ipc')
|
|
||||||
const sdk = require('etcher-sdk')
|
|
||||||
// eslint-disable-next-line node/no-missing-require
|
|
||||||
const EXIT_CODES = require('../../shared/exit-codes')
|
|
||||||
// eslint-disable-next-line node/no-missing-require
|
|
||||||
const errors = require('../../shared/errors')
|
|
||||||
|
|
||||||
ipc.config.id = process.env.IPC_CLIENT_ID
|
|
||||||
ipc.config.socketRoot = process.env.IPC_SOCKET_ROOT
|
|
||||||
|
|
||||||
// NOTE: Ensure this isn't disabled, as it will cause
|
|
||||||
// the stdout maxBuffer size to be exceeded when flashing
|
|
||||||
ipc.config.silent = true
|
|
||||||
|
|
||||||
// > If set to 0, the client will NOT try to reconnect.
|
|
||||||
// See https://github.com/RIAEvangelist/node-ipc/
|
|
||||||
//
|
|
||||||
// The purpose behind this change is for this process
|
|
||||||
// to emit a "disconnect" event as soon as the GUI
|
|
||||||
// process is closed, so we can kill this process as well.
|
|
||||||
ipc.config.stopRetrying = 0
|
|
||||||
|
|
||||||
const DISCONNECT_DELAY = 100
|
|
||||||
const IPC_SERVER_ID = process.env.IPC_SERVER_ID
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @summary Send a log debug message to the IPC server
|
|
||||||
* @function
|
|
||||||
* @private
|
|
||||||
*
|
|
||||||
* @param {String} message - message
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* log('Hello world!')
|
|
||||||
*/
|
|
||||||
const log = (message) => {
|
|
||||||
ipc.of[IPC_SERVER_ID].emit('log', message)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @summary Terminate the child writer process
|
|
||||||
* @function
|
|
||||||
* @private
|
|
||||||
*
|
|
||||||
* @param {Number} [code=0] - exit code
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* terminate(1)
|
|
||||||
*/
|
|
||||||
const terminate = (code) => {
|
|
||||||
ipc.disconnect(IPC_SERVER_ID)
|
|
||||||
process.nextTick(() => {
|
|
||||||
process.exit(code || EXIT_CODES.SUCCESS)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @summary Handle a child writer error
|
|
||||||
* @function
|
|
||||||
* @private
|
|
||||||
*
|
|
||||||
* @param {Error} error - error
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* handleError(new Error('Something bad happened!'))
|
|
||||||
*/
|
|
||||||
const handleError = async (error) => {
|
|
||||||
ipc.of[IPC_SERVER_ID].emit('error', errors.toJSON(error))
|
|
||||||
await Bluebird.delay(DISCONNECT_DELAY)
|
|
||||||
terminate(EXIT_CODES.GENERAL_ERROR)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @summary writes the source to the destinations and valiates the writes
|
|
||||||
* @param {SourceDestination} source - source
|
|
||||||
* @param {SourceDestination[]} destinations - destinations
|
|
||||||
* @param {Boolean} verify - whether to validate the writes or not
|
|
||||||
* @param {Boolean} trim - whether to trim ext partitions before writing
|
|
||||||
* @param {Function} onProgress - function to call on progress
|
|
||||||
* @param {Function} onFail - function to call on fail
|
|
||||||
* @returns {Promise<{ bytesWritten, devices, errors} >}
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* writeAndValidate(source, destinations, verify, onProgress, onFail, onFinish, onError)
|
|
||||||
*/
|
|
||||||
const writeAndValidate = async (source, destinations, verify, trim, onProgress, onFail) => {
|
|
||||||
let innerSource = await source.getInnerSource()
|
|
||||||
if (trim && (await innerSource.canRead())) {
|
|
||||||
innerSource = new sdk.sourceDestination.ConfiguredSource(
|
|
||||||
innerSource,
|
|
||||||
trim,
|
|
||||||
|
|
||||||
// Create stream from file-disk (not source stream)
|
|
||||||
true
|
|
||||||
)
|
|
||||||
}
|
|
||||||
const { failures, bytesWritten } = await sdk.multiWrite.pipeSourceToDestinations(
|
|
||||||
innerSource,
|
|
||||||
destinations,
|
|
||||||
onFail,
|
|
||||||
onProgress,
|
|
||||||
verify
|
|
||||||
)
|
|
||||||
const result = {
|
|
||||||
bytesWritten,
|
|
||||||
devices: {
|
|
||||||
failed: failures.size,
|
|
||||||
successful: destinations.length - failures.size
|
|
||||||
},
|
|
||||||
errors: []
|
|
||||||
}
|
|
||||||
for (const [ destination, error ] of failures) {
|
|
||||||
error.device = destination.drive.device
|
|
||||||
result.errors.push(error)
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
ipc.connectTo(IPC_SERVER_ID, () => {
|
|
||||||
process.once('uncaughtException', handleError)
|
|
||||||
|
|
||||||
// Gracefully exit on the following cases. If the parent
|
|
||||||
// process detects that child exit successfully but
|
|
||||||
// no flashing information is available, then it will
|
|
||||||
// assume that the child died halfway through.
|
|
||||||
|
|
||||||
process.once('SIGINT', () => {
|
|
||||||
terminate(EXIT_CODES.SUCCESS)
|
|
||||||
})
|
|
||||||
|
|
||||||
process.once('SIGTERM', () => {
|
|
||||||
terminate(EXIT_CODES.SUCCESS)
|
|
||||||
})
|
|
||||||
|
|
||||||
// The IPC server failed. Abort.
|
|
||||||
ipc.of[IPC_SERVER_ID].on('error', () => {
|
|
||||||
terminate(EXIT_CODES.SUCCESS)
|
|
||||||
})
|
|
||||||
|
|
||||||
// The IPC server was disconnected. Abort.
|
|
||||||
ipc.of[IPC_SERVER_ID].on('disconnect', () => {
|
|
||||||
terminate(EXIT_CODES.SUCCESS)
|
|
||||||
})
|
|
||||||
|
|
||||||
ipc.of[IPC_SERVER_ID].on('write', async (options) => {
|
|
||||||
/**
|
|
||||||
* @summary Progress handler
|
|
||||||
* @param {Object} state - progress state
|
|
||||||
* @example
|
|
||||||
* writer.on('progress', onProgress)
|
|
||||||
*/
|
|
||||||
const onProgress = (state) => {
|
|
||||||
ipc.of[IPC_SERVER_ID].emit('state', state)
|
|
||||||
}
|
|
||||||
|
|
||||||
let exitCode = EXIT_CODES.SUCCESS
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @summary Abort handler
|
|
||||||
* @example
|
|
||||||
* writer.on('abort', onAbort)
|
|
||||||
*/
|
|
||||||
const onAbort = async () => {
|
|
||||||
log('Abort')
|
|
||||||
ipc.of[IPC_SERVER_ID].emit('abort')
|
|
||||||
await Bluebird.delay(DISCONNECT_DELAY)
|
|
||||||
terminate(exitCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
ipc.of[IPC_SERVER_ID].on('cancel', onAbort)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @summary Failure handler (non-fatal errors)
|
|
||||||
* @param {SourceDestination} destination - destination
|
|
||||||
* @param {Error} error - error
|
|
||||||
* @example
|
|
||||||
* writer.on('fail', onFail)
|
|
||||||
*/
|
|
||||||
const onFail = (destination, error) => {
|
|
||||||
ipc.of[IPC_SERVER_ID].emit('fail', {
|
|
||||||
// TODO: device should be destination
|
|
||||||
device: destination.drive,
|
|
||||||
error: errors.toJSON(error)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const destinations = _.map(options.destinations, 'device')
|
|
||||||
log(`Image: ${options.imagePath}`)
|
|
||||||
log(`Devices: ${destinations.join(', ')}`)
|
|
||||||
log(`Umount on success: ${options.unmountOnSuccess}`)
|
|
||||||
log(`Validate on success: ${options.validateWriteOnSuccess}`)
|
|
||||||
log(`Trim: ${options.trim}`)
|
|
||||||
const dests = _.map(options.destinations, (destination) => {
|
|
||||||
return new sdk.sourceDestination.BlockDevice(destination, options.unmountOnSuccess)
|
|
||||||
})
|
|
||||||
const source = new sdk.sourceDestination.File(options.imagePath, sdk.sourceDestination.File.OpenFlags.Read)
|
|
||||||
try {
|
|
||||||
const results = await writeAndValidate(
|
|
||||||
source,
|
|
||||||
dests,
|
|
||||||
options.validateWriteOnSuccess,
|
|
||||||
options.trim,
|
|
||||||
onProgress,
|
|
||||||
onFail
|
|
||||||
)
|
|
||||||
log(`Finish: ${results.bytesWritten}`)
|
|
||||||
results.errors = _.map(results.errors, (error) => {
|
|
||||||
return errors.toJSON(error)
|
|
||||||
})
|
|
||||||
ipc.of[IPC_SERVER_ID].emit('done', { results })
|
|
||||||
await Bluebird.delay(DISCONNECT_DELAY)
|
|
||||||
terminate(exitCode)
|
|
||||||
} catch (error) {
|
|
||||||
log(`Error: ${error.message}`)
|
|
||||||
exitCode = EXIT_CODES.GENERAL_ERROR
|
|
||||||
ipc.of[IPC_SERVER_ID].emit('error', errors.toJSON(error))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
ipc.of[IPC_SERVER_ID].on('connect', () => {
|
|
||||||
log(`Successfully connected to IPC server: ${IPC_SERVER_ID}, socket root ${ipc.config.socketRoot}`)
|
|
||||||
ipc.of[IPC_SERVER_ID].emit('ready', {})
|
|
||||||
})
|
|
||||||
})
|
|
260
lib/gui/modules/child-writer.ts
Normal file
260
lib/gui/modules/child-writer.ts
Normal file
@ -0,0 +1,260 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 balena.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 { delay } from 'bluebird';
|
||||||
|
import { Drive as DrivelistDrive } from 'drivelist';
|
||||||
|
import * as sdk from 'etcher-sdk';
|
||||||
|
import * as _ from 'lodash';
|
||||||
|
import * as ipc from 'node-ipc';
|
||||||
|
|
||||||
|
import { toJSON } from '../../shared/errors';
|
||||||
|
import { GENERAL_ERROR, SUCCESS } from '../../shared/exit-codes';
|
||||||
|
|
||||||
|
ipc.config.id = process.env.IPC_CLIENT_ID as string;
|
||||||
|
ipc.config.socketRoot = process.env.IPC_SOCKET_ROOT as string;
|
||||||
|
|
||||||
|
// NOTE: Ensure this isn't disabled, as it will cause
|
||||||
|
// the stdout maxBuffer size to be exceeded when flashing
|
||||||
|
ipc.config.silent = true;
|
||||||
|
|
||||||
|
// > If set to 0, the client will NOT try to reconnect.
|
||||||
|
// See https://github.com/RIAEvangelist/node-ipc/
|
||||||
|
//
|
||||||
|
// The purpose behind this change is for this process
|
||||||
|
// to emit a "disconnect" event as soon as the GUI
|
||||||
|
// process is closed, so we can kill this process as well.
|
||||||
|
// @ts-ignore (0 is a valid value for stopRetrying and is not the same as false)
|
||||||
|
ipc.config.stopRetrying = 0;
|
||||||
|
|
||||||
|
const DISCONNECT_DELAY = 100;
|
||||||
|
const IPC_SERVER_ID = process.env.IPC_SERVER_ID as string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @summary Send a log debug message to the IPC server
|
||||||
|
*/
|
||||||
|
function log(message: string) {
|
||||||
|
ipc.of[IPC_SERVER_ID].emit('log', message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @summary Terminate the child writer process
|
||||||
|
*/
|
||||||
|
function terminate(exitCode: number) {
|
||||||
|
ipc.disconnect(IPC_SERVER_ID);
|
||||||
|
process.nextTick(() => {
|
||||||
|
process.exit(exitCode || SUCCESS);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @summary Handle a child writer error
|
||||||
|
*/
|
||||||
|
async function handleError(error: Error) {
|
||||||
|
ipc.of[IPC_SERVER_ID].emit('error', toJSON(error));
|
||||||
|
await delay(DISCONNECT_DELAY);
|
||||||
|
terminate(GENERAL_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface WriteResult {
|
||||||
|
bytesWritten: number;
|
||||||
|
devices: {
|
||||||
|
failed: number;
|
||||||
|
successful: number;
|
||||||
|
};
|
||||||
|
errors: Array<Error & { device: string }>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @summary writes the source to the destinations and valiates the writes
|
||||||
|
* @param {SourceDestination} source - source
|
||||||
|
* @param {SourceDestination[]} destinations - destinations
|
||||||
|
* @param {Boolean} verify - whether to validate the writes or not
|
||||||
|
* @param {Boolean} trim - whether to trim ext partitions before writing
|
||||||
|
* @param {Function} onProgress - function to call on progress
|
||||||
|
* @param {Function} onFail - function to call on fail
|
||||||
|
* @returns {Promise<{ bytesWritten, devices, errors} >}
|
||||||
|
*/
|
||||||
|
async function writeAndValidate(
|
||||||
|
source: sdk.sourceDestination.SourceDestination,
|
||||||
|
destinations: sdk.sourceDestination.BlockDevice[],
|
||||||
|
verify: boolean,
|
||||||
|
trim: boolean,
|
||||||
|
onProgress: sdk.multiWrite.OnProgressFunction,
|
||||||
|
onFail: sdk.multiWrite.OnFailFunction,
|
||||||
|
): Promise<WriteResult> {
|
||||||
|
let innerSource: sdk.sourceDestination.SourceDestination = await source.getInnerSource();
|
||||||
|
if (trim && (await innerSource.canRead())) {
|
||||||
|
// @ts-ignore FIXME: ts thinks that SparseReadStream can't be assigned to SparseReadable (which it implements)
|
||||||
|
innerSource = new sdk.sourceDestination.ConfiguredSource(
|
||||||
|
innerSource,
|
||||||
|
trim,
|
||||||
|
// Create stream from file-disk (not source stream)
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const {
|
||||||
|
failures,
|
||||||
|
bytesWritten,
|
||||||
|
} = await sdk.multiWrite.pipeSourceToDestinations(
|
||||||
|
innerSource,
|
||||||
|
// @ts-ignore FIXME: ts thinks that BlockWriteStream can't be assigned to WritableStream (which it implements)
|
||||||
|
destinations,
|
||||||
|
onFail,
|
||||||
|
onProgress,
|
||||||
|
verify,
|
||||||
|
);
|
||||||
|
const result: WriteResult = {
|
||||||
|
bytesWritten,
|
||||||
|
devices: {
|
||||||
|
failed: failures.size,
|
||||||
|
successful: destinations.length - failures.size,
|
||||||
|
},
|
||||||
|
errors: [],
|
||||||
|
};
|
||||||
|
for (const [destination, error] of failures) {
|
||||||
|
(error as (Error & { device: string })).device = destination.drive.device;
|
||||||
|
result.errors.push(error);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface WriteOptions {
|
||||||
|
imagePath: string;
|
||||||
|
destinations: DrivelistDrive[];
|
||||||
|
unmountOnSuccess: boolean;
|
||||||
|
validateWriteOnSuccess: boolean;
|
||||||
|
trim: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
ipc.connectTo(IPC_SERVER_ID, () => {
|
||||||
|
process.once('uncaughtException', handleError);
|
||||||
|
|
||||||
|
// Gracefully exit on the following cases. If the parent
|
||||||
|
// process detects that child exit successfully but
|
||||||
|
// no flashing information is available, then it will
|
||||||
|
// assume that the child died halfway through.
|
||||||
|
|
||||||
|
process.once('SIGINT', () => {
|
||||||
|
terminate(SUCCESS);
|
||||||
|
});
|
||||||
|
|
||||||
|
process.once('SIGTERM', () => {
|
||||||
|
terminate(SUCCESS);
|
||||||
|
});
|
||||||
|
|
||||||
|
// The IPC server failed. Abort.
|
||||||
|
ipc.of[IPC_SERVER_ID].on('error', () => {
|
||||||
|
terminate(SUCCESS);
|
||||||
|
});
|
||||||
|
|
||||||
|
// The IPC server was disconnected. Abort.
|
||||||
|
ipc.of[IPC_SERVER_ID].on('disconnect', () => {
|
||||||
|
terminate(SUCCESS);
|
||||||
|
});
|
||||||
|
|
||||||
|
ipc.of[IPC_SERVER_ID].on('write', async (options: WriteOptions) => {
|
||||||
|
/**
|
||||||
|
* @summary Progress handler
|
||||||
|
* @param {Object} state - progress state
|
||||||
|
* @example
|
||||||
|
* writer.on('progress', onProgress)
|
||||||
|
*/
|
||||||
|
const onProgress = (state: sdk.multiWrite.MultiDestinationProgress) => {
|
||||||
|
ipc.of[IPC_SERVER_ID].emit('state', state);
|
||||||
|
};
|
||||||
|
|
||||||
|
let exitCode = SUCCESS;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @summary Abort handler
|
||||||
|
* @example
|
||||||
|
* writer.on('abort', onAbort)
|
||||||
|
*/
|
||||||
|
const onAbort = async () => {
|
||||||
|
log('Abort');
|
||||||
|
ipc.of[IPC_SERVER_ID].emit('abort');
|
||||||
|
await delay(DISCONNECT_DELAY);
|
||||||
|
terminate(exitCode);
|
||||||
|
};
|
||||||
|
|
||||||
|
ipc.of[IPC_SERVER_ID].on('cancel', onAbort);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @summary Failure handler (non-fatal errors)
|
||||||
|
* @param {SourceDestination} destination - destination
|
||||||
|
* @param {Error} error - error
|
||||||
|
* @example
|
||||||
|
* writer.on('fail', onFail)
|
||||||
|
*/
|
||||||
|
const onFail = (
|
||||||
|
destination: sdk.sourceDestination.BlockDevice,
|
||||||
|
error: Error,
|
||||||
|
) => {
|
||||||
|
ipc.of[IPC_SERVER_ID].emit('fail', {
|
||||||
|
// TODO: device should be destination
|
||||||
|
// @ts-ignore (destination.drive is private)
|
||||||
|
device: destination.drive,
|
||||||
|
error: toJSON(error),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const destinations = _.map(options.destinations, 'device');
|
||||||
|
log(`Image: ${options.imagePath}`);
|
||||||
|
log(`Devices: ${destinations.join(', ')}`);
|
||||||
|
log(`Umount on success: ${options.unmountOnSuccess}`);
|
||||||
|
log(`Validate on success: ${options.validateWriteOnSuccess}`);
|
||||||
|
log(`Trim: ${options.trim}`);
|
||||||
|
const dests = _.map(options.destinations, destination => {
|
||||||
|
return new sdk.sourceDestination.BlockDevice(
|
||||||
|
destination,
|
||||||
|
options.unmountOnSuccess,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
const source = new sdk.sourceDestination.File(
|
||||||
|
options.imagePath,
|
||||||
|
sdk.sourceDestination.File.OpenFlags.Read,
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
const results = await writeAndValidate(
|
||||||
|
// @ts-ignore FIXME: ts thinks that SparseWriteStream can't be assigned to SparseWritable (which it implements)
|
||||||
|
source,
|
||||||
|
dests,
|
||||||
|
options.validateWriteOnSuccess,
|
||||||
|
options.trim,
|
||||||
|
onProgress,
|
||||||
|
onFail,
|
||||||
|
);
|
||||||
|
log(`Finish: ${results.bytesWritten}`);
|
||||||
|
results.errors = _.map(results.errors, error => {
|
||||||
|
return toJSON(error);
|
||||||
|
});
|
||||||
|
ipc.of[IPC_SERVER_ID].emit('done', { results });
|
||||||
|
await delay(DISCONNECT_DELAY);
|
||||||
|
terminate(exitCode);
|
||||||
|
} catch (error) {
|
||||||
|
log(`Error: ${error.message}`);
|
||||||
|
exitCode = GENERAL_ERROR;
|
||||||
|
ipc.of[IPC_SERVER_ID].emit('error', toJSON(error));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ipc.of[IPC_SERVER_ID].on('connect', () => {
|
||||||
|
log(
|
||||||
|
`Successfully connected to IPC server: ${IPC_SERVER_ID}, socket root ${ipc.config.socketRoot}`,
|
||||||
|
);
|
||||||
|
ipc.of[IPC_SERVER_ID].emit('ready', {});
|
||||||
|
});
|
||||||
|
});
|
@ -24,6 +24,7 @@
|
|||||||
// or the entry point file (this file) manually as an argument.
|
// or the entry point file (this file) manually as an argument.
|
||||||
|
|
||||||
if (process.env.ELECTRON_RUN_AS_NODE) {
|
if (process.env.ELECTRON_RUN_AS_NODE) {
|
||||||
|
// eslint-disable-next-line node/no-missing-require
|
||||||
require('./gui/modules/child-writer')
|
require('./gui/modules/child-writer')
|
||||||
} else {
|
} else {
|
||||||
require('./gui/etcher')
|
require('./gui/etcher')
|
||||||
|
9
npm-shrinkwrap.json
generated
9
npm-shrinkwrap.json
generated
@ -1215,6 +1215,15 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.24.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.24.tgz",
|
||||||
"integrity": "sha512-1Ciqv9pqwVtW6FsIUKSZNB82E5Cu1I2bBTj1xuIHXLe/1zYLl3956Nbhg2MzSYHVfl9/rmanjbQIb7LibfCnug=="
|
"integrity": "sha512-1Ciqv9pqwVtW6FsIUKSZNB82E5Cu1I2bBTj1xuIHXLe/1zYLl3956Nbhg2MzSYHVfl9/rmanjbQIb7LibfCnug=="
|
||||||
},
|
},
|
||||||
|
"@types/node-ipc": {
|
||||||
|
"version": "9.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node-ipc/-/node-ipc-9.1.2.tgz",
|
||||||
|
"integrity": "sha512-140YlGizUg2Dbbmypc97RZ2iaWOEdcwec6QPJ9C5AWy8H/Hus6co4MeEF2lRPmOTBY3GJu+Xaxyr4FfyE6Hjew==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@types/normalize-package-data": {
|
"@types/normalize-package-data": {
|
||||||
"version": "2.4.0",
|
"version": "2.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
|
||||||
|
@ -97,6 +97,7 @@
|
|||||||
"@types/bindings": "^1.3.0",
|
"@types/bindings": "^1.3.0",
|
||||||
"@types/mime-types": "^2.1.0",
|
"@types/mime-types": "^2.1.0",
|
||||||
"@types/node": "^12.12.24",
|
"@types/node": "^12.12.24",
|
||||||
|
"@types/node-ipc": "^9.1.2",
|
||||||
"@types/react-dom": "^16.8.4",
|
"@types/react-dom": "^16.8.4",
|
||||||
"@types/request": "^2.48.4",
|
"@types/request": "^2.48.4",
|
||||||
"@types/semver": "^6.2.0",
|
"@types/semver": "^6.2.0",
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
const m = require('mochainon')
|
const m = require('mochainon')
|
||||||
const ipc = require('node-ipc')
|
const ipc = require('node-ipc')
|
||||||
|
// eslint-disable-next-line node/no-missing-require
|
||||||
require('../../../lib/gui/modules/child-writer')
|
require('../../../lib/gui/modules/child-writer')
|
||||||
|
|
||||||
describe('Browser: childWriter', function () {
|
describe('Browser: childWriter', function () {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user