+60
-2
knotserver/git/git.go
+60
-2
knotserver/git/git.go
···
3
3
import (
4
4
"archive/tar"
5
5
"bytes"
6
+
"errors"
6
7
"fmt"
7
8
"io"
8
9
"io/fs"
···
12
13
"time"
13
14
14
15
"github.com/go-git/go-git/v5"
16
+
"github.com/go-git/go-git/v5/config"
15
17
"github.com/go-git/go-git/v5/plumbing"
16
18
"github.com/go-git/go-git/v5/plumbing/object"
17
19
)
18
20
19
21
var (
20
-
ErrBinaryFile = fmt.Errorf("binary file")
21
-
ErrNotBinaryFile = fmt.Errorf("not binary file")
22
+
ErrBinaryFile = errors.New("binary file")
23
+
ErrNotBinaryFile = errors.New("not binary file")
24
+
ErrMissingGitModules = errors.New("no .gitmodules file found")
25
+
ErrInvalidGitModules = errors.New("invalid .gitmodules file")
26
+
ErrNotSubmodule = errors.New("path is not a submodule")
22
27
)
23
28
24
29
type GitRepo struct {
···
188
193
defer reader.Close()
189
194
190
195
return io.ReadAll(reader)
196
+
}
197
+
198
+
// read and parse .gitmodules
199
+
func (g *GitRepo) Submodules() (*config.Modules, error) {
200
+
c, err := g.r.CommitObject(g.h)
201
+
if err != nil {
202
+
return nil, fmt.Errorf("commit object: %w", err)
203
+
}
204
+
205
+
tree, err := c.Tree()
206
+
if err != nil {
207
+
return nil, fmt.Errorf("tree: %w", err)
208
+
}
209
+
210
+
// read .gitmodules file
211
+
modulesEntry, err := tree.FindEntry(".gitmodules")
212
+
if err != nil {
213
+
return nil, fmt.Errorf("%w: %w", ErrMissingGitModules, err)
214
+
}
215
+
216
+
modulesFile, err := tree.TreeEntryFile(modulesEntry)
217
+
if err != nil {
218
+
return nil, fmt.Errorf("%w: failed to read file: %w", ErrInvalidGitModules, err)
219
+
}
220
+
221
+
content, err := modulesFile.Contents()
222
+
if err != nil {
223
+
return nil, fmt.Errorf("%w: failed to read contents: %w", ErrInvalidGitModules, err)
224
+
}
225
+
226
+
// parse .gitmodules
227
+
modules := config.NewModules()
228
+
if err = modules.Unmarshal([]byte(content)); err != nil {
229
+
return nil, fmt.Errorf("%w: failed to parse: %w", ErrInvalidGitModules, err)
230
+
}
231
+
232
+
return modules, nil
233
+
}
234
+
235
+
func (g *GitRepo) Submodule(path string) (*config.Submodule, error) {
236
+
modules, err := g.Submodules()
237
+
if err != nil {
238
+
return nil, err
239
+
}
240
+
241
+
for _, submodule := range modules.Submodules {
242
+
if submodule.Path == path {
243
+
return submodule, nil
244
+
}
245
+
}
246
+
247
+
// path is not a submodule
248
+
return nil, ErrNotSubmodule
191
249
}
192
250
193
251
func (g *GitRepo) Branch(name string) (*plumbing.Reference, error) {