diff --git a/markdownlint-cli2.js b/markdownlint-cli2.js index 52b4c9a2..e762f844 100755 --- a/markdownlint-cli2.js +++ b/markdownlint-cli2.js @@ -285,7 +285,6 @@ const getAndProcessDirInfo = ( dirToDirInfo, dir, relativeDir, - modulePaths, noRequire, allowPackageJson ) => { @@ -325,13 +324,13 @@ const getAndProcessDirInfo = ( fs, dir, ".markdownlint-cli2.cjs", - modulePaths, + [], noRequire, importOrRequireConfig( fs, dir, ".markdownlint-cli2.mjs", - modulePaths, + [], noRequire, () => (allowPackageJson ? fs.promises.access(packageJson) @@ -390,13 +389,13 @@ const getAndProcessDirInfo = ( fs, dir, ".markdownlint.cjs", - modulePaths, + [], noRequire, importOrRequireConfig( fs, dir, ".markdownlint.mjs", - modulePaths, + [], noRequire, noop ) @@ -434,7 +433,6 @@ const getBaseOptions = async ( dirToDirInfo, baseDir, relativeDir, - [], noRequire, true ); @@ -468,91 +466,95 @@ const getBaseOptions = async ( }; // Enumerate files from globs and build directory infos -const enumerateFiles = - // eslint-disable-next-line max-len - async (fs, baseDirSystem, baseDir, globPatterns, dirToDirInfo, modulePaths, noErrors, noRequire) => { - const tasks = []; - const globbyOptions = { - "absolute": true, - "cwd": baseDir, - "dot": true, - "expandDirectories": false, - fs - }; - if (noErrors) { - globbyOptions.suppressErrors = true; - } - // Special-case literal files - const literalFiles = []; - const filteredGlobPatterns = globPatterns.filter( - (globPattern) => { - if (globPattern.startsWith(":")) { - literalFiles.push( - posixPath(pathDefault.resolve(baseDirSystem, globPattern.slice(1))) - ); - return false; - } - return true; +const enumerateFiles = async ( + fs, + baseDirSystem, + baseDir, + globPatterns, + dirToDirInfo, + noErrors, + noRequire +) => { + const tasks = []; + const globbyOptions = { + "absolute": true, + "cwd": baseDir, + "dot": true, + "expandDirectories": false, + fs + }; + if (noErrors) { + globbyOptions.suppressErrors = true; + } + // Special-case literal files + const literalFiles = []; + const filteredGlobPatterns = globPatterns.filter( + (globPattern) => { + if (globPattern.startsWith(":")) { + literalFiles.push( + posixPath(pathDefault.resolve(baseDirSystem, globPattern.slice(1))) + ); + return false; } - ).map((globPattern) => globPattern.replace(/^\\:/u, ":")); - const baseMarkdownlintOptions = dirToDirInfo[baseDir].markdownlintOptions; - const globsForIgnore = - (baseMarkdownlintOptions.globs || []). - filter((glob) => glob.startsWith("!")); - const filteredLiteralFiles = - ((literalFiles.length > 0) && (globsForIgnore.length > 0)) - ? removeIgnoredFiles(baseDir, literalFiles, globsForIgnore) - : literalFiles; - // Manually expand directories to avoid globby call to dir-glob.sync - const expandedDirectories = await Promise.all( - filteredGlobPatterns.map((globPattern) => { - const barePattern = - globPattern.startsWith("!") - ? globPattern.slice(1) - : globPattern; - const globPath = ( - pathPosix.isAbsolute(barePattern) || - pathDefault.isAbsolute(barePattern) - ) - ? barePattern - : pathPosix.join(baseDir, barePattern); - return fs.promises.stat(globPath). - then((stats) => (stats.isDirectory() - ? pathPosix.join(globPattern, "**") - : globPattern)). - catch(() => globPattern); - }) - ); - // Process glob patterns - // eslint-disable-next-line no-inline-comments - const { globby } = await import(/* webpackMode: "eager" */ "globby"); - const files = [ - ...await globby(expandedDirectories, globbyOptions), - ...filteredLiteralFiles - ]; - for (const file of files) { - const dir = pathPosix.dirname(file); - const dirInfo = getAndProcessDirInfo( - fs, - tasks, - dirToDirInfo, - dir, - null, - modulePaths, - noRequire, - false - ); - dirInfo.files.push(file); + return true; } - await Promise.all(tasks); - }; + ).map((globPattern) => globPattern.replace(/^\\:/u, ":")); + const baseMarkdownlintOptions = dirToDirInfo[baseDir].markdownlintOptions; + const globsForIgnore = + (baseMarkdownlintOptions.globs || []). + filter((glob) => glob.startsWith("!")); + const filteredLiteralFiles = + ((literalFiles.length > 0) && (globsForIgnore.length > 0)) + ? removeIgnoredFiles(baseDir, literalFiles, globsForIgnore) + : literalFiles; + // Manually expand directories to avoid globby call to dir-glob.sync + const expandedDirectories = await Promise.all( + filteredGlobPatterns.map((globPattern) => { + const barePattern = + globPattern.startsWith("!") + ? globPattern.slice(1) + : globPattern; + const globPath = ( + pathPosix.isAbsolute(barePattern) || + pathDefault.isAbsolute(barePattern) + ) + ? barePattern + : pathPosix.join(baseDir, barePattern); + return fs.promises.stat(globPath). + then((stats) => (stats.isDirectory() + ? pathPosix.join(globPattern, "**") + : globPattern)). + catch(() => globPattern); + }) + ); + // Process glob patterns + // eslint-disable-next-line no-inline-comments + const { globby } = await import(/* webpackMode: "eager" */ "globby"); + const files = [ + ...await globby(expandedDirectories, globbyOptions), + ...filteredLiteralFiles + ]; + for (const file of files) { + const dir = pathPosix.dirname(file); + const dirInfo = getAndProcessDirInfo( + fs, + tasks, + dirToDirInfo, + dir, + null, + noRequire, + false + ); + dirInfo.files.push(file); + } + await Promise.all(tasks); +}; // Enumerate (possibly missing) parent directories and update directory infos const enumerateParents = async ( fs, baseDir, dirToDirInfo, - modulePaths, noRequire ) => { const tasks = []; @@ -582,7 +584,6 @@ const enumerateParents = async ( dirToDirInfo, dir, null, - modulePaths, noRequire, false ); @@ -599,138 +600,144 @@ const enumerateParents = async ( }; // Create directory info objects by enumerating file globs -const createDirInfos = - // eslint-disable-next-line max-len - async (fs, baseDirSystem, baseDir, globPatterns, modulePaths, dirToDirInfo, optionsOverride, noErrors, noRequire) => { - await enumerateFiles( - fs, - baseDirSystem, - baseDir, - globPatterns, - dirToDirInfo, - modulePaths, - noErrors, - noRequire - ); - await enumerateParents( - fs, - baseDir, - dirToDirInfo, - modulePaths, - noRequire - ); +const createDirInfos = async ( + fs, + baseDirSystem, + baseDir, + globPatterns, + modulePaths, + dirToDirInfo, + optionsOverride, + noErrors, + noRequire +) => { + await enumerateFiles( + fs, + baseDirSystem, + baseDir, + globPatterns, + dirToDirInfo, + noErrors, + noRequire + ); + await enumerateParents( + fs, + baseDir, + dirToDirInfo, + noRequire + ); - // Merge file lists with identical configuration - const dirs = Object.keys(dirToDirInfo); - dirs.sort((a, b) => b.length - a.length); - const dirInfos = []; - const noConfigDirInfo = - // eslint-disable-next-line unicorn/consistent-function-scoping - (dirInfo) => ( - dirInfo.parent && - !dirInfo.markdownlintConfig && - !dirInfo.markdownlintOptions - ); - const tasks = []; - for (const dir of dirs) { - const dirInfo = dirToDirInfo[dir]; - if (noConfigDirInfo(dirInfo)) { - if (dirInfo.parent) { - appendToArray(dirInfo.parent.files, dirInfo.files); - } - dirToDirInfo[dir] = null; - } else { - const { markdownlintOptions, relativeDir } = dirInfo; - if (markdownlintOptions && markdownlintOptions.customRules) { - tasks.push( - importOrRequireIds( - [ relativeDir || dir, ...modulePaths ], - markdownlintOptions.customRules, - noRequire - ).then((customRules) => { - // Expand nested arrays (for packages that export multiple rules) - markdownlintOptions.customRules = customRules.flat(); - }) - ); - } - if (markdownlintOptions && markdownlintOptions.markdownItPlugins) { - tasks.push( - importOrRequireIdsAndParams( - [ relativeDir || dir, ...modulePaths ], - markdownlintOptions.markdownItPlugins, - noRequire - ).then((markdownItPlugins) => { - markdownlintOptions.markdownItPlugins = markdownItPlugins; - }) - ); - } - dirInfos.push(dirInfo); + // Merge file lists with identical configuration + const dirs = Object.keys(dirToDirInfo); + dirs.sort((a, b) => b.length - a.length); + const dirInfos = []; + const noConfigDirInfo = + // eslint-disable-next-line unicorn/consistent-function-scoping + (dirInfo) => ( + dirInfo.parent && + !dirInfo.markdownlintConfig && + !dirInfo.markdownlintOptions + ); + const tasks = []; + for (const dir of dirs) { + const dirInfo = dirToDirInfo[dir]; + if (noConfigDirInfo(dirInfo)) { + if (dirInfo.parent) { + appendToArray(dirInfo.parent.files, dirInfo.files); } - } - await Promise.all(tasks); - for (const dirInfo of dirInfos) { - while (dirInfo.parent && !dirToDirInfo[dirInfo.parent.dir]) { - dirInfo.parent = dirInfo.parent.parent; + dirToDirInfo[dir] = null; + } else { + const { markdownlintOptions, relativeDir } = dirInfo; + if (markdownlintOptions && markdownlintOptions.customRules) { + tasks.push( + importOrRequireIds( + [ relativeDir || dir, ...modulePaths ], + markdownlintOptions.customRules, + noRequire + ).then((customRules) => { + // Expand nested arrays (for packages that export multiple rules) + markdownlintOptions.customRules = customRules.flat(); + }) + ); + } + if (markdownlintOptions && markdownlintOptions.markdownItPlugins) { + tasks.push( + importOrRequireIdsAndParams( + [ relativeDir || dir, ...modulePaths ], + markdownlintOptions.markdownItPlugins, + noRequire + ).then((markdownItPlugins) => { + markdownlintOptions.markdownItPlugins = markdownItPlugins; + }) + ); } + dirInfos.push(dirInfo); } + } + await Promise.all(tasks); + for (const dirInfo of dirInfos) { + while (dirInfo.parent && !dirToDirInfo[dirInfo.parent.dir]) { + dirInfo.parent = dirInfo.parent.parent; + } + } - // Verify dirInfos is simplified - // if ( - // dirInfos.filter( - // (di) => di.parent && !dirInfos.includes(di.parent) - // ).length > 0 - // ) { - // throw new Error("Extra parent"); - // } - // if ( - // dirInfos.filter( - // (di) => !di.parent && (di.dir !== baseDir) - // ).length > 0 - // ) { - // throw new Error("Missing parent"); - // } - // if ( - // dirInfos.filter( - // (di) => di.parent && - // !((di.markdownlintConfig ? 1 : 0) ^ (di.markdownlintOptions ? 1 : 0)) - // ).length > 0 - // ) { - // throw new Error("Missing object"); - // } - // if (dirInfos.filter((di) => di.dir === "/").length > 0) { - // throw new Error("Includes root"); - // } + // Verify dirInfos is simplified + // if ( + // dirInfos.filter( + // (di) => di.parent && !dirInfos.includes(di.parent) + // ).length > 0 + // ) { + // throw new Error("Extra parent"); + // } + // if ( + // dirInfos.filter( + // (di) => !di.parent && (di.dir !== baseDir) + // ).length > 0 + // ) { + // throw new Error("Missing parent"); + // } + // if ( + // dirInfos.filter( + // (di) => di.parent && + // !((di.markdownlintConfig ? 1 : 0) ^ (di.markdownlintOptions ? 1 : 0)) + // ).length > 0 + // ) { + // throw new Error("Missing object"); + // } + // if (dirInfos.filter((di) => di.dir === "/").length > 0) { + // throw new Error("Includes root"); + // } - // Merge configuration by inheritance - for (const dirInfo of dirInfos) { - let markdownlintOptions = dirInfo.markdownlintOptions || {}; - let { markdownlintConfig } = dirInfo; - let parent = dirInfo; - // eslint-disable-next-line prefer-destructuring - while ((parent = parent.parent)) { - if (parent.markdownlintOptions) { - markdownlintOptions = mergeOptions( - parent.markdownlintOptions, - markdownlintOptions - ); - } - if ( - !markdownlintConfig && - parent.markdownlintConfig && - !markdownlintOptions.config - ) { - // eslint-disable-next-line prefer-destructuring - markdownlintConfig = parent.markdownlintConfig; - } + // Merge configuration by inheritance + for (const dirInfo of dirInfos) { + let markdownlintOptions = dirInfo.markdownlintOptions || {}; + let { markdownlintConfig } = dirInfo; + let parent = dirInfo; + // eslint-disable-next-line prefer-destructuring + while ((parent = parent.parent)) { + if (parent.markdownlintOptions) { + markdownlintOptions = mergeOptions( + parent.markdownlintOptions, + markdownlintOptions + ); + } + if ( + !markdownlintConfig && + parent.markdownlintConfig && + !markdownlintOptions.config + ) { + // eslint-disable-next-line prefer-destructuring + markdownlintConfig = parent.markdownlintConfig; } - dirInfo.markdownlintOptions = mergeOptions( - markdownlintOptions, - optionsOverride - ); - dirInfo.markdownlintConfig = markdownlintConfig; } - return dirInfos; - }; + dirInfo.markdownlintOptions = mergeOptions( + markdownlintOptions, + optionsOverride + ); + dirInfo.markdownlintConfig = markdownlintConfig; + } + return dirInfos; +}; // Lint files in groups by shared configuration const lintFiles = async (fs, dirInfos, fileContents) => {