Skip to content
This repository has been archived by the owner on Mar 25, 2021. It is now read-only.

config: use resolved exclude pattern #3205

Merged
merged 2 commits into from
Sep 11, 2017
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
2 changes: 1 addition & 1 deletion docs/usage/configuration/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ A path to a directory or an array of paths to directories of [custom rules][2].
* `jsRules?: any`: Same format as `rules`. These rules are applied to `.js` and `.jsx` files.
* `defaultSeverity?: "error" | "warning" | "off"`: The severity level used when a rule specifies a default warning level. If undefined, "error" is used. This value is not inherited and is only applied to rules in this file.
* `linterOptions?: { exclude?: string[] }`:
- `exclude: string[]`: An array of globs. Any file matching these globs will not be linted.
- `exclude: string[]`: An array of globs. Any file matching these globs will not be linted. All exclude patterns are relative to the configuration file they were specified in.

`tslint.json` configuration files may have JavaScript-style `// single-line` and `/* multi-line */` comments in them (even though this is technically invalid JSON). If this confuses your syntax highlighter, you may want to switch it to JavaScript format.

Expand Down
13 changes: 12 additions & 1 deletion src/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ export function parseConfigFile(configFile: RawConfigFile, configFileDir?: strin
return {
extends: arrayify(configFile.extends),
jsRules: parseRules(configFile.jsRules),
linterOptions: configFile.linterOptions !== undefined ? configFile.linterOptions : {},
linterOptions: parseLinterOptions(configFile.linterOptions),
rules: parseRules(configFile.rules),
rulesDirectory: getRulesDirectories(configFile.rulesDirectory, configFileDir),
};
Expand All @@ -491,6 +491,17 @@ export function parseConfigFile(configFile: RawConfigFile, configFileDir?: strin
}
return map;
}

function parseLinterOptions(raw: RawConfigFile["linterOptions"]): IConfigurationFile["linterOptions"] {
if (raw === undefined || raw.exclude === undefined) {
return {};
}
return {
exclude: arrayify(raw.exclude).map(
(pattern) => configFileDir === undefined ? path.resolve(pattern) : path.resolve(configFileDir, pattern),
),
};
}
}

/**
Expand Down
14 changes: 14 additions & 0 deletions test/configurationTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,20 @@ describe("Configuration", () => {
ruleSeverity: "error",
});
});

it("resolves exclude pattern relative to the configuration file", () => {
const config: RawConfigFile = {
linterOptions: {
exclude: ["foo.ts", "**/*.d.ts"],
},
};
assert.deepEqual(
parseConfigFile(config, "/path").linterOptions,
{
exclude: [path.resolve("/path", "foo.ts"), path.resolve("/path", "**/*.d.ts")],
},
);
});
});

describe("defaultSeverity", () => {
Expand Down
51 changes: 37 additions & 14 deletions test/executable/executableTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,32 +164,55 @@ describe("Executable", function(this: Mocha.ISuiteCallbackContext) {
});

describe("Config with excluded files", () => {
it("exits with code 1 if linter options doesn't exclude file with lint errors", (done) => {
const tempFile = createTempFile("included.ts");
fs.writeFileSync(tempFile, "console.log(\"missing semi-colon at end of line\")", { encoding: "utf8" });
execCli(["-c", "./test/config/tslint-exclude.json", tempFile], (err) => {
it("exits with code 2 if linter options doesn't exclude file with lint errors", (done) => {
execCli(["-c", "./test/files/config-exclude/tslint-exclude-one.json", "./test/files/config-exclude/included.ts"], (err) => {
assert.isNotNull(err, "process should exit with error");
assert.strictEqual(err.code, 1, "error code should be 1");
assert.strictEqual(err.code, 2, "error code should be 2");
done();
});
});

it("exits with code 0 if linter options exclude one file with lint errors", (done) => {
const tempFile = createTempFile("excluded.ts");
fs.writeFileSync(tempFile, "console.log(\"missing semi-colon at end of line\")", { encoding: "utf8" });
execCli(["-c", "./test/config/tslint-exclude-one.json", tempFile], (err) => {
execCli(["-c", "./test/files/config-exclude/tslint-exclude-one.json", "./test/rules/config-exclude/excluded.ts"], (err) => {
assert.isNull(err, "process should exit without an error");
done();
});
});

it("exits with code 0 if linter options excludes many files with lint errors", (done) => {
const tempFiles = [1, 2].map((x) => createTempFile(`excluded${x}.ts`));
tempFiles.forEach((f) => fs.writeFileSync(f, "console.log(\"missing semi-colon at end of line\")", { encoding: "utf8" }));
execCli(["-c", "./test/config/tslint-exclude-many.json", ...tempFiles], (err) => {
assert.isNull(err, "process should exit without an error");
done();
});
execCli(
[
"-c",
"./test/files/config-exclude/tslint-exclude-many.json",
"./test/rules/config-exclude/excluded1.ts",
"./test/rules/config-exclude/subdir/excluded2.ts"],
(err) => {
assert.isNull(err, "process should exit without an error");
done();
},
);
});

it("excludes files relative to tslint.json", (done) => {
execCli(
["-c", "./test/files/config-exclude/tslint-exclude-one.json", "./test/files/config-exclude/subdir/excluded.ts"],
(err) => {
assert.isNotNull(err, "process should exit an error");
assert.equal(err.code, 2, "exit code should be 2");
done();
},
);
});

it("excludes files relative to tslint.json they were declared in", (done) => {
execCli(
["-c", "./test/files/config-exclude/subdir/tslint-extending.json", "./test/files/config-exclude/subdir/excluded.ts"],
(err) => {
assert.isNotNull(err, "process should exit an error");
assert.equal(err.code, 2, "exit code should be 2");
done();
},
);
});
});

Expand Down
1 change: 1 addition & 0 deletions test/files/config-exclude/excluded.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log("missing semicolon at end of line")
1 change: 1 addition & 0 deletions test/files/config-exclude/excluded1.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log("missing semicolon at end of line")
1 change: 1 addition & 0 deletions test/files/config-exclude/included.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log("missing semicolon at end of line")
1 change: 1 addition & 0 deletions test/files/config-exclude/subdir/excluded.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log("missing semicolon at end of line")
1 change: 1 addition & 0 deletions test/files/config-exclude/subdir/excluded2.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log("missing semicolon at end of line")
3 changes: 3 additions & 0 deletions test/files/config-exclude/subdir/tslint-extending.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "../tslint-exclude-one.json"
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
},
"linterOptions": {
"exclude": [
"**/*excluded.ts"
"excluded.ts"
]
}
}