Skip to content

Commit

Permalink
feat: support for dynamic and async rules
Browse files Browse the repository at this point in the history
  • Loading branch information
marionebl committed Feb 25, 2016
1 parent 91806a2 commit efce01a
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 16 deletions.
32 changes: 27 additions & 5 deletions documentation/rules.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,36 @@
# Rules
Rules are made up by a name and a configuration array. The configuration array contains:
* **Level** `[0..2]`: `0` disables the rule. For `1` it will be considered a warning for `2` an error.
* **Applicable** `always|never`: `never` inverts the rule.
* **Value**: value to use for this rule.

Rule configurations are either of type `array` residing on a key with the rule's name as key on the rules `object` or of type function returning type `array` or `Promise<array>`. This means all of the following notations are supported.

**Plain array**
```js
"rules": {
"header-max-length": [0, "always", 72],
// name: [level, applicable, value]
}
```
Rules are made up by a name and a configuration array. The configuration array contains:
* **Level** `[0..2]`: `0` disables the rule. For `1` it will be considered a warning for `2` an error.
* **Applicable** `always|never`: `never` inverts the rule.
* **Value**: value to use for this rule.
**Function returning array**
```js
"rules": {
"header-max-length": () => [0, "always", 72],
}
```
**Async function returning array**
```js
"rules": {
"header-max-length": async () => [0, "always", 72],
}
```
**Function returning a promise resolving to array**
```js
"rules": {
"header-max-length": () => Promise.resolve([0, "always", 72]),
}
```


### Available rules
#### type-enum
Expand Down
7 changes: 2 additions & 5 deletions source/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ async function main(options) {
seed.extends = flags.extends.split(',');
}

const report = lint(commit, {
const report = await lint(commit, {
preset: await getPreset(flags.preset),
configuration: await getConfiguration(
'conventional-changelog-lint',
Expand All @@ -117,10 +117,7 @@ async function main(options) {

if (!flags.quiet) {
console.log(`${fmt.grey('⧗')} input: ${fmt.bold(commit.split('\n')[0])}`);
console.log(
formatted
.join('\n')
);
console.log(formatted.join('\n'));
}

if (report.errors.length > 0) {
Expand Down
31 changes: 25 additions & 6 deletions source/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,14 @@ export getMessages from './library/get-messages';
export getPreset from './library/get-preset';
export format from './library/format';

export default (message, options = {}) => {
async function executeRule(entry) {
const [name, config] = entry;
return typeof config === 'function' ?
[name, await config()] :
[name, await config];
}

export default async (message, options = {}) => {
const {
preset: {
parserOpts: parserOptions
Expand All @@ -22,8 +29,14 @@ export default (message, options = {}) => {
parse(message, parserOptions)
);

// execute wildcard rules
const executedWildcards = await Promise.all(
Object.entries(wildcards || {})
.map(async entry => await executeRule(entry))
);

// wildcard matches skip the linting
const bails = Object.entries(wildcards || {})
const bails = executedWildcards
.filter(entry => {
const [, pattern] = entry;
return Array.isArray(pattern);
Expand All @@ -33,7 +46,7 @@ export default (message, options = {}) => {
const expression = new RegExp(...pattern);
return parsed.header.match(expression);
})
.map(entry => entry[0]);
.map(entry => entry[0])

if (bails.length > 0) {
return {
Expand All @@ -45,8 +58,14 @@ export default (message, options = {}) => {
};
}

// validate against all rules
const results = Object.entries(rules || {})
// execute linting rules
const executedRules = await Promise.all(
Object.entries(rules || {})
.map(async entry => await executeRule(entry))
);

// validate against all rules
const results = executedRules
.filter(entry => {
const [, [level]] = entry;
return level > 0;
Expand All @@ -70,7 +89,7 @@ export default (message, options = {}) => {
message
};
})
.filter(Boolean);
.filter(Boolean)

const errors = results.filter(result =>
result.level > 1 && !result.valid);
Expand Down

0 comments on commit efce01a

Please sign in to comment.