mirror of
https://github.com/DavidAnson/markdownlint.git
synced 2025-12-16 22:10:13 +01:00
Add lint rules from eslint-plugin-unicorn.
This commit is contained in:
parent
0f4745efe3
commit
5ab938a6ab
11 changed files with 96 additions and 31 deletions
|
|
@ -8,7 +8,8 @@
|
||||||
},
|
},
|
||||||
"plugins": [
|
"plugins": [
|
||||||
"jsdoc",
|
"jsdoc",
|
||||||
"node"
|
"node",
|
||||||
|
"unicorn"
|
||||||
],
|
],
|
||||||
"extends": [
|
"extends": [
|
||||||
"eslint:all",
|
"eslint:all",
|
||||||
|
|
@ -113,6 +114,62 @@
|
||||||
"node/prefer-global/url-search-params": "error",
|
"node/prefer-global/url-search-params": "error",
|
||||||
"node/prefer-global/url": "error",
|
"node/prefer-global/url": "error",
|
||||||
"node/prefer-promises/dns": "error",
|
"node/prefer-promises/dns": "error",
|
||||||
"node/prefer-promises/fs": "off"
|
"node/prefer-promises/fs": "off",
|
||||||
|
|
||||||
|
"unicorn/better-regex": "off",
|
||||||
|
"unicorn/catch-error-name": "error",
|
||||||
|
"unicorn/consistent-function-scoping": "off",
|
||||||
|
"unicorn/custom-error-definition": "error",
|
||||||
|
"unicorn/error-message": "error",
|
||||||
|
"unicorn/escape-case": "error",
|
||||||
|
"unicorn/expiring-todo-comments": "error",
|
||||||
|
"unicorn/explicit-length-check": "error",
|
||||||
|
"unicorn/filename-case": "off",
|
||||||
|
"unicorn/import-index": "error",
|
||||||
|
"unicorn/new-for-builtins": "error",
|
||||||
|
"unicorn/no-abusive-eslint-disable": "error",
|
||||||
|
"unicorn/no-array-instanceof": "error",
|
||||||
|
"unicorn/no-console-spaces": "error",
|
||||||
|
"unicorn/no-fn-reference-in-iterator": "off",
|
||||||
|
"unicorn/no-for-loop": "error",
|
||||||
|
"unicorn/no-hex-escape": "error",
|
||||||
|
"unicorn/no-keyword-prefix": "off",
|
||||||
|
"unicorn/no-nested-ternary": "error",
|
||||||
|
"unicorn/no-new-buffer": "error",
|
||||||
|
"unicorn/no-null": "off",
|
||||||
|
"unicorn/no-object-as-default-parameter": "error",
|
||||||
|
"unicorn/no-process-exit": "error",
|
||||||
|
"unicorn/no-reduce": "error",
|
||||||
|
"unicorn/no-unreadable-array-destructuring": "error",
|
||||||
|
"unicorn/no-unsafe-regex": "off",
|
||||||
|
"unicorn/no-unused-properties": "error",
|
||||||
|
"unicorn/no-useless-undefined": "error",
|
||||||
|
"unicorn/no-zero-fractions": "error",
|
||||||
|
"unicorn/number-literal-case": "error",
|
||||||
|
"unicorn/prefer-add-event-listener": "error",
|
||||||
|
"unicorn/prefer-array-find": "error",
|
||||||
|
"unicorn/prefer-dataset": "error",
|
||||||
|
"unicorn/prefer-event-key": "error",
|
||||||
|
"unicorn/prefer-flat-map": "error",
|
||||||
|
"unicorn/prefer-includes": "error",
|
||||||
|
"unicorn/prefer-modern-dom-apis": "error",
|
||||||
|
"unicorn/prefer-negative-index": "error",
|
||||||
|
"unicorn/prefer-node-append": "error",
|
||||||
|
"unicorn/prefer-node-remove": "error",
|
||||||
|
"unicorn/prefer-number-properties": "error",
|
||||||
|
"unicorn/prefer-optional-catch-binding": "error",
|
||||||
|
"unicorn/prefer-query-selector": "error",
|
||||||
|
"unicorn/prefer-reflect-apply": "error",
|
||||||
|
"unicorn/prefer-replace-all": "off",
|
||||||
|
"unicorn/prefer-set-has": "error",
|
||||||
|
"unicorn/prefer-spread": "error",
|
||||||
|
"unicorn/prefer-starts-ends-with": "error",
|
||||||
|
"unicorn/prefer-string-slice": "off",
|
||||||
|
"unicorn/prefer-text-content": "error",
|
||||||
|
"unicorn/prefer-trim-start-end": "off",
|
||||||
|
"unicorn/prefer-type-error": "error",
|
||||||
|
"unicorn/prevent-abbreviations": "off",
|
||||||
|
"unicorn/string-content": "error",
|
||||||
|
"unicorn/throw-new-error": "error"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -196,7 +196,8 @@
|
||||||
if (hashPrefix === decodedHash.substring(0, hashPrefix.length)) {
|
if (hashPrefix === decodedHash.substring(0, hashPrefix.length)) {
|
||||||
markdown.value = decodedHash.substring(hashPrefix.length);
|
markdown.value = decodedHash.substring(hashPrefix.length);
|
||||||
}
|
}
|
||||||
} catch (ex) {
|
/* eslint-disable-next-line unicorn/prefer-optional-catch-binding */
|
||||||
|
} catch (error) {
|
||||||
// Invalid
|
// Invalid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -205,7 +206,8 @@
|
||||||
try {
|
try {
|
||||||
/* eslint-disable-next-line no-new */
|
/* eslint-disable-next-line no-new */
|
||||||
new URL(rulesMd);
|
new URL(rulesMd);
|
||||||
} catch (ex) {
|
/* eslint-disable-next-line unicorn/prefer-optional-catch-binding */
|
||||||
|
} catch (error) {
|
||||||
markdown.value = [
|
markdown.value = [
|
||||||
"# Sorry",
|
"# Sorry",
|
||||||
"",
|
"",
|
||||||
|
|
|
||||||
|
|
@ -2782,10 +2782,10 @@ module.exports = {
|
||||||
// Close current run
|
// Close current run
|
||||||
var content = line.substring(emphasisIndex, matchIndex);
|
var content = line.substring(emphasisIndex, matchIndex);
|
||||||
if (!emphasisLength) {
|
if (!emphasisLength) {
|
||||||
content = content.trimStart();
|
content = content.trimLeft();
|
||||||
}
|
}
|
||||||
if (!match) {
|
if (!match) {
|
||||||
content = content.trimEnd();
|
content = content.trimRight();
|
||||||
}
|
}
|
||||||
var leftSpace = leftSpaceRe.test(content);
|
var leftSpace = leftSpaceRe.test(content);
|
||||||
var rightSpace = rightSpaceRe.test(content);
|
var rightSpace = rightSpaceRe.test(content);
|
||||||
|
|
|
||||||
|
|
@ -154,7 +154,7 @@ function removeFrontMatter(content, frontMatter) {
|
||||||
const contentMatched = frontMatterMatch[0];
|
const contentMatched = frontMatterMatch[0];
|
||||||
content = content.slice(contentMatched.length);
|
content = content.slice(contentMatched.length);
|
||||||
frontMatterLines = contentMatched.split(helpers.newLineRe);
|
frontMatterLines = contentMatched.split(helpers.newLineRe);
|
||||||
if (frontMatterLines.length &&
|
if ((frontMatterLines.length > 0) &&
|
||||||
(frontMatterLines[frontMatterLines.length - 1] === "")) {
|
(frontMatterLines[frontMatterLines.length - 1] === "")) {
|
||||||
frontMatterLines.length--;
|
frontMatterLines.length--;
|
||||||
}
|
}
|
||||||
|
|
@ -343,7 +343,8 @@ function getEnabledRulesPerLineNumber(
|
||||||
...config,
|
...config,
|
||||||
...json
|
...json
|
||||||
};
|
};
|
||||||
} catch (ex) {
|
// eslint-disable-next-line unicorn/prefer-optional-catch-binding
|
||||||
|
} catch (error) {
|
||||||
// Ignore parse errors for inline configuration
|
// Ignore parse errors for inline configuration
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -459,7 +460,7 @@ function lintContent(
|
||||||
resultVersion,
|
resultVersion,
|
||||||
callback) {
|
callback) {
|
||||||
// Remove UTF-8 byte order marker (if present)
|
// Remove UTF-8 byte order marker (if present)
|
||||||
content = content.replace(/^\ufeff/, "");
|
content = content.replace(/^\uFEFF/, "");
|
||||||
// Remove front matter
|
// Remove front matter
|
||||||
const removeFrontMatterResult = removeFrontMatter(content, frontMatter);
|
const removeFrontMatterResult = removeFrontMatter(content, frontMatter);
|
||||||
const frontMatterLines = removeFrontMatterResult.frontMatterLines;
|
const frontMatterLines = removeFrontMatterResult.frontMatterLines;
|
||||||
|
|
@ -582,17 +583,17 @@ function lintContent(
|
||||||
if (handleRuleFailures) {
|
if (handleRuleFailures) {
|
||||||
try {
|
try {
|
||||||
rule.function(params, onError);
|
rule.function(params, onError);
|
||||||
} catch (ex) {
|
} catch (error) {
|
||||||
onError({
|
onError({
|
||||||
"lineNumber": 1,
|
"lineNumber": 1,
|
||||||
"detail": `This rule threw an exception: ${ex.message}`
|
"detail": `This rule threw an exception: ${error.message}`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rule.function(params, onError);
|
rule.function(params, onError);
|
||||||
}
|
}
|
||||||
// Record any errors (significant performance benefit from length check)
|
// Record any errors (significant performance benefit from length check)
|
||||||
if (errors.length) {
|
if (errors.length > 0) {
|
||||||
errors.sort(lineNumberComparison);
|
errors.sort(lineNumberComparison);
|
||||||
const filteredErrors = errors
|
const filteredErrors = errors
|
||||||
.filter((resultVersion === 3) ?
|
.filter((resultVersion === 3) ?
|
||||||
|
|
@ -624,7 +625,7 @@ function lintContent(
|
||||||
}
|
}
|
||||||
return errorObject;
|
return errorObject;
|
||||||
});
|
});
|
||||||
if (filteredErrors.length) {
|
if (filteredErrors.length > 0) {
|
||||||
if (resultVersion === 0) {
|
if (resultVersion === 0) {
|
||||||
result[ruleNameFriendly] = filteredErrors;
|
result[ruleNameFriendly] = filteredErrors;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -636,9 +637,9 @@ function lintContent(
|
||||||
// Run all rules
|
// Run all rules
|
||||||
try {
|
try {
|
||||||
ruleList.forEach(forRule);
|
ruleList.forEach(forRule);
|
||||||
} catch (ex) {
|
} catch (error) {
|
||||||
cache.clear();
|
cache.clear();
|
||||||
return callback(ex);
|
return callback(error);
|
||||||
}
|
}
|
||||||
cache.clear();
|
cache.clear();
|
||||||
return callback(null, result);
|
return callback(null, result);
|
||||||
|
|
@ -819,8 +820,8 @@ function parseConfiguration(name, content, parsers) {
|
||||||
(parsers || [ JSON.parse ]).every((parser) => {
|
(parsers || [ JSON.parse ]).every((parser) => {
|
||||||
try {
|
try {
|
||||||
config = parser(content);
|
config = parser(content);
|
||||||
} catch (ex) {
|
} catch (error) {
|
||||||
errors.push(ex.message);
|
errors.push(error.message);
|
||||||
}
|
}
|
||||||
return !config;
|
return !config;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ module.exports = {
|
||||||
"function": function MD001(params, onError) {
|
"function": function MD001(params, onError) {
|
||||||
let prevLevel = 0;
|
let prevLevel = 0;
|
||||||
filterTokens(params, "heading_open", function forToken(token) {
|
filterTokens(params, "heading_open", function forToken(token) {
|
||||||
const level = parseInt(token.tag.slice(1), 10);
|
const level = Number.parseInt(token.tag.slice(1), 10);
|
||||||
if (prevLevel && (level > prevLevel)) {
|
if (prevLevel && (level > prevLevel)) {
|
||||||
addErrorDetailIf(onError, token.lineNumber,
|
addErrorDetailIf(onError, token.lineNumber,
|
||||||
"h" + (prevLevel + 1), "h" + level);
|
"h" + (prevLevel + 1), "h" + level);
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ module.exports = {
|
||||||
const maximum = Number(params.config.maximum || 1);
|
const maximum = Number(params.config.maximum || 1);
|
||||||
let count = 0;
|
let count = 0;
|
||||||
forEachLine(lineMetadata(), (line, lineIndex, inCode) => {
|
forEachLine(lineMetadata(), (line, lineIndex, inCode) => {
|
||||||
count = (inCode || line.trim().length) ? 0 : count + 1;
|
count = (inCode || (line.trim().length > 0)) ? 0 : count + 1;
|
||||||
if (maximum < count) {
|
if (maximum < count) {
|
||||||
addErrorDetailIf(
|
addErrorDetailIf(
|
||||||
onError,
|
onError,
|
||||||
|
|
|
||||||
|
|
@ -32,10 +32,10 @@ module.exports = {
|
||||||
// Close current run
|
// Close current run
|
||||||
let content = line.substring(emphasisIndex, matchIndex);
|
let content = line.substring(emphasisIndex, matchIndex);
|
||||||
if (!emphasisLength) {
|
if (!emphasisLength) {
|
||||||
content = content.trimStart();
|
content = content.trimLeft();
|
||||||
}
|
}
|
||||||
if (!match) {
|
if (!match) {
|
||||||
content = content.trimEnd();
|
content = content.trimRight();
|
||||||
}
|
}
|
||||||
const leftSpace = leftSpaceRe.test(content);
|
const leftSpace = leftSpaceRe.test(content);
|
||||||
const rightSpace = rightSpaceRe.test(content);
|
const rightSpace = rightSpaceRe.test(content);
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
"test-cover": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 node test/markdownlint-test.js",
|
"test-cover": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 node test/markdownlint-test.js",
|
||||||
"test-declaration": "cd example/typescript && tsc && node type-check.js",
|
"test-declaration": "cd example/typescript && tsc && node type-check.js",
|
||||||
"test-extra": "node test/markdownlint-test-extra.js",
|
"test-extra": "node test/markdownlint-test-extra.js",
|
||||||
"lint": "eslint --max-warnings 0 lib helpers test schema && eslint --env browser --global markdownit --global markdownlint --rule \"no-unused-vars: 0, no-extend-native: 0, max-statements: 0, no-console: 0, no-var: 0\" demo && eslint --rule \"no-console: 0, no-invalid-this: 0, no-shadow: 0, object-property-newline: 0, node/no-missing-require: 0, node/no-extraneous-require: 0\" example",
|
"lint": "eslint --max-warnings 0 lib helpers test schema && eslint --env browser --global markdownit --global markdownlint --rule \"no-unused-vars: 0, no-extend-native: 0, max-statements: 0, no-console: 0, no-var: 0, unicorn/prefer-add-event-listener: 0, unicorn/prefer-query-selector: 0, unicorn/prefer-replace-all: 0\" demo && eslint --rule \"no-console: 0, no-invalid-this: 0, no-shadow: 0, object-property-newline: 0, node/no-missing-require: 0, node/no-extraneous-require: 0\" example",
|
||||||
"ci": "npm run test-cover && npm run lint && npm run test-declaration",
|
"ci": "npm run test-cover && npm run lint && npm run test-declaration",
|
||||||
"build-config-schema": "node schema/build-config-schema.js",
|
"build-config-schema": "node schema/build-config-schema.js",
|
||||||
"build-declaration": "tsc --allowJs --declaration --outDir declaration --resolveJsonModule lib/markdownlint.js && cpy declaration/lib/markdownlint.d.ts lib && rimraf declaration",
|
"build-declaration": "tsc --allowJs --declaration --outDir declaration --resolveJsonModule lib/markdownlint.js && cpy declaration/lib/markdownlint.d.ts lib && rimraf declaration",
|
||||||
|
|
@ -43,6 +43,7 @@
|
||||||
"eslint": "~7.8.1",
|
"eslint": "~7.8.1",
|
||||||
"eslint-plugin-jsdoc": "~30.3.1",
|
"eslint-plugin-jsdoc": "~30.3.1",
|
||||||
"eslint-plugin-node": "~11.1.0",
|
"eslint-plugin-node": "~11.1.0",
|
||||||
|
"eslint-plugin-unicorn": "~21.0.0",
|
||||||
"globby": "~11.0.1",
|
"globby": "~11.0.1",
|
||||||
"js-yaml": "~3.14.0",
|
"js-yaml": "~3.14.0",
|
||||||
"make-dir-cli": "~2.0.0",
|
"make-dir-cli": "~2.0.0",
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ function lintTestRepo(test, globPatterns, configPath) {
|
||||||
};
|
};
|
||||||
return markdownlintPromise(options).then((results) => {
|
return markdownlintPromise(options).then((results) => {
|
||||||
const resultsString = results.toString();
|
const resultsString = results.toString();
|
||||||
if (resultsString.length) {
|
if (resultsString.length > 0) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log(resultsString);
|
console.log(resultsString);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ const configSchema = require("../schema/markdownlint-config-schema.json");
|
||||||
const homepage = packageJson.homepage;
|
const homepage = packageJson.homepage;
|
||||||
const version = packageJson.version;
|
const version = packageJson.version;
|
||||||
|
|
||||||
const deprecatedRuleNames = [ "MD002", "MD006" ];
|
const deprecatedRuleNames = new Set([ "MD002", "MD006" ]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a test function for the specified test file.
|
* Create a test function for the specified test file.
|
||||||
|
|
@ -128,7 +128,11 @@ function createTestForFile(file) {
|
||||||
while ((match = regex.exec(line))) {
|
while ((match = regex.exec(line))) {
|
||||||
const rule = match[1];
|
const rule = match[1];
|
||||||
const errors = results[rule] || [];
|
const errors = results[rule] || [];
|
||||||
errors.push(match[2] ? parseInt(match[2], 10) : lineNum + 1);
|
errors.push(
|
||||||
|
match[2] ?
|
||||||
|
Number.parseInt(match[2], 10) :
|
||||||
|
lineNum + 1
|
||||||
|
);
|
||||||
results[rule] = errors;
|
results[rule] = errors;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -1504,7 +1508,7 @@ tape("readme", (test) => {
|
||||||
let expected = "**[" + ruleName + "](doc/Rules.md#" +
|
let expected = "**[" + ruleName + "](doc/Rules.md#" +
|
||||||
ruleName.toLowerCase() + ")** *" +
|
ruleName.toLowerCase() + ")** *" +
|
||||||
ruleAliases.join("/") + "* - " + rule.description;
|
ruleAliases.join("/") + "* - " + rule.description;
|
||||||
if (deprecatedRuleNames.includes(ruleName)) {
|
if (deprecatedRuleNames.has(ruleName)) {
|
||||||
expected = "~~" + expected + "~~";
|
expected = "~~" + expected + "~~";
|
||||||
}
|
}
|
||||||
test.equal(token.content, expected, "Rule mismatch.");
|
test.equal(token.content, expected, "Rule mismatch.");
|
||||||
|
|
@ -1566,7 +1570,7 @@ tape("rules", (test) => {
|
||||||
"Missing rule implementation for " + token.content + ".");
|
"Missing rule implementation for " + token.content + ".");
|
||||||
const ruleName = rule.names[0];
|
const ruleName = rule.names[0];
|
||||||
let headingContent = ruleName + " - " + rule.description;
|
let headingContent = ruleName + " - " + rule.description;
|
||||||
if (deprecatedRuleNames.includes(ruleName)) {
|
if (deprecatedRuleNames.has(ruleName)) {
|
||||||
headingContent = "~~" + headingContent + "~~";
|
headingContent = "~~" + headingContent + "~~";
|
||||||
}
|
}
|
||||||
test.equal(token.content,
|
test.equal(token.content,
|
||||||
|
|
@ -1580,16 +1584,16 @@ tape("rules", (test) => {
|
||||||
});
|
});
|
||||||
ruleUsesParams.sort();
|
ruleUsesParams.sort();
|
||||||
}
|
}
|
||||||
} else if (/^Tags: /.test(token.content) && rule) {
|
} else if (token.content.startsWith("Tags: ") && rule) {
|
||||||
test.deepEqual(token.content.split(tagAliasParameterRe).slice(1),
|
test.deepEqual(token.content.split(tagAliasParameterRe).slice(1),
|
||||||
rule.tags, "Tag mismatch for rule " + rule.names + ".");
|
rule.tags, "Tag mismatch for rule " + rule.names + ".");
|
||||||
ruleHasTags = true;
|
ruleHasTags = true;
|
||||||
} else if (/^Aliases: /.test(token.content) && rule) {
|
} else if (token.content.startsWith("Aliases: ") && rule) {
|
||||||
test.deepEqual(token.content.split(tagAliasParameterRe).slice(1),
|
test.deepEqual(token.content.split(tagAliasParameterRe).slice(1),
|
||||||
rule.names.slice(1),
|
rule.names.slice(1),
|
||||||
"Alias mismatch for rule " + rule.names + ".");
|
"Alias mismatch for rule " + rule.names + ".");
|
||||||
ruleHasAliases = true;
|
ruleHasAliases = true;
|
||||||
} else if (/^Parameters: /.test(token.content) && rule) {
|
} else if (token.content.startsWith("Parameters: ") && rule) {
|
||||||
let inDetails = false;
|
let inDetails = false;
|
||||||
const parameters = token.content.split(tagAliasParameterRe)
|
const parameters = token.content.split(tagAliasParameterRe)
|
||||||
.slice(1)
|
.slice(1)
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ const languageJavaScript = /js|javascript/i;
|
||||||
function cleanJsdocRulesFromEslintConfig(config) {
|
function cleanJsdocRulesFromEslintConfig(config) {
|
||||||
const cleanedConfig = { ...config };
|
const cleanedConfig = { ...config };
|
||||||
for (const rule in config.rules) {
|
for (const rule in config.rules) {
|
||||||
if (/^(jsdoc|node)\//.test(rule)) {
|
if (/^(jsdoc|node|unicorn)\//.test(rule)) {
|
||||||
delete cleanedConfig.rules[rule];
|
delete cleanedConfig.rules[rule];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue