diff --git a/modules/packages/maven/metadata.go b/modules/packages/maven/metadata.go index 42aa250718..fa48b4e0d7 100644 --- a/modules/packages/maven/metadata.go +++ b/modules/packages/maven/metadata.go @@ -7,6 +7,7 @@ import ( "encoding/xml" "io" + "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/validation" "golang.org/x/net/html/charset" @@ -49,8 +50,16 @@ type pomStruct struct { Version string `xml:"version"` Scope string `xml:"scope"` } `xml:"dependencies>dependency"` + Parent struct { + GroupID string `xml:"groupId"` + ArtifactID string `xml:"artifactId"` + Version string `xml:"version"` + RelativePath string `xml:"relativePath"` + } `xml:"parent"` } +var ErrNoGroupID = util.NewInvalidArgumentErrorf("group ID is missing") + // ParsePackageMetaData parses the metadata of a pom file func ParsePackageMetaData(r io.Reader) (*Metadata, error) { var pom pomStruct @@ -65,6 +74,17 @@ func ParsePackageMetaData(r io.Reader) (*Metadata, error) { pom.URL = "" } + groupID := pom.GroupID + + if groupID == "" { + // If a project inherits from a parent project, the groupId element is optional. + // Refer to: https://maven.apache.org/pom.html#Inheritance + if pom.Parent.GroupID == "" { + return nil, ErrNoGroupID + } + groupID = pom.Parent.GroupID + } + licenses := make([]string, 0, len(pom.Licenses)) for _, l := range pom.Licenses { if l.Name != "" { @@ -82,7 +102,7 @@ func ParsePackageMetaData(r io.Reader) (*Metadata, error) { } return &Metadata{ - GroupID: pom.GroupID, + GroupID: groupID, ArtifactID: pom.ArtifactID, Name: pom.Name, Description: pom.Description, diff --git a/modules/packages/maven/metadata_test.go b/modules/packages/maven/metadata_test.go index d0093013f9..3b087989e6 100644 --- a/modules/packages/maven/metadata_test.go +++ b/modules/packages/maven/metadata_test.go @@ -14,6 +14,7 @@ import ( const ( groupID = "org.gitea" + parentGroupID = "org.gitea.parent" artifactID = "my-project" version = "1.0.1" name = "My Gitea Project" @@ -27,6 +28,11 @@ const ( const pomContent = ` + + ` + parentGroupID + ` + parent-project + 1.0.0 + ` + groupID + ` ` + artifactID + ` ` + version + ` @@ -47,6 +53,24 @@ const pomContent = ` ` +const pomWithParentGroupID = ` + + + ` + parentGroupID + ` + parent-project + 1.0.0 + + + ` + artifactID + ` + ` + version + ` +` + +const pomWithMissingGroupID = ` + + ` + artifactID + ` + ` + version + ` +` + func TestParsePackageMetaData(t *testing.T) { t.Run("InvalidFile", func(t *testing.T) { m, err := ParsePackageMetaData(strings.NewReader("")) @@ -87,4 +111,19 @@ func TestParsePackageMetaData(t *testing.T) { require.NoError(t, err) assert.NotNil(t, m) }) + + t.Run("UseParentGroupID", func(t *testing.T) { + m, err := ParsePackageMetaData(strings.NewReader(pomWithParentGroupID)) + require.NoError(t, err) + assert.NotNil(t, m) + + assert.Equal(t, parentGroupID, m.GroupID) + }) + + t.Run("MissingGroupIDThrowsError", func(t *testing.T) { + m, err := ParsePackageMetaData(strings.NewReader(pomWithMissingGroupID)) + assert.Nil(t, m) + require.Error(t, err) + assert.Equal(t, ErrNoGroupID, err) + }) }