Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add compilation status and error/warning count to the error message formatter #68

Merged
merged 1 commit into from
Apr 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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