Files
angular__angular/tools/tslint-rules/missingRollupGlobalsRule.ts
T
Paul Gschwendtner 9644840e4c build: write custom tslint rules in typescript (#6650)
Currently the custom TSLint rules of the repository had to be pushed as JavaScript files because TSLint was only able to run them as JavaScript files.

Recently with TSLint 5.7.0 (https://github.com/palantir/tslint/commit/90dd3f472199c68662eaecc47663969cb8ea6ed1), custom rules can be also loaded directly as TypeScript files in combination with ts-node.
2017-08-28 16:29:57 -07:00

57 lines
2.0 KiB
TypeScript

import * as path from 'path';
import * as ts from 'typescript';
import * as Lint from 'tslint';
import * as minimatch from 'minimatch';
/**
* Rule that enforces that the specified external packages have been included in our Rollup config.
* Usage: [true, './path/to/rollup/config.json']
*/
export class Rule extends Lint.Rules.AbstractRule {
apply(sourceFile: ts.SourceFile) {
return this.applyWithWalker(new Walker(sourceFile, this.getOptions()));
}
}
class Walker extends Lint.RuleWalker {
/** Path to the rollup globals configuration file. */
private _configPath: string;
/** Rollup globals configuration object. */
private _config: {[globalName: string]: string};
/** Whether the walker should check the current source file. */
private _enabled: boolean;
constructor(sourceFile: ts.SourceFile, options: Lint.IOptions) {
super(sourceFile, options);
if (!options.ruleArguments.length) {
throw Error('missing-rollup-globals: The Rollup config path has to be specified.');
}
const [configPath, ...fileGlobs] = options.ruleArguments;
// Relative path for the current TypeScript source file.
const relativeFilePath = path.relative(process.cwd(), sourceFile.fileName);
this._configPath = path.resolve(process.cwd(), configPath);
this._config = require(this._configPath).rollupGlobals;
this._enabled = fileGlobs.some(p => minimatch(relativeFilePath, p));
}
visitImportDeclaration(node: ts.ImportDeclaration) {
// Parse out the module name. The first and last characters are the quote marks.
const module = node.moduleSpecifier.getText().slice(1, -1);
const isExternal = !module.startsWith('.') && !module.startsWith('/');
// Check whether the module is external and whether it's in our config.
if (this._enabled && isExternal && !this._config[module]) {
this.addFailureAtNode(node, `Module "${module}" is missing from file ${this._configPath}.`);
}
super.visitImportDeclaration(node);
}
}