Ajout de promotion et de commande
This commit is contained in:
+1109
File diff suppressed because it is too large
Load Diff
+541
File diff suppressed because it is too large
Load Diff
+18
@@ -0,0 +1,18 @@
|
||||
[
|
||||
{
|
||||
"name": "html",
|
||||
"description": "Outputs results to HTML. The `html` formatter is useful for visual presentation in the browser."
|
||||
},
|
||||
{
|
||||
"name": "json-with-metadata",
|
||||
"description": "Outputs JSON-serialized results. The `json-with-metadata` provides the same linting results as the [`json`](#json) formatter with additional metadata about the rules applied. The linting results are included in the `results` property and the rules metadata is included in the `metadata` property.\n\nAlternatively, you can use the [ESLint Node.js API](../../integrate/nodejs-api) to programmatically use ESLint."
|
||||
},
|
||||
{
|
||||
"name": "json",
|
||||
"description": "Outputs JSON-serialized results. The `json` formatter is useful when you want to programmatically work with the CLI's linting results.\n\nAlternatively, you can use the [ESLint Node.js API](../../integrate/nodejs-api) to programmatically use ESLint."
|
||||
},
|
||||
{
|
||||
"name": "stylish",
|
||||
"description": "Human-readable output format. This is the default formatter."
|
||||
}
|
||||
]
|
||||
+359
File diff suppressed because one or more lines are too long
+16
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* @fileoverview JSON reporter, including rules metadata
|
||||
* @author Chris Meyer
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Public Interface
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
module.exports = function (results, data) {
|
||||
return JSON.stringify({
|
||||
results,
|
||||
metadata: data,
|
||||
});
|
||||
};
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* @fileoverview JSON reporter
|
||||
* @author Burak Yigit Kaya aka BYK
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Public Interface
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
module.exports = function (results) {
|
||||
return JSON.stringify(results);
|
||||
};
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
/**
|
||||
* @fileoverview Stylish reporter
|
||||
* @author Sindre Sorhus
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
const chalk = require("chalk"),
|
||||
util = require("node:util"),
|
||||
table = require("../../shared/text-table");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Given a word and a count, append an s if count is not one.
|
||||
* @param {string} word A word in its singular form.
|
||||
* @param {number} count A number controlling whether word should be pluralized.
|
||||
* @returns {string} The original word with an s on the end if count is not one.
|
||||
*/
|
||||
function pluralize(word, count) {
|
||||
return count === 1 ? word : `${word}s`;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Public Interface
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
module.exports = function (results) {
|
||||
let output = "\n",
|
||||
errorCount = 0,
|
||||
warningCount = 0,
|
||||
fixableErrorCount = 0,
|
||||
fixableWarningCount = 0,
|
||||
summaryColor = "yellow";
|
||||
|
||||
results.forEach(result => {
|
||||
const messages = result.messages;
|
||||
|
||||
if (messages.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
errorCount += result.errorCount;
|
||||
warningCount += result.warningCount;
|
||||
fixableErrorCount += result.fixableErrorCount;
|
||||
fixableWarningCount += result.fixableWarningCount;
|
||||
|
||||
output += `${chalk.underline(result.filePath)}\n`;
|
||||
|
||||
output += `${table(
|
||||
messages.map(message => {
|
||||
let messageType;
|
||||
|
||||
if (message.fatal || message.severity === 2) {
|
||||
messageType = chalk.red("error");
|
||||
summaryColor = "red";
|
||||
} else {
|
||||
messageType = chalk.yellow("warning");
|
||||
}
|
||||
|
||||
return [
|
||||
"",
|
||||
String(message.line || 0),
|
||||
String(message.column || 0),
|
||||
messageType,
|
||||
message.message.replace(/([^ ])\.$/u, "$1"),
|
||||
chalk.dim(message.ruleId || ""),
|
||||
];
|
||||
}),
|
||||
{
|
||||
align: ["", "r", "l"],
|
||||
stringLength(str) {
|
||||
return util.stripVTControlCharacters(str).length;
|
||||
},
|
||||
},
|
||||
)
|
||||
.split("\n")
|
||||
.map(el =>
|
||||
el.replace(/(\d+)\s+(\d+)/u, (m, p1, p2) =>
|
||||
chalk.dim(`${p1}:${p2}`),
|
||||
),
|
||||
)
|
||||
.join("\n")}\n\n`;
|
||||
});
|
||||
|
||||
const total = errorCount + warningCount;
|
||||
|
||||
if (total > 0) {
|
||||
output += chalk[summaryColor].bold(
|
||||
[
|
||||
"\u2716 ",
|
||||
total,
|
||||
pluralize(" problem", total),
|
||||
" (",
|
||||
errorCount,
|
||||
pluralize(" error", errorCount),
|
||||
", ",
|
||||
warningCount,
|
||||
pluralize(" warning", warningCount),
|
||||
")\n",
|
||||
].join(""),
|
||||
);
|
||||
|
||||
if (fixableErrorCount > 0 || fixableWarningCount > 0) {
|
||||
output += chalk[summaryColor].bold(
|
||||
[
|
||||
" ",
|
||||
fixableErrorCount,
|
||||
pluralize(" error", fixableErrorCount),
|
||||
" and ",
|
||||
fixableWarningCount,
|
||||
pluralize(" warning", fixableWarningCount),
|
||||
" potentially fixable with the `--fix` option.\n",
|
||||
].join(""),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Resets output color, for prevent change on top level
|
||||
return total > 0 ? chalk.reset(output) : "";
|
||||
};
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* @fileoverview Defining the hashing function in one place.
|
||||
* @author Michael Ficarra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const murmur = require("imurmurhash");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Private
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* hash the given string
|
||||
* @param {string} str the string to hash
|
||||
* @returns {string} the hash
|
||||
*/
|
||||
function hash(str) {
|
||||
return murmur(str).result().toString(36);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Public Interface
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
module.exports = hash;
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
const { CLIEngine } = require("./cli-engine");
|
||||
|
||||
module.exports = {
|
||||
CLIEngine,
|
||||
};
|
||||
+220
@@ -0,0 +1,220 @@
|
||||
/**
|
||||
* @fileoverview Utility for caching lint results.
|
||||
* @author Kevin Partington
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const fs = require("node:fs");
|
||||
const fileEntryCache = require("file-entry-cache");
|
||||
const stringify = require("json-stable-stringify-without-jsonify");
|
||||
const pkg = require("../../package.json");
|
||||
const assert = require("../shared/assert");
|
||||
const hash = require("./hash");
|
||||
|
||||
const debug = require("debug")("eslint:lint-result-cache");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Typedefs
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** @typedef {import("../types").Linter.Config} Config */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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 {Config} 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 {Config} 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) {
|
||||
const cachedResults = this.getValidCachedLintResults(filePath, config);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve cached lint results for a given file path, if present in the
|
||||
* cache and still valid.
|
||||
* @param {string} filePath The file for which to retrieve lint results.
|
||||
* @param {Config} config The config of the file.
|
||||
* @returns {Object|null} The cached lint results if present in the cache
|
||||
* and still valid; null otherwise.
|
||||
*/
|
||||
getValidCachedLintResults(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);
|
||||
|
||||
if (fileDescriptor.notFound) {
|
||||
debug(`File not found on the file system: ${filePath}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
const hashOfConfig = hashOfConfigFor(config);
|
||||
const changed =
|
||||
fileDescriptor.changed ||
|
||||
fileDescriptor.meta.hashOfConfig !== hashOfConfig;
|
||||
|
||||
if (changed) {
|
||||
debug(`Cache entry not found or no longer valid: ${filePath}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
return fileDescriptor.meta.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 {Config} 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.hasOwn(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.hasOwn(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;
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* @fileoverview Module for loading rules from files and directories.
|
||||
* @author Michael Ficarra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const fs = require("node:fs"),
|
||||
path = require("node:path");
|
||||
|
||||
const rulesDirCache = {};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Public Interface
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Load all rule modules from specified directory.
|
||||
* @param {string} relativeRulesDir Path to rules directory, may be relative.
|
||||
* @param {string} cwd Current working directory
|
||||
* @returns {Object} Loaded rule modules.
|
||||
*/
|
||||
module.exports = function (relativeRulesDir, cwd) {
|
||||
const rulesDir = path.resolve(cwd, relativeRulesDir);
|
||||
|
||||
// cache will help performance as IO operation are expensive
|
||||
if (rulesDirCache[rulesDir]) {
|
||||
return rulesDirCache[rulesDir];
|
||||
}
|
||||
|
||||
const rules = Object.create(null);
|
||||
|
||||
fs.readdirSync(rulesDir).forEach(file => {
|
||||
if (path.extname(file) !== ".js") {
|
||||
return;
|
||||
}
|
||||
rules[file.slice(0, -3)] = require(path.join(rulesDir, file));
|
||||
});
|
||||
rulesDirCache[rulesDir] = rules;
|
||||
|
||||
return rules;
|
||||
};
|
||||
Reference in New Issue
Block a user