Skip to content

Commit f38120b

Browse files
authored
Merge pull request TypeStrong#62 from DorianGrey/linterOptions-exclude
Correctly handle linterOptions.exclude from tslint config, if present (TypeStrong#61)
2 parents 39d7986 + dc50aae commit f38120b

File tree

4 files changed

+79
-5
lines changed

4 files changed

+79
-5
lines changed

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
"@types/lodash.isfunction": "^3.0.3",
5050
"@types/lodash.isstring": "^4.0.3",
5151
"@types/lodash.startswith": "^4.2.3",
52+
"@types/minimatch": "^3.0.1",
5253
"@types/node": "^8.0.26",
5354
"@types/webpack": "^3.0.10",
5455
"chai": "^3.5.0",
@@ -75,6 +76,7 @@
7576
"lodash.endswith": "^4.2.1",
7677
"lodash.isfunction": "^3.0.8",
7778
"lodash.isstring": "^4.0.1",
78-
"lodash.startswith": "^4.2.1"
79+
"lodash.startswith": "^4.2.1",
80+
"minimatch": "^3.0.4"
7981
}
8082
}

src/IncrementalChecker.ts

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@ import FilesWatcher = require('./FilesWatcher');
88
import WorkSet = require('./WorkSet');
99
import NormalizedMessage = require('./NormalizedMessage');
1010
import CancellationToken = require('./CancellationToken');
11+
import minimatch = require('minimatch');
12+
13+
// Need some augmentation here - linterOptions.exclude is not (yet) part of the official
14+
// types for tslint.
15+
interface ConfigurationFile extends tslintTypes.Configuration.IConfigurationFile {
16+
linterOptions?: {
17+
typeCheck?: boolean;
18+
exclude?: string[];
19+
};
20+
}
1121

1222
class IncrementalChecker {
1323
programConfigFile: string;
@@ -19,7 +29,8 @@ class IncrementalChecker {
1929
files: FilesRegister;
2030

2131
linter: tslintTypes.Linter;
22-
linterConfig: tslintTypes.Configuration.IConfigurationFile;
32+
linterConfig: ConfigurationFile;
33+
linterExclusions: minimatch.IMinimatch[];
2334

2435
program: ts.Program;
2536
programConfig: ts.ParsedCommandLine;
@@ -39,6 +50,9 @@ class IncrementalChecker {
3950
this.workNumber = workNumber || 0;
4051
this.workDivision = workDivision || 1;
4152
this.checkSyntacticErrors = checkSyntacticErrors || false;
53+
// Use empty array of exclusions in general to avoid having
54+
// to check of its existence later on.
55+
this.linterExclusions = [];
4256

4357
// it's shared between compilations
4458
this.files = new FilesRegister(() => ({
@@ -58,10 +72,10 @@ class IncrementalChecker {
5872
);
5973
}
6074

61-
static loadLinterConfig(configFile: string) {
75+
static loadLinterConfig(configFile: string): ConfigurationFile {
6276
const tslint: typeof tslintTypes = require('tslint');
6377

64-
return tslint.Configuration.loadConfigurationFromPath(configFile);
78+
return tslint.Configuration.loadConfigurationFromPath(configFile) as ConfigurationFile;
6579
}
6680

6781
static createProgram(
@@ -110,6 +124,10 @@ class IncrementalChecker {
110124
return new tslint.Linter({ fix: false }, program);
111125
}
112126

127+
static isFileExcluded(filePath: string, linterExclusions: minimatch.IMinimatch[]): boolean {
128+
return endsWith(filePath, '.d.ts') || linterExclusions.some(matcher => matcher.match(filePath));
129+
}
130+
113131
nextIteration() {
114132
if (!this.watcher) {
115133
this.watcher = new FilesWatcher(this.watchPaths, ['.ts', '.tsx']);
@@ -131,6 +149,13 @@ class IncrementalChecker {
131149

132150
if (!this.linterConfig && this.linterConfigFile) {
133151
this.linterConfig = IncrementalChecker.loadLinterConfig(this.linterConfigFile);
152+
153+
if (this.linterConfig.linterOptions && this.linterConfig.linterOptions.exclude) {
154+
// Pre-build minimatch patterns to avoid additional overhead later on.
155+
// Note: Resolving the path is required to properly match against the full file paths,
156+
// and also deals with potential cross-platform problems regarding path separators.
157+
this.linterExclusions = this.linterConfig.linterOptions.exclude.map(pattern => new minimatch.Minimatch(path.resolve(pattern)));
158+
}
134159
}
135160

136161
this.program = IncrementalChecker.createProgram(this.programConfig, this.files, this.watcher, this.program);
@@ -179,7 +204,7 @@ class IncrementalChecker {
179204

180205
// select files to lint
181206
const filesToLint = this.files.keys().filter(filePath =>
182-
!endsWith(filePath, '.d.ts') && !this.files.getData(filePath).linted
207+
!this.files.getData(filePath).linted && !IncrementalChecker.isFileExcluded(filePath, this.linterExclusions)
183208
);
184209

185210
// calculate subset of work to do

test/unit/IncrementalChecker.spec.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
var describe = require('mocha').describe;
2+
var it = require('mocha').it;
3+
var expect = require('chai').expect;
4+
var path = require('path');
5+
var minimatch = require('minimatch');
6+
7+
var IncrementalChecker = require('../../lib/IncrementalChecker');
8+
9+
describe('[UNIT] IncrementalChecker', function () {
10+
describe('isFileExcluded', function() {
11+
it('should properly filter definition files and listed exclusions', function() {
12+
var linterConfig = {
13+
linterOptions: {
14+
exclude: [
15+
'src/formatter/**/*.ts'
16+
]
17+
}
18+
};
19+
20+
var exclusions = linterConfig.linterOptions.exclude.map(function(pattern) {
21+
return new minimatch.Minimatch(path.resolve(pattern));
22+
});
23+
24+
var testPaths = [
25+
'src/formatter/codeframeFormatter.ts',
26+
'src/formatter/defaultFormatter.ts',
27+
'src/service.ts',
28+
'node_modules/tslint/lib/configuration.d.ts',
29+
].map(function(p) {
30+
return path.resolve(p);
31+
});
32+
33+
var pathsAreExcluded = testPaths.map(function(p) {
34+
return IncrementalChecker.isFileExcluded(p, exclusions);
35+
});
36+
37+
expect(pathsAreExcluded[0]).to.be.true;
38+
expect(pathsAreExcluded[1]).to.be.true;
39+
expect(pathsAreExcluded[2]).to.be.false;
40+
expect(pathsAreExcluded[3]).to.be.true;
41+
});
42+
});
43+
});

yarn.lock

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@
4444
version "4.14.74"
4545
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.74.tgz#ac3bd8db988e7f7038e5d22bd76a7ba13f876168"
4646

47+
"@types/minimatch@^3.0.1":
48+
version "3.0.1"
49+
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.1.tgz#b683eb60be358304ef146f5775db4c0e3696a550"
50+
4751
"@types/node@*", "@types/node@^8.0.26":
4852
version "8.0.26"
4953
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.26.tgz#4d58be925306fd22b1141085535a0268b8beb189"

0 commit comments

Comments
 (0)