From 7ee2b0a8ff25fc79bc78fe9a2afe9b6c1e3af622 Mon Sep 17 00:00:00 2001 From: Nikita Elfimov Date: Mon, 23 Dec 2024 15:27:26 +0300 Subject: [PATCH] feat(code-commit): support getting project scopes (#466) --- code/code-commit/src/commit.linter.ts | 49 +++++++++++++++++-- .../sources/commit-message-lint.command.ts | 25 +++++++--- 2 files changed, 64 insertions(+), 10 deletions(-) diff --git a/code/code-commit/src/commit.linter.ts b/code/code-commit/src/commit.linter.ts index 7e820134..b5fdf27b 100644 --- a/code/code-commit/src/commit.linter.ts +++ b/code/code-commit/src/commit.linter.ts @@ -1,6 +1,9 @@ -import type { LintOutcome } from '@commitlint/types' import type { FormattableReport } from '@commitlint/types' +import type { LintOptions } from '@commitlint/types' +import { RuleConfigSeverity } from '@commitlint/types' +import { LintOutcome } from '@commitlint/types' +import { QualifiedRules } from '@commitlint/types' import { format } from '@commitlint/format/lib/format.js' import commitlint from '@commitlint/lint' @@ -15,11 +18,29 @@ const defaultParserOpts = { revertCorrespondence: ['header', 'hash'], } +const options: LintOptions = { + parserOpts: defaultParserOpts, +} + +interface CommitLinterOptions { + scopes?: Array + workspaceNames?: Array +} + export class CommitLinter { + readonly scopes?: Array + + readonly workspaceNames?: Array + + constructor({ scopes, workspaceNames }: CommitLinterOptions) { + this.scopes = scopes + this.workspaceNames = workspaceNames + } + async lint(message: string): Promise { - return commitlint(message, rules, { - parserOpts: defaultParserOpts, - }) + const lintRules = this.prepareConfig(rules) + + return commitlint(message, lintRules, options) } format( @@ -30,4 +51,24 @@ export class CommitLinter { ): string { return format(report, options) } + + /** + * Prepares config, including scopes + */ + private prepareConfig(rules: QualifiedRules) { + const allowedScopes = [] + + if (this.scopes) { + allowedScopes.push(...this.scopes.filter((scope) => scope && scope !== 'atls')) + } + + if (this.workspaceNames) { + allowedScopes.push(...this.workspaceNames.filter((workspaceName) => workspaceName)) + } + + const possibleScopeValuesArray = ['common', 'github', ...allowedScopes] + rules['scope-enum'] = [RuleConfigSeverity.Error, 'always', possibleScopeValuesArray] + + return rules + } } diff --git a/yarn/plugin-commit/sources/commit-message-lint.command.ts b/yarn/plugin-commit/sources/commit-message-lint.command.ts index 61110e0d..4a1730b5 100644 --- a/yarn/plugin-commit/sources/commit-message-lint.command.ts +++ b/yarn/plugin-commit/sources/commit-message-lint.command.ts @@ -1,16 +1,29 @@ -import { BaseCommand } from '@yarnpkg/cli' +import { BaseCommand } from '@yarnpkg/cli' +import { Configuration } from '@yarnpkg/core' +import { Project } from '@yarnpkg/core' -import { CommitLinter } from '@atls/code-commit' -import { read } from '@atls/code-commit' +import { CommitLinter } from '@atls/code-commit' +import { read } from '@atls/code-commit' class CommitMessageLintCommand extends BaseCommand { - static paths = [['commit', 'message', 'lint']] + static override paths = [['commit', 'message', 'lint']] async execute(): Promise { - const linter = new CommitLinter() + const configuration = await Configuration.find(this.context.cwd, this.context.plugins) + const { + project: { workspaces }, + } = await Project.find(configuration, this.context.cwd) + + const workspaceNames = new Set(workspaces.map(({ manifest }) => manifest.name?.name ?? '')) + const scopes = new Set(workspaces.map(({ manifest }) => manifest.name?.scope ?? '')) + + const linter = new CommitLinter({ + scopes: Array.from(scopes), + workspaceNames: Array.from(workspaceNames), + }) const messages = await read({ edit: true }) - const results = await Promise.all(messages.map(linter.lint)) + const results = await Promise.all(messages.map((message) => linter.lint(message))) const output = linter.format({ results })