diff options
Diffstat (limited to 'node_modules/tslint/lib/runner.js')
-rw-r--r-- | node_modules/tslint/lib/runner.js | 316 |
1 files changed, 175 insertions, 141 deletions
diff --git a/node_modules/tslint/lib/runner.js b/node_modules/tslint/lib/runner.js index 594d595bb..0bcf5b9ed 100644 --- a/node_modules/tslint/lib/runner.js +++ b/node_modules/tslint/lib/runner.js @@ -16,180 +16,214 @@ * limitations under the License. */ Object.defineProperty(exports, "__esModule", { value: true }); -// tslint:disable strict-boolean-expressions prefer-template -// (wait on https://github.com/palantir/tslint/pull/2572) +var tslib_1 = require("tslib"); +// tslint:disable strict-boolean-expressions (TODO: Fix up options) var fs = require("fs"); var glob = require("glob"); +var minimatch_1 = require("minimatch"); var path = require("path"); var ts = require("typescript"); var configuration_1 = require("./configuration"); var error_1 = require("./error"); var Linter = require("./linter"); var test_1 = require("./test"); -var Runner = (function () { - function Runner(options, outputStream) { - this.options = options; - this.outputStream = outputStream; - } - Runner.trimSingleQuotes = function (str) { - return str.replace(/^'|'$/g, ""); - }; - Runner.prototype.run = function (onComplete) { - var _this = this; - if (this.options.version) { - this.outputStream.write(Linter.VERSION + "\n"); - return onComplete(0); - } - if (this.options.init) { - if (fs.existsSync(configuration_1.CONFIG_FILENAME)) { - console.error("Cannot generate " + configuration_1.CONFIG_FILENAME + ": file already exists"); - return onComplete(1); +var utils_1 = require("./utils"); +function run(options, logger) { + return tslib_1.__awaiter(this, void 0, void 0, function () { + var error_2; + return tslib_1.__generator(this, function (_a) { + switch (_a.label) { + case 0: + _a.trys.push([0, 2, , 3]); + return [4 /*yield*/, runWorker(options, logger)]; + case 1: return [2 /*return*/, _a.sent()]; + case 2: + error_2 = _a.sent(); + if (error_2.name === error_1.FatalError.NAME) { + logger.error(error_2.message); + return [2 /*return*/, 1 /* FatalError */]; + } + throw error_2; + case 3: return [2 /*return*/]; } - var tslintJSON = JSON.stringify(configuration_1.DEFAULT_CONFIG, undefined, " "); - fs.writeFileSync(configuration_1.CONFIG_FILENAME, tslintJSON); - return onComplete(0); - } - if (this.options.test) { - var results = test_1.runTests((this.options.files || []).map(Runner.trimSingleQuotes), this.options.rulesDirectory); - var didAllTestsPass = test_1.consoleTestResultsHandler(results); - return onComplete(didAllTestsPass ? 0 : 1); - } - // when provided, it should point to an existing location - if (this.options.config && !fs.existsSync(this.options.config)) { - console.error("Invalid option for configuration: " + this.options.config); - return onComplete(1); - } - // if both files and tsconfig are present, use files - var files = this.options.files === undefined ? [] : this.options.files; - var program; - if (this.options.project != null) { - var project = findTsconfig(this.options.project); - if (project === undefined) { - console.error("Invalid option for project: " + this.options.project); - return onComplete(1); - } - program = Linter.createProgram(project); - if (files.length === 0) { - files = Linter.getFileNames(program); - } - if (this.options.typeCheck) { - // if type checking, run the type checker - var diagnostics = ts.getPreEmitDiagnostics(program); - if (diagnostics.length > 0) { - var messages = diagnostics.map(function (diag) { - // emit any error messages - var message = ts.DiagnosticCategory[diag.category]; - if (diag.file) { - var _a = diag.file.getLineAndCharacterOfPosition(diag.start), line = _a.line, character = _a.character; - var file = void 0; - var currentDirectory = program.getCurrentDirectory(); - file = _this.options.outputAbsolutePaths - ? path.resolve(currentDirectory, diag.file.fileName) - : path.relative(currentDirectory, diag.file.fileName); - message += " at " + file + ":" + (line + 1) + ":" + (character + 1) + ":"; + }); + }); +} +exports.run = run; +function runWorker(options, logger) { + return tslib_1.__awaiter(this, void 0, void 0, function () { + var results, _a, output, errorCount; + return tslib_1.__generator(this, function (_b) { + switch (_b.label) { + case 0: + if (options.init) { + if (fs.existsSync(configuration_1.CONFIG_FILENAME)) { + throw new error_1.FatalError("Cannot generate " + configuration_1.CONFIG_FILENAME + ": file already exists"); } - message += " " + ts.flattenDiagnosticMessageText(diag.messageText, "\n"); - return message; - }); - console.error(messages.join("\n")); - return onComplete(this.options.force ? 0 : 1); - } - } - else { - // if not type checking, we don't need to pass in a program object - program = undefined; - } - } - var ignorePatterns = []; - if (this.options.exclude) { - var excludeArguments = Array.isArray(this.options.exclude) ? this.options.exclude : [this.options.exclude]; - ignorePatterns = excludeArguments.map(Runner.trimSingleQuotes); - } - files = files - .map(Runner.trimSingleQuotes) - .map(function (file) { return glob.sync(file, { ignore: ignorePatterns, nodir: true }); }) - .reduce(function (a, b) { return a.concat(b); }, []) - .map(function (file) { - if (_this.options.outputAbsolutePaths) { - return path.resolve(file); + fs.writeFileSync(configuration_1.CONFIG_FILENAME, JSON.stringify(configuration_1.DEFAULT_CONFIG, undefined, " ")); + return [2 /*return*/, 0 /* Ok */]; + } + if (options.test) { + results = test_1.runTests((options.files || []).map(trimSingleQuotes), options.rulesDirectory); + return [2 /*return*/, test_1.consoleTestResultsHandler(results) ? 0 /* Ok */ : 1 /* FatalError */]; + } + if (options.config && !fs.existsSync(options.config)) { + throw new error_1.FatalError("Invalid option for configuration: " + options.config); + } + return [4 /*yield*/, runLinter(options, logger)]; + case 1: + _a = _b.sent(), output = _a.output, errorCount = _a.errorCount; + logger.log(output); + return [2 /*return*/, options.force || errorCount === 0 ? 0 /* Ok */ : 2 /* LintError */]; } - return path.relative(process.cwd(), file); }); - try { - this.processFiles(onComplete, files, program); - } - catch (error) { - if (error.name === error_1.FatalError.NAME) { - console.error(error.message); - return onComplete(1); + }); +} +function runLinter(options, logger) { + return tslib_1.__awaiter(this, void 0, void 0, function () { + var _a, files, program, diagnostics, message; + return tslib_1.__generator(this, function (_b) { + _a = resolveFilesAndProgram(options), files = _a.files, program = _a.program; + // if type checking, run the type checker + if (program && options.typeCheck) { + diagnostics = ts.getPreEmitDiagnostics(program); + if (diagnostics.length !== 0) { + message = diagnostics.map(function (d) { return showDiagnostic(d, program, options.outputAbsolutePaths); }).join("\n"); + if (options.force) { + logger.error(message); + } + else { + throw new error_1.FatalError(message); + } + } } - // rethrow unhandled error - throw error; + return [2 /*return*/, doLinting(options, files, program, logger)]; + }); + }); +} +function resolveFilesAndProgram(_a) { + var files = _a.files, project = _a.project, exclude = _a.exclude, outputAbsolutePaths = _a.outputAbsolutePaths; + // remove single quotes which break matching on Windows when glob is passed in single quotes + var ignore = utils_1.arrayify(exclude).map(trimSingleQuotes); + if (project === undefined) { + return { files: resolveGlobs(files, ignore, outputAbsolutePaths) }; + } + var projectPath = findTsconfig(project); + if (projectPath === undefined) { + throw new error_1.FatalError("Invalid option for project: " + project); + } + var program = Linter.createProgram(projectPath); + var filesFound; + if (files === undefined || files.length === 0) { + filesFound = Linter.getFileNames(program); + if (ignore.length !== 0) { + var mm_1 = ignore.map(function (pattern) { return new minimatch_1.Minimatch(path.resolve(pattern)); }); + filesFound = filesFound.filter(function (file) { return !mm_1.some(function (matcher) { return matcher.match(file); }); }); } - }; - Runner.prototype.processFiles = function (onComplete, files, program) { - var _this = this; - var possibleConfigAbsolutePath = this.options.config != null ? path.resolve(this.options.config) : null; - var linter = new Linter({ - fix: !!this.options.fix, - formatter: this.options.format, - formattersDirectory: this.options.formattersDirectory || "", - rulesDirectory: this.options.rulesDirectory || "", - }, program); - var lastFolder; - var configFile; - for (var _i = 0, files_1 = files; _i < files_1.length; _i++) { - var file = files_1[_i]; - if (!fs.existsSync(file)) { - console.error("Unable to open file: " + file); - return onComplete(1); + } + else { + filesFound = resolveGlobs(files, ignore, outputAbsolutePaths); + } + return { files: filesFound, program: program }; +} +function resolveGlobs(files, ignore, outputAbsolutePaths) { + return utils_1.flatMap(utils_1.arrayify(files), function (file) { + return glob.sync(trimSingleQuotes(file), { ignore: ignore, nodir: true }); + }) + .map(function (file) { return outputAbsolutePaths ? path.resolve(file) : path.relative(process.cwd(), file); }); +} +function doLinting(options, files, program, logger) { + return tslib_1.__awaiter(this, void 0, void 0, function () { + var possibleConfigAbsolutePath, linter, lastFolder, configFile, _i, files_1, file, contents, folder; + return tslib_1.__generator(this, function (_a) { + switch (_a.label) { + case 0: + possibleConfigAbsolutePath = options.config !== undefined ? path.resolve(options.config) : null; + linter = new Linter({ + fix: !!options.fix, + formatter: options.format, + formattersDirectory: options.formattersDirectory, + rulesDirectory: options.rulesDirectory, + }, program); + _i = 0, files_1 = files; + _a.label = 1; + case 1: + if (!(_i < files_1.length)) return [3 /*break*/, 4]; + file = files_1[_i]; + if (!fs.existsSync(file)) { + throw new error_1.FatalError("Unable to open file: " + file); + } + return [4 /*yield*/, tryReadFile(file, logger)]; + case 2: + contents = _a.sent(); + if (contents !== undefined) { + folder = path.dirname(file); + if (lastFolder !== folder) { + configFile = configuration_1.findConfiguration(possibleConfigAbsolutePath, folder).results; + lastFolder = folder; + } + linter.lint(file, contents, configFile); + } + _a.label = 3; + case 3: + _i++; + return [3 /*break*/, 1]; + case 4: return [2 /*return*/, linter.getResult()]; } - var buffer = new Buffer(256); - var fd = fs.openSync(file, "r"); + }); + }); +} +/** Read a file, but return undefined if it is an MPEG '.ts' file. */ +function tryReadFile(filename, logger) { + return tslib_1.__awaiter(this, void 0, void 0, function () { + var buffer, fd; + return tslib_1.__generator(this, function (_a) { + buffer = new Buffer(256); + fd = fs.openSync(filename, "r"); try { fs.readSync(fd, buffer, 0, 256, 0); if (buffer.readInt8(0, true) === 0x47 && buffer.readInt8(188, true) === 0x47) { // MPEG transport streams use the '.ts' file extension. They use 0x47 as the frame // separator, repeating every 188 bytes. It is unlikely to find that pattern in // TypeScript source, so tslint ignores files with the specific pattern. - console.warn(file + ": ignoring MPEG transport stream"); - continue; + logger.error(filename + ": ignoring MPEG transport stream"); + return [2 /*return*/, undefined]; } } finally { fs.closeSync(fd); } - var contents = fs.readFileSync(file, "utf8"); - var folder = path.dirname(file); - if (lastFolder !== folder) { - configFile = configuration_1.findConfiguration(possibleConfigAbsolutePath, folder).results; - lastFolder = folder; - } - linter.lint(file, contents, configFile); - } - var lintResult = linter.getResult(); - this.outputStream.write(lintResult.output, function () { - if (_this.options.force || lintResult.errorCount === 0) { - onComplete(0); - } - else { - onComplete(2); - } + return [2 /*return*/, fs.readFileSync(filename, "utf8")]; }); - }; - return Runner; -}()); -exports.Runner = Runner; + }); +} +function showDiagnostic(_a, program, outputAbsolutePaths) { + var file = _a.file, start = _a.start, category = _a.category, messageText = _a.messageText; + var message = ts.DiagnosticCategory[category]; + if (file !== undefined && start !== undefined) { + var _b = file.getLineAndCharacterOfPosition(start), line = _b.line, character = _b.character; + var currentDirectory = program.getCurrentDirectory(); + var filePath = outputAbsolutePaths + ? path.resolve(currentDirectory, file.fileName) + : path.relative(currentDirectory, file.fileName); + message += " at " + filePath + ":" + (line + 1) + ":" + (character + 1) + ":"; + } + return message + " " + ts.flattenDiagnosticMessageText(messageText, "\n"); +} +function trimSingleQuotes(str) { + return str.replace(/^'|'$/g, ""); +} function findTsconfig(project) { try { var stats = fs.statSync(project); // throws if file does not exist - if (stats.isDirectory()) { - project = path.join(project, "tsconfig.json"); - fs.accessSync(project); // throws if file does not exist + if (!stats.isDirectory()) { + return project; } + var projectFile = path.join(project, "tsconfig.json"); + fs.accessSync(projectFile); // throws if file does not exist + return projectFile; } catch (e) { return undefined; } - return project; } |