Skip to content

Commit 2932f07

Browse files
committed
rewrite parse submodule
1 parent f96ddce commit 2932f07

File tree

3 files changed

+96
-32
lines changed

3 files changed

+96
-32
lines changed

modules/git/commit.go

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,13 @@ import (
99
"bytes"
1010
"context"
1111
"errors"
12-
"fmt"
1312
"io"
1413
"os/exec"
1514
"strconv"
1615
"strings"
1716

1817
"code.gitea.io/gitea/modules/log"
1918
"code.gitea.io/gitea/modules/util"
20-
21-
"github.com/go-git/go-git/v5/config"
2219
)
2320

2421
// Commit represents a git commit.
@@ -373,34 +370,20 @@ func (c *Commit) GetSubModules() (*ObjectCache, error) {
373370
return nil, err
374371
}
375372

376-
content, err := entry.Blob().GetBlobContent(10 * 1024)
373+
rd, err := entry.Blob().DataAsync()
377374
if err != nil {
378375
return nil, err
379376
}
377+
defer rd.Close()
380378

381-
c.submoduleCache, err = parseSubmoduleContent([]byte(content))
379+
r := io.LimitReader(rd, 100*1024) // limit to 100KB
380+
c.submoduleCache, err = parseSubmoduleContent(r)
382381
if err != nil {
383382
return nil, err
384383
}
385384
return c.submoduleCache, nil
386385
}
387386

388-
func parseSubmoduleContent(bs []byte) (*ObjectCache, error) {
389-
cfg := config.NewModules()
390-
if err := cfg.Unmarshal(bs); err != nil {
391-
return nil, err
392-
}
393-
submoduleCache := newObjectCache()
394-
if len(cfg.Submodules) == 0 {
395-
return nil, fmt.Errorf("no submodules found")
396-
}
397-
for _, subModule := range cfg.Submodules {
398-
submoduleCache.Set(subModule.Path, subModule.URL)
399-
}
400-
401-
return submoduleCache, nil
402-
}
403-
404387
// GetSubModule get the sub module according entryname
405388
func (c *Commit) GetSubModule(entryname string) (*SubModule, error) {
406389
modules, err := c.GetSubModules()

modules/git/commit_test.go

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -365,30 +365,45 @@ func Test_GetCommitBranchStart(t *testing.T) {
365365

366366
func Test_parseSubmoduleContent(t *testing.T) {
367367
submoduleFiles := []struct {
368-
fileContent string
369-
expectedPath string
370-
expectedURL string
368+
fileContent string
369+
expectedPath string
370+
expectedURL string
371+
expectedBranch string
371372
}{
372373
{
373374
fileContent: `[submodule "jakarta-servlet"]
374375
url = ../../ALP-pool/jakarta-servlet
375376
path = jakarta-servlet`,
376-
expectedPath: "jakarta-servlet",
377-
expectedURL: "../../ALP-pool/jakarta-servlet",
377+
expectedPath: "jakarta-servlet",
378+
expectedURL: "../../ALP-pool/jakarta-servlet",
379+
expectedBranch: "",
378380
},
379381
{
380382
fileContent: `[submodule "jakarta-servlet"]
381383
path = jakarta-servlet
382384
url = ../../ALP-pool/jakarta-servlet`,
383-
expectedPath: "jakarta-servlet",
384-
expectedURL: "../../ALP-pool/jakarta-servlet",
385+
expectedPath: "jakarta-servlet",
386+
expectedURL: "../../ALP-pool/jakarta-servlet",
387+
expectedBranch: "",
388+
},
389+
{
390+
fileContent: `[submodule "jakarta-servlet"]
391+
path = jakarta-servlet
392+
url = ../../ALP-pool/jakarta-servlet
393+
branch = stable`,
394+
expectedPath: "jakarta-servlet",
395+
expectedURL: "../../ALP-pool/jakarta-servlet",
396+
expectedBranch: "stable",
385397
},
386398
}
387399
for _, kase := range submoduleFiles {
388-
submodule, err := parseSubmoduleContent([]byte(kase.fileContent))
400+
submodule, err := parseSubmoduleContent(strings.NewReader(kase.fileContent))
389401
assert.NoError(t, err)
390402
v, ok := submodule.Get(kase.expectedPath)
391403
assert.True(t, ok)
392-
assert.Equal(t, kase.expectedURL, v)
404+
subModule := v.(*SubModule)
405+
assert.Equal(t, kase.expectedPath, subModule.Path)
406+
assert.Equal(t, kase.expectedURL, subModule.URL)
407+
assert.Equal(t, kase.expectedBranch, subModule.Branch)
393408
}
394409
}

modules/git/submodule.go

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
package git
66

77
import (
8+
"bufio"
89
"fmt"
10+
"io"
911
"net"
1012
"net/url"
1113
"path"
@@ -17,8 +19,72 @@ var scpSyntax = regexp.MustCompile(`^([a-zA-Z0-9_]+@)?([a-zA-Z0-9._-]+):(.*)$`)
1719

1820
// SubModule submodule is a reference on git repository
1921
type SubModule struct {
20-
Name string
21-
URL string
22+
Path string
23+
URL string
24+
Branch string
25+
}
26+
27+
// parseSubmoduleContent this is not a complete parse for gitmodules file, it only
28+
// parses the url and path of submodules
29+
func parseSubmoduleContent(r io.Reader) (*ObjectCache, error) {
30+
var path, url, branch string
31+
var state int // 0: find section, 1: find path and url
32+
subModules := newObjectCache()
33+
scanner := bufio.NewScanner(r)
34+
for scanner.Scan() {
35+
line := strings.TrimSpace(scanner.Text())
36+
37+
// Skip empty lines and comments
38+
if line == "" || strings.HasPrefix(line, "#") || strings.HasPrefix(line, ";") {
39+
continue
40+
}
41+
42+
// Section header [section]
43+
if strings.HasPrefix(line, "[submodule") && strings.HasSuffix(line, "]") {
44+
subModules.Set(path, &SubModule{
45+
Path: path,
46+
URL: url,
47+
Branch: branch,
48+
})
49+
state = 1
50+
path = ""
51+
url = ""
52+
branch = ""
53+
continue
54+
}
55+
56+
if state != 1 {
57+
continue
58+
}
59+
60+
parts := strings.SplitN(line, "=", 2)
61+
if len(parts) != 2 {
62+
continue
63+
}
64+
key := strings.TrimSpace(parts[0])
65+
value := strings.TrimSpace(parts[1])
66+
switch key {
67+
case "path":
68+
path = value
69+
case "url":
70+
url = value
71+
case "branch":
72+
branch = value
73+
}
74+
}
75+
76+
if err := scanner.Err(); err != nil {
77+
return nil, fmt.Errorf("error reading file: %w", err)
78+
}
79+
if path != "" && url != "" {
80+
subModules.Set(path, &SubModule{
81+
Path: path,
82+
URL: url,
83+
Branch: branch,
84+
})
85+
}
86+
87+
return subModules, nil
2288
}
2389

2490
// SubModuleFile represents a file with submodule type.

0 commit comments

Comments
 (0)