110 lines
2.8 KiB
Go
110 lines
2.8 KiB
Go
// Copyright 2026 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package repository
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
|
|
activities_model "code.gitea.io/gitea/models/activities"
|
|
repo_model "code.gitea.io/gitea/models/repo"
|
|
user_model "code.gitea.io/gitea/models/user"
|
|
"code.gitea.io/gitea/modules/git"
|
|
"code.gitea.io/gitea/modules/gitrepo"
|
|
"code.gitea.io/gitea/modules/timeutil"
|
|
)
|
|
|
|
const heatmapIndexCommitsPageSize = 100
|
|
|
|
// IndexDefaultBranchHeatmapContributions indexes commit author-date heatmap contributions reachable from repo's default branch.
|
|
func IndexDefaultBranchHeatmapContributions(ctx context.Context, repo *repo_model.Repository) error {
|
|
if repo == nil || repo.ID == 0 {
|
|
return nil
|
|
}
|
|
if repo.DefaultBranch == "" || repo.IsEmpty {
|
|
return activities_model.DeleteStaleHeatmapContributions(ctx, repo.ID, nil)
|
|
}
|
|
|
|
gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, repo)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer closer.Close()
|
|
|
|
head, err := gitRepo.GetBranchCommit(repo.DefaultBranch)
|
|
if git.IsErrNotExist(err) {
|
|
return activities_model.DeleteStaleHeatmapContributions(ctx, repo.ID, nil)
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
currentIdentities := make([]activities_model.HeatmapContributionIdentity, 0)
|
|
now := timeutil.TimeStampNow()
|
|
for page := 1; ; page++ {
|
|
commits, err := head.CommitsByRange(page, heatmapIndexCommitsPageSize, "", "", "")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if len(commits) == 0 {
|
|
break
|
|
}
|
|
|
|
for _, commit := range commits {
|
|
commitSHA := commit.ID.String()
|
|
if commit.Author == nil || commit.Author.Email == "" {
|
|
continue
|
|
}
|
|
|
|
authorUnix := timeutil.TimeStamp(commit.Author.When.Unix())
|
|
if authorUnix > now {
|
|
continue
|
|
}
|
|
|
|
userID, ok, err := getHeatmapAuthorUserIDByEmail(ctx, commit.Author.Email)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if !ok {
|
|
continue
|
|
}
|
|
|
|
if err := activities_model.UpsertHeatmapContribution(ctx, &activities_model.HeatmapContribution{
|
|
UserID: userID,
|
|
RepoID: repo.ID,
|
|
CommitSHA: commitSHA,
|
|
AuthorEmail: strings.ToLower(commit.Author.Email),
|
|
AuthorUnix: authorUnix,
|
|
}); err != nil {
|
|
return err
|
|
}
|
|
currentIdentities = append(currentIdentities, activities_model.HeatmapContributionIdentity{
|
|
RepoID: repo.ID,
|
|
CommitSHA: commitSHA,
|
|
UserID: userID,
|
|
})
|
|
}
|
|
|
|
if len(commits) < heatmapIndexCommitsPageSize {
|
|
break
|
|
}
|
|
}
|
|
|
|
return activities_model.DeleteStaleHeatmapContributions(ctx, repo.ID, currentIdentities)
|
|
}
|
|
|
|
func getHeatmapAuthorUserIDByEmail(ctx context.Context, email string) (int64, bool, error) {
|
|
address, err := user_model.GetEmailAddressByEmail(ctx, email)
|
|
if user_model.IsErrEmailAddressNotExist(err) {
|
|
return 0, false, nil
|
|
}
|
|
if err != nil {
|
|
return 0, false, err
|
|
}
|
|
if !address.IsActivated {
|
|
return 0, false, nil
|
|
}
|
|
return address.UID, true, nil
|
|
}
|