refactor: extract application messages to lib/shared/messages.js (#1022)

There are certain application messages that should be re-used between
the CLI and the GUI. In order to allow such re-usability, we extract out
the application messages used in JavaScript into
`lib/shared/messages.js` as a collection of Lodash `_.template`
templates.

Notice this file doesn't include application messages included in
Angular templates directly since it'd be hard to refactor all of them.
We plan to move to React soon, which will allow moving the remaining
messages very easily.

Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
This commit is contained in:
Juan Cruz Viotti 2017-01-13 11:03:46 -04:00 committed by GitHub
parent 2b4b1da492
commit c552494480
7 changed files with 143 additions and 15 deletions

View File

@ -26,11 +26,12 @@ const writer = require('./writer');
const errors = require('./errors');
const options = require('./cli');
const robot = require('../shared/robot');
const messages = require('../shared/messages');
const EXIT_CODES = require('../shared/exit-codes');
isElevated().then((elevated) => {
if (!elevated) {
throw new Error('This should should be run with root/administrator permissions');
throw new Error(messages.error.elevationRequired());
}
return form.run([
@ -102,7 +103,7 @@ isElevated().then((elevated) => {
});
}
console.log('Your flash is complete!');
console.log(messages.info.flashComplete());
if (results.sourceChecksum) {
console.log(`Checksum: ${results.sourceChecksum}`);

View File

@ -25,6 +25,7 @@
var angular = require('angular');
const electron = require('electron');
const EXIT_CODES = require('../shared/exit-codes');
const messages = require('../shared/messages');
/* eslint-enable no-var */
@ -168,11 +169,7 @@ app.run(($window, WarningModalService, ErrorService, FlashStateModel) => {
WarningModalService.display({
confirmationLabel: 'Yes, quit',
rejectionLabel: 'Cancel',
description: [
'You are currently flashing a drive. Closing Etcher may leave',
'your drive in an unusable state.\n\nAre you sure you want to',
'close Etcher?'
].join(' ')
description: messages.warning.exitWhileFlashing()
}).then((confirmed) => {
if (confirmed) {

View File

@ -17,6 +17,7 @@
'use strict';
const _ = require('lodash');
const messages = require('../../../../shared/messages');
module.exports = function(
$q,
@ -79,8 +80,10 @@ module.exports = function(
return WarningModalService.display({
confirmationLabel: 'Yes, continue',
description: [
`This image recommends a ${SelectionStateModel.getImageRecommendedDriveSize()}`,
`bytes drive, however ${drive.device} is only ${drive.size} bytes.`,
messages.warning.unrecommendedDriveSize({
image: SelectionStateModel.getImage(),
drive: drive
}),
'Are you sure you want to continue?'
].join(' ')
});

View File

@ -16,6 +16,8 @@
'use strict';
const messages = require('../../../../shared/messages');
module.exports = function(
$state,
FlashStateModel,
@ -65,20 +67,20 @@ module.exports = function(
return;
}
OSNotificationService.send('Success!', 'Your flash is complete');
OSNotificationService.send('Success!', messages.info.flashComplete());
AnalyticsService.logEvent('Done');
$state.go('success');
})
.catch((error) => {
OSNotificationService.send('Oops!', 'Looks like your flash has failed');
OSNotificationService.send('Oops!', messages.error.flashFailure());
if (error.code === 'EVALIDATION') {
FlashErrorModalService.show('Your removable drive may be corrupted. Try inserting a different one and try again.');
FlashErrorModalService.show(messages.error.validation());
AnalyticsService.logEvent('Validation error');
} else if (error.code === 'ENOSPC') {
FlashErrorModalService.show('Not enough space on the drive. Please insert larger one and try again.');
FlashErrorModalService.show(messages.error.notEnoughSpaceInDrive());
} else {
FlashErrorModalService.show('Oops, seems something went wrong.');
FlashErrorModalService.show(messages.error.genericFlashError());
ErrorService.reportException(error);
AnalyticsService.logEvent('Flash error');
}

View File

@ -17,6 +17,7 @@
'use strict';
const _ = require('lodash');
const messages = require('../../../../shared/messages');
module.exports = function(SupportedFormatsModel, SelectionStateModel, AnalyticsService, ErrorService, OSDialogService) {
@ -56,7 +57,10 @@ module.exports = function(SupportedFormatsModel, SelectionStateModel, AnalyticsS
*/
this.selectImage = (image) => {
if (!SupportedFormatsModel.isSupportedImage(image.path)) {
OSDialogService.showError('Invalid image', `${image.path} is not a supported image type.`);
OSDialogService.showError('Invalid image', messages.error.invalidImage({
image: image
}));
AnalyticsService.logEvent('Invalid image', image);
return;
}

86
lib/shared/messages.js Normal file
View File

@ -0,0 +1,86 @@
/*
* Copyright 2016 resin.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 _ = require('lodash');
/**
* @summary Application messages
* @namespace messages
* @public
*/
module.exports = {
/**
* @summary Informational messages
* @namespace info
* @memberof messages
*/
info: {
flashComplete: _.template('Your flash is complete!')
},
/**
* @summary Warning messages
* @namespace warning
* @memberof messages
*/
warning: {
unrecommendedDriveSize: _.template([
'This image recommends a <%= image.recommendedDriveSize %>',
'bytes drive, however <%= drive.device %> is only <%= drive.size %> bytes.'
].join(' ')),
exitWhileFlashing: _.template([
'You are currently flashing a drive. Closing Etcher may leave',
'your drive in an unusable state.\n\n',
'Are you sure you want to close Etcher?'
].join(' '))
},
/**
* @summary Error messages
* @namespace error
* @memberof messages
*/
error: {
notEnoughSpaceInDrive: _.template([
'Not enough space on the drive.',
'Please insert larger one and try again.'
].join(' ')),
genericFlashError: _.template('Oops, seems something went wrong.'),
validation: _.template([
'Your removable drive may be corrupted.',
'Try inserting a different one and try again.'
].join(' ')),
invalidImage: _.template('<%= image.path %> is not a supported image type.'),
elevationRequired: _.template('This should should be run with root/administrator permissions.'),
flashFailure: _.template('Looks like your flash has failed!')
}
};

View File

@ -0,0 +1,35 @@
/*
* Copyright 2016 resin.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 m = require('mochainon');
const _ = require('lodash');
const messages = require('../../lib/shared/messages');
describe('Shared: Messages', function() {
it('should contain object properties', function() {
m.chai.expect(_.every(_.map(messages, _.isPlainObject))).to.be.true;
});
it('should contain function properties in each category', function() {
_.each(messages, (category) => {
m.chai.expect(_.every(_.map(category, _.isFunction))).to.be.true;
});
});
});