Files

145 lines
4.6 KiB
C#

namespace MarketAlly.GitCommitEditor.Models.HistoryHealth;
/// <summary>
/// Represents a group of duplicate commits.
/// </summary>
public sealed class DuplicateCommitGroup
{
public required string CanonicalMessage { get; init; }
public required IReadOnlyList<string> CommitHashes { get; init; }
public required DuplicateType Type { get; init; }
public int InstanceCount => CommitHashes.Count;
}
/// <summary>
/// Metrics for duplicate commit detection.
/// </summary>
public sealed class DuplicateCommitMetrics
{
public int TotalCommitsAnalyzed { get; init; }
public int TotalDuplicateGroups { get; init; }
public int TotalDuplicateInstances { get; init; }
public int ExactDuplicates { get; init; }
public int CherryPicks { get; init; }
public int FuzzyMatches { get; init; }
public IReadOnlyList<DuplicateCommitGroup> DuplicateGroups { get; init; } = [];
public double DuplicateRatio => TotalCommitsAnalyzed > 0
? (double)TotalDuplicateInstances / TotalCommitsAnalyzed * 100
: 0;
}
/// <summary>
/// Metrics for merge commit analysis.
/// </summary>
public sealed class MergeCommitMetrics
{
public int TotalCommits { get; init; }
public int TotalMerges { get; init; }
public int TrivialMerges { get; init; }
public int ConflictMerges { get; init; }
public int MergeFixCommits { get; init; }
public int NullMerges { get; init; }
public double AverageMergeComplexity { get; init; }
public IReadOnlyList<string> MessyMergePatterns { get; init; } = [];
public IReadOnlyList<string> MergeFixCommitHashes { get; init; } = [];
public int MergeRatio => TotalCommits > 0
? (int)Math.Round((double)TotalMerges / TotalCommits * 100)
: 0;
}
/// <summary>
/// Metrics for branch complexity analysis.
/// </summary>
public sealed class BranchComplexityMetrics
{
public int TotalBranches { get; init; }
public int ActiveBranches { get; init; }
public int StaleBranches { get; init; }
public int CrossMerges { get; init; }
public double AverageBranchAge { get; init; }
public double AverageBranchLength { get; init; }
public int LongLivedBranches { get; init; }
public BranchTopologyType Topology { get; init; }
public IReadOnlyList<string> StaleBranchNames { get; init; } = [];
}
/// <summary>
/// A cluster of commits with similar quality scores.
/// </summary>
public sealed class QualityCluster
{
public DateTimeOffset StartDate { get; init; }
public DateTimeOffset EndDate { get; init; }
public int CommitCount { get; init; }
public double AverageScore { get; init; }
public string? PossibleCause { get; init; }
}
/// <summary>
/// Distribution of commit message quality scores.
/// </summary>
public sealed class MessageQualityDistribution
{
public int TotalCommits { get; init; }
public int Excellent { get; init; }
public int Good { get; init; }
public int Fair { get; init; }
public int Poor { get; init; }
public double AverageScore { get; init; }
public double MedianScore { get; init; }
public double StandardDeviation { get; init; }
public TrendDirection Trend { get; init; }
public IReadOnlyList<QualityCluster> Clusters { get; init; } = [];
public IReadOnlyList<string> PoorCommitHashes { get; init; } = [];
}
/// <summary>
/// Statistics for a single author.
/// </summary>
public sealed class AuthorStats
{
public required string Name { get; init; }
public required string Email { get; init; }
public int CommitCount { get; init; }
public double AverageMessageQuality { get; init; }
public int MergeCommitCount { get; init; }
}
/// <summary>
/// Metrics for authorship analysis.
/// </summary>
public sealed class AuthorshipMetrics
{
public int TotalAuthors { get; init; }
public int TotalCommits { get; init; }
public int MissingEmailCount { get; init; }
public int InvalidEmailCount { get; init; }
public int BotCommits { get; init; }
public IReadOnlyDictionary<string, AuthorStats> AuthorBreakdown { get; init; }
= new Dictionary<string, AuthorStats>();
}
/// <summary>
/// Component scores breakdown.
/// </summary>
public sealed class ComponentScores
{
public int DuplicateScore { get; init; }
public int MergeScore { get; init; }
public int BranchScore { get; init; }
public int MessageScore { get; init; }
public int AuthorshipScore { get; init; }
}
/// <summary>
/// Overall health score with breakdown.
/// </summary>
public sealed class HealthScore
{
public int OverallScore { get; init; }
public HealthGrade Grade { get; init; }
public required ComponentScores ComponentScores { get; init; }
}