Ohm-Management - Projektarbeit B-ME
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

lint-result-cache.js 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /**
  2. * @fileoverview Utility for caching lint results.
  3. * @author Kevin Partington
  4. */
  5. "use strict";
  6. //-----------------------------------------------------------------------------
  7. // Requirements
  8. //-----------------------------------------------------------------------------
  9. const assert = require("assert"),
  10. fs = require("fs"),
  11. fileEntryCache = require("file-entry-cache"),
  12. hash = require("./hash"),
  13. pkg = require("../../package.json"),
  14. stringify = require("json-stable-stringify-without-jsonify");
  15. //-----------------------------------------------------------------------------
  16. // Helpers
  17. //-----------------------------------------------------------------------------
  18. const configHashCache = new WeakMap();
  19. /**
  20. * Calculates the hash of the config file used to validate a given file
  21. * @param {Object} configHelper The config helper for retrieving configuration information
  22. * @param {string} filename The path of the file to retrieve a config object for to calculate the hash
  23. * @returns {string} The hash of the config
  24. */
  25. function hashOfConfigFor(configHelper, filename) {
  26. const config = configHelper.getConfig(filename);
  27. if (!configHashCache.has(config)) {
  28. configHashCache.set(config, hash(`${pkg.version}_${stringify(config)}`));
  29. }
  30. return configHashCache.get(config);
  31. }
  32. //-----------------------------------------------------------------------------
  33. // Public Interface
  34. //-----------------------------------------------------------------------------
  35. /**
  36. * Lint result cache. This wraps around the file-entry-cache module,
  37. * transparently removing properties that are difficult or expensive to
  38. * serialize and adding them back in on retrieval.
  39. */
  40. class LintResultCache {
  41. /**
  42. * Creates a new LintResultCache instance.
  43. * @constructor
  44. * @param {string} cacheFileLocation The cache file location.
  45. * @param {Object} configHelper The configuration helper (used for
  46. * configuration lookup by file path).
  47. */
  48. constructor(cacheFileLocation, configHelper) {
  49. assert(cacheFileLocation, "Cache file location is required");
  50. assert(configHelper, "Config helper is required");
  51. this.fileEntryCache = fileEntryCache.create(cacheFileLocation);
  52. this.configHelper = configHelper;
  53. }
  54. /**
  55. * Retrieve cached lint results for a given file path, if present in the
  56. * cache. If the file is present and has not been changed, rebuild any
  57. * missing result information.
  58. * @param {string} filePath The file for which to retrieve lint results.
  59. * @returns {Object|null} The rebuilt lint results, or null if the file is
  60. * changed or not in the filesystem.
  61. */
  62. getCachedLintResults(filePath) {
  63. /*
  64. * Cached lint results are valid if and only if:
  65. * 1. The file is present in the filesystem
  66. * 2. The file has not changed since the time it was previously linted
  67. * 3. The ESLint configuration has not changed since the time the file
  68. * was previously linted
  69. * If any of these are not true, we will not reuse the lint results.
  70. */
  71. const fileDescriptor = this.fileEntryCache.getFileDescriptor(filePath);
  72. const hashOfConfig = hashOfConfigFor(this.configHelper, filePath);
  73. const changed = fileDescriptor.changed || fileDescriptor.meta.hashOfConfig !== hashOfConfig;
  74. if (fileDescriptor.notFound || changed) {
  75. return null;
  76. }
  77. // If source is present but null, need to reread the file from the filesystem.
  78. if (fileDescriptor.meta.results && fileDescriptor.meta.results.source === null) {
  79. fileDescriptor.meta.results.source = fs.readFileSync(filePath, "utf-8");
  80. }
  81. return fileDescriptor.meta.results;
  82. }
  83. /**
  84. * Set the cached lint results for a given file path, after removing any
  85. * information that will be both unnecessary and difficult to serialize.
  86. * Avoids caching results with an "output" property (meaning fixes were
  87. * applied), to prevent potentially incorrect results if fixes are not
  88. * written to disk.
  89. * @param {string} filePath The file for which to set lint results.
  90. * @param {Object} result The lint result to be set for the file.
  91. * @returns {void}
  92. */
  93. setCachedLintResults(filePath, result) {
  94. if (result && Object.prototype.hasOwnProperty.call(result, "output")) {
  95. return;
  96. }
  97. const fileDescriptor = this.fileEntryCache.getFileDescriptor(filePath);
  98. if (fileDescriptor && !fileDescriptor.notFound) {
  99. // Serialize the result, except that we want to remove the file source if present.
  100. const resultToSerialize = Object.assign({}, result);
  101. /*
  102. * Set result.source to null.
  103. * In `getCachedLintResults`, if source is explicitly null, we will
  104. * read the file from the filesystem to set the value again.
  105. */
  106. if (Object.prototype.hasOwnProperty.call(resultToSerialize, "source")) {
  107. resultToSerialize.source = null;
  108. }
  109. fileDescriptor.meta.results = resultToSerialize;
  110. fileDescriptor.meta.hashOfConfig = hashOfConfigFor(this.configHelper, result.filePath);
  111. }
  112. }
  113. /**
  114. * Persists the in-memory cache to disk.
  115. * @returns {void}
  116. */
  117. reconcile() {
  118. this.fileEntryCache.reconcile();
  119. }
  120. }
  121. module.exports = LintResultCache;