diff --git a/lib/gui/app/app.js b/lib/gui/app/app.js index fc418695..935d10fe 100644 --- a/lib/gui/app/app.js +++ b/lib/gui/app/app.js @@ -27,6 +27,7 @@ const uuidV4 = require('uuid/v4') // eslint-disable-next-line node/no-missing-require const EXIT_CODES = require('../../shared/exit-codes') +// eslint-disable-next-line node/no-missing-require const messages = require('../../shared/messages') const store = require('./models/store') const packageJSON = require('../../../package.json') diff --git a/lib/shared/drive-constraints.js b/lib/shared/drive-constraints.js index 15c4f2f8..a719de87 100644 --- a/lib/shared/drive-constraints.js +++ b/lib/shared/drive-constraints.js @@ -19,6 +19,7 @@ const _ = require('lodash') const pathIsInside = require('path-is-inside') const prettyBytes = require('pretty-bytes') +// eslint-disable-next-line node/no-missing-require const messages = require('./messages') /** diff --git a/lib/shared/messages.js b/lib/shared/messages.js deleted file mode 100644 index f26b6275..00000000 --- a/lib/shared/messages.js +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright 2016 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. - */ - -/* eslint-disable lodash/prefer-constant */ - -'use strict' - -/** - * @summary Application messages - * @namespace messages - * @public - */ -module.exports = { - - /** - * @summary Progress messages - * @namespace progress - * @memberof messages - */ - progress: { - - successful: (quantity) => { - // eslint-disable-next-line no-magic-numbers - const plural = quantity === 1 ? '' : 's' - return `Successful device${plural}` - }, - - failed: (quantity) => { - // eslint-disable-next-line no-magic-numbers - const plural = quantity === 1 ? '' : 's' - return `Failed device${plural}` - } - }, - - /** - * @summary Informational messages - * @namespace info - * @memberof messages - */ - info: { - - flashComplete: (imageBasename, [ drive ], { failed, successful }) => { - /* eslint-disable no-magic-numbers */ - const targets = [] - if (failed + successful === 1) { - targets.push(`to ${drive.description} (${drive.displayName})`) - } else { - if (successful) { - const plural = successful === 1 ? '' : 's' - targets.push(`to ${successful} target${plural}`) - } - if (failed) { - const plural = failed === 1 ? '' : 's' - targets.push(`and failed to be flashed to ${failed} target${plural}`) - } - } - return `${imageBasename} was successfully flashed ${targets.join(' ')}` - /* eslint-enable no-magic-numbers */ - } - - }, - - /** - * @summary Drive compatibility messages - * @namespace compatibility - * @memberof messages - */ - compatibility: { - - sizeNotRecommended () { - return 'Not Recommended' - }, - - tooSmall (additionalSpace) { - return `Insufficient space, additional ${additionalSpace} required` - }, - - locked () { - return 'Locked' - }, - - system () { - return 'System Drive' - }, - - containsImage () { - return 'Drive Mountpoint Contains Image' - }, - - // The drive is large and therefore likely not a medium you want to write to. - largeDrive () { - return 'Large Drive' - } - - }, - - /** - * @summary Warning messages - * @namespace warning - * @memberof messages - */ - warning: { - - unrecommendedDriveSize: (image, drive) => { - return [ - `This image recommends a ${image.recommendedDriveSize}`, - `bytes drive, however ${drive.device} is only ${drive.size} bytes.` - ].join(' ') - }, - - exitWhileFlashing: () => { - return [ - 'You are currently flashing a drive.', - 'Closing Etcher may leave your drive in an unusable state.' - ].join(' ') - }, - - looksLikeWindowsImage: () => { - return [ - 'It looks like you are trying to burn a Windows image.\n\n', - 'Unlike other images, Windows images require special processing to be made bootable.', - 'We suggest you use a tool specially designed for this purpose, such as', - 'Rufus (Windows),', - 'WoeUSB (Linux),', - 'or Boot Camp Assistant (macOS).' - ].join(' ') - }, - - missingPartitionTable: () => { - return [ - 'It looks like this is not a bootable image.\n\n', - 'The image does not appear to contain a partition table,', - 'and might not be recognized or bootable by your device.' - ].join(' ') - }, - - largeDriveSize: (drive) => { - return [ - `Drive ${drive.description} (${drive.device}) is unusually large for an SD card or USB stick.`, - '\n\nAre you sure you want to flash this drive?' - ].join(' ') - } - - }, - - /** - * @summary Error messages - * @namespace error - * @memberof messages - */ - error: { - - notEnoughSpaceInDrive: () => { - return [ - 'Not enough space on the drive.', - 'Please insert larger one and try again.' - ].join(' ') - }, - - genericFlashError: () => { - return 'Something went wrong. If it is a compressed image, please check that the archive is not corrupted.' - }, - - validation: () => { - return [ - 'The write has been completed successfully but Etcher detected potential', - 'corruption issues when reading the image back from the drive.', - '\n\nPlease consider writing the image to a different drive.' - ].join(' ') - }, - - invalidImage: (imagePath) => { - return `${imagePath} is not a supported image type.` - }, - - openImage: (imageBasename, errorMessage) => { - return [ - `Something went wrong while opening ${imageBasename}\n\n`, - `Error: ${errorMessage}` - ].join('') - }, - - elevationRequired: () => { - return 'This should should be run with root/administrator permissions.' - }, - - flashFailure: (imageBasename, drives) => { - /* eslint-disable no-magic-numbers */ - const target = drives.length === 1 - ? `${drives[0].description} (${drives[0].displayName})` - : `${drives.length} targets` - return `Something went wrong while writing ${imageBasename} to ${target}.` - /* eslint-enable no-magic-numbers */ - }, - - driveUnplugged: () => { - return [ - 'Looks like Etcher lost access to the drive.', - 'Did it get unplugged accidentally?', - '\n\nSometimes this error is caused by faulty readers that don\'t provide stable access to the drive.' - ].join(' ') - }, - - inputOutput: () => { - return [ - 'Looks like Etcher is not able to write to this location of the drive.', - 'This error is usually caused by a faulty drive, reader, or port.', - '\n\nPlease try again with another drive, reader, or port.' - ].join(' ') - }, - - childWriterDied: () => { - return [ - 'The writer process ended unexpectedly.', - 'Please try again, and contact the Etcher team if the problem persists.' - ].join(' ') - } - - } - -} diff --git a/lib/shared/messages.ts b/lib/shared/messages.ts new file mode 100644 index 00000000..322a3de0 --- /dev/null +++ b/lib/shared/messages.ts @@ -0,0 +1,192 @@ +/* + * Copyright 2016 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. + */ + +export const progress = { + successful: (quantity: number) => { + const plural = quantity === 1 ? '' : 's'; + return `Successful device${plural}`; + }, + + failed: (quantity: number) => { + const plural = quantity === 1 ? '' : 's'; + return `Failed device${plural}`; + }, +}; + +export const info = { + flashComplete: ( + imageBasename: string, + [drive]: [{ description: string; displayName: string }], + { failed, successful }: { failed: number; successful: number }, + ) => { + const targets = []; + if (failed + successful === 1) { + targets.push(`to ${drive.description} (${drive.displayName})`); + } else { + if (successful) { + const plural = successful === 1 ? '' : 's'; + targets.push(`to ${successful} target${plural}`); + } + if (failed) { + const plural = failed === 1 ? '' : 's'; + targets.push(`and failed to be flashed to ${failed} target${plural}`); + } + } + return `${imageBasename} was successfully flashed ${targets.join(' ')}`; + }, +}; + +export const compatibility = { + sizeNotRecommended() { + return 'Not Recommended'; + }, + + tooSmall(additionalSpace: number) { + return `Insufficient space, additional ${additionalSpace} required`; + }, + + locked() { + return 'Locked'; + }, + + system() { + return 'System Drive'; + }, + + containsImage() { + return 'Drive Mountpoint Contains Image'; + }, + + // The drive is large and therefore likely not a medium you want to write to. + largeDrive() { + return 'Large Drive'; + }, +}; + +export const warning = { + unrecommendedDriveSize: ( + image: { recommendedDriveSize: number }, + drive: { device: string; size: number }, + ) => { + return [ + `This image recommends a ${image.recommendedDriveSize}`, + `bytes drive, however ${drive.device} is only ${drive.size} bytes.`, + ].join(' '); + }, + + exitWhileFlashing: () => { + return [ + 'You are currently flashing a drive.', + 'Closing Etcher may leave your drive in an unusable state.', + ].join(' '); + }, + + looksLikeWindowsImage: () => { + return [ + 'It looks like you are trying to burn a Windows image.\n\n', + 'Unlike other images, Windows images require special processing to be made bootable.', + 'We suggest you use a tool specially designed for this purpose, such as', + 'Rufus (Windows),', + 'WoeUSB (Linux),', + 'or Boot Camp Assistant (macOS).', + ].join(' '); + }, + + missingPartitionTable: () => { + return [ + 'It looks like this is not a bootable image.\n\n', + 'The image does not appear to contain a partition table,', + 'and might not be recognized or bootable by your device.', + ].join(' '); + }, + + largeDriveSize: (drive: { description: string; device: string }) => { + return [ + `Drive ${drive.description} (${drive.device}) is unusually large for an SD card or USB stick.`, + '\n\nAre you sure you want to flash this drive?', + ].join(' '); + }, +}; + +export const error = { + notEnoughSpaceInDrive: () => { + return [ + 'Not enough space on the drive.', + 'Please insert larger one and try again.', + ].join(' '); + }, + + genericFlashError: () => { + return 'Something went wrong. If it is a compressed image, please check that the archive is not corrupted.'; + }, + + validation: () => { + return [ + 'The write has been completed successfully but Etcher detected potential', + 'corruption issues when reading the image back from the drive.', + '\n\nPlease consider writing the image to a different drive.', + ].join(' '); + }, + + invalidImage: (imagePath: string) => { + return `${imagePath} is not a supported image type.`; + }, + + openImage: (imageBasename: string, errorMessage: string) => { + return [ + `Something went wrong while opening ${imageBasename}\n\n`, + `Error: ${errorMessage}`, + ].join(''); + }, + + elevationRequired: () => { + return 'This should should be run with root/administrator permissions.'; + }, + + flashFailure: ( + imageBasename: string, + drives: Array<{ description: string; displayName: string }>, + ) => { + const target = + drives.length === 1 + ? `${drives[0].description} (${drives[0].displayName})` + : `${drives.length} targets`; + return `Something went wrong while writing ${imageBasename} to ${target}.`; + }, + + driveUnplugged: () => { + return [ + 'Looks like Etcher lost access to the drive.', + 'Did it get unplugged accidentally?', + "\n\nSometimes this error is caused by faulty readers that don't provide stable access to the drive.", + ].join(' '); + }, + + inputOutput: () => { + return [ + 'Looks like Etcher is not able to write to this location of the drive.', + 'This error is usually caused by a faulty drive, reader, or port.', + '\n\nPlease try again with another drive, reader, or port.', + ].join(' '); + }, + + childWriterDied: () => { + return [ + 'The writer process ended unexpectedly.', + 'Please try again, and contact the Etcher team if the problem persists.', + ].join(' '); + }, +}; diff --git a/tests/shared/drive-constraints.spec.js b/tests/shared/drive-constraints.spec.js index 36d6cd0e..f15fb82e 100644 --- a/tests/shared/drive-constraints.spec.js +++ b/tests/shared/drive-constraints.spec.js @@ -20,6 +20,7 @@ const m = require('mochainon') const _ = require('lodash') const path = require('path') const constraints = require('../../lib/shared/drive-constraints') +// eslint-disable-next-line node/no-missing-require const messages = require('../../lib/shared/messages') describe('Shared: DriveConstraints', function () { diff --git a/tests/shared/messages.spec.js b/tests/shared/messages.spec.js index 39a6ea8e..83257682 100644 --- a/tests/shared/messages.spec.js +++ b/tests/shared/messages.spec.js @@ -18,6 +18,7 @@ const m = require('mochainon') const _ = require('lodash') +// eslint-disable-next-line node/no-missing-require const messages = require('../../lib/shared/messages') describe('Shared: Messages', function () {