cerrado @ v0.0.2

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