classifyCommit method

ClassifiedCommit classifyCommit(
  1. GitCommit commit
)

Classifies a single GitCommit.

Implementation

ClassifiedCommit classifyCommit(GitCommit commit) {
  final subject = commit.subject.trim();
  final body = commit.body.trim();

  final match = _conventionalRegex.firstMatch(subject);

  bool isBreaking = false;
  String? breakingDescription;
  bool isRevert = subject.toLowerCase().startsWith('revert');

  // Check breaking change indicators
  if (subject.contains('!:') ||
      subject.contains('BREAKING CHANGE:') ||
      body.contains('BREAKING CHANGE:') ||
      body.contains('BREAKING-CHANGE:')) {
    isBreaking = true;
    if (body.contains('BREAKING CHANGE:')) {
      final idx = body.indexOf('BREAKING CHANGE:');
      breakingDescription =
          body.substring(idx + 'BREAKING CHANGE:'.length).trim();
    } else if (body.contains('BREAKING-CHANGE:')) {
      final idx = body.indexOf('BREAKING-CHANGE:');
      breakingDescription =
          body.substring(idx + 'BREAKING-CHANGE:'.length).trim();
    } else {
      breakingDescription = subject;
    }
  }

  if (match != null) {
    final type = match.namedGroup('type')!.toLowerCase();
    final scope = match.namedGroup('scope');
    final desc = match.namedGroup('description')!.trim();
    final breakingFlag = match.namedGroup('breaking') != null;

    if (breakingFlag) isBreaking = true;

    final cleanDesc =
        scope != null && scope.isNotEmpty ? '**$scope:** $desc' : desc;

    CommitCategory category;
    switch (type) {
      case 'feat':
        category = CommitCategory.features;
        break;
      case 'fix':
        category = CommitCategory.bugFixes;
        break;
      case 'perf':
        category = CommitCategory.performance;
        break;
      case 'refactor':
        category = CommitCategory.refactoring;
        break;
      case 'docs':
        category = CommitCategory.documentation;
        break;
      case 'test':
        category = CommitCategory.tests;
        break;
      case 'build':
      case 'ci':
        category = CommitCategory.buildCi;
        break;
      case 'revert':
        category = CommitCategory.otherChanges;
        isRevert = true;
        break;
      case 'chore':
      case 'style':
      default:
        category = CommitCategory.otherChanges;
        break;
    }

    return ClassifiedCommit(
      commit: commit,
      category: category,
      cleanDescription: cleanDesc,
      isBreaking: isBreaking,
      breakingDescription: breakingDescription,
      isRevert: isRevert,
    );
  }

  // Fallback for non-conventional commit messages
  return ClassifiedCommit(
    commit: commit,
    category: CommitCategory.otherChanges,
    cleanDescription: subject,
    isBreaking: isBreaking,
    breakingDescription: breakingDescription,
    isRevert: isRevert,
  );
}