Files
codeql-action/node_modules/eslint/lib/cli-engine/lint-result-cache.js
dependabot[bot] 80150c2141 Bump the npm group with 12 updates (#2003)
* Bump the npm group with 12 updates

Bumps the npm group with 12 updates:

| Package | From | To |
| --- | --- | --- |
| [@octokit/types](https://github.com/octokit/types.ts) | `12.1.1` | `12.3.0` |
| [@types/uuid](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/uuid) | `9.0.6` | `9.0.7` |
| [@types/adm-zip](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/adm-zip) | `0.5.3` | `0.5.4` |
| [@types/js-yaml](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/js-yaml) | `4.0.8` | `4.0.9` |
| [@types/semver](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/semver) | `7.5.4` | `7.5.5` |
| [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) | `6.9.1` | `6.12.0` |
| [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) | `6.9.1` | `6.12.0` |
| [eslint](https://github.com/eslint/eslint) | `8.52.0` | `8.54.0` |
| [nock](https://github.com/nock/nock) | `13.3.7` | `13.3.8` |
| [sinon](https://github.com/sinonjs/sinon) | `17.0.0` | `17.0.1` |
| [@types/sinon](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/sinon) | `10.0.20` | `17.0.1` |
| [typescript](https://github.com/Microsoft/TypeScript) | `5.2.2` | `5.3.2` |


Updates `@octokit/types` from 12.1.1 to 12.3.0
- [Release notes](https://github.com/octokit/types.ts/releases)
- [Commits](https://github.com/octokit/types.ts/compare/v12.1.1...v12.3.0)

Updates `@types/uuid` from 9.0.6 to 9.0.7
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/uuid)

Updates `@types/adm-zip` from 0.5.3 to 0.5.4
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/adm-zip)

Updates `@types/js-yaml` from 4.0.8 to 4.0.9
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/js-yaml)

Updates `@types/semver` from 7.5.4 to 7.5.5
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/semver)

Updates `@typescript-eslint/eslint-plugin` from 6.9.1 to 6.12.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.12.0/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 6.9.1 to 6.12.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.12.0/packages/parser)

Updates `eslint` from 8.52.0 to 8.54.0
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v8.52.0...v8.54.0)

Updates `nock` from 13.3.7 to 13.3.8
- [Release notes](https://github.com/nock/nock/releases)
- [Changelog](https://github.com/nock/nock/blob/main/CHANGELOG.md)
- [Commits](https://github.com/nock/nock/compare/v13.3.7...v13.3.8)

Updates `sinon` from 17.0.0 to 17.0.1
- [Release notes](https://github.com/sinonjs/sinon/releases)
- [Changelog](https://github.com/sinonjs/sinon/blob/main/docs/changelog.md)
- [Commits](https://github.com/sinonjs/sinon/compare/v17.0.0...v17.0.1)

Updates `@types/sinon` from 10.0.20 to 17.0.1
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/sinon)

Updates `typescript` from 5.2.2 to 5.3.2
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Commits](https://github.com/Microsoft/TypeScript/commits)

---
updated-dependencies:
- dependency-name: "@octokit/types"
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm
- dependency-name: "@types/uuid"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm
- dependency-name: "@types/adm-zip"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm
- dependency-name: "@types/js-yaml"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm
- dependency-name: "@types/semver"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm
- dependency-name: nock
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm
- dependency-name: sinon
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm
- dependency-name: "@types/sinon"
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm
- dependency-name: typescript
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm
...

Signed-off-by: dependabot[bot] <support@github.com>

* Update checked-in dependencies

* Rebuild

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-11-20 14:35:28 -08:00

204 lines
7.2 KiB
JavaScript

/**
* @fileoverview Utility for caching lint results.
* @author Kevin Partington
*/
"use strict";
//-----------------------------------------------------------------------------
// Requirements
//-----------------------------------------------------------------------------
const assert = require("assert");
const fs = require("fs");
const fileEntryCache = require("file-entry-cache");
const stringify = require("json-stable-stringify-without-jsonify");
const pkg = require("../../package.json");
const hash = require("./hash");
const debug = require("debug")("eslint:lint-result-cache");
//-----------------------------------------------------------------------------
// Helpers
//-----------------------------------------------------------------------------
const configHashCache = new WeakMap();
const nodeVersion = process && process.version;
const validCacheStrategies = ["metadata", "content"];
const invalidCacheStrategyErrorMessage = `Cache strategy must be one of: ${validCacheStrategies
.map(strategy => `"${strategy}"`)
.join(", ")}`;
/**
* Tests whether a provided cacheStrategy is valid
* @param {string} cacheStrategy The cache strategy to use
* @returns {boolean} true if `cacheStrategy` is one of `validCacheStrategies`; false otherwise
*/
function isValidCacheStrategy(cacheStrategy) {
return (
validCacheStrategies.includes(cacheStrategy)
);
}
/**
* Calculates the hash of the config
* @param {ConfigArray} config The config.
* @returns {string} The hash of the config
*/
function hashOfConfigFor(config) {
if (!configHashCache.has(config)) {
configHashCache.set(config, hash(`${pkg.version}_${nodeVersion}_${stringify(config)}`));
}
return configHashCache.get(config);
}
//-----------------------------------------------------------------------------
// Public Interface
//-----------------------------------------------------------------------------
/**
* Lint result cache. This wraps around the file-entry-cache module,
* transparently removing properties that are difficult or expensive to
* serialize and adding them back in on retrieval.
*/
class LintResultCache {
/**
* Creates a new LintResultCache instance.
* @param {string} cacheFileLocation The cache file location.
* @param {"metadata" | "content"} cacheStrategy The cache strategy to use.
*/
constructor(cacheFileLocation, cacheStrategy) {
assert(cacheFileLocation, "Cache file location is required");
assert(cacheStrategy, "Cache strategy is required");
assert(
isValidCacheStrategy(cacheStrategy),
invalidCacheStrategyErrorMessage
);
debug(`Caching results to ${cacheFileLocation}`);
const useChecksum = cacheStrategy === "content";
debug(
`Using "${cacheStrategy}" strategy to detect changes`
);
this.fileEntryCache = fileEntryCache.create(
cacheFileLocation,
void 0,
useChecksum
);
this.cacheFileLocation = cacheFileLocation;
}
/**
* Retrieve cached lint results for a given file path, if present in the
* cache. If the file is present and has not been changed, rebuild any
* missing result information.
* @param {string} filePath The file for which to retrieve lint results.
* @param {ConfigArray} config The config of the file.
* @returns {Object|null} The rebuilt lint results, or null if the file is
* changed or not in the filesystem.
*/
getCachedLintResults(filePath, config) {
/*
* Cached lint results are valid if and only if:
* 1. The file is present in the filesystem
* 2. The file has not changed since the time it was previously linted
* 3. The ESLint configuration has not changed since the time the file
* was previously linted
* If any of these are not true, we will not reuse the lint results.
*/
const fileDescriptor = this.fileEntryCache.getFileDescriptor(filePath);
const hashOfConfig = hashOfConfigFor(config);
const changed =
fileDescriptor.changed ||
fileDescriptor.meta.hashOfConfig !== hashOfConfig;
if (fileDescriptor.notFound) {
debug(`File not found on the file system: ${filePath}`);
return null;
}
if (changed) {
debug(`Cache entry not found or no longer valid: ${filePath}`);
return null;
}
const cachedResults = fileDescriptor.meta.results;
// Just in case, not sure if this can ever happen.
if (!cachedResults) {
return cachedResults;
}
/*
* Shallow clone the object to ensure that any properties added or modified afterwards
* will not be accidentally stored in the cache file when `reconcile()` is called.
* https://github.com/eslint/eslint/issues/13507
* All intentional changes to the cache file must be done through `setCachedLintResults()`.
*/
const results = { ...cachedResults };
// If source is present but null, need to reread the file from the filesystem.
if (results.source === null) {
debug(`Rereading cached result source from filesystem: ${filePath}`);
results.source = fs.readFileSync(filePath, "utf-8");
}
return results;
}
/**
* Set the cached lint results for a given file path, after removing any
* information that will be both unnecessary and difficult to serialize.
* Avoids caching results with an "output" property (meaning fixes were
* applied), to prevent potentially incorrect results if fixes are not
* written to disk.
* @param {string} filePath The file for which to set lint results.
* @param {ConfigArray} config The config of the file.
* @param {Object} result The lint result to be set for the file.
* @returns {void}
*/
setCachedLintResults(filePath, config, result) {
if (result && Object.prototype.hasOwnProperty.call(result, "output")) {
return;
}
const fileDescriptor = this.fileEntryCache.getFileDescriptor(filePath);
if (fileDescriptor && !fileDescriptor.notFound) {
debug(`Updating cached result: ${filePath}`);
// Serialize the result, except that we want to remove the file source if present.
const resultToSerialize = Object.assign({}, result);
/*
* Set result.source to null.
* In `getCachedLintResults`, if source is explicitly null, we will
* read the file from the filesystem to set the value again.
*/
if (Object.prototype.hasOwnProperty.call(resultToSerialize, "source")) {
resultToSerialize.source = null;
}
fileDescriptor.meta.results = resultToSerialize;
fileDescriptor.meta.hashOfConfig = hashOfConfigFor(config);
}
}
/**
* Persists the in-memory cache to disk.
* @returns {void}
*/
reconcile() {
debug(`Persisting cached results: ${this.cacheFileLocation}`);
this.fileEntryCache.reconcile();
}
}
module.exports = LintResultCache;