145 lines
4.6 KiB
C#
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; }
|
|
}
|