Skip to content

Commit

Permalink
Working on 30d commits history (#8)
Browse files Browse the repository at this point in the history
* Working on 30d commits history

* working on commits history

* fix

* working on commit history

* add unique commit authors
  • Loading branch information
emanuelef committed Nov 21, 2023
1 parent 4763f8f commit eae6e80
Show file tree
Hide file tree
Showing 3 changed files with 183 additions and 13 deletions.
6 changes: 3 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,16 @@ func main() {

ctx := context.Background()

result, _ = clientGQL.GetAllStats(ctx, "ceccopierangiolieugenio/pyTermTk")
fmt.Println(result)

// repoTest := "kubernetes/kubernetes"
// repoTest := "agnivade/levenshtein"
repoTest := "mattn/go-colorable"

result, _ = clientGQL.GetAllStats(ctx, repoTest)
fmt.Println(result)

result, _ = clientGQL.GetAllStats(ctx, "ceccopierangiolieugenio/pyTermTk")
fmt.Println(result)

allStars, _ := clientGQL.GetAllStarsHistory(ctx, repoTest, result.CreatedAt, nil)
// fmt.Println(allStars)
fmt.Println(time.Time(allStars[len(allStars)-1].Day))
Expand Down
152 changes: 142 additions & 10 deletions repostats/gqlstats.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,129 @@ func (c *ClientGQL) getStarsHistory(ctx context.Context, owner, name string, tot
return result, nil
}

func (c *ClientGQL) getCommitsShortHistory(ctx context.Context, owner, name string, totalCommits int) (stats.CommitsHistory, error) {
result := stats.CommitsHistory{}

ctx, span := tracer.Start(ctx, "fetch-short-commits")
defer span.End()

if totalCommits == 0 {
return result, nil
}

currentTime := time.Now()

var uniqueAuthors = make(map[string]struct{})

variablesCommits := map[string]any{
"owner": githubv4.String(owner),
"name": githubv4.String(name),
"commitsCursor": (*githubv4.String)(nil),
}

type commit struct {
Node struct {
Author struct {
User struct {
Id string
}
}
CommittedDate time.Time
Additions int
}
}

var queryCommits struct {
Repository struct {
DefaultBranchRef struct {
Name string
Target struct {
Commit struct {
History struct {
Edges []commit
PageInfo struct {
EndCursor githubv4.String
HasNextPage bool
}
} `graphql:"history(first: 100, after: $commitsCursor)"`
} `graphql:"... on Commit"`
}
}
} `graphql:"repository(owner: $owner, name: $name)"`
}

for i := 1; i < 31; i++ {
result.CommitsTimeline = append(result.CommitsTimeline, stats.CommitsPerDay{Day: stats.JSONDay(currentTime.AddDate(0, 0, -(30 - i)).Truncate(24 * time.Hour))})
}

for {
err := c.query(ctx, &queryCommits, variablesCommits)
if err != nil {
return result, err
}

// fmt.Println("Desc:", len(queryStars.Repository.Stargazers.Edges))

res := queryCommits.Repository.DefaultBranchRef.Target.Commit.History.Edges

if len(res) > 0 && result.LastCommitDate.IsZero() {
result.LastCommitDate = res[0].Node.CommittedDate
}

moreThan30daysFlag := false

for _, star := range res {
days := currentTime.Sub(star.Node.CommittedDate).Hours() / 24

if days > 30 {
moreThan30daysFlag = true
break
}

if days <= 1 {
result.AddedLast24H += 1
}

if days <= 7 {
result.AddedLast7d += 1
}

if days <= 14 {
result.AddedLast14d += 1
}

if days <= 30 {
result.AddedLast30d += 1
}

result.CommitsTimeline[29-int(days)].Commits += 1
uniqueAuthors[star.Node.Author.User.Id] = struct{}{}
}

if !queryCommits.Repository.DefaultBranchRef.Target.Commit.History.PageInfo.HasNextPage || moreThan30daysFlag {
break
}

variablesCommits["commitsCursor"] = githubv4.NewString(queryCommits.Repository.DefaultBranchRef.Target.Commit.History.PageInfo.EndCursor)
}

if totalCommits > 0 {
result.AddedPerMille30d = 1000 * (float32(result.AddedLast30d) / float32(totalCommits))
}

result.DifferentAuthors = len(uniqueAuthors)

for i := len(result.CommitsTimeline) - 1; i >= 0; i-- {
if i == len(result.CommitsTimeline)-1 {
result.CommitsTimeline[i].TotalCommits = totalCommits
} else {
result.CommitsTimeline[i].TotalCommits = result.CommitsTimeline[i+1].TotalCommits - result.CommitsTimeline[i+1].Commits
}
}

return result, nil
}

func (c *ClientGQL) GetAllStarsHistoryTwoWays(ctx context.Context, ghRepo string, updateChannel chan<- int) ([]stats.StarsPerDay, error) {
repoSplit := strings.Split(ghRepo, "/")

Expand Down Expand Up @@ -585,6 +708,7 @@ func (c *ClientGQL) GetAllStats(ctx context.Context, ghRepo string) (*stats.Repo
result.GHPath = ghRepo
result.CreatedAt = query.Repository.CreatedAt
result.Stars = query.Repository.StargazerCount
result.Commits = query.Repository.DefaultBranchRef.Target.Commit.History.TotalCount
result.DefaultBranch = query.Repository.DefaultBranchRef.Name
result.Archived = query.Repository.IsArchived
result.Forks = query.Repository.ForkCount
Expand All @@ -602,12 +726,20 @@ func (c *ClientGQL) GetAllStats(ctx context.Context, ghRepo string) (*stats.Repo
result.LastReleaseDate = releases[0].Node.CreatedAt
}

// 30d stars history
result.StarsHistory, err = c.getStarsHistory(ctx, repoSplit[0], repoSplit[1], result.Stars)
if err != nil {
log.Printf("%v\n", err)
return &result, err
}

// 30d commits history
result.CommitsHistory, err = c.getCommitsShortHistory(ctx, repoSplit[0], repoSplit[1], result.Commits)
if err != nil {
log.Printf("%v\n", err)
return &result, err
}

if depFetcher := deps.CreateFetcher(result.Language); depFetcher != nil {
depFetcher.GetDepsList(ctx, c.restyClient, ghRepo, &result)
}
Expand Down Expand Up @@ -666,40 +798,40 @@ func getLivenessScore(ctx context.Context, restyClient *resty.Client, ghRepo str
}

switch {
case result.AddedLast30d > 20:
case result.StarsHistory.AddedLast30d > 20:
score += 10
break
case result.AddedLast30d > 10:
case result.StarsHistory.AddedLast30d > 10:
score += 6
break
case result.AddedLast30d > 1:
case result.StarsHistory.AddedLast30d > 1:
score += 2
break
}

switch {
case result.AddedLast14d > 50:
case result.StarsHistory.AddedLast14d > 50:
score += 30
break
case result.AddedLast14d > 30:
case result.StarsHistory.AddedLast14d > 30:
score += 20
break
case result.AddedLast14d > 20:
case result.StarsHistory.AddedLast14d > 20:
score += 10
break
case result.AddedLast14d > 5:
case result.StarsHistory.AddedLast14d > 5:
score += 5
break
}

switch {
case result.AddedLast24H > 30:
case result.StarsHistory.AddedLast24H > 30:
score += 10
break
case result.AddedLast24H > 20:
case result.StarsHistory.AddedLast24H > 20:
score += 5
break
case result.AddedLast24H > 5:
case result.StarsHistory.AddedLast24H > 5:
score += 2
break
}
Expand Down
38 changes: 38 additions & 0 deletions stats/stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ type StarsPerDay struct {
TotalStars int
}

type CommitsPerDay struct {
Day JSONDay
Commits int
TotalCommits int
}

func (t StarsPerDay) MarshalJSON() ([]byte, error) {
return json.Marshal([]any{t.Day, t.Stars, t.TotalStars})
}
Expand All @@ -38,6 +44,34 @@ type StarsHistory struct {
StarsTimeline []StarsPerDay
}

type CommitsHistory struct {
AddedLast24H int
AddedLast7d int
AddedLast14d int
AddedLast30d int
LastCommitDate time.Time
AddedPerMille30d float32
CommitsTimeline []CommitsPerDay
DifferentAuthors int
}

func (sh CommitsHistory) String() string {
return fmt.Sprintf(`Last Commit Date: %s
Commits Different Authors %d
Commits AddedLast24H: %d
Commits AddedLast7d: %d
Commits AddedLast14d: %d
Commits AddedLast30d: %d
Commits AddedPerMille30d: %.2f`,
sh.LastCommitDate,
sh.DifferentAuthors,
sh.AddedLast24H,
sh.AddedLast7d,
sh.AddedLast14d,
sh.AddedLast30d,
sh.AddedPerMille30d)
}

func (sh StarsHistory) String() string {
return fmt.Sprintf(`Last Star Date: %s
Stars AddedLast24H: %d
Expand All @@ -55,6 +89,7 @@ Stars AddedPerMille30d: %.2f`, sh.LastStarDate,
type RepoStats struct {
GHPath string
Stars int
Commits int
Size int
Language string
OpenIssues int
Expand All @@ -67,6 +102,7 @@ type RepoStats struct {
LastReleaseDate time.Time
LivenessScore float32
StarsHistory
CommitsHistory
GoRepo
}

Expand All @@ -85,6 +121,7 @@ Archived: %t
Mentionable Users: %d
Default Branch: %s
%s
%s
Liveness Score: %.2f
Go version: %s
Go Direct dependencies: %d
Expand All @@ -101,6 +138,7 @@ Go Direct dependencies: %d
rs.MentionableUsers,
rs.DefaultBranch,
rs.StarsHistory,
rs.CommitsHistory,
rs.LivenessScore,
rs.GoVersion,
len(rs.DirectDeps))
Expand Down

0 comments on commit eae6e80

Please sign in to comment.