Skip to content

Commit ae7faf8

Browse files
author
Piotr Oleś
committed
Add formatters
1 parent af91b09 commit ae7faf8

File tree

5 files changed

+236
-12
lines changed

5 files changed

+236
-12
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
var os = require('os');
2+
var codeFrame = require('babel-code-frame');
3+
var chalk = require('chalk');
4+
var fs = require('fs');
5+
6+
/**
7+
* Create new code frame formatter.
8+
*
9+
* @param options Options for babel-code-frame - see https://www.npmjs.com/package/babel-code-frame
10+
* @returns {codeframeFormatter}
11+
*/
12+
module.exports = function createCodeframeFormatter(options) {
13+
return function codeframeFormatter(message, useColors) {
14+
var colors = new chalk.constructor({enabled: useColors});
15+
var messageColor = message.isWarningSeverity() ? colors.bold.yellow : colors.bold.red;
16+
var positionColor = colors.dim;
17+
18+
var source = message.getFile() && fs.existsSync(message.getFile()) && fs.readFileSync(message.getFile(), 'utf-8');
19+
var frame = '';
20+
21+
if (source) {
22+
frame = codeFrame(
23+
source,
24+
message.line,
25+
message.character,
26+
Object.assign({}, options || {}, { highlightCode: useColors })
27+
)
28+
.split('\n')
29+
.map(function (str) { return ' ' + str; })
30+
.join(os.EOL);
31+
}
32+
33+
return (
34+
messageColor(message.getSeverity().toUpperCase() + ' at ' + message.getFile()) + os.EOL +
35+
positionColor(message.getLine() + ':' + message.getCharacter()) + ' ' + message.getContent() +
36+
(frame ? os.EOL + frame : '')
37+
);
38+
};
39+
};

lib/formatter/defaultFormatter.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
2+
var chalk = require('chalk');
3+
var os = require('os');
4+
5+
/**
6+
* Creates new default formatter.
7+
*
8+
* @returns {defaultFormatter}
9+
*/
10+
module.exports = function createDefaultFormatter() {
11+
return function defaultFormatter(message, useColors) {
12+
var colors = new chalk.constructor({enabled: useColors});
13+
var messageColor = message.isWarningSeverity() ? colors.bold.yellow : colors.bold.red;
14+
var numberColor = colors.bold.cyan;
15+
var codeColor = colors.grey;
16+
17+
return [
18+
messageColor(message.getSeverity().toUpperCase() + ' at ' + message.getFile()) +
19+
'(' + numberColor(message.getLine()) + ',' + numberColor(message.getCharacter()) + '): ',
20+
codeColor(message.getFormattedCode() + ': ') + message.getContent()
21+
].join(os.EOL);
22+
};
23+
};

lib/index.js

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@ var chalk = require('chalk');
55
var fs = require('fs');
66
var os = require('os');
77
var isString = require('lodash.isstring');
8+
var isFunction = require('lodash.isfunction');
89
var CancellationToken = require('./CancellationToken');
910
var NormalizedMessage = require('./NormalizedMessage');
11+
var createDefaultFormatter = require('./formatter/defaultFormatter');
12+
var createCodeframeFormatter = require('./formatter/codeframeFormatter');
1013

1114
/**
1215
* ForkTsCheckerWebpackPlugin
@@ -30,7 +33,10 @@ function ForkTsCheckerWebpackPlugin (options) {
3033
this.async = options.async !== false; // default true
3134
this.workersNumber = options.workers || ForkTsCheckerWebpackPlugin.ONE_CPU;
3235
this.memoryLimit = options.memoryLimit || ForkTsCheckerWebpackPlugin.DEFAULT_MEMORY_LIMIT;
33-
this.colors = new chalk.constructor({ enabled: options.colors === undefined ? true : !!options.colors });
36+
this.useColors = options.colors !== false; // default true
37+
this.colors = new chalk.constructor({ enabled: this.useColors });
38+
this.formatter = (options.formatter && isFunction(options.formatter)) ?
39+
options.formatter : ForkTsCheckerWebpackPlugin.createFormatter(options.formatter || 'default', options.formatterOptions || {});
3440

3541
this.tsconfigPath = undefined;
3642
this.tslintPath = undefined;
@@ -62,6 +68,17 @@ ForkTsCheckerWebpackPlugin.ALL_CPUS = os.cpus().length;
6268
ForkTsCheckerWebpackPlugin.ONE_CPU_FREE = Math.max(1, ForkTsCheckerWebpackPlugin.ALL_CPUS - 1);
6369
ForkTsCheckerWebpackPlugin.TWO_CPUS_FREE = Math.max(1, ForkTsCheckerWebpackPlugin.ALL_CPUS - 2);
6470

71+
ForkTsCheckerWebpackPlugin.createFormatter = function (type, options) {
72+
switch (type) {
73+
case 'default':
74+
return createDefaultFormatter(options);
75+
case 'codeframe':
76+
return createCodeframeFormatter(options);
77+
default:
78+
throw new Error('Unknown "' + type + '" formatter. Available are: default, codeframe.');
79+
}
80+
};
81+
6582
ForkTsCheckerWebpackPlugin.prototype.apply = function (compiler) {
6683
this.compiler = compiler;
6784

@@ -384,17 +401,9 @@ ForkTsCheckerWebpackPlugin.prototype.createDoneCallback = function () {
384401
if (!this.silent && this.logger) {
385402
if (this.diagnostics.length || this.lints.length) {
386403
(this.lints || []).concat(this.diagnostics).forEach(function (message) {
387-
var logColor = message.isWarningSeverity() ? this.colors.bold.yellow : this.colors.bold.red;
388-
var logMethod = message.isWarningSeverity() ? this.logger.warn : this.logger.error;
389-
390-
logMethod(
391-
logColor(message.getSeverity().toUpperCase() + ' at ' + message.getFile()) +
392-
'(' + this.colors.bold.cyan(message.getLine()) + ',' + this.colors.bold.cyan(message.getCharacter()) + '): '
393-
);
394-
logMethod(
395-
this.colors.grey(message.getFormattedCode() + ': ') +
396-
message.getContent() + '\n'
397-
);
404+
var formattedMessage = this.formatter(message, this.useColors);
405+
406+
message.isWarningSeverity() ? this.logger.warn(formattedMessage) : this.logger.error(formattedMessage);
398407
}.bind(this));
399408
}
400409
if (!this.diagnostics.length) {
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
2+
var describe = require('mocha').describe;
3+
var it = require('mocha').it;
4+
var os = require('os');
5+
var beforeEach = require('mocha').beforeEach;
6+
var afterEach = require('mocha').afterEach;
7+
var expect = require('chai').expect;
8+
var mockFs = require('mock-fs');
9+
var NormalizedMessage = require('../../lib/NormalizedMessage');
10+
var createCodeframeFormatter = require('../../lib/formatter/codeframeFormatter');
11+
12+
describe('[UNIT] formatter/codeframeFormatter', function () {
13+
14+
beforeEach(function () {
15+
mockFs({
16+
some: {
17+
'file.ts': [
18+
'class SomeClass {',
19+
' private someProperty: boolean;',
20+
' constructor() {',
21+
' console.log(\'anything special\');',
22+
' }',
23+
'}'
24+
].join('\n')
25+
}
26+
});
27+
});
28+
29+
afterEach(function () {
30+
mockFs.restore();
31+
});
32+
33+
it('should format normalized diagnostic message', function () {
34+
var message = new NormalizedMessage({
35+
type: NormalizedMessage.TYPE_DIAGNOSTIC,
36+
code: 123,
37+
severity: NormalizedMessage.SEVERITY_ERROR,
38+
content: 'Some diagnostic content',
39+
file: 'some/file.ts',
40+
line: 1,
41+
character: 7
42+
});
43+
var formatter = createCodeframeFormatter({
44+
linesAbove: 1,
45+
linesBelow: 1
46+
});
47+
var formattedMessage = formatter(message, false);
48+
49+
expect(formattedMessage).to.be.equal(
50+
'ERROR at some/file.ts' + os.EOL +
51+
'1:7 Some diagnostic content' + os.EOL +
52+
' > 1 | class SomeClass {' + os.EOL +
53+
' | ^' + os.EOL +
54+
' 2 | private someProperty: boolean;'
55+
);
56+
});
57+
58+
it('should format normalized lint message', function () {
59+
var message = new NormalizedMessage({
60+
type: NormalizedMessage.TYPE_LINT,
61+
code: 'some-lint-rule',
62+
severity: NormalizedMessage.SEVERITY_WARNING,
63+
content: 'Some lint content',
64+
file: 'some/file.ts',
65+
line: 2,
66+
character: 11
67+
});
68+
var formatter = createCodeframeFormatter({
69+
linesAbove: 1,
70+
linesBelow: 1
71+
});
72+
var formattedMessage = formatter(message, false);
73+
74+
expect(formattedMessage).to.be.equal(
75+
'WARNING at some/file.ts' + os.EOL +
76+
'2:11 Some lint content' + os.EOL +
77+
' 1 | class SomeClass {' + os.EOL +
78+
' > 2 | private someProperty: boolean;' + os.EOL +
79+
' | ^' + os.EOL +
80+
' 3 | constructor() {'
81+
);
82+
});
83+
84+
it('should format normalized message without file', function () {
85+
var message = new NormalizedMessage({
86+
type: NormalizedMessage.TYPE_LINT,
87+
code: 'some-lint-rule',
88+
severity: NormalizedMessage.SEVERITY_WARNING,
89+
content: 'Some lint content',
90+
file: 'some/unknown-file.ts',
91+
line: 2,
92+
character: 11
93+
});
94+
var formatter = createCodeframeFormatter({
95+
linesAbove: 1,
96+
linesBelow: 1
97+
});
98+
var formattedMessage = formatter(message, false);
99+
100+
expect(formattedMessage).to.be.equal(
101+
'WARNING at some/unknown-file.ts' + os.EOL +
102+
'2:11 Some lint content'
103+
);
104+
});
105+
});

test/unit/defaultFormatter.spec.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
2+
var describe = require('mocha').describe;
3+
var it = require('mocha').it;
4+
var os = require('os');
5+
var expect = require('chai').expect;
6+
var NormalizedMessage = require('../../lib/NormalizedMessage');
7+
var createDefaultFormatter = require('../../lib/formatter/defaultFormatter');
8+
9+
describe('[UNIT] formatter/defaultFormatter', function () {
10+
11+
it('should format normalized diagnostic message', function () {
12+
var message = new NormalizedMessage({
13+
type: NormalizedMessage.TYPE_DIAGNOSTIC,
14+
code: 123,
15+
severity: NormalizedMessage.SEVERITY_ERROR,
16+
content: 'Some diagnostic content',
17+
file: '/some/file.ts',
18+
line: 1,
19+
character: 5
20+
});
21+
var formatter = createDefaultFormatter();
22+
var formattedMessage = formatter(message, false);
23+
24+
expect(formattedMessage).to.be.equal(
25+
'ERROR at /some/file.ts(1,5): ' + os.EOL +
26+
'TS123: Some diagnostic content'
27+
);
28+
});
29+
30+
it('should format normalized lint message', function () {
31+
var message = new NormalizedMessage({
32+
type: NormalizedMessage.TYPE_LINT,
33+
code: 'some-lint-rule',
34+
severity: NormalizedMessage.SEVERITY_WARNING,
35+
content: 'Some lint content',
36+
file: '/some/file.ts',
37+
line: 2,
38+
character: 6
39+
});
40+
var formatter = createDefaultFormatter();
41+
var formattedMessage = formatter(message, false);
42+
43+
expect(formattedMessage).to.be.equal(
44+
'WARNING at /some/file.ts(2,6): ' + os.EOL +
45+
'some-lint-rule: Some lint content'
46+
);
47+
});
48+
});

0 commit comments

Comments
 (0)