markdownlint-cli
Advanced tools
Comparing version 0.30.0 to 0.31.0
@@ -13,9 +13,6 @@ #!/usr/bin/env node | ||
const options = program.opts(); | ||
const differenceWith = require('lodash.differencewith'); | ||
const flatten = require('lodash.flatten'); | ||
const glob = require('glob'); | ||
const markdownlint = require('markdownlint'); | ||
const rc = require('run-con'); | ||
const glob = require('glob'); | ||
const minimatch = require('minimatch'); | ||
const minimist = require('minimist'); | ||
const pkg = require('./package.json'); | ||
@@ -31,7 +28,10 @@ | ||
const projectConfigFiles = [ | ||
'.markdownlint.json', | ||
'.markdownlint.yaml', | ||
'.markdownlint.yml' | ||
]; | ||
const exitCodes = { | ||
lintFindings: 1, | ||
failedToWriteOutputFile: 2, | ||
failedToLoadCustomRules: 3, | ||
unexpectedError: 4 | ||
}; | ||
const projectConfigFiles = ['.markdownlint.json', '.markdownlint.yaml', '.markdownlint.yml']; | ||
const configFileParsers = [jsoncParse, jsYamlSafeLoad]; | ||
@@ -43,10 +43,5 @@ const fsOptions = {encoding: 'utf8'}; | ||
const jsConfigFile = /\.js$/i.test(userConfigFile); | ||
const rcArgv = minimist(process.argv.slice(2)); | ||
if (jsConfigFile) { | ||
// Prevent rc package from parsing .js config file as INI | ||
delete rcArgv.config; | ||
} | ||
// Load from well-known config files | ||
let config = rc('markdownlint', {}, rcArgv); | ||
let config = rc('markdownlint', {}); | ||
for (const projectConfigFile of projectConfigFiles) { | ||
@@ -56,3 +51,3 @@ try { | ||
const projectConfig = markdownlint.readConfigSync(projectConfigFile, configFileParsers); | ||
config = require('deep-extend')(config, projectConfig); | ||
config = {...config, ...projectConfig}; | ||
break; | ||
@@ -64,17 +59,11 @@ } catch { | ||
// Normally parsing this file is not needed, | ||
// because it is already parsed by rc package. | ||
// However I have to do it to overwrite configuration | ||
// from .markdownlint.{json,yaml,yml}. | ||
// Normally parsing this file is not needed, because it is already parsed by rc package. | ||
// However I have to do it to overwrite configuration from .markdownlint.{json,yaml,yml}. | ||
if (userConfigFile) { | ||
try { | ||
const userConfig = jsConfigFile | ||
// Evaluate .js configuration file as code | ||
? require(path.resolve(processCwd, userConfigFile)) | ||
// Load JSON/YAML configuration as data | ||
: markdownlint.readConfigSync(userConfigFile, configFileParsers); | ||
const userConfig = jsConfigFile ? require(path.resolve(processCwd, userConfigFile)) : markdownlint.readConfigSync(userConfigFile, configFileParsers); | ||
config = require('deep-extend')(config, userConfig); | ||
} catch (error) { | ||
console.error(`Cannot read or parse config file '${userConfigFile}': ${error.message}`); | ||
process.exitCode = 1; | ||
process.exitCode = exitCodes.unexpectedError; | ||
} | ||
@@ -99,3 +88,3 @@ } | ||
files = files.map(function (file) { | ||
files = files.map(file => { | ||
try { | ||
@@ -105,9 +94,4 @@ if (fs.lstatSync(file).isDirectory()) { | ||
if (previousResults) { | ||
const matcher = new minimatch.Minimatch( | ||
path.resolve(processCwd, path.join(file, '**', extensionGlobPart)), globOptions); | ||
return previousResults.filter(function (fileInfo) { | ||
return matcher.match(fileInfo.absolute); | ||
}).map(function (fileInfo) { | ||
return fileInfo.original; | ||
}); | ||
const matcher = new minimatch.Minimatch(path.resolve(processCwd, path.join(file, '**', extensionGlobPart)), globOptions); | ||
return previousResults.filter(fileInfo => matcher.match(fileInfo.absolute)).map(fileInfo => fileInfo.original); | ||
} | ||
@@ -121,7 +105,3 @@ | ||
const matcher = new minimatch.Minimatch(path.resolve(processCwd, file), globOptions); | ||
return previousResults.filter(function (fileInfo) { | ||
return matcher.match(fileInfo.absolute); | ||
}).map(function (fileInfo) { | ||
return fileInfo.original; | ||
}); | ||
return previousResults.filter(fileInfo => matcher.match(fileInfo.absolute)).map(fileInfo => fileInfo.original); | ||
} | ||
@@ -135,46 +115,44 @@ | ||
}); | ||
return flatten(files).map(function (file) { | ||
return { | ||
original: file, | ||
relative: path.relative(processCwd, file), | ||
absolute: path.resolve(file) | ||
}; | ||
}); | ||
return files.flat().map(file => ({ | ||
original: file, | ||
relative: path.relative(processCwd, file), | ||
absolute: path.resolve(file) | ||
})); | ||
} | ||
function printResult(lintResult) { | ||
const results = flatten(Object.keys(lintResult).map(file => lintResult[file].map(result => { | ||
if (options.json) { | ||
const results = Object.keys(lintResult).flatMap(file => | ||
lintResult[file].map(result => { | ||
if (options.json) { | ||
return { | ||
fileName: file, | ||
...result | ||
}; | ||
} | ||
return { | ||
fileName: file, | ||
...result | ||
file: file, | ||
lineNumber: result.lineNumber, | ||
column: (result.errorRange && result.errorRange[0]) || 0, | ||
names: result.ruleNames.join('/'), | ||
description: result.ruleDescription + (result.errorDetail ? ' [' + result.errorDetail + ']' : '') + (result.errorContext ? ' [Context: "' + result.errorContext + '"]' : '') | ||
}; | ||
} | ||
}) | ||
); | ||
return { | ||
file: file, | ||
lineNumber: result.lineNumber, | ||
column: (result.errorRange && result.errorRange[0]) || 0, | ||
names: result.ruleNames.join('/'), | ||
description: result.ruleDescription | ||
+ (result.errorDetail ? ' [' + result.errorDetail + ']' : '') | ||
+ (result.errorContext ? ' [Context: "' + result.errorContext + '"]' : '') | ||
}; | ||
}))); | ||
let lintResultString = ''; | ||
if (results.length > 0) { | ||
if (options.json) { | ||
results.sort((a, b) => a.fileName.localeCompare(b.fileName) || a.lineNumber - b.lineNumber | ||
|| a.ruleDescription.localeCompare(b.ruleDescription)); | ||
results.sort((a, b) => a.fileName.localeCompare(b.fileName) || a.lineNumber - b.lineNumber || a.ruleDescription.localeCompare(b.ruleDescription)); | ||
lintResultString = JSON.stringify(results, null, 2); | ||
} else { | ||
results.sort((a, b) => a.file.localeCompare(b.file) || a.lineNumber - b.lineNumber | ||
|| a.names.localeCompare(b.names) || a.description.localeCompare(b.description)); | ||
results.sort((a, b) => a.file.localeCompare(b.file) || a.lineNumber - b.lineNumber || a.names.localeCompare(b.names) || a.description.localeCompare(b.description)); | ||
lintResultString = results.map(result => { | ||
const {file, lineNumber, column, names, description} = result; | ||
const columnText = column ? `:${column}` : ''; | ||
return `${file}:${lineNumber}${columnText} ${names} ${description}`; | ||
}).join('\n'); | ||
lintResultString = results | ||
.map(result => { | ||
const {file, lineNumber, column, names, description} = result; | ||
const columnText = column ? `:${column}` : ''; | ||
return `${file}:${lineNumber}${columnText} ${names} ${description}`; | ||
}) | ||
.join('\n'); | ||
} | ||
@@ -187,9 +165,7 @@ | ||
// @see {@link https://github.com/igorshubovych/markdownlint-cli/pull/29#issuecomment-343535291} | ||
process.exitCode = 1; | ||
process.exitCode = exitCodes.lintFindings; | ||
} | ||
if (options.output) { | ||
lintResultString = lintResultString.length > 0 | ||
? lintResultString + os.EOL | ||
: lintResultString; | ||
lintResultString = lintResultString.length > 0 ? lintResultString + os.EOL : lintResultString; | ||
try { | ||
@@ -199,3 +175,3 @@ fs.writeFileSync(options.output, lintResultString); | ||
console.warn('Cannot write to output file ' + options.output + ': ' + error.message); | ||
process.exitCode = 2; | ||
process.exitCode = exitCodes.failedToWriteOutputFile; | ||
} | ||
@@ -255,8 +231,6 @@ } else if (lintResultString && !options.quiet) { | ||
function loadCustomRules(rules) { | ||
return flatten(rules.map(function (rule) { | ||
return rules.flatMap(rule => { | ||
try { | ||
const resolvedPath = [tryResolvePath(rule)]; | ||
const fileList = flatten(prepareFileList(resolvedPath, ['js']).map(function (filepath) { | ||
return require(filepath.absolute); | ||
})); | ||
const fileList = prepareFileList(resolvedPath, ['js']).flatMap(filepath => require(filepath.absolute)); | ||
if (fileList.length === 0) { | ||
@@ -269,5 +243,5 @@ throw new Error('No such rule'); | ||
console.error('Cannot load custom rule ' + rule + ': ' + error.message); | ||
return process.exit(3); | ||
return process.exit(exitCodes.failedToLoadCustomRules); | ||
} | ||
})); | ||
}); | ||
} | ||
@@ -290,11 +264,6 @@ | ||
const files = prepareFileList(program.args, ['md', 'markdown']) | ||
.filter(value => ignoreFilter(value)); | ||
const files = prepareFileList(program.args, ['md', 'markdown']).filter(value => ignoreFilter(value)); | ||
const ignores = prepareFileList(options.ignore, ['md', 'markdown'], files); | ||
const customRules = loadCustomRules(options.rules); | ||
const diff = differenceWith(files, ignores, function (a, b) { | ||
return a.absolute === b.absolute; | ||
}).map(function (paths) { | ||
return paths.original; | ||
}); | ||
const diff = files.filter(file => !ignores.some(ignore => ignore.absolute === file.absolute)).map(paths => paths.original); | ||
@@ -355,9 +324,16 @@ function lintAndPrint(stdin, files) { | ||
if ((files.length > 0) && !options.stdin) { | ||
lintAndPrint(null, diff); | ||
} else if ((files.length === 0) && options.stdin && !options.fix) { | ||
const getStdin = require('get-stdin'); | ||
getStdin().then(lintAndPrint); | ||
} else { | ||
program.help(); | ||
try { | ||
if (files.length > 0 && !options.stdin) { | ||
lintAndPrint(null, diff); | ||
} else if (files.length === 0 && options.stdin && !options.fix) { | ||
// eslint-disable-next-line node/no-unsupported-features/es-syntax | ||
import('get-stdin') | ||
.then(module => module.default()) | ||
.then(lintAndPrint); | ||
} else { | ||
program.help(); | ||
} | ||
} catch (error) { | ||
console.error(error); | ||
process.exit(exitCodes.unexpectedError); | ||
} |
{ | ||
"name": "markdownlint-cli", | ||
"version": "0.30.0", | ||
"version": "0.31.0", | ||
"description": "MarkdownLint Command Line Interface", | ||
@@ -16,3 +16,3 @@ "main": "markdownlint.js", | ||
"test": "ava", | ||
"watch": "npm test -- --watch --tap | tap-growl", | ||
"watch": "npm test --watch", | ||
"start": "node ./markdownlint.js", | ||
@@ -41,26 +41,21 @@ "precommit": "xo && npm test" | ||
"dependencies": { | ||
"commander": "~8.3.0", | ||
"deep-extend": "~0.6.0", | ||
"get-stdin": "~8.0.0", | ||
"commander": "~9.0.0", | ||
"get-stdin": "~9.0.0", | ||
"glob": "~7.2.0", | ||
"ignore": "~5.1.9", | ||
"ignore": "~5.2.0", | ||
"js-yaml": "^4.1.0", | ||
"jsonc-parser": "~3.0.0", | ||
"lodash.differencewith": "~4.5.0", | ||
"lodash.flatten": "~4.4.0", | ||
"markdownlint": "~0.24.0", | ||
"markdownlint-rule-helpers": "~0.15.0", | ||
"markdownlint": "~0.25.1", | ||
"markdownlint-rule-helpers": "~0.16.0", | ||
"minimatch": "~3.0.4", | ||
"minimist": "~1.2.5", | ||
"run-con": "~1.2.10" | ||
}, | ||
"devDependencies": { | ||
"ava": "^3.15.0", | ||
"execa": "^5.1.1", | ||
"husky": "^7.0.4", | ||
"tap-growl": "^3.0.0", | ||
"ava": "^4.0.1", | ||
"execa": "^6.0.0", | ||
"test-rule-package": "./test/custom-rules/test-rule-package", | ||
"xo": "^0.46.4" | ||
"xo": "^0.47.0" | ||
}, | ||
"xo": { | ||
"prettier": true, | ||
"space": true, | ||
@@ -78,2 +73,10 @@ "rules": { | ||
}, | ||
"prettier": { | ||
"arrowParens": "avoid", | ||
"bracketSpacing": false, | ||
"endOfLine": "auto", | ||
"printWidth": 1000, | ||
"singleQuote": true, | ||
"trailingComma": "none" | ||
}, | ||
"ava": { | ||
@@ -85,4 +88,5 @@ "files": [ | ||
], | ||
"failFast": true | ||
"failFast": true, | ||
"workerThreads": false | ||
} | ||
} |
@@ -115,5 +115,6 @@ # markdownlint-cli | ||
- `0`: Program ran successfully | ||
- `1`: Linting errors / bad parameter | ||
- `1`: Linting errors | ||
- `2`: Unable to write `-o`/`--output` output file | ||
- `3`: Unable to load `-r`/`--rules` custom rule | ||
- `4`: Unexpected error (e.g. malformed config) | ||
@@ -126,3 +127,3 @@ ## Use with pre-commit | ||
- repo: https://github.com/igorshubovych/markdownlint-cli | ||
rev: v0.30.0 | ||
rev: v0.31.0 | ||
hooks: | ||
@@ -129,0 +130,0 @@ - id: markdownlint |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
10
4
158
21426
283
+ Addedcommander@9.0.0(transitive)
+ Addedget-stdin@9.0.0(transitive)
+ Addedignore@5.2.4(transitive)
+ Addedmarkdown-it@12.3.2(transitive)
+ Addedmarkdownlint@0.25.1(transitive)
+ Addedmarkdownlint-rule-helpers@0.16.0(transitive)
- Removeddeep-extend@~0.6.0
- Removedlodash.differencewith@~4.5.0
- Removedlodash.flatten@~4.4.0
- Removedminimist@~1.2.5
- Removedcommander@8.3.0(transitive)
- Removedget-stdin@8.0.0(transitive)
- Removedignore@5.1.9(transitive)
- Removedlodash.differencewith@4.5.0(transitive)
- Removedlodash.flatten@4.4.0(transitive)
- Removedmarkdown-it@12.2.0(transitive)
- Removedmarkdownlint@0.24.0(transitive)
- Removedmarkdownlint-rule-helpers@0.15.0(transitive)
Updatedcommander@~9.0.0
Updatedget-stdin@~9.0.0
Updatedignore@~5.2.0
Updatedmarkdownlint@~0.25.1