mirror of
https://github.com/lukaszraczylo/git-velocity.git
synced 2026-06-11 23:19:24 +00:00
Initial commit.
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
|
||||
// PRState represents the state of a pull request
|
||||
type PRState string
|
||||
|
||||
const (
|
||||
PRStateOpen PRState = "open"
|
||||
PRStateClosed PRState = "closed"
|
||||
PRStateMerged PRState = "merged"
|
||||
)
|
||||
|
||||
// PullRequest represents a GitHub pull request
|
||||
type PullRequest struct {
|
||||
Number int `json:"number"`
|
||||
Title string `json:"title"`
|
||||
State PRState `json:"state"`
|
||||
Author Author `json:"author"`
|
||||
Repository string `json:"repository"` // owner/repo format
|
||||
BaseBranch string `json:"base_branch"` // Target branch (e.g., main, master)
|
||||
HeadBranch string `json:"head_branch"` // Source branch
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
MergedAt *time.Time `json:"merged_at,omitempty"`
|
||||
ClosedAt *time.Time `json:"closed_at,omitempty"`
|
||||
Additions int `json:"additions"`
|
||||
Deletions int `json:"deletions"`
|
||||
FilesChanged int `json:"files_changed"`
|
||||
CommitCount int `json:"commit_count"`
|
||||
Comments int `json:"comments"`
|
||||
Reviews []Review `json:"reviews,omitempty"`
|
||||
URL string `json:"url"`
|
||||
|
||||
// Derived fields
|
||||
TimeToMerge *time.Duration `json:"time_to_merge,omitempty"`
|
||||
TimeToFirstReview *time.Duration `json:"time_to_first_review,omitempty"`
|
||||
}
|
||||
|
||||
// IsMerged returns true if the PR has been merged
|
||||
func (pr *PullRequest) IsMerged() bool {
|
||||
return pr.State == PRStateMerged || pr.MergedAt != nil
|
||||
}
|
||||
|
||||
// TotalChanges returns the total lines changed (additions + deletions)
|
||||
func (pr *PullRequest) TotalChanges() int {
|
||||
return pr.Additions + pr.Deletions
|
||||
}
|
||||
|
||||
// CalculateTimeToMerge calculates the time from PR creation to merge
|
||||
func (pr *PullRequest) CalculateTimeToMerge() *time.Duration {
|
||||
if pr.MergedAt == nil {
|
||||
return nil
|
||||
}
|
||||
d := pr.MergedAt.Sub(pr.CreatedAt)
|
||||
return &d
|
||||
}
|
||||
|
||||
// CalculateTimeToFirstReview calculates the time from PR creation to first review
|
||||
func (pr *PullRequest) CalculateTimeToFirstReview() *time.Duration {
|
||||
if len(pr.Reviews) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
var firstReview *time.Time
|
||||
for _, review := range pr.Reviews {
|
||||
if firstReview == nil || review.SubmittedAt.Before(*firstReview) {
|
||||
t := review.SubmittedAt
|
||||
firstReview = &t
|
||||
}
|
||||
}
|
||||
|
||||
if firstReview == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
d := firstReview.Sub(pr.CreatedAt)
|
||||
return &d
|
||||
}
|
||||
|
||||
// PRSize represents the size category of a pull request
|
||||
type PRSize string
|
||||
|
||||
const (
|
||||
PRSizeXS PRSize = "xs" // < 10 lines
|
||||
PRSizeS PRSize = "s" // 10-50 lines
|
||||
PRSizeM PRSize = "m" // 50-200 lines
|
||||
PRSizeL PRSize = "l" // 200-500 lines
|
||||
PRSizeXL PRSize = "xl" // > 500 lines
|
||||
)
|
||||
|
||||
// Size returns the size category of the PR based on total changes
|
||||
func (pr *PullRequest) Size() PRSize {
|
||||
total := pr.TotalChanges()
|
||||
switch {
|
||||
case total < 10:
|
||||
return PRSizeXS
|
||||
case total < 50:
|
||||
return PRSizeS
|
||||
case total < 200:
|
||||
return PRSizeM
|
||||
case total < 500:
|
||||
return PRSizeL
|
||||
default:
|
||||
return PRSizeXL
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user