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

update importBlacklistRule to use regular expressions #3504

Merged
merged 8 commits into from
Dec 18, 2018
73 changes: 63 additions & 10 deletions src/rules/importBlacklistRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,25 +24,61 @@ export class Rule extends Lint.Rules.AbstractRule {
public static metadata: Lint.IRuleMetadata = {
ruleName: "import-blacklist",
description: Lint.Utils.dedent`
Disallows importing the specified modules directly via \`import\` and \`require\`.
Instead only sub modules may be imported from that module.`,
Disallows importing the specified modules directly via \`import\` and \`require\`.`,
rationale: Lint.Utils.dedent`
Some libraries allow importing their submodules instead of the entire module.
This is good practise as it avoids loading unused modules.`,
optionsDescription: "A list of blacklisted modules.",
This is good practise as it avoids loading unused modules.
Some projects may simply wish to exclude imports matching certain patterns.`,
optionsDescription: Lint.Utils.dedent`
A list of blacklisted modules and/or regular expression patterns.`,
options: {
type: "array",
items: {
type: "string",
anyOf: [
{
type: "string",
},
{
type: "array",
items: {
type: "string",
},
minLength: 1,
},
],
},
minLength: 1,
},
optionExamples: [true, [true, "rxjs", "lodash"]],
optionExamples: [
true,
[
true,
"rxjs",
"lodash",
],
[
true,
[
".*\\.temp$",
".*\\.tmp$",
],
],
[
true,
"rxjs",
"lodash",
[
".*\\.temp$",
".*\\.tmp$",
],
],
],
type: "functionality",
typescriptOnly: false,
};

public static FAILURE_STRING = "This import is blacklisted, import a submodule instead";
public static FAILURE_STRING_MODULE = "This import is blacklisted, import a submodule instead";
public static FAILURE_STRING_REGEX = "This import is blacklisted by ";

public isEnabled(): boolean {
return super.isEnabled() && this.ruleArguments.length > 0;
Expand All @@ -53,10 +89,27 @@ export class Rule extends Lint.Rules.AbstractRule {
}
}

function walk(ctx: Lint.WalkContext<string[]>) {
function walk(ctx: Lint.WalkContext<string[] | string[][]>) {
const moduleOptions = [];
const regexOptions = [];
for (const option of ctx.options) {
if (typeof option === "string") {
moduleOptions.push(option);
} else if (Array.isArray(option)) {
for (const pattern of option) {
regexOptions.push(RegExp(pattern));
}
}
}
for (const name of findImports(ctx.sourceFile, ImportKind.All)) {
if (ctx.options.indexOf(name.text) !== -1) {
ctx.addFailure(name.getStart(ctx.sourceFile) + 1, name.end - 1, Rule.FAILURE_STRING);
if (moduleOptions.indexOf(name.text) !== -1) {
ctx.addFailure(name.getStart(ctx.sourceFile) + 1, name.end - 1, Rule.FAILURE_STRING_MODULE);
} else {
for (const regex of regexOptions) {
if (regex.test(name.text)) {
ctx.addFailure(name.getStart(ctx.sourceFile) + 1, name.end - 1, Rule.FAILURE_STRING_REGEX + regex.toString());
}
}
}
}
}
8 changes: 8 additions & 0 deletions test/rules/import-blacklist/test.ts.lint
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,12 @@ import * as notBlacklisted from "not-blacklisted";
export * from 'lodash';
~~~~~~ [0]

import {myFunc} from './my.temp';
~~~~~~~~~ [1]

import {myFunc} from './my.tmp';
~~~~~~~~ [2]

[0]: This import is blacklisted, import a submodule instead
[1]: This import is blacklisted by /.*\.temp$/
[2]: This import is blacklisted by /.*\.tmp$/
2 changes: 1 addition & 1 deletion test/rules/import-blacklist/tslint.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"rules": {
"import-blacklist": [true, "lodash", "rxjs"]
"import-blacklist": [true, "lodash", "rxjs", [".*\\.temp$", ".*\\.tmp$"]]
}
}