mirror of
https://github.com/angular/angular-cli.git
synced 2025-05-16 02:24:10 +08:00
* docs: add README files to all root folders Except benchmark and tools. * refactor: move rules/ directory to etc/ And fix a linting error that was found while updating tslint usage * ci: lint errors out if TSLint shows a warning This is not a warning from the code itself, but from TSLint. For example, if a rule was missing, TSLint will just ignore the rule, show something on STDOUT and not fail. This fixes CI where local rules were missing for unknown reasons. It will now fail CI when that happens, which is the correct behaviour.
112 lines
3.5 KiB
TypeScript
112 lines
3.5 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright Google Inc. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://angular.io/license
|
|
*/
|
|
// tslint:disable:no-implicit-dependencies
|
|
import { logging } from '@angular-devkit/core';
|
|
import { ParsedArgs } from 'minimist';
|
|
import * as path from 'path';
|
|
import { Configuration, ILinterOptions, Linter, findFormatter } from 'tslint';
|
|
import * as ts from 'typescript';
|
|
|
|
// Blacklist (regexes) of the files to not lint. Generated files should not be linted.
|
|
// TODO: when moved to using bazel for the build system, this won't be needed.
|
|
const blacklist = [
|
|
/^dist-schema[\\\/].*/,
|
|
];
|
|
|
|
|
|
function _buildRules(logger: logging.Logger) {
|
|
const tsConfigPath = path.join(__dirname, '../etc/rules/tsconfig.json');
|
|
const configFile = ts.readConfigFile(tsConfigPath, ts.sys.readFile);
|
|
|
|
const parsedTsConfig = ts.parseJsonConfigFileContent(
|
|
configFile.config,
|
|
ts.sys,
|
|
path.dirname(tsConfigPath),
|
|
);
|
|
const lintRulesProgram = ts.createProgram(parsedTsConfig.fileNames, parsedTsConfig.options);
|
|
const result = lintRulesProgram.emit();
|
|
|
|
if (result.emitSkipped) {
|
|
const host: ts.FormatDiagnosticsHost = {
|
|
getCurrentDirectory: () => ts.sys.getCurrentDirectory(),
|
|
getNewLine: () => ts.sys.newLine,
|
|
getCanonicalFileName: (fileName: string) => fileName,
|
|
};
|
|
logger.fatal(ts.formatDiagnostics(result.diagnostics, host));
|
|
process.exit(100);
|
|
}
|
|
}
|
|
|
|
|
|
export default async function (options: ParsedArgs, logger: logging.Logger) {
|
|
_buildRules(logger);
|
|
|
|
const lintOptions: ILinterOptions = {
|
|
fix: options.fix,
|
|
};
|
|
|
|
const program = Linter.createProgram(path.join(__dirname, '../tsconfig.json'));
|
|
const linter = new Linter(lintOptions, program);
|
|
const tsLintPath = path.join(__dirname, '../tslint.json');
|
|
const tsLintConfig = Configuration.loadConfigurationFromPath(tsLintPath);
|
|
|
|
// Remove comments from the configuration, ie. keys that starts with "//".
|
|
[...tsLintConfig.rules.keys()]
|
|
.filter(x => x.startsWith('//'))
|
|
.forEach(key => tsLintConfig.rules.delete(key));
|
|
|
|
// Console is used directly by tslint, and when finding a rule that doesn't exist it's considered
|
|
// a warning by TSLint but _only_ shown on the console and impossible to see through the API.
|
|
// In order to see any warnings that happen from TSLint itself, we hook into console.warn() and
|
|
// record any calls.
|
|
const oldWarn = console.warn;
|
|
let warnings = false;
|
|
console.warn = (...args) => {
|
|
warnings = true;
|
|
oldWarn(...args);
|
|
};
|
|
|
|
program.getRootFileNames().forEach(fileName => {
|
|
if (blacklist.some(x => x.test(path.relative(process.cwd(), fileName)))) {
|
|
return;
|
|
}
|
|
|
|
linter.lint(fileName, ts.sys.readFile(fileName) || '', tsLintConfig);
|
|
});
|
|
|
|
console.warn = oldWarn;
|
|
|
|
const result = linter.getResult();
|
|
const Formatter = findFormatter('codeFrame');
|
|
if (!Formatter) {
|
|
throw new Error('Cannot find lint formatter.');
|
|
}
|
|
const formatter = new Formatter();
|
|
|
|
if (result.errorCount > 0) {
|
|
logger.error(formatter.format(result.failures));
|
|
logger.info(`Errors: ${result.errorCount}`);
|
|
if (result.warningCount > 0) {
|
|
logger.info(`Warnings: ${result.warningCount}`);
|
|
}
|
|
|
|
return 2;
|
|
} else if (result.warningCount > 0) {
|
|
logger.warn(formatter.format(result.failures));
|
|
logger.info(`Warnings: ${result.warningCount}`);
|
|
|
|
return 1;
|
|
} else if (warnings) {
|
|
logger.warn('TSLint found warnings, but code is okay. See above.');
|
|
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|