cerrado @ 19839337ce0c74b67c5480b71e98d97a112aa104

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