mirror of
https://github.com/DavidAnson/markdownlint.git
synced 2025-12-17 06:20:12 +01:00
Update readConfig to use fs.access so the async path is fully async.
This commit is contained in:
parent
211f09afbc
commit
709e314836
5 changed files with 108 additions and 28 deletions
|
|
@ -649,7 +649,7 @@ In advanced scenarios, it may be desirable to bypass the default file system API
|
||||||
If a custom file system implementation is provided, `markdownlint` will use that
|
If a custom file system implementation is provided, `markdownlint` will use that
|
||||||
instead of invoking `require("fs")`.
|
instead of invoking `require("fs")`.
|
||||||
|
|
||||||
Note: The only methods called are `readFile`, `readFileSync`, and `accessSync`.
|
Note: The only methods called are `readFile`, `readFileSync`, `access`, and `accessSync`.
|
||||||
|
|
||||||
#### callback
|
#### callback
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1638,6 +1638,33 @@ function parseConfiguration(name, content, parsers) {
|
||||||
message: message
|
message: message
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Resolve referenced "extends" path in a configuration file
|
||||||
|
* using path.resolve() with require.resolve() as a fallback.
|
||||||
|
*
|
||||||
|
* @param {string} configFile Configuration file name.
|
||||||
|
* @param {string} referenceId Referenced identifier to resolve.
|
||||||
|
* @param {Object} fs File system implementation.
|
||||||
|
* @param {ResolveConfigExtendsCallback} [callback] Callback (err, result)
|
||||||
|
* function.
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function resolveConfigExtends(configFile, referenceId, fs, callback) {
|
||||||
|
var configFileDirname = path.dirname(configFile);
|
||||||
|
var resolvedExtendsFile = path.resolve(configFileDirname, referenceId);
|
||||||
|
fs.access(resolvedExtendsFile, function (err) {
|
||||||
|
if (err) {
|
||||||
|
// Not a file, try require.resolve
|
||||||
|
try {
|
||||||
|
return callback(null, dynamicRequire.resolve(referenceId, { "paths": [configFileDirname] }));
|
||||||
|
}
|
||||||
|
catch (_a) {
|
||||||
|
// Unable to resolve, use resolvedExtendsFile
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return callback(null, resolvedExtendsFile);
|
||||||
|
});
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Resolve referenced "extends" path in a configuration file
|
* Resolve referenced "extends" path in a configuration file
|
||||||
* using path.resolve() with require.resolve() as a fallback.
|
* using path.resolve() with require.resolve() as a fallback.
|
||||||
|
|
@ -1647,7 +1674,7 @@ function parseConfiguration(name, content, parsers) {
|
||||||
* @param {Object} fs File system implementation.
|
* @param {Object} fs File system implementation.
|
||||||
* @returns {string} Resolved path to file.
|
* @returns {string} Resolved path to file.
|
||||||
*/
|
*/
|
||||||
function resolveConfigExtends(configFile, referenceId, fs) {
|
function resolveConfigExtendsSync(configFile, referenceId, fs) {
|
||||||
var configFileDirname = path.dirname(configFile);
|
var configFileDirname = path.dirname(configFile);
|
||||||
var resolvedExtendsFile = path.resolve(configFileDirname, referenceId);
|
var resolvedExtendsFile = path.resolve(configFileDirname, referenceId);
|
||||||
try {
|
try {
|
||||||
|
|
@ -1705,13 +1732,12 @@ function readConfig(file, parsers, fs, callback) {
|
||||||
var configExtends = config["extends"];
|
var configExtends = config["extends"];
|
||||||
if (configExtends) {
|
if (configExtends) {
|
||||||
delete config["extends"];
|
delete config["extends"];
|
||||||
var resolvedExtends = resolveConfigExtends(file, configExtends, fs);
|
return resolveConfigExtends(file, configExtends, fs, function (_, resolvedExtends) { return readConfig(resolvedExtends, parsers, fs, function (errr, extendsConfig) {
|
||||||
return readConfig(resolvedExtends, parsers, fs, function (errr, extendsConfig) {
|
|
||||||
if (errr) {
|
if (errr) {
|
||||||
return callback(errr);
|
return callback(errr);
|
||||||
}
|
}
|
||||||
return callback(null, __assign(__assign({}, extendsConfig), config));
|
return callback(null, __assign(__assign({}, extendsConfig), config));
|
||||||
});
|
}); });
|
||||||
}
|
}
|
||||||
return callback(null, config);
|
return callback(null, config);
|
||||||
});
|
});
|
||||||
|
|
@ -1752,7 +1778,7 @@ function readConfigSync(file, parsers, fs) {
|
||||||
var configExtends = config["extends"];
|
var configExtends = config["extends"];
|
||||||
if (configExtends) {
|
if (configExtends) {
|
||||||
delete config["extends"];
|
delete config["extends"];
|
||||||
var resolvedExtends = resolveConfigExtends(file, configExtends, fs);
|
var resolvedExtends = resolveConfigExtendsSync(file, configExtends, fs);
|
||||||
return __assign(__assign({}, readConfigSync(resolvedExtends, parsers, fs)), config);
|
return __assign(__assign({}, readConfigSync(resolvedExtends, parsers, fs)), config);
|
||||||
}
|
}
|
||||||
return config;
|
return config;
|
||||||
|
|
|
||||||
10
lib/markdownlint.d.ts
vendored
10
lib/markdownlint.d.ts
vendored
|
|
@ -8,7 +8,7 @@ export = markdownlint;
|
||||||
*/
|
*/
|
||||||
declare function markdownlint(options: Options, callback: LintCallback): void;
|
declare function markdownlint(options: Options, callback: LintCallback): void;
|
||||||
declare namespace markdownlint {
|
declare namespace markdownlint {
|
||||||
export { markdownlintSync as sync, readConfig, readConfigSync, getVersion, promises, RuleFunction, RuleParams, MarkdownItToken, RuleOnError, RuleOnErrorInfo, RuleOnErrorFixInfo, Rule, Options, Plugin, ToStringCallback, LintResults, LintError, FixInfo, LintCallback, Configuration, RuleConfiguration, ConfigurationParser, ReadConfigCallback };
|
export { markdownlintSync as sync, readConfig, readConfigSync, getVersion, promises, RuleFunction, RuleParams, MarkdownItToken, RuleOnError, RuleOnErrorInfo, RuleOnErrorFixInfo, Rule, Options, Plugin, ToStringCallback, LintResults, LintError, FixInfo, LintCallback, Configuration, RuleConfiguration, ConfigurationParser, ReadConfigCallback, ResolveConfigExtendsCallback };
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Configuration options.
|
* Configuration options.
|
||||||
|
|
@ -58,7 +58,7 @@ type Options = {
|
||||||
fs?: any;
|
fs?: any;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* Called with the result of the lint operation.
|
* Called with the result of the lint function.
|
||||||
*/
|
*/
|
||||||
type LintCallback = (err: Error | null, results?: LintResults) => void;
|
type LintCallback = (err: Error | null, results?: LintResults) => void;
|
||||||
/**
|
/**
|
||||||
|
|
@ -355,9 +355,13 @@ type RuleConfiguration = boolean | any;
|
||||||
*/
|
*/
|
||||||
type ConfigurationParser = (text: string) => Configuration;
|
type ConfigurationParser = (text: string) => Configuration;
|
||||||
/**
|
/**
|
||||||
* Called with the result of the readConfig operation.
|
* Called with the result of the readConfig function.
|
||||||
*/
|
*/
|
||||||
type ReadConfigCallback = (err: Error | null, config?: Configuration) => void;
|
type ReadConfigCallback = (err: Error | null, config?: Configuration) => void;
|
||||||
|
/**
|
||||||
|
* Called with the result of the resolveConfigExtends function.
|
||||||
|
*/
|
||||||
|
type ResolveConfigExtendsCallback = (err: Error | null, path?: string) => void;
|
||||||
/**
|
/**
|
||||||
* Lint specified Markdown files.
|
* Lint specified Markdown files.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -926,6 +926,36 @@ function parseConfiguration(name, content, parsers) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve referenced "extends" path in a configuration file
|
||||||
|
* using path.resolve() with require.resolve() as a fallback.
|
||||||
|
*
|
||||||
|
* @param {string} configFile Configuration file name.
|
||||||
|
* @param {string} referenceId Referenced identifier to resolve.
|
||||||
|
* @param {Object} fs File system implementation.
|
||||||
|
* @param {ResolveConfigExtendsCallback} [callback] Callback (err, result)
|
||||||
|
* function.
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function resolveConfigExtends(configFile, referenceId, fs, callback) {
|
||||||
|
const configFileDirname = path.dirname(configFile);
|
||||||
|
const resolvedExtendsFile = path.resolve(configFileDirname, referenceId);
|
||||||
|
fs.access(resolvedExtendsFile, (err) => {
|
||||||
|
if (err) {
|
||||||
|
// Not a file, try require.resolve
|
||||||
|
try {
|
||||||
|
return callback(null, dynamicRequire.resolve(
|
||||||
|
referenceId,
|
||||||
|
{ "paths": [ configFileDirname ] }
|
||||||
|
));
|
||||||
|
} catch {
|
||||||
|
// Unable to resolve, use resolvedExtendsFile
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return callback(null, resolvedExtendsFile);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve referenced "extends" path in a configuration file
|
* Resolve referenced "extends" path in a configuration file
|
||||||
* using path.resolve() with require.resolve() as a fallback.
|
* using path.resolve() with require.resolve() as a fallback.
|
||||||
|
|
@ -935,7 +965,7 @@ function parseConfiguration(name, content, parsers) {
|
||||||
* @param {Object} fs File system implementation.
|
* @param {Object} fs File system implementation.
|
||||||
* @returns {string} Resolved path to file.
|
* @returns {string} Resolved path to file.
|
||||||
*/
|
*/
|
||||||
function resolveConfigExtends(configFile, referenceId, fs) {
|
function resolveConfigExtendsSync(configFile, referenceId, fs) {
|
||||||
const configFileDirname = path.dirname(configFile);
|
const configFileDirname = path.dirname(configFile);
|
||||||
const resolvedExtendsFile = path.resolve(configFileDirname, referenceId);
|
const resolvedExtendsFile = path.resolve(configFileDirname, referenceId);
|
||||||
try {
|
try {
|
||||||
|
|
@ -994,8 +1024,15 @@ function readConfig(file, parsers, fs, callback) {
|
||||||
const configExtends = config.extends;
|
const configExtends = config.extends;
|
||||||
if (configExtends) {
|
if (configExtends) {
|
||||||
delete config.extends;
|
delete config.extends;
|
||||||
const resolvedExtends = resolveConfigExtends(file, configExtends, fs);
|
return resolveConfigExtends(
|
||||||
return readConfig(resolvedExtends, parsers, fs, (errr, extendsConfig) => {
|
file,
|
||||||
|
configExtends,
|
||||||
|
fs,
|
||||||
|
(_, resolvedExtends) => readConfig(
|
||||||
|
resolvedExtends,
|
||||||
|
parsers,
|
||||||
|
fs,
|
||||||
|
(errr, extendsConfig) => {
|
||||||
if (errr) {
|
if (errr) {
|
||||||
return callback(errr);
|
return callback(errr);
|
||||||
}
|
}
|
||||||
|
|
@ -1003,7 +1040,9 @@ function readConfig(file, parsers, fs, callback) {
|
||||||
...extendsConfig,
|
...extendsConfig,
|
||||||
...config
|
...config
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return callback(null, config);
|
return callback(null, config);
|
||||||
});
|
});
|
||||||
|
|
@ -1047,7 +1086,7 @@ function readConfigSync(file, parsers, fs) {
|
||||||
const configExtends = config.extends;
|
const configExtends = config.extends;
|
||||||
if (configExtends) {
|
if (configExtends) {
|
||||||
delete config.extends;
|
delete config.extends;
|
||||||
const resolvedExtends = resolveConfigExtends(file, configExtends, fs);
|
const resolvedExtends = resolveConfigExtendsSync(file, configExtends, fs);
|
||||||
return {
|
return {
|
||||||
...readConfigSync(resolvedExtends, parsers, fs),
|
...readConfigSync(resolvedExtends, parsers, fs),
|
||||||
...config
|
...config
|
||||||
|
|
@ -1221,7 +1260,7 @@ module.exports = markdownlint;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called with the result of the lint operation.
|
* Called with the result of the lint function.
|
||||||
*
|
*
|
||||||
* @callback LintCallback
|
* @callback LintCallback
|
||||||
* @param {Error | null} err Error object or null.
|
* @param {Error | null} err Error object or null.
|
||||||
|
|
@ -1251,10 +1290,19 @@ module.exports = markdownlint;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called with the result of the readConfig operation.
|
* Called with the result of the readConfig function.
|
||||||
*
|
*
|
||||||
* @callback ReadConfigCallback
|
* @callback ReadConfigCallback
|
||||||
* @param {Error | null} err Error object or null.
|
* @param {Error | null} err Error object or null.
|
||||||
* @param {Configuration} [config] Configuration object.
|
* @param {Configuration} [config] Configuration object.
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called with the result of the resolveConfigExtends function.
|
||||||
|
*
|
||||||
|
* @callback ResolveConfigExtendsCallback
|
||||||
|
* @param {Error | null} err Error object or null.
|
||||||
|
* @param {string} [path] Resolved path to file.
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1155,8 +1155,9 @@ test.cb("configCustomFileSystem", (t) => {
|
||||||
"MD002": true
|
"MD002": true
|
||||||
};
|
};
|
||||||
const fsApi = {
|
const fsApi = {
|
||||||
"accessSync": (p) => {
|
"access": (p, m, cb) => {
|
||||||
t.is(p, extended);
|
t.is(path.resolve(p), extended);
|
||||||
|
return (cb || m)();
|
||||||
},
|
},
|
||||||
"readFile": (p, o, cb) => {
|
"readFile": (p, o, cb) => {
|
||||||
switch (p) {
|
switch (p) {
|
||||||
|
|
@ -1455,7 +1456,7 @@ test("configCustomFileSystemSync", (t) => {
|
||||||
};
|
};
|
||||||
const fsApi = {
|
const fsApi = {
|
||||||
"accessSync": (p) => {
|
"accessSync": (p) => {
|
||||||
t.is(p, extended);
|
t.is(path.resolve(p), extended);
|
||||||
},
|
},
|
||||||
"readFileSync": (p) => {
|
"readFileSync": (p) => {
|
||||||
switch (p) {
|
switch (p) {
|
||||||
|
|
@ -1520,8 +1521,9 @@ test.cb("configCustomFileSystemPromise", (t) => {
|
||||||
"MD002": true
|
"MD002": true
|
||||||
};
|
};
|
||||||
const fsApi = {
|
const fsApi = {
|
||||||
"accessSync": (p) => {
|
"access": (p, m, cb) => {
|
||||||
t.is(p, extended);
|
t.is(path.resolve(p), extended);
|
||||||
|
return (cb || m)();
|
||||||
},
|
},
|
||||||
"readFile": (p, o, cb) => {
|
"readFile": (p, o, cb) => {
|
||||||
switch (p) {
|
switch (p) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue