mirror of
https://github.com/DavidAnson/markdownlint.git
synced 2025-12-17 06:20:12 +01:00
Allow custom file system implementation to be passed when linting or reading configuration.
This commit is contained in:
parent
b10147f16b
commit
211f09afbc
6 changed files with 277 additions and 52 deletions
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const { promisify } = require("util");
|
||||
const markdownIt = require("markdown-it");
|
||||
|
|
@ -685,6 +684,7 @@ function lintContent(
|
|||
* @param {boolean} handleRuleFailures Whether to handle exceptions in rules.
|
||||
* @param {boolean} noInlineConfig Whether to allow inline configuration.
|
||||
* @param {number} resultVersion Version of the LintResults object to return.
|
||||
* @param {Object} fs File system implementation.
|
||||
* @param {boolean} synchronous Whether to execute synchronously.
|
||||
* @param {Function} callback Callback (err, result) function.
|
||||
* @returns {void}
|
||||
|
|
@ -698,6 +698,7 @@ function lintFile(
|
|||
handleRuleFailures,
|
||||
noInlineConfig,
|
||||
resultVersion,
|
||||
fs,
|
||||
synchronous,
|
||||
callback) {
|
||||
// eslint-disable-next-line jsdoc/require-jsdoc
|
||||
|
|
@ -710,7 +711,6 @@ function lintFile(
|
|||
}
|
||||
// Make a/synchronous call to read file
|
||||
if (synchronous) {
|
||||
// @ts-ignore
|
||||
lintContentWrapper(null, fs.readFileSync(file, "utf8"));
|
||||
} else {
|
||||
fs.readFile(file, "utf8", lintContentWrapper);
|
||||
|
|
@ -756,6 +756,7 @@ function lintInput(options, synchronous, callback) {
|
|||
// @ts-ignore
|
||||
md.use(...plugin);
|
||||
});
|
||||
const fs = options.fs || require("fs");
|
||||
const results = newResults(ruleList);
|
||||
let done = false;
|
||||
// Linting of strings is always synchronous
|
||||
|
|
@ -795,6 +796,7 @@ function lintInput(options, synchronous, callback) {
|
|||
handleRuleFailures,
|
||||
noInlineConfig,
|
||||
resultVersion,
|
||||
fs,
|
||||
synchronous,
|
||||
syncCallback
|
||||
);
|
||||
|
|
@ -819,6 +821,7 @@ function lintInput(options, synchronous, callback) {
|
|||
handleRuleFailures,
|
||||
noInlineConfig,
|
||||
resultVersion,
|
||||
fs,
|
||||
synchronous,
|
||||
(err, result) => {
|
||||
concurrency--;
|
||||
|
|
@ -929,17 +932,17 @@ function parseConfiguration(name, content, parsers) {
|
|||
*
|
||||
* @param {string} configFile Configuration file name.
|
||||
* @param {string} referenceId Referenced identifier to resolve.
|
||||
* @param {Object} fs File system implementation.
|
||||
* @returns {string} Resolved path to file.
|
||||
*/
|
||||
function resolveConfigExtends(configFile, referenceId) {
|
||||
function resolveConfigExtends(configFile, referenceId, fs) {
|
||||
const configFileDirname = path.dirname(configFile);
|
||||
const resolvedExtendsFile = path.resolve(configFileDirname, referenceId);
|
||||
try {
|
||||
if (fs.statSync(resolvedExtendsFile).isFile()) {
|
||||
return resolvedExtendsFile;
|
||||
}
|
||||
fs.accessSync(resolvedExtendsFile);
|
||||
return resolvedExtendsFile;
|
||||
} catch {
|
||||
// If not a file or fs.statSync throws, try require.resolve
|
||||
// Not a file, try require.resolve
|
||||
}
|
||||
try {
|
||||
return dynamicRequire.resolve(
|
||||
|
|
@ -947,7 +950,7 @@ function resolveConfigExtends(configFile, referenceId) {
|
|||
{ "paths": [ configFileDirname ] }
|
||||
);
|
||||
} catch {
|
||||
// If require.resolve throws, return resolvedExtendsFile
|
||||
// Unable to resolve, return resolvedExtendsFile
|
||||
}
|
||||
return resolvedExtendsFile;
|
||||
}
|
||||
|
|
@ -958,14 +961,23 @@ function resolveConfigExtends(configFile, referenceId) {
|
|||
* @param {string} file Configuration file name.
|
||||
* @param {ConfigurationParser[] | ReadConfigCallback} parsers Parsing
|
||||
* function(s).
|
||||
* @param {Object} [fs] File system implementation.
|
||||
* @param {ReadConfigCallback} [callback] Callback (err, result) function.
|
||||
* @returns {void}
|
||||
*/
|
||||
function readConfig(file, parsers, callback) {
|
||||
function readConfig(file, parsers, fs, callback) {
|
||||
if (!callback) {
|
||||
// @ts-ignore
|
||||
callback = parsers;
|
||||
parsers = null;
|
||||
if (fs) {
|
||||
callback = fs;
|
||||
fs = null;
|
||||
} else {
|
||||
// @ts-ignore
|
||||
callback = parsers;
|
||||
parsers = null;
|
||||
}
|
||||
}
|
||||
if (!fs) {
|
||||
fs = require("fs");
|
||||
}
|
||||
// Read file
|
||||
fs.readFile(file, "utf8", (err, content) => {
|
||||
|
|
@ -982,8 +994,8 @@ function readConfig(file, parsers, callback) {
|
|||
const configExtends = config.extends;
|
||||
if (configExtends) {
|
||||
delete config.extends;
|
||||
const resolvedExtends = resolveConfigExtends(file, configExtends);
|
||||
return readConfig(resolvedExtends, parsers, (errr, extendsConfig) => {
|
||||
const resolvedExtends = resolveConfigExtends(file, configExtends, fs);
|
||||
return readConfig(resolvedExtends, parsers, fs, (errr, extendsConfig) => {
|
||||
if (errr) {
|
||||
return callback(errr);
|
||||
}
|
||||
|
|
@ -1004,11 +1016,12 @@ const readConfigPromisify = promisify && promisify(readConfig);
|
|||
*
|
||||
* @param {string} file Configuration file name.
|
||||
* @param {ConfigurationParser[]} [parsers] Parsing function(s).
|
||||
* @param {Object} [fs] File system implementation.
|
||||
* @returns {Promise<Configuration>} Configuration object.
|
||||
*/
|
||||
function readConfigPromise(file, parsers) {
|
||||
function readConfigPromise(file, parsers, fs) {
|
||||
// @ts-ignore
|
||||
return readConfigPromisify(file, parsers);
|
||||
return readConfigPromisify(file, parsers, fs);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1016,11 +1029,14 @@ function readConfigPromise(file, parsers) {
|
|||
*
|
||||
* @param {string} file Configuration file name.
|
||||
* @param {ConfigurationParser[]} [parsers] Parsing function(s).
|
||||
* @param {Object} [fs] File system implementation.
|
||||
* @returns {Configuration} Configuration object.
|
||||
*/
|
||||
function readConfigSync(file, parsers) {
|
||||
function readConfigSync(file, parsers, fs) {
|
||||
if (!fs) {
|
||||
fs = require("fs");
|
||||
}
|
||||
// Read file
|
||||
// @ts-ignore
|
||||
const content = fs.readFileSync(file, "utf8");
|
||||
// Try to parse file
|
||||
const { config, message } = parseConfiguration(file, content, parsers);
|
||||
|
|
@ -1031,9 +1047,9 @@ function readConfigSync(file, parsers) {
|
|||
const configExtends = config.extends;
|
||||
if (configExtends) {
|
||||
delete config.extends;
|
||||
const resolvedExtends = resolveConfigExtends(file, configExtends);
|
||||
const resolvedExtends = resolveConfigExtends(file, configExtends, fs);
|
||||
return {
|
||||
...readConfigSync(resolvedExtends, parsers),
|
||||
...readConfigSync(resolvedExtends, parsers, fs),
|
||||
...config
|
||||
};
|
||||
}
|
||||
|
|
@ -1156,6 +1172,7 @@ module.exports = markdownlint;
|
|||
* @property {boolean} [noInlineConfig] True to ignore HTML directives.
|
||||
* @property {number} [resultVersion] Results object version.
|
||||
* @property {Plugin[]} [markdownItPlugins] Additional plugins.
|
||||
* @property {Object} [fs] File system implementation.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue