Skip to content

Commit

Permalink
fix: unify rule config types
Browse files Browse the repository at this point in the history
  • Loading branch information
marionebl committed Feb 9, 2020
1 parent a0c4bb3 commit 6fea4cf
Show file tree
Hide file tree
Showing 13 changed files with 178 additions and 139 deletions.
Empty file modified @commitlint/cli/cli.js 100644 → 100755
Empty file.
11 changes: 5 additions & 6 deletions @commitlint/cli/src/cli.ts
Expand Up @@ -13,7 +13,8 @@ import {
LintOutcome,
ParserOptions,
ParserPreset,
QualifiedConfig
QualifiedConfig,
Formatter
} from '@commitlint/types';
import {CliError} from './cli-error';

Expand Down Expand Up @@ -177,7 +178,7 @@ async function main(options: CliFlags) {

const results = await Promise.all(
// TODO: validate why those types do not match
messages.map(message => lint(message, loaded.rules as any, opts))
messages.map(message => lint(message, loaded.rules, opts))
);

if (Object.keys(loaded.rules).length === 0) {
Expand Down Expand Up @@ -338,10 +339,8 @@ function selectParserOpts(parserPreset: ParserPreset) {
return parserPreset.parserOpts;
}

function loadFormatter(config: QualifiedConfig, flags: CliFlags) {
// TODO: validate why formatter is unknown????
const moduleName: string =
flags.format || (config.formatter as any) || '@commitlint/format';
function loadFormatter(config: QualifiedConfig, flags: CliFlags): Formatter {
const moduleName = flags.format || config.formatter || '@commitlint/format';
const modulePath =
resolveFrom.silent(__dirname, moduleName) ||
resolveFrom.silent(flags.cwd, moduleName) ||
Expand Down
1 change: 1 addition & 0 deletions @commitlint/format/package.json
Expand Up @@ -37,6 +37,7 @@
"@commitlint/utils": "^8.3.4"
},
"dependencies": {
"@commitlint/types": "^8.3.5",
"chalk": "^3.0.0"
}
}
38 changes: 8 additions & 30 deletions @commitlint/format/src/format.ts
@@ -1,41 +1,19 @@
import chalk from 'chalk';
import {
ChalkColor,
FormattableReport,
FormatOptions,
FormattableResult,
WithInput
} from '@commitlint/types';

const DEFAULT_SIGNS = [' ', '⚠', '✖'] as const;
const DEFAULT_COLORS = ['white', 'yellow', 'red'] as const;

export interface FormattableProblem {
level: 0 | 1 | 2;
name: string;
message: string;
}

export interface FormattableResult {
errors?: FormattableProblem[];
warnings?: FormattableProblem[];
}

export interface WithInput {
input?: string;
}

export interface FormattableReport {
results?: (FormattableResult & WithInput)[];
}

export type ChalkColor = keyof typeof chalk;

export interface FormatOptions {
color?: boolean;
signs?: readonly [string, string, string];
colors?: readonly [ChalkColor, ChalkColor, ChalkColor];
verbose?: boolean;
helpUrl?: string;
}

export function format(
report: FormattableReport = {},
options: FormatOptions = {}
) {
): string {
const {results = []} = report;
const fi = (result: FormattableResult & WithInput) =>
formatInput(result, options);
Expand Down
3 changes: 2 additions & 1 deletion @commitlint/format/tsconfig.json
Expand Up @@ -6,5 +6,6 @@
"outDir": "./lib"
},
"include": ["./src"],
"exclude": ["./src/**/*.test.ts", "./lib/**/*"]
"exclude": ["./src/**/*.test.ts", "./lib/**/*"],
"references": [{"path": "../types"}]
}
4 changes: 2 additions & 2 deletions @commitlint/lint/src/lint.test.ts
Expand Up @@ -125,8 +125,8 @@ test('throws for rule with invalid level', async () => {

test('throws for rule with out of range level', async () => {
const error = lint('type(scope): foo', {
'type-enum': [-1, 'always'],
'header-max-length': [3, 'always']
'type-enum': [-1, 'always'] as any,
'header-max-length': [3, 'always'] as any
});

await expect(error).rejects.toThrow('rule type-enum must be between 0 and 2');
Expand Down
15 changes: 7 additions & 8 deletions @commitlint/lint/src/lint.ts
Expand Up @@ -4,17 +4,17 @@ import parse from '@commitlint/parse';
import defaultRules from '@commitlint/rules';
import {buildCommitMesage} from './commit-message';
import {
LintRuleConfig,
LintOptions,
LintOutcome,
LintRuleOutcome,
Rule,
RuleSeverity
RuleConfigSeverity,
QualifiedRules
} from '@commitlint/types';

export default async function lint(
message: string,
rawRulesConfig?: LintRuleConfig,
rawRulesConfig?: QualifiedRules,
rawOpts?: LintOptions
): Promise<LintOutcome> {
const opts = rawOpts
Expand Down Expand Up @@ -76,7 +76,7 @@ export default async function lint(

const [level] = config;

if (level === RuleSeverity.Disabled && config.length === 1) {
if (level === RuleConfigSeverity.Disabled && config.length === 1) {
return null;
}

Expand Down Expand Up @@ -132,10 +132,10 @@ export default async function lint(

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

// Level 0 rules are ignored
if (level === 0) {
Expand All @@ -148,8 +148,7 @@ export default async function lint(
throw new Error(`Could not find rule implementation for ${name}`);
}

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

return {
level,
Expand Down
37 changes: 37 additions & 0 deletions @commitlint/types/src/format.ts
@@ -0,0 +1,37 @@
import chalk from 'chalk';
import {QualifiedRules} from './load';
import {RuleConfigSeverity} from './rules';

export type Formatter = (
report: FormattableReport,
options: FormatOptions
) => string;

export interface FormattableProblem {
level: RuleConfigSeverity;
name: keyof QualifiedRules;
message: string;
}

export interface FormattableResult {
errors?: FormattableProblem[];
warnings?: FormattableProblem[];
}

export interface WithInput {
input?: string;
}

export interface FormattableReport {
results?: (FormattableResult & WithInput)[];
}

export type ChalkColor = keyof typeof chalk;

export interface FormatOptions {
color?: boolean;
signs?: readonly [string, string, string];
colors?: readonly [ChalkColor, ChalkColor, ChalkColor];
verbose?: boolean;
helpUrl?: string;
}
1 change: 1 addition & 0 deletions @commitlint/types/src/index.ts
@@ -1,4 +1,5 @@
export * from './ensure';
export * from './format';
export * from './is-ignored';
export * from './rules';
export * from './lint';
Expand Down
7 changes: 4 additions & 3 deletions @commitlint/types/src/lint.ts
@@ -1,10 +1,11 @@
import {IsIgnoredOptions} from './is-ignored';
import {RuleConfigTuple, PluginRecords, RuleSeverity} from './load';
import {PluginRecords} from './load';
import {ParserOptions} from './parse';
import {RuleConfigSeverity, RuleConfigTuple} from './rules';

export type LintRuleConfig = Record<
string,
| Readonly<[RuleSeverity.Disabled]>
| Readonly<[RuleConfigSeverity.Disabled]>
| RuleConfigTuple<void>
| RuleConfigTuple<unknown>
>;
Expand Down Expand Up @@ -35,7 +36,7 @@ export interface LintRuleOutcome {
/** If the commit is considered valid for the rule */
valid: boolean;
/** The "severity" of the rule (1 = warning, 2 = error) */
level: RuleSeverity;
level: RuleConfigSeverity;
/** The name of the rule */
name: string;
/** The message returned from the rule, if invalid */
Expand Down
84 changes: 4 additions & 80 deletions @commitlint/types/src/load.ts
@@ -1,5 +1,4 @@
import {TargetCaseType} from './ensure';
import {Rule, RuleCondition} from './rules';
import {Rule, RulesConfig, RuleConfigQuality} from './rules';

export type PluginRecords = Record<string, Plugin>;

Expand All @@ -14,84 +13,9 @@ export interface LoadOptions {
file?: string;
}

export enum RuleSeverity {
Disabled = 0,
Warning = 1,
Error = 2
}

export type RuleConfigTuple<T> = T extends void
? Readonly<[RuleSeverity, RuleCondition]>
: Readonly<[RuleSeverity, RuleCondition, T]>;

export enum RuleConfigQuality {
User,
Qualified
}

export type QualifiedRuleConfig<T> =
| (() => RuleConfigTuple<T>)
| (() => RuleConfigTuple<Promise<T>>)
| RuleConfigTuple<T>;

export type RuleConfig<
V = RuleConfigQuality.Qualified,
T = void
> = V extends RuleConfigQuality.Qualified
? RuleConfigTuple<T>
: QualifiedRuleConfig<T>;

export type CaseRuleConfig<V = RuleConfigQuality.User> = RuleConfig<
V,
TargetCaseType
>;
export type LengthRuleConfig<V = RuleConfigQuality.User> = RuleConfig<
V,
number
>;
export type EnumRuleConfig<V = RuleConfigQuality.User> = RuleConfig<
V,
string[]
>;

export type RulesConfig<V = RuleConfigQuality.User> = {
'body-case': CaseRuleConfig<V>;
'body-empty': RuleConfig<V>;
'body-leading-blank': RuleConfig<V>;
'body-max-length': LengthRuleConfig<V>;
'body-max-line-length': LengthRuleConfig<V>;
'body-min-length': LengthRuleConfig<V>;
'footer-empty': RuleConfig<V>;
'footer-leading-blank': RuleConfig<V>;
'footer-max-length': LengthRuleConfig<V>;
'footer-max-line-length': LengthRuleConfig<V>;
'footer-min-length': LengthRuleConfig<V>;
'header-case': CaseRuleConfig<V>;
'header-full-stop': RuleConfig<V>;
'header-max-length': LengthRuleConfig<V>;
'header-min-length': LengthRuleConfig<V>;
'references-empty': RuleConfig<V>;
'scope-case': CaseRuleConfig<V>;
'scope-empty': RuleConfig<V>;
'scope-enum': EnumRuleConfig<V>;
'scope-max-length': LengthRuleConfig<V>;
'scope-min-length': LengthRuleConfig<V>;
'signed-off-by': RuleConfig<V>;
'subject-case': CaseRuleConfig<V>;
'subject-empty': RuleConfig<V>;
'subject-full-stop': RuleConfig<V>;
'subject-max-length': LengthRuleConfig<V>;
'subject-min-length': LengthRuleConfig<V>;
'type-case': CaseRuleConfig<V>;
'type-empty': RuleConfig<V>;
'type-enum': EnumRuleConfig<V>;
'type-max-length': LengthRuleConfig<V>;
'type-min-length': LengthRuleConfig<V>;
};

export interface UserConfig {
extends?: string[];
formatter?: unknown;
formatter?: string;
rules?: Partial<RulesConfig>;
parserPreset?: string | ParserPreset;
ignores?: ((commit: string) => boolean)[];
Expand All @@ -101,7 +25,7 @@ export interface UserConfig {

export interface UserPreset {
extends?: string[];
formatter?: unknown;
formatter?: string;
rules?: Partial<RulesConfig>;
parserPreset?: string | ParserPreset;
ignores?: ((commit: string) => boolean)[];
Expand All @@ -113,7 +37,7 @@ export type QualifiedRules = Partial<RulesConfig<RuleConfigQuality.Qualified>>;

export interface QualifiedConfig {
extends: string[];
formatter: unknown;
formatter: string;
rules: QualifiedRules;
parserPreset: ParserPreset;
ignores: ((commit: string) => boolean)[];
Expand Down

0 comments on commit 6fea4cf

Please sign in to comment.