1package file
2
3import (
4 "errors"
5 "os"
6 "path/filepath"
7 "strconv"
8 "strings"
9
10 "github.com/charmbracelet/soft-serve/git"
11 "github.com/charmbracelet/soft-serve/proto"
12)
13
14type key int
15
16const (
17 projectName key = iota
18 description
19 private
20)
21
22var keys = map[key]string{
23 projectName: "soft-serve.projectName",
24 description: "soft-serve.description",
25 private: "soft-serve.private",
26}
27
28var _ proto.Provider = &File{}
29
30// File is a file-based repository provider.
31type File struct {
32 repoPath string
33}
34
35// New returns a new File provider.
36func New(repoPath string) *File {
37 f := &File{
38 repoPath: repoPath,
39 }
40 return f
41}
42
43// Open opens a new repository and returns a new FileRepo.
44func (f *File) Open(name string) (proto.RepositoryService, error) {
45 fp := filepath.Join(f.repoPath, name)
46 r, err := git.Open(fp)
47 if errors.Is(err, os.ErrNotExist) {
48 r, err = git.Open(fp + ".git")
49 }
50 if err != nil {
51 return nil, err
52 }
53 return &FileRepo{r}, nil
54}
55
56var _ proto.Repository = &FileRepo{}
57
58// FileRepo is a file-based repository.
59type FileRepo struct { // nolint:revive
60 repo *git.Repository
61}
62
63// Name returns the name of the repository.
64func (r *FileRepo) Name() string {
65 return strings.TrimSuffix(r.repo.Name(), ".git")
66}
67
68// ProjectName returns the project name of the repository.
69func (r *FileRepo) ProjectName() string {
70 pn, err := r.repo.Config(keys[projectName])
71 if err != nil {
72 return ""
73 }
74 return pn
75}
76
77// SetProjectName sets the project name of the repository.
78func (r *FileRepo) SetProjectName(name string) error {
79 return r.repo.SetConfig(keys[projectName], name)
80}
81
82// Description returns the description of the repository.
83func (r *FileRepo) Description() string {
84 desc, err := r.repo.Config(keys[description])
85 if err != nil {
86 return ""
87 }
88 return desc
89}
90
91// SetDescription sets the description of the repository.
92func (r *FileRepo) SetDescription(desc string) error {
93 return r.repo.SetConfig(keys[description], desc)
94}
95
96// IsPrivate returns whether the repository is private.
97func (r *FileRepo) IsPrivate() bool {
98 p, err := r.repo.Config(keys[private])
99 if err != nil {
100 return false
101 }
102 return p == "true"
103}
104
105// SetPrivate sets whether the repository is private.
106func (r *FileRepo) SetPrivate(p bool) error {
107 return r.repo.SetConfig(keys[private], strconv.FormatBool(p))
108}