lint-utils.js 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. var fs = require("fs");
  4. var errors_1 = require("../util/errors");
  5. var lint_factory_1 = require("./lint-factory");
  6. var helpers_1 = require("../util/helpers");
  7. var logger_1 = require("../logger/logger");
  8. var logger_diagnostics_1 = require("../logger/logger-diagnostics");
  9. var logger_typescript_1 = require("../logger/logger-typescript");
  10. var logger_tslint_1 = require("../logger/logger-tslint");
  11. /**
  12. * Lint files
  13. * @param {BuildContext} context
  14. * @param {Program} program
  15. * @param {string} tsLintConfig - TSLint config file path
  16. * @param {Array<string>} filePaths
  17. * @param {LinterOptions} linterOptions
  18. */
  19. function lintFiles(context, program, tsLintConfig, filePaths, linterOptions) {
  20. var linter = lint_factory_1.createLinter(context, program);
  21. var config = lint_factory_1.getTsLintConfig(tsLintConfig, linterOptions);
  22. return lint_factory_1.typeCheck(context, program, linterOptions)
  23. .then(function (diagnostics) { return processTypeCheckDiagnostics(context, diagnostics); })
  24. .then(function () { return Promise.all(filePaths.map(function (filePath) { return lintFile(linter, config, filePath); }))
  25. .then(function () { return lint_factory_1.getLintResult(linter); })
  26. .then(function (result) { return processLintResult(context, result); }); });
  27. }
  28. exports.lintFiles = lintFiles;
  29. function lintFile(linter, config, filePath) {
  30. if (isMpegFile(filePath)) {
  31. return Promise.reject(filePath + " is not a valid TypeScript file");
  32. }
  33. return helpers_1.readFileAsync(filePath)
  34. .then(function (fileContents) { return lint_factory_1.lint(linter, config, filePath, fileContents); });
  35. }
  36. exports.lintFile = lintFile;
  37. /**
  38. * Process typescript diagnostics after type checking
  39. * NOTE: This will throw a BuildError if there were any type errors.
  40. * @param {BuildContext} context
  41. * @param {Array<Diagnostic>} tsDiagnostics
  42. */
  43. function processTypeCheckDiagnostics(context, tsDiagnostics) {
  44. if (tsDiagnostics.length > 0) {
  45. var diagnostics = logger_typescript_1.runTypeScriptDiagnostics(context, tsDiagnostics);
  46. logger_diagnostics_1.printDiagnostics(context, logger_diagnostics_1.DiagnosticsType.TypeScript, diagnostics, true, false);
  47. var files = removeDuplicateFileNames(diagnostics.map(function (diagnostic) { return diagnostic.relFileName; }));
  48. var errorMessage = generateErrorMessageForFiles(files, 'The following files failed type checking:');
  49. throw new errors_1.BuildError(errorMessage);
  50. }
  51. }
  52. exports.processTypeCheckDiagnostics = processTypeCheckDiagnostics;
  53. /**
  54. * Process lint results
  55. * NOTE: This will throw a BuildError if there were any warnings or errors in any of the lint results.
  56. * @param {BuildContext} context
  57. * @param {LintResult} result
  58. */
  59. function processLintResult(context, result) {
  60. var files = [];
  61. // Only process the lint result if there are errors or warnings (there's no point otherwise)
  62. if (result.errorCount !== 0 || result.warningCount !== 0) {
  63. var diagnostics = logger_tslint_1.runTsLintDiagnostics(context, result.failures);
  64. logger_diagnostics_1.printDiagnostics(context, logger_diagnostics_1.DiagnosticsType.TsLint, diagnostics, true, false);
  65. files.push.apply(files, getFileNames(context, result.failures));
  66. }
  67. if (files.length > 0) {
  68. var errorMessage = generateErrorMessageForFiles(files);
  69. throw new errors_1.BuildError(errorMessage);
  70. }
  71. }
  72. exports.processLintResult = processLintResult;
  73. function generateErrorMessageForFiles(failingFiles, message) {
  74. return (message || 'The following files did not pass tslint:') + "\n" + failingFiles.join('\n');
  75. }
  76. exports.generateErrorMessageForFiles = generateErrorMessageForFiles;
  77. function getFileNames(context, failures) {
  78. return failures.map(function (failure) { return failure.getFileName()
  79. .replace(context.rootDir, '')
  80. .replace(/^\//g, ''); });
  81. }
  82. exports.getFileNames = getFileNames;
  83. function removeDuplicateFileNames(fileNames) {
  84. return Array.from(new Set(fileNames));
  85. }
  86. exports.removeDuplicateFileNames = removeDuplicateFileNames;
  87. function isMpegFile(file) {
  88. var buffer = new Buffer(256);
  89. buffer.fill(0);
  90. var fd = fs.openSync(file, 'r');
  91. try {
  92. fs.readSync(fd, buffer, 0, 256, null);
  93. if (buffer.readInt8(0) === 0x47 && buffer.readInt8(188) === 0x47) {
  94. logger_1.Logger.debug("tslint: " + file + ": ignoring MPEG transport stream");
  95. return true;
  96. }
  97. }
  98. finally {
  99. fs.closeSync(fd);
  100. }
  101. return false;
  102. }