mirror of
https://github.com/remarkjs/remark-lint.git
synced 2024-09-11 19:57:15 +03:00
Add support for passing severities
Previously, messages could be either turned on (as warnings), or turned off. This update adds support for setting these through an integer (`1` and `0` respectivly), in array form: ```js remark().use(lint, {finalNewline:[0]}); ``` Additionally, the integer `2` can be passed to turn a message into a fatal error: ```js remark().use(lint, {maximumLineLength: [2, 72]}); ``` Closes GH-65.
This commit is contained in:
parent
9bdd69e653
commit
77709f56ac
29
doc/rules.md
29
doc/rules.md
@ -6,7 +6,7 @@ This document describes all (57)
|
||||
available rules, what they check for, examples of
|
||||
what they warn for, and how to fix their warnings.
|
||||
|
||||
Note: both camel-cased and dash-cases versions of rule id’s
|
||||
Both camel-cased and dash-cases versions of rule id’s
|
||||
are supported in configuration objects:
|
||||
|
||||
```json
|
||||
@ -23,6 +23,33 @@ are supported in configuration objects:
|
||||
}
|
||||
```
|
||||
|
||||
Additionally, each rule can be configured with a severity
|
||||
instead of a boolean as well. The following is handled the
|
||||
same as passing `false`:
|
||||
|
||||
```json
|
||||
{
|
||||
"final-newline": [0]
|
||||
}
|
||||
```
|
||||
|
||||
...and passing `[1]` is as passing `true`. To trigger an
|
||||
error instead of a warning, pass `2`:
|
||||
|
||||
```json
|
||||
{
|
||||
"final-newline": [2]
|
||||
}
|
||||
```
|
||||
|
||||
It’s also possible to pass both a severity and configuration:
|
||||
|
||||
```json
|
||||
{
|
||||
"maximum-line-length": [2, 70]
|
||||
}
|
||||
```
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [reset](#reset)
|
||||
|
72
lib/index.js
72
lib/index.js
@ -51,30 +51,17 @@ function lint(remark, options) {
|
||||
var disable = [];
|
||||
var known = [];
|
||||
var pipeline = trough();
|
||||
var setting;
|
||||
var config;
|
||||
var id;
|
||||
|
||||
/* Add each rule. */
|
||||
for (id in rules) {
|
||||
setting = settings[id];
|
||||
|
||||
known.push(id);
|
||||
config = coerce(id, settings[id], reset);
|
||||
|
||||
if (setting != null) {
|
||||
/* Pass turned on rules `undefined`. */
|
||||
if (reset && setting === true) {
|
||||
setting = undefined;
|
||||
}
|
||||
(config[0] ? enable : disable).push(id);
|
||||
|
||||
if (setting === false) {
|
||||
setting = undefined;
|
||||
disable.push(id);
|
||||
} else {
|
||||
enable.push(id);
|
||||
}
|
||||
}
|
||||
|
||||
pipeline.use(ruleFactory(id, rules[id], setting));
|
||||
pipeline.use(ruleFactory(id, rules[id], config[0], config[1]));
|
||||
}
|
||||
|
||||
/* Run all rules. */
|
||||
@ -155,11 +142,13 @@ function loadExternals(externals) {
|
||||
*
|
||||
* @param {string} id - Identifier.
|
||||
* @param {Function} rule - Rule
|
||||
* @param {number} severity - Severity.
|
||||
* @param {*} options - Options for respective rule.
|
||||
* @return {Function} - Trough ware.
|
||||
*/
|
||||
function ruleFactory(id, rule, options) {
|
||||
function ruleFactory(id, rule, severity, options) {
|
||||
var fn = wrapped(rule);
|
||||
var fatal = severity === 2;
|
||||
|
||||
return function (ast, file, next) {
|
||||
var scope = file.namespace('remark-lint');
|
||||
@ -169,10 +158,13 @@ function ruleFactory(id, rule, options) {
|
||||
|
||||
fn(ast, file, options, function (err) {
|
||||
var messages = file.messages;
|
||||
var message;
|
||||
|
||||
while (scope.index < messages.length) {
|
||||
messages[scope.index].ruleId = id;
|
||||
messages[scope.index].source = SOURCE;
|
||||
message = messages[scope.index];
|
||||
message.ruleId = id;
|
||||
message.source = SOURCE;
|
||||
message.fatal = fatal;
|
||||
|
||||
scope.index++;
|
||||
}
|
||||
@ -182,13 +174,7 @@ function ruleFactory(id, rule, options) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to ensure ruleId’s are dash-cased instead of
|
||||
* camel-cased.
|
||||
*
|
||||
* @param {Object} source - Original settings.
|
||||
* @return {Object} - Dash-cased settings.
|
||||
*/
|
||||
/* Ensure ruleId’s are dash-cased. */
|
||||
function decamelizeSettings(source) {
|
||||
var result = {};
|
||||
var key;
|
||||
@ -199,3 +185,35 @@ function decamelizeSettings(source) {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Coerce a value to a severity--options tuple. */
|
||||
function coerce(name, value, reset) {
|
||||
var def = reset ? 0 : 1;
|
||||
var result;
|
||||
|
||||
if (value == null) {
|
||||
result = [def];
|
||||
} else if (typeof value === 'boolean') {
|
||||
result = [value];
|
||||
} else if (
|
||||
typeof value === 'object' &&
|
||||
(typeof value[0] === 'number' || typeof value[0] === 'boolean')
|
||||
) {
|
||||
result = value.concat();
|
||||
} else {
|
||||
result = [1, value];
|
||||
}
|
||||
|
||||
if (typeof result[0] === 'boolean') {
|
||||
result[0] = result[0] ? 1 : 0;
|
||||
}
|
||||
|
||||
if (result[0] < 0 || result[0] > 2) {
|
||||
throw new Error(
|
||||
'Invalid severity `' + result[0] + '` for `' + name + '`, ' +
|
||||
'expected 0, 1, or 2'
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ var markdown = remark().use(toc);
|
||||
'available rules, what they check for, examples of',
|
||||
'what they warn for, and how to fix their warnings.',
|
||||
'',
|
||||
'Note: both camel-cased and dash-cases versions of rule id’s',
|
||||
'Both camel-cased and dash-cases versions of rule id’s',
|
||||
'are supported in configuration objects:',
|
||||
'',
|
||||
'```json',
|
||||
@ -121,6 +121,33 @@ var markdown = remark().use(toc);
|
||||
'}',
|
||||
'```',
|
||||
'',
|
||||
'Additionally, each rule can be configured with a severity',
|
||||
'instead of a boolean as well. The following is handled the',
|
||||
'same as passing `false`:',
|
||||
'',
|
||||
'```json',
|
||||
'{',
|
||||
' "final-newline": [0]',
|
||||
'}',
|
||||
'```',
|
||||
'',
|
||||
'...and passing `[1]` is as passing `true`. To trigger an',
|
||||
'error instead of a warning, pass `2`:',
|
||||
'',
|
||||
'```json',
|
||||
'{',
|
||||
' "final-newline": [2]',
|
||||
'}',
|
||||
'```',
|
||||
'',
|
||||
'It’s also possible to pass both a severity and configuration:',
|
||||
'',
|
||||
'```json',
|
||||
'{',
|
||||
' "maximum-line-length": [2, 70]',
|
||||
'}',
|
||||
'```',
|
||||
'',
|
||||
'## Table of Contents',
|
||||
'',
|
||||
'## `reset`',
|
||||
|
@ -85,6 +85,42 @@ test('core', function (t) {
|
||||
});
|
||||
});
|
||||
|
||||
t.test('should support a list with a severity', function (st) {
|
||||
st.plan(3);
|
||||
|
||||
remark()
|
||||
.use(lint, {reset: true, finalNewline: [2]})
|
||||
.process('.', function (err, file) {
|
||||
st.ifErr(err, 'should not fail');
|
||||
st.equal(
|
||||
file.messages.join(),
|
||||
'1:1: Missing newline character at end of file',
|
||||
'should trigger fatally (1)'
|
||||
);
|
||||
st.equal(file.messages[0].fatal, true, 'should trigger fatally (2)');
|
||||
});
|
||||
});
|
||||
|
||||
t.test('should fail on invalid severities', function (st) {
|
||||
st.throws(
|
||||
function () {
|
||||
remark().use(lint, {finalNewline: [3]});
|
||||
},
|
||||
/^Error: Invalid severity `3` for `final-newline`, expected 0, 1, or 2$/,
|
||||
'should throw when too high'
|
||||
);
|
||||
|
||||
st.throws(
|
||||
function () {
|
||||
remark().use(lint, {finalNewline: [-1]});
|
||||
},
|
||||
/^Error: Invalid severity `-1` for `final-newline`, expected 0, 1, or 2$/,
|
||||
'should throw too low'
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user