blob: 698b3105f10048ec692921d2ec6edbe5b9ebaea9 [file] [log] [blame]
Mathias Bynens79e2cf02020-05-29 16:46:17 +02001'use strict';
2
3const debug = require('debug')('stylelint:file-cache');
4const fileEntryCache = require('file-entry-cache');
5const getCacheFile = require('./getCacheFile');
6const path = require('path');
7
8const DEFAULT_CACHE_LOCATION = './.stylelintcache';
9const DEFAULT_HASH = '';
10
Tim van der Lippeefb716a2020-12-01 12:54:04 +000011/** @typedef {import('file-entry-cache').FileDescriptor["meta"] & { hashOfConfig?: string }} CacheMetadata */
12
Mathias Bynens79e2cf02020-05-29 16:46:17 +020013/**
14 * @param {string} [cacheLocation]
15 * @param {string} [hashOfConfig]
16 * @constructor
17 */
18class FileCache {
Tim van der Lippe4cb09742022-01-07 14:25:03 +010019 constructor(
20 cacheLocation = DEFAULT_CACHE_LOCATION,
21 cwd = process.cwd(),
22 hashOfConfig = DEFAULT_HASH,
23 ) {
24 const cacheFile = path.resolve(getCacheFile(cacheLocation, cwd));
Mathias Bynens79e2cf02020-05-29 16:46:17 +020025
26 debug(`Cache file is created at ${cacheFile}`);
27 this._fileCache = fileEntryCache.create(cacheFile);
28 this._hashOfConfig = hashOfConfig;
29 }
30
31 /**
32 * @param {string} absoluteFilepath
33 * @return {boolean}
34 */
35 hasFileChanged(absoluteFilepath) {
36 // Get file descriptor compares current metadata against cached
37 // one and stores the result to "changed" prop.w
38 const descriptor = this._fileCache.getFileDescriptor(absoluteFilepath);
Tim van der Lippeefb716a2020-12-01 12:54:04 +000039 /** @type {CacheMetadata} */
Mathias Bynens79e2cf02020-05-29 16:46:17 +020040 const meta = descriptor.meta || {};
41 const changed = descriptor.changed || meta.hashOfConfig !== this._hashOfConfig;
42
43 if (!changed) {
44 debug(`Skip linting ${absoluteFilepath}. File hasn't changed.`);
45 }
46
47 // Mutate file descriptor object and store config hash to each file.
48 // Running lint with different config should invalidate the cache.
49 if (meta.hashOfConfig !== this._hashOfConfig) {
50 meta.hashOfConfig = this._hashOfConfig;
51 }
52
53 return changed;
54 }
55
56 reconcile() {
57 this._fileCache.reconcile();
58 }
59
60 destroy() {
61 this._fileCache.destroy();
62 }
63
64 /**
65 * @param {string} absoluteFilepath
66 */
67 removeEntry(absoluteFilepath) {
68 this._fileCache.removeEntry(absoluteFilepath);
69 }
70}
71
72module.exports = FileCache;