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
33 changes: 24 additions & 9 deletions src/rules/importBlacklistRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,25 +24,32 @@ 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.",
Some projects may wish to exclude imports matching certain patterns.

Examples:
^lodash$ Blacklist any import of the entire lodash module.
Since lodash allows importing submodules, a better practice
would be to import the desired submodule instead.

.*\\.temp$ Blacklist any imports ending in .temp`,
optionsDescription: Lint.Utils.dedent`
A list of blacklist pattern strings to be compiled to regular expressions.
The corresponding regular expressions will be tested against the imports.`,
options: {
type: "array",
items: {
type: "string",
},
minLength: 1,
},
optionExamples: [true, [true, "rxjs", "lodash"]],
optionExamples: [true, [true, "^rxjs$", "^lodash$", ".*\\.temp$"]],
type: "functionality",
typescriptOnly: false,
};

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

public isEnabled(): boolean {
return super.isEnabled() && this.ruleArguments.length > 0;
Expand All @@ -54,9 +61,17 @@ export class Rule extends Lint.Rules.AbstractRule {
}

function walk(ctx: Lint.WalkContext<string[]>) {
const regexOptions = [];
for (const option of ctx.options) {
if (typeof option === "string") {
regexOptions.push(RegExp(option));
}
}
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);
for (const regex of regexOptions) {
if (regex.test(name.text)) {
ctx.addFailure(name.getStart(ctx.sourceFile) + 1, name.end - 1, Rule.FAILURE_STRING + regex.toString());
}
}
}
}
11 changes: 8 additions & 3 deletions test/rules/import-blacklist/test.ts.lint
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Observable } from 'rxjs';
import { Observable } from 'rxjs/Observable';

import forOwn = require('lodash');
~~~~~~ [0]
~~~~~~ [1]
import forOwn = require('lodash/forOwn');

// non-static imports cannot be checked
Expand All @@ -13,6 +13,11 @@ import forOwn = require(lodash);
import * as notBlacklisted from "not-blacklisted";

export * from 'lodash';
~~~~~~ [0]
~~~~~~ [1]

[0]: This import is blacklisted, import a submodule instead
import {myFunc} from './my.temp';
~~~~~~~~~ [2]

[0]: This import is blacklisted by /^rxjs$/
[1]: This import is blacklisted by /^lodash$/
[2]: This import is blacklisted by /.*\.temp$/
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$"]
}
}