1package service
2
3import (
4 "log/slog"
5 "os"
6 "path"
7
8 "git.gabrielgio.me/cerrado/pkg/config"
9 "git.gabrielgio.me/cerrado/pkg/git"
10 "git.gabrielgio.me/cerrado/pkg/u"
11 "github.com/go-git/go-git/v5/plumbing"
12 "github.com/go-git/go-git/v5/plumbing/object"
13)
14
15type (
16 Repository struct {
17 Name string
18 Title string
19 Description string
20 LastCommitDate string
21 Ref string
22 }
23
24 GitService struct {
25 configRepo configurationRepository
26 }
27
28 configurationRepository interface {
29 List() []*config.GitRepositoryConfiguration
30 GetByName(name string) *config.GitRepositoryConfiguration
31 }
32)
33
34// TODO: make it configurable
35const timeFormat = "2006.01.02 15:04:05"
36
37func NewGitService(configRepo configurationRepository) *GitService {
38 return &GitService{
39 configRepo: configRepo,
40 }
41}
42
43func (g *GitService) ListRepositories() ([]*Repository, error) {
44 rs := g.configRepo.List()
45
46 repos := make([]*Repository, len(rs))
47 for i, r := range rs {
48 repo, err := git.OpenRepository(r.Path)
49 if err != nil {
50 return nil, err
51 }
52
53 obj, err := repo.LastCommit()
54 if err != nil {
55 return nil, err
56 }
57
58 head, err := repo.Head()
59 if err != nil {
60 return nil, err
61 }
62
63 d := path.Join(r.Path, "description")
64 description := ""
65 if u.FileExist(d) {
66 if b, err := os.ReadFile(d); err == nil {
67 description = string(b)
68 } else {
69 slog.Error("Error loading description file", "err", err)
70 }
71 }
72
73 baseName := path.Base(r.Path)
74 repos[i] = &Repository{
75 Name: baseName,
76 Title: baseName,
77 Description: description,
78 LastCommitDate: obj.Author.When.Format(timeFormat),
79 Ref: head.Name().Short(),
80 }
81 }
82
83 return repos, nil
84}
85
86func (g *GitService) ListCommits(name, ref string) ([]*object.Commit, error) {
87 // TODO: handle nil
88 r := g.configRepo.GetByName(name)
89
90 repo, err := git.OpenRepository(r.Path)
91 if err != nil {
92 return nil, err
93 }
94
95 err = repo.SetRef(ref)
96 if err != nil {
97 return nil, err
98 }
99 return repo.Commits()
100}
101
102func (g *GitService) GetTree(name, ref, path string) (*object.Tree, error) {
103 // TODO: handle nil
104 r := g.configRepo.GetByName(name)
105
106 repo, err := git.OpenRepository(r.Path)
107 if err != nil {
108 return nil, err
109 }
110 err = repo.SetRef(ref)
111 if err != nil {
112 return nil, err
113 }
114
115 return repo.Tree(path)
116}
117
118func (g *GitService) GetFileContent(name, ref, path string) (string, error) {
119 // TODO: handle nil
120 r := g.configRepo.GetByName(name)
121
122 repo, err := git.OpenRepository(r.Path)
123 if err != nil {
124 return "", err
125 }
126 err = repo.SetRef(ref)
127 if err != nil {
128 return "", err
129 }
130
131 return repo.FileContent(path)
132}
133
134func (g *GitService) ListTags(name string) ([]*object.Tag, error) {
135 // TODO: handle nil
136 r := g.configRepo.GetByName(name)
137
138 repo, err := git.OpenRepository(r.Path)
139 if err != nil {
140 return nil, err
141 }
142 return repo.Tags()
143}
144
145func (g *GitService) ListBranches(name string) ([]*plumbing.Reference, error) {
146 // TODO: handle nil
147 r := g.configRepo.GetByName(name)
148
149 repo, err := git.OpenRepository(r.Path)
150 if err != nil {
151 return nil, err
152 }
153 return repo.Branches()
154}
155
156func (g *GitService) GetHead(name string) (*plumbing.Reference, error) {
157 // TODO: handle nil
158 r := g.configRepo.GetByName(name)
159
160 repo, err := git.OpenRepository(r.Path)
161 if err != nil {
162 return nil, err
163 }
164
165 return repo.Head()
166}