1// SPDX-License-Identifier: AGPL-3.0-or-later
2
3package web
4
5import (
6 "context"
7 "net/http"
8 "sort"
9
10 "github.com/a-h/templ"
11
12 "bnema.dev/ermite/internal/domain"
13)
14
15// refs lists the branches and the tags of a repository with the commit each
16// designates: branches by name with the default first, tags newest first.
17func (s *Server) refs(ctx context.Context, r *http.Request) (templ.Component, int, error) {
18 d, err := s.loadRepo(ctx, r.PathValue("repo"))
19 if err != nil {
20 return nil, 0, err
21 }
22 p := s.refsPage(ctx, d)
23
24 l := s.repoLayout(ctx, d, "refs")
25 l.Title = "refs · " + d.name() + " · " + s.instance
26 l.Live, l.LiveURL = true, liveURL("repo:"+d.name(), "view=refs")
27 l.Crumbs[0].Current = false
28 l.Crumbs = append(l.Crumbs, Crumb{Label: "refs", Current: true})
29 l.HasRail = true
30 return Refs(l, p), http.StatusOK, nil
31}
32
33// refsPage is the content of the refs page, which the live updates of the
34// page render again.
35func (s *Server) refsPage(ctx context.Context, d *repoData) RefsPage {
36 commits := s.commitsOf(ctx, d.repo.Name, d.allRefs())
37
38 def := d.repo.DefaultBranch
39 p := RefsPage{Default: def}
40 branches := append([]domain.Ref(nil), d.branches...)
41 sort.SliceStable(branches, func(i, j int) bool {
42 a, b := branches[i].ShortName == def, branches[j].ShortName == def
43 return a && !b
44 })
45 for i, b := range branches {
46 p.Branches = append(p.Branches, s.refRow(ctx, d, b, commits, b.ShortName == def, i == 0))
47 }
48 tags := append([]domain.Ref(nil), d.tags...)
49 sort.SliceStable(tags, func(i, j int) bool {
50 return commits[tags[i].CommitID.String()].at > commits[tags[j].CommitID.String()].at
51 })
52 for i, t := range tags {
53 p.Tags = append(p.Tags, s.refRow(ctx, d, t, commits, false, len(p.Branches) == 0 && i == 0))
54 }
55 if len(tags) > 0 {
56 p.Latest = tags[0].ShortName
57 }
58 if d.cut {
59 p.Note = "this repository has more refs than are listed here."
60 }
61 return p
62}
63
64func (s *Server) refRow(ctx context.Context, d *repoData, r domain.Ref, commits map[string]refCommit, isDefault, cursor bool) RefRow {
65 id := r.CommitID.String()
66 c := commits[id]
67 row := RefRow{
68 Name: r.ShortName, Href: repoHref(d.name(), "tree", r.ShortName),
69 Short: short(id), Subject: c.subject, When: c.when, WhenAt: c.whenAt,
70 Default: isDefault, Cursor: cursor,
71 }
72 if id != "" {
73 row.CHref = repoHref(d.name(), "commit", id)
74 row.Checks = checksSummary(d.repo.Name, id, s.checksFor(ctx, d.repo.Name, id))
75 }
76 return row
77}