Skip to content

Commit

Permalink
feat: add async promise based rules methods into lint (#976)
Browse files Browse the repository at this point in the history
* feat(rules): add async promise based rules methods into lint

* fix: accomodate async rules in type system

* style: apply autoformatting
  • Loading branch information
marionebl committed Feb 18, 2020
1 parent 89168b8 commit 4443062
Show file tree
Hide file tree
Showing 35 changed files with 111 additions and 74 deletions.
20 changes: 20 additions & 0 deletions @commitlint/lint/src/lint.test.ts
Expand Up @@ -283,3 +283,23 @@ test('returns original message with commit header, body and footer, parsing comm

expect(report.input).toBe(expected);
});

test('passes for async rule', async () => {
const report = await lint(
'somehting #1',
{
'async-rule': [2, 'never']
},
{
plugins: {
'example-plugin': {
rules: {
'async-rule': async () => [true, 'all good'] as const
}
}
}
}
);

expect(report.valid).toBe(true);
});
19 changes: 12 additions & 7 deletions @commitlint/lint/src/lint.ts
Expand Up @@ -8,7 +8,9 @@ import {
LintOptions,
LintRuleOutcome,
Rule,
RuleSeverity
RuleSeverity,
BaseRule,
RuleType
} from '@commitlint/types';

export default async function lint(
Expand All @@ -35,7 +37,7 @@ export default async function lint(

// Parse the commit message
const parsed = await parse(message, undefined, opts.parserOpts);
const allRules: Map<string, Rule<unknown> | Rule<never>> = new Map(
const allRules: Map<string, BaseRule<never, RuleType>> = new Map(
Object.entries(defaultRules)
);

Expand Down Expand Up @@ -130,9 +132,9 @@ export default async function lint(
}

// Validate against all rules
const results = Object.entries(rulesConfig)
const pendingResults = Object.entries(rulesConfig)
.filter(([, [level]]) => level > 0)
.map(entry => {
.map(async entry => {
const [name, config] = entry;
const [level, when, value] = config;

Expand All @@ -148,16 +150,19 @@ export default async function lint(
}

const executableRule = rule as Rule<unknown>;
const [valid, message] = executableRule(parsed, when, value);
const [valid, message] = await executableRule(parsed, when, value);

return {
level,
valid,
name,
message
};
})
.filter((result): result is LintRuleOutcome => result !== null);
});

const results = (await Promise.all(pendingResults)).filter(
(result): result is LintRuleOutcome => result !== null
);

const errors = results.filter(result => result.level === 2 && !result.valid);
const warnings = results.filter(
Expand Down
4 changes: 2 additions & 2 deletions @commitlint/rules/src/body-case.ts
@@ -1,8 +1,8 @@
import {case as ensureCase} from '@commitlint/ensure';
import message from '@commitlint/message';
import {TargetCaseType, Rule} from '@commitlint/types';
import {TargetCaseType, SyncRule} from '@commitlint/types';

export const bodyCase: Rule<TargetCaseType> = (
export const bodyCase: SyncRule<TargetCaseType> = (
parsed,
when = 'always',
value = undefined
Expand Down
4 changes: 2 additions & 2 deletions @commitlint/rules/src/body-empty.ts
@@ -1,8 +1,8 @@
import * as ensure from '@commitlint/ensure';
import message from '@commitlint/message';
import {Rule} from '@commitlint/types';
import {SyncRule} from '@commitlint/types';

export const bodyEmpty: Rule = (parsed, when = 'always') => {
export const bodyEmpty: SyncRule = (parsed, when = 'always') => {
const negated = when === 'never';
const notEmpty = ensure.notEmpty(parsed.body || '');

Expand Down
4 changes: 2 additions & 2 deletions @commitlint/rules/src/body-leading-blank.ts
@@ -1,8 +1,8 @@
import toLines from '@commitlint/to-lines';
import message from '@commitlint/message';
import {Rule} from '@commitlint/types';
import {SyncRule} from '@commitlint/types';

export const bodyLeadingBlank: Rule = (parsed, when) => {
export const bodyLeadingBlank: SyncRule = (parsed, when) => {
// Flunk if no body is found
if (!parsed.body) {
return [true];
Expand Down
4 changes: 2 additions & 2 deletions @commitlint/rules/src/body-max-length.ts
@@ -1,7 +1,7 @@
import {maxLength} from '@commitlint/ensure';
import {Rule} from '@commitlint/types';
import {SyncRule} from '@commitlint/types';

export const bodyMaxLength: Rule<number> = (
export const bodyMaxLength: SyncRule<number> = (
parsed,
_when = undefined,
value = 0
Expand Down
4 changes: 2 additions & 2 deletions @commitlint/rules/src/body-max-line-length.ts
@@ -1,7 +1,7 @@
import {maxLineLength} from '@commitlint/ensure';
import {Rule} from '@commitlint/types';
import {SyncRule} from '@commitlint/types';

export const bodyMaxLineLength: Rule<number> = (
export const bodyMaxLineLength: SyncRule<number> = (
parsed,
_when = undefined,
value = 0
Expand Down
4 changes: 2 additions & 2 deletions @commitlint/rules/src/body-min-length.ts
@@ -1,7 +1,7 @@
import {minLength} from '@commitlint/ensure';
import {Rule} from '@commitlint/types';
import {SyncRule} from '@commitlint/types';

export const bodyMinLength: Rule<number> = (
export const bodyMinLength: SyncRule<number> = (
parsed,
_when = undefined,
value = 0
Expand Down
4 changes: 2 additions & 2 deletions @commitlint/rules/src/footer-empty.ts
@@ -1,8 +1,8 @@
import * as ensure from '@commitlint/ensure';
import message from '@commitlint/message';
import {Rule} from '@commitlint/types';
import {SyncRule} from '@commitlint/types';

export const footerEmpty: Rule = (parsed, when = 'always') => {
export const footerEmpty: SyncRule = (parsed, when = 'always') => {
const negated = when === 'never';
const notEmpty = ensure.notEmpty(parsed.footer || '');

Expand Down
4 changes: 2 additions & 2 deletions @commitlint/rules/src/footer-leading-blank.ts
@@ -1,8 +1,8 @@
import toLines from '@commitlint/to-lines';
import message from '@commitlint/message';
import {Rule} from '@commitlint/types';
import {SyncRule} from '@commitlint/types';

export const footerLeadingBlank: Rule = (parsed, when = 'always') => {
export const footerLeadingBlank: SyncRule = (parsed, when = 'always') => {
// Flunk if no footer is found
if (!parsed.footer) {
return [true];
Expand Down
4 changes: 2 additions & 2 deletions @commitlint/rules/src/footer-max-length.ts
@@ -1,7 +1,7 @@
import {maxLength} from '@commitlint/ensure';
import {Rule} from '@commitlint/types';
import {SyncRule} from '@commitlint/types';

export const footerMaxLength: Rule<number> = (
export const footerMaxLength: SyncRule<number> = (
parsed,
_when = undefined,
value = 0
Expand Down
4 changes: 2 additions & 2 deletions @commitlint/rules/src/footer-max-line-length.ts
@@ -1,7 +1,7 @@
import {maxLineLength} from '@commitlint/ensure';
import {Rule} from '@commitlint/types';
import {SyncRule} from '@commitlint/types';

export const footerMaxLineLength: Rule<number> = (
export const footerMaxLineLength: SyncRule<number> = (
parsed,
_when = undefined,
value = 0
Expand Down
4 changes: 2 additions & 2 deletions @commitlint/rules/src/footer-min-length.ts
@@ -1,7 +1,7 @@
import {minLength} from '@commitlint/ensure';
import {Rule} from '@commitlint/types';
import {SyncRule} from '@commitlint/types';

export const footerMinLength: Rule<number> = (
export const footerMinLength: SyncRule<number> = (
parsed,
_when = undefined,
value = 0
Expand Down
4 changes: 2 additions & 2 deletions @commitlint/rules/src/header-case.ts
@@ -1,10 +1,10 @@
import {case as ensureCase} from '@commitlint/ensure';
import message from '@commitlint/message';
import {TargetCaseType, Rule} from '@commitlint/types';
import {TargetCaseType, SyncRule} from '@commitlint/types';

const negated = (when?: string) => when === 'never';

export const headerCase: Rule<TargetCaseType | TargetCaseType[]> = (
export const headerCase: SyncRule<TargetCaseType | TargetCaseType[]> = (
parsed,
when = 'always',
value = []
Expand Down
4 changes: 2 additions & 2 deletions @commitlint/rules/src/header-full-stop.ts
@@ -1,7 +1,7 @@
import message from '@commitlint/message';
import {Rule} from '@commitlint/types';
import {SyncRule} from '@commitlint/types';

export const headerFullStop: Rule<string> = (
export const headerFullStop: SyncRule<string> = (
parsed,
when = 'always',
value = '.'
Expand Down
4 changes: 2 additions & 2 deletions @commitlint/rules/src/header-max-length.ts
@@ -1,7 +1,7 @@
import {maxLength} from '@commitlint/ensure';
import {Rule} from '@commitlint/types';
import {SyncRule} from '@commitlint/types';

export const headerMaxLength: Rule<number> = (
export const headerMaxLength: SyncRule<number> = (
parsed,
_when = undefined,
value = 0
Expand Down
4 changes: 2 additions & 2 deletions @commitlint/rules/src/header-min-length.ts
@@ -1,7 +1,7 @@
import {minLength} from '@commitlint/ensure';
import {Rule} from '@commitlint/types';
import {SyncRule} from '@commitlint/types';

export const headerMinLength: Rule<number> = (
export const headerMinLength: SyncRule<number> = (
parsed,
_when = undefined,
value = 0
Expand Down
4 changes: 2 additions & 2 deletions @commitlint/rules/src/references-empty.ts
@@ -1,7 +1,7 @@
import message from '@commitlint/message';
import {Rule} from '@commitlint/types';
import {SyncRule} from '@commitlint/types';

export const referencesEmpty: Rule = (parsed, when = 'never') => {
export const referencesEmpty: SyncRule = (parsed, when = 'never') => {
const negated = when === 'always';
const notEmpty = parsed.references.length > 0;
return [
Expand Down
4 changes: 2 additions & 2 deletions @commitlint/rules/src/scope-case.ts
@@ -1,10 +1,10 @@
import {case as ensureCase} from '@commitlint/ensure';
import message from '@commitlint/message';
import {TargetCaseType, Rule} from '@commitlint/types';
import {TargetCaseType, SyncRule} from '@commitlint/types';

const negated = (when?: string) => when === 'never';

export const scopeCase: Rule<TargetCaseType | TargetCaseType[]> = (
export const scopeCase: SyncRule<TargetCaseType | TargetCaseType[]> = (
parsed,
when = 'always',
value = []
Expand Down
4 changes: 2 additions & 2 deletions @commitlint/rules/src/scope-empty.ts
@@ -1,8 +1,8 @@
import * as ensure from '@commitlint/ensure';
import message from '@commitlint/message';
import {Rule} from '@commitlint/types';
import {SyncRule} from '@commitlint/types';

export const scopeEmpty: Rule = (parsed, when = 'never') => {
export const scopeEmpty: SyncRule = (parsed, when = 'never') => {
const negated = when === 'always';
const notEmpty = ensure.notEmpty(parsed.scope || '');
return [
Expand Down
4 changes: 2 additions & 2 deletions @commitlint/rules/src/scope-enum.ts
@@ -1,8 +1,8 @@
import * as ensure from '@commitlint/ensure';
import message from '@commitlint/message';
import {Rule} from '@commitlint/types';
import {SyncRule} from '@commitlint/types';

export const scopeEnum: Rule<string[]> = (
export const scopeEnum: SyncRule<string[]> = (
parsed,
when = 'always',
value = []
Expand Down
4 changes: 2 additions & 2 deletions @commitlint/rules/src/scope-max-length.ts
@@ -1,7 +1,7 @@
import {maxLength} from '@commitlint/ensure';
import {Rule} from '@commitlint/types';
import {SyncRule} from '@commitlint/types';

export const scopeMaxLength: Rule<number> = (
export const scopeMaxLength: SyncRule<number> = (
parsed,
_when = undefined,
value = 0
Expand Down
4 changes: 2 additions & 2 deletions @commitlint/rules/src/scope-min-length.ts
@@ -1,7 +1,7 @@
import {minLength} from '@commitlint/ensure';
import {Rule} from '@commitlint/types';
import {SyncRule} from '@commitlint/types';

export const scopeMinLength: Rule<number> = (
export const scopeMinLength: SyncRule<number> = (
parsed,
_when = undefined,
value = 0
Expand Down
4 changes: 2 additions & 2 deletions @commitlint/rules/src/signed-off-by.ts
@@ -1,8 +1,8 @@
import message from '@commitlint/message';
import toLines from '@commitlint/to-lines';
import {Rule} from '@commitlint/types';
import {SyncRule} from '@commitlint/types';

export const signedOffBy: Rule<string> = (
export const signedOffBy: SyncRule<string> = (
parsed,
when = 'always',
value = ''
Expand Down
4 changes: 2 additions & 2 deletions @commitlint/rules/src/subject-case.ts
@@ -1,10 +1,10 @@
import {case as ensureCase} from '@commitlint/ensure';
import message from '@commitlint/message';
import {TargetCaseType, Rule} from '@commitlint/types';
import {TargetCaseType, SyncRule} from '@commitlint/types';

const negated = (when?: string) => when === 'never';

export const subjectCase: Rule<TargetCaseType | TargetCaseType[]> = (
export const subjectCase: SyncRule<TargetCaseType | TargetCaseType[]> = (
parsed,
when = 'always',
value = []
Expand Down
4 changes: 2 additions & 2 deletions @commitlint/rules/src/subject-empty.ts
@@ -1,8 +1,8 @@
import * as ensure from '@commitlint/ensure';
import message from '@commitlint/message';
import {Rule} from '@commitlint/types';
import {SyncRule} from '@commitlint/types';

export const subjectEmpty: Rule = (parsed, when = 'always') => {
export const subjectEmpty: SyncRule = (parsed, when = 'always') => {
const negated = when === 'never';
const notEmpty = ensure.notEmpty(parsed.subject || '');

Expand Down
4 changes: 2 additions & 2 deletions @commitlint/rules/src/subject-full-stop.ts
@@ -1,7 +1,7 @@
import message from '@commitlint/message';
import {Rule} from '@commitlint/types';
import {SyncRule} from '@commitlint/types';

export const subjectFullStop: Rule<string> = (
export const subjectFullStop: SyncRule<string> = (
parsed,
when = 'always',
value = '.'
Expand Down
4 changes: 2 additions & 2 deletions @commitlint/rules/src/subject-max-length.ts
@@ -1,7 +1,7 @@
import {maxLength} from '@commitlint/ensure';
import {Rule} from '@commitlint/types';
import {SyncRule} from '@commitlint/types';

export const subjectMaxLength: Rule<number> = (
export const subjectMaxLength: SyncRule<number> = (
parsed,
_when = undefined,
value = 0
Expand Down
4 changes: 2 additions & 2 deletions @commitlint/rules/src/subject-min-length.ts
@@ -1,7 +1,7 @@
import {minLength} from '@commitlint/ensure';
import {Rule} from '@commitlint/types';
import {SyncRule} from '@commitlint/types';

export const subjectMinLength: Rule<number> = (
export const subjectMinLength: SyncRule<number> = (
parsed,
_when = undefined,
value = 0
Expand Down
4 changes: 2 additions & 2 deletions @commitlint/rules/src/type-case.ts
@@ -1,10 +1,10 @@
import {case as ensureCase} from '@commitlint/ensure';
import message from '@commitlint/message';
import {TargetCaseType, Rule} from '@commitlint/types';
import {TargetCaseType, SyncRule} from '@commitlint/types';

const negated = (when?: string) => when === 'never';

export const typeCase: Rule<TargetCaseType | TargetCaseType[]> = (
export const typeCase: SyncRule<TargetCaseType | TargetCaseType[]> = (
parsed,
when = 'always',
value = []
Expand Down
4 changes: 2 additions & 2 deletions @commitlint/rules/src/type-empty.ts
@@ -1,8 +1,8 @@
import * as ensure from '@commitlint/ensure';
import message from '@commitlint/message';
import {Rule} from '@commitlint/types';
import {SyncRule} from '@commitlint/types';

export const typeEmpty: Rule = (parsed, when = 'always') => {
export const typeEmpty: SyncRule = (parsed, when = 'always') => {
const negated = when === 'never';
const notEmpty = ensure.notEmpty(parsed.type || '');
return [
Expand Down

0 comments on commit 4443062

Please sign in to comment.