Skip to content

Commit

Permalink
Add compilation status and error/warning count to the error message f…
Browse files Browse the repository at this point in the history
…ormatter (#68)
  • Loading branch information
astorije committed Apr 28, 2021
1 parent 82e6ae2 commit 51a607d
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 8 deletions.
4 changes: 3 additions & 1 deletion README.md
Expand Up @@ -105,9 +105,11 @@ The absolute path to the icon to be displayed for compilation started notificati
![Compile](https://github.com/RoccoC/webpack-build-notifier/blob/master/src/icons/compile.png?raw=true "Compile")

#### messageFormatter
A function which returns a formatted notification message. The function is passed two parameters:
A function which returns a formatted notification message. The function is passed 4 parameters:
* {Object} error/warning - The raw error or warning object.
* {String} filepath - The path to the file containing the error/warning (if available).
* {CompilationStatus} status - Error or warning
* {number} count - How many errors or warnings were raised

This function must return a String.
The default messageFormatter will display the filename which contains the error/warning followed by the
Expand Down
54 changes: 49 additions & 5 deletions src/index.ts
Expand Up @@ -41,7 +41,12 @@ export default class WebpackBuildNotifierPlugin {
private onComplete?: (compilation: webpack.compilation.Compilation, status: CompilationStatus) => void;
private onClick: (notifier: notifier.NodeNotifier, options: Notification) => void = () => this.activateTerminalWindow;
private onTimeout?: (notifier: notifier.NodeNotifier, options: Notification) => void;
private messageFormatter?: (error: CompilationResult, filepath: string) => string;
private messageFormatter?: (
error: CompilationResult,
filepath: string,
status: CompilationStatus,
errorCount: number
) => string;
private notifyOptions?: Notification;

constructor(cfg?: Config) {
Expand Down Expand Up @@ -96,11 +101,13 @@ export default class WebpackBuildNotifierPlugin {

private readonly formatMessage = (
error: CompilationResult,
filepath: string
filepath: string,
status: CompilationStatus,
errorCount: number
): string => {
let message: string | undefined = undefined;
if (this.messageFormatter) {
message = this.messageFormatter(error, filepath);
message = this.messageFormatter(error, filepath, status, errorCount);
} else {
message = (error.message || error.details);
if (message && error.module && error.module.resource) {
Expand Down Expand Up @@ -131,7 +138,12 @@ export default class WebpackBuildNotifierPlugin {
notify = true;
compilationStatus = CompilationStatus.ERROR;
title += 'Error';
msg = this.formatMessage(error, errorFilePath);
msg = this.formatMessage(
error,
errorFilePath,
compilationStatus,
this.getWarningOrErrorCount(results.compilation, 'errors')
);
icon = this.failureIcon;
sound = this.failureSound;
this.buildSuccessful = false;
Expand All @@ -141,7 +153,12 @@ export default class WebpackBuildNotifierPlugin {
notify = true;
compilationStatus = CompilationStatus.WARNING;
title += 'Warning';
msg = this.formatMessage(warning, warningFilePath);
msg = this.formatMessage(
warning,
warningFilePath,
compilationStatus,
this.getWarningOrErrorCount(results.compilation, 'warnings')
);
icon = this.warningIcon;
sound = this.warningSound;
this.buildSuccessful = false;
Expand Down Expand Up @@ -258,6 +275,33 @@ export default class WebpackBuildNotifierPlugin {
}
return compilation[type][0];
}

private readonly getWarningOrErrorCount = (
compilation: webpack.compilation.Compilation,
type: 'warnings' | 'errors',
): number => {
/* istanbul ignore else */
if (compilation.children && compilation.children.length) {
const count = compilation.children.reduce(
(acc, child) => {
let currentCount = acc;
const warningsOrErrors = child[type];
/* istanbul ignore else */
if (warningsOrErrors) {
currentCount += warningsOrErrors.length;
}
return currentCount;
},
0,
);

/* istanbul ignore else */
if (count > 0) {
return count;
}
}
return compilation[type].length;
};
}

module.exports = WebpackBuildNotifierPlugin;
4 changes: 3 additions & 1 deletion src/types.ts
Expand Up @@ -129,10 +129,12 @@ export type Config = {
*/
onTimeout?: (notifier: NotificationCenter, options: NotificationCenter.Notification) => void;
/**
* A function which returns a formatted notification message. The function is passed two parameters:
* A function which returns a formatted notification message. The function is passed 4 parameters:
*
* 1. {CompilationResult} error/warning - The raw error or warning object.
* 2. {string} filepath - The path to the file containing the error/warning (if available).
* 3. {CompilationStatus} status - Error or warning
* 4. {number} count - How many errors or warnings were raised
*
* This function must return a String.
*
Expand Down
20 changes: 19 additions & 1 deletion tests/test.spec.ts
Expand Up @@ -189,7 +189,7 @@ describe('Test Webpack build', () => {
const messageFormatter = jest.fn().mockImplementation(() => 'Hello, you have an error!');
expect.assertions(2);
webpack(getWebpackConfig({ messageFormatter }, 'error'), (err, stats) => {
expect(messageFormatter).toHaveBeenCalledWith(expect.any(Object), require.resolve('./error.js'));
expect(messageFormatter).toHaveBeenCalledWith(expect.any(Object), require.resolve('./error.js'), 'error', 1);
expect(notifier.notify).toHaveBeenCalledWith({
appName: platformName === 'Windows' ? 'Snore.DesktopToasts' : undefined,
contentImage: undefined,
Expand All @@ -203,6 +203,24 @@ describe('Test Webpack build', () => {
});
});

it('Should show a warning notification with a custom message', (done) => {
const messageFormatter = jest.fn().mockImplementation(() => 'Hello, you have a warning!');
expect.assertions(2);
webpack(getWebpackConfig({ messageFormatter }, 'warning'), (err, stats) => {
expect(messageFormatter).toHaveBeenCalledWith(expect.any(Object), '', 'warning', 2);
expect(notifier.notify).toHaveBeenCalledWith({
appName: platformName === 'Windows' ? 'Snore.DesktopToasts' : undefined,
contentImage: undefined,
icon: require.resolve('../src/icons/warning.png'),
message: 'Hello, you have a warning!',
sound: 'Submarine',
title: 'Build Notification Test - Warning',
wait: true,
});
done();
});
});

it('Should show "Unknown" if message is not defined', (done) => {
const messageFormatter = jest.fn().mockImplementation(() => undefined);
expect.assertions(1);
Expand Down

0 comments on commit 51a607d

Please sign in to comment.