forked from
tangled.org/core
Monorepo for Tangled — https://tangled.org
1package repo
2
3import (
4 "crypto/rand"
5 "math/big"
6 "slices"
7 "sort"
8 "strings"
9
10 "tangled.org/core/appview/db"
11 "tangled.org/core/appview/models"
12 "tangled.org/core/appview/pages/repoinfo"
13 "tangled.org/core/types"
14
15 "github.com/go-git/go-git/v5/plumbing/object"
16)
17
18func sortFiles(files []types.NiceTree) {
19 sort.Slice(files, func(i, j int) bool {
20 iIsFile := files[i].IsFile
21 jIsFile := files[j].IsFile
22 if iIsFile != jIsFile {
23 return !iIsFile
24 }
25 return files[i].Name < files[j].Name
26 })
27}
28
29func sortBranches(branches []types.Branch) {
30 slices.SortFunc(branches, func(a, b types.Branch) int {
31 if a.IsDefault {
32 return -1
33 }
34 if b.IsDefault {
35 return 1
36 }
37 if a.Commit != nil && b.Commit != nil {
38 if a.Commit.Committer.When.Before(b.Commit.Committer.When) {
39 return 1
40 } else {
41 return -1
42 }
43 }
44 return strings.Compare(a.Name, b.Name)
45 })
46}
47
48func uniqueEmails(commits []*object.Commit) []string {
49 emails := make(map[string]struct{})
50 for _, commit := range commits {
51 if commit.Author.Email != "" {
52 emails[commit.Author.Email] = struct{}{}
53 }
54 if commit.Committer.Email != "" {
55 emails[commit.Committer.Email] = struct{}{}
56 }
57 }
58 var uniqueEmails []string
59 for email := range emails {
60 uniqueEmails = append(uniqueEmails, email)
61 }
62 return uniqueEmails
63}
64
65func balanceIndexItems(commitCount, branchCount, tagCount, fileCount int) (commitsTrunc int, branchesTrunc int, tagsTrunc int) {
66 if commitCount == 0 && tagCount == 0 && branchCount == 0 {
67 return
68 }
69
70 // typically 1 item on right side = 2 files in height
71 availableSpace := fileCount / 2
72
73 // clamp tagcount
74 if tagCount > 0 {
75 tagsTrunc = 1
76 availableSpace -= 1 // an extra subtracted for headers etc.
77 }
78
79 // clamp branchcount
80 if branchCount > 0 {
81 branchesTrunc = min(max(branchCount, 1), 3)
82 availableSpace -= branchesTrunc // an extra subtracted for headers etc.
83 }
84
85 // show
86 if commitCount > 0 {
87 commitsTrunc = max(availableSpace, 3)
88 }
89
90 return
91}
92
93func randomString(n int) string {
94 const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
95 result := make([]byte, n)
96
97 for i := 0; i < n; i++ {
98 n, _ := rand.Int(rand.Reader, big.NewInt(int64(len(letters))))
99 result[i] = letters[n.Int64()]
100 }
101
102 return string(result)
103}
104
105// grab pipelines from DB and munge that into a hashmap with commit sha as key
106//
107// golang is so blessed that it requires 35 lines of imperative code for this
108func getPipelineStatuses(
109 d *db.DB,
110 repoInfo repoinfo.RepoInfo,
111 shas []string,
112) (map[string]models.Pipeline, error) {
113 m := make(map[string]models.Pipeline)
114
115 if len(shas) == 0 {
116 return m, nil
117 }
118
119 ps, err := db.GetPipelineStatuses(
120 d,
121 db.FilterEq("repo_owner", repoInfo.OwnerDid),
122 db.FilterEq("repo_name", repoInfo.Name),
123 db.FilterEq("knot", repoInfo.Knot),
124 db.FilterIn("sha", shas),
125 )
126 if err != nil {
127 return nil, err
128 }
129
130 for _, p := range ps {
131 m[p.Sha] = p
132 }
133
134 return m, nil
135}