Skip to content

Commit a79b7fe

Browse files
authored
Regex patterns are not efficient enough (#242)
1 parent f97ecd0 commit a79b7fe

File tree

2 files changed

+144
-23
lines changed

2 files changed

+144
-23
lines changed

commands/utils/mavenutils.go

+52-23
Original file line numberDiff line numberDiff line change
@@ -8,51 +8,80 @@ import (
88
"strings"
99
)
1010

11+
const (
12+
modulePattern = "<module>(\\S|\\s)*?<\\/module>"
13+
dependenciesPattern = "(<dependency>(\\S|\\s)*?<\\/dependency>)|(<plugin>(\\S|\\s)*?<\\/plugin>)"
14+
)
15+
16+
var (
17+
moduleRegexp = regexp.MustCompile(modulePattern)
18+
dependenciesRegexp = regexp.MustCompile(dependenciesPattern)
19+
)
20+
1121
func GetVersionProperties(projectPath string, depToPropertyMap map[string][]string) error {
1222
contentBytes, err := os.ReadFile(filepath.Join(projectPath, "pom.xml")) // #nosec G304
1323
if err != nil {
1424
return err
1525
}
16-
dependenciesPattern := "(<dependency>(.|\\s)*?<\\/dependency>)|(<plugin>(.|\\s)*?<\\/plugin>)"
17-
dependenciesRegexp, err := regexp.Compile(dependenciesPattern)
26+
mavenDependencies, err := getDependenciesFromPomXml(contentBytes)
1827
if err != nil {
1928
return err
2029
}
21-
dependencyStrings := dependenciesRegexp.FindAll(contentBytes, -1)
22-
for _, depStr := range dependencyStrings {
23-
dep := &mavenDependency{}
24-
err = xml.Unmarshal(depStr, dep)
25-
if err != nil {
26-
return err
27-
}
28-
depName := dep.GroupId + ":" + dep.ArtifactId
30+
for _, mavenDependency := range mavenDependencies {
31+
depName := mavenDependency.GroupId + ":" + mavenDependency.ArtifactId
2932
if _, exist := depToPropertyMap[depName]; !exist {
3033
depToPropertyMap[depName] = []string{}
3134
}
32-
if strings.HasPrefix(dep.Version, "${") {
33-
depToPropertyMap[depName] = append(depToPropertyMap[dep.GroupId+":"+dep.ArtifactId], strings.TrimPrefix(strings.TrimSuffix(dep.Version, "}"), "${"))
35+
if strings.HasPrefix(mavenDependency.Version, "${") {
36+
depToPropertyMap[depName] = append(depToPropertyMap[mavenDependency.GroupId+":"+mavenDependency.ArtifactId], strings.TrimPrefix(strings.TrimSuffix(mavenDependency.Version, "}"), "${"))
3437
}
3538
}
3639

37-
modulePattern := "<module>(.|\\s)*?<\\/module>"
38-
moduleRegexp, err := regexp.Compile(modulePattern)
39-
if err != nil {
40-
return err
41-
}
42-
moduleStrings := moduleRegexp.FindAllString(string(contentBytes), -1)
43-
for _, moduleStr := range moduleStrings {
44-
modulePath := strings.TrimPrefix(strings.TrimSuffix(moduleStr, "</module>"), "<module>")
45-
modulePath = strings.TrimSpace(modulePath)
46-
err = GetVersionProperties(filepath.Join(projectPath, modulePath), depToPropertyMap)
47-
if err != nil {
40+
for _, moduleStr := range getMavenModuleFromPomXml(contentBytes) {
41+
if err = GetVersionProperties(filepath.Join(projectPath, moduleStr), depToPropertyMap); err != nil {
4842
return err
4943
}
5044
}
5145
return nil
5246
}
5347

48+
// Extract all dependencies from the input pom.xml
49+
// pomXmlContent - The pom.xml content
50+
func getDependenciesFromPomXml(pomXmlContent []byte) ([]mavenDependency, error) {
51+
var results []mavenDependency
52+
dependencyStrings := dependenciesRegexp.FindAll(pomXmlContent, -1)
53+
for _, depStr := range dependencyStrings {
54+
dep := &mavenDependency{}
55+
err := xml.Unmarshal(depStr, dep)
56+
if err != nil {
57+
return []mavenDependency{}, err
58+
}
59+
dep.trimSpaces()
60+
results = append(results, *dep)
61+
}
62+
return results, nil
63+
}
64+
65+
// Extract all modules from pom.xml
66+
// pomXmlContent - The pom.xml content
67+
func getMavenModuleFromPomXml(pomXmlContent []byte) []string {
68+
var results []string
69+
moduleStrings := moduleRegexp.FindAllString(string(pomXmlContent), -1)
70+
for _, moduleStr := range moduleStrings {
71+
modulePath := strings.TrimPrefix(strings.TrimSuffix(moduleStr, "</module>"), "<module>")
72+
results = append(results, strings.TrimSpace(modulePath))
73+
}
74+
return results
75+
}
76+
5477
type mavenDependency struct {
5578
GroupId string `xml:"groupId"`
5679
ArtifactId string `xml:"artifactId"`
5780
Version string `xml:"version"`
5881
}
82+
83+
func (md *mavenDependency) trimSpaces() {
84+
md.GroupId = strings.TrimSpace(md.GroupId)
85+
md.ArtifactId = strings.TrimSpace(md.ArtifactId)
86+
md.Version = strings.TrimSpace(md.Version)
87+
}

commands/utils/mavenutils_test.go

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package utils
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func TestGetDependenciesFromPomXmlSingleDependency(t *testing.T) {
10+
testCases := []string{`<dependency>
11+
<groupId>org.apache.commons</groupId>
12+
<artifactId>commons-email</artifactId>
13+
<version>1.1</version>
14+
<scope>compile</scope>
15+
</dependency>`,
16+
`<dependency>
17+
<groupId> org.apache.commons</groupId>
18+
<artifactId>commons-email </artifactId>
19+
<version> 1.1 </version>
20+
<scope> compile </scope>
21+
</dependency>`,
22+
}
23+
24+
for _, testCase := range testCases {
25+
result, err := getDependenciesFromPomXml([]byte(testCase))
26+
assert.NoError(t, err)
27+
28+
assert.Len(t, result, 1)
29+
assert.Equal(t, "org.apache.commons", result[0].GroupId)
30+
assert.Equal(t, "commons-email", result[0].ArtifactId)
31+
assert.Equal(t, "1.1", result[0].Version)
32+
}
33+
}
34+
35+
func TestGetDependenciesFromPomXmlMultiDependency(t *testing.T) {
36+
testCases := []string{`<dependencies>
37+
<dependency>
38+
<groupId>org.apache.commons</groupId>
39+
<artifactId>commons-email</artifactId>
40+
<version>1.1</version>
41+
<scope>compile</scope>
42+
</dependency>
43+
<dependency>
44+
<groupId>org.codehaus.plexus</groupId>
45+
<artifactId>plexus-utils</artifactId>
46+
<version>1.5.1</version>
47+
</dependency>
48+
</dependencies>`,
49+
`<dependencies><dependency><groupId>org.apache.commons</groupId><artifactId>commons-email</artifactId>
50+
<version>1.1</version><scope>compile</scope>
51+
</dependency>
52+
53+
some-xml-tags
54+
55+
<dependency>
56+
<groupId>org.codehaus.plexus</groupId>
57+
<artifactId>plexus-utils</artifactId>
58+
<version>1.5.1</version>
59+
</dependency></dependencies>`,
60+
}
61+
62+
for _, testCase := range testCases {
63+
result, err := getDependenciesFromPomXml([]byte(testCase))
64+
assert.NoError(t, err)
65+
66+
assert.Len(t, result, 2)
67+
assert.Equal(t, "org.apache.commons", result[0].GroupId)
68+
assert.Equal(t, "commons-email", result[0].ArtifactId)
69+
assert.Equal(t, "1.1", result[0].Version)
70+
71+
assert.Equal(t, "org.codehaus.plexus", result[1].GroupId)
72+
assert.Equal(t, "plexus-utils", result[1].ArtifactId)
73+
assert.Equal(t, "1.5.1", result[1].Version)
74+
}
75+
}
76+
77+
func TestGetMavenModuleFromPomXml(t *testing.T) {
78+
testCases := []string{`<module>multi-1</module>`, ` <module> multi-1 </module> `}
79+
for _, testCase := range testCases {
80+
modules := getMavenModuleFromPomXml([]byte(testCase))
81+
assert.ElementsMatch(t, modules, []string{"multi-1"})
82+
}
83+
}
84+
85+
func TestGetMavenModuleFromPomXmlMultiModules(t *testing.T) {
86+
testCases := []string{`<module>multi-1</module><module>multi-2</module>`,
87+
`<module>multi-1</module> some-xml-tags <module>multi-2</module>`}
88+
for _, testCase := range testCases {
89+
modules := getMavenModuleFromPomXml([]byte(testCase))
90+
assert.ElementsMatch(t, modules, []string{"multi-1", "multi-2"})
91+
}
92+
}

0 commit comments

Comments
 (0)