-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathTsLint.js
78 lines (70 loc) · 2.13 KB
/
TsLint.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
'use strict';
const PreCommitBase = require('./Base');
/**
* @class TsLint
* @extends PreCommitBase
* @classdesc Run tslint on changed files
*/
class TsLint extends PreCommitBase {
/**
* Run `tslint` against files that apply.
* Uses spawnPromiseOnApplicableFiles to parallelize
*
* @returns {Promise}
* @resolves {HookMessage[]} An array of hook messages produced by the hook
* @rejects {Error} An Error thrown or emitted while running the hook
*/
run() {
return new Promise((resolve, reject) => {
this.spawnPromiseOnApplicableFiles().then((result) => {
let output = result.stdout.trim();
if (result.status === 0 && !output) { return resolve('pass'); }
resolve(this.extractMessages(
this.parseTsLintOutput(output),
TsLint.MESSAGE_REGEX,
TsLint.MESSAGE_CAPTURE_MAP,
TsLint.MESSAGE_TYPE_CATEGORIZER
));
}, reject);
});
}
// Parses the output stream of TsLint to produce an array of
// output messages. Ensures we only send valid lines to the
// standard `extractMessages` function.
// For example, TsLint will print a warning if some rules aren't well defined like:
// `Warning: The 'deprecation' rule requires type information.`
// which is useful information, but not for our purposes.
parseTsLintOutput(output) {
let outputLines = output.split('\n');
return outputLines.filter((outputLine) => {
return /ERROR|WARNING/.test(outputLine);
});
}
static MESSAGE_TYPE_CATEGORIZER(capturedType) {
return capturedType.toLowerCase();
}
}
/**
* Regex to capture various parts of TsLint "prose" output.
* The output lines look like this:
* ERROR: relative/path.ts:L:C - Rule name
*
* @type {RegExp}
*/
TsLint.MESSAGE_REGEX = new RegExp(
'^(ERROR|WARNING):\\s+' + // 1: Type
'([^:]+):' + // 2: File name
'(\\d+):.*$' // 3: Line number
);
/**
* Maps the types of captured data to the index in the
* matches array produced when executing `MESSAGE_REGEX`
*
* @type {{file: number, line: number, type: number}}
*/
TsLint.MESSAGE_CAPTURE_MAP = {
'type': 1,
'file': 2,
'line': 3
};
module.exports = TsLint;