internal/httpd/facts.go

58 lines · 1613 bytes

 1package httpd
 2
 3import (
 4	"gitbay.org/gitbay/internal/control"
 5	"gitbay.org/gitbay/internal/gitutil"
 6)
 7
 8// repoFacts is the "what is this repository" summary on a repo home: the
 9// counts a visitor uses to size up a project before reading any code.
10type repoFacts struct {
11	Commits      int
12	Branches     int
13	Tags         int
14	Contributors []factContributor
15	Languages    []gitutil.Language
16	License      string
17	Release      string // newest release tag, if any
18	Build        string // latest build status on the default branch
19}
20
21type factContributor struct {
22	Name    string
23	User    string // account, when the email is verified here
24	Email   string
25	Commits int
26}
27
28const maxContributors = 12
29
30func (s *Server) factsFor(p repoPage) repoFacts {
31	f := repoFacts{
32		Commits: gitutil.CountCommits(p.Dir, p.Ref),
33		License: control.DetectLicense(p.Dir, p.Ref),
34	}
35	if heads, err := gitutil.Refs(p.Dir, "heads"); err == nil {
36		f.Branches = len(heads)
37	}
38	if tags, err := gitutil.Refs(p.Dir, "tags"); err == nil {
39		f.Tags = len(tags)
40	}
41	f.Languages = gitutil.Languages(p.Dir, p.Ref, langOf)
42
43	names := s.authorNames()
44	for _, c := range gitutil.Contributors(p.Dir, p.Ref, maxContributors) {
45		user, _ := names.account(c.Email)
46		f.Contributors = append(f.Contributors, factContributor{
47			Name: names.name(c.Email, c.Name), User: user, Email: c.Email, Commits: c.Commits,
48		})
49	}
50
51	if rels, err := s.st.ListReleases(p.Repo.ID); err == nil && len(rels) > 0 {
52		f.Release = rels[0].Tag
53	}
54	if builds, err := s.st.ListBuilds(p.Repo.ID, 1); err == nil && len(builds) > 0 {
55		f.Build = builds[0].Status
56	}
57	return f
58}