diff --git a/compose_files/pulp/assets/maven-fixture/foo/bar/1.2.3.rhlw-00001/foo.bar.1.2.3.rhlw-00001.jar b/compose_files/pulp/assets/maven-fixture/foo/bar/1.2.3.rhlw-00001/foo.bar.1.2.3.rhlw-00001.jar
new file mode 100644
index 0000000..518a38a
Binary files /dev/null and b/compose_files/pulp/assets/maven-fixture/foo/bar/1.2.3.rhlw-00001/foo.bar.1.2.3.rhlw-00001.jar differ
diff --git a/compose_files/pulp/assets/maven-fixture/foo/bar/1.2.3/foo.bar.1.2.3.pom b/compose_files/pulp/assets/maven-fixture/foo/bar/1.2.3.rhlw-00001/foo.bar.1.2.3.rhlw-00001.pom
similarity index 83%
rename from compose_files/pulp/assets/maven-fixture/foo/bar/1.2.3/foo.bar.1.2.3.pom
rename to compose_files/pulp/assets/maven-fixture/foo/bar/1.2.3.rhlw-00001/foo.bar.1.2.3.rhlw-00001.pom
index 3745968..6130be7 100644
--- a/compose_files/pulp/assets/maven-fixture/foo/bar/1.2.3/foo.bar.1.2.3.pom
+++ b/compose_files/pulp/assets/maven-fixture/foo/bar/1.2.3.rhlw-00001/foo.bar.1.2.3.rhlw-00001.pom
@@ -3,5 +3,5 @@
4.0.0
foo
bar
- 1.2.3
+ 1.2.3.rhlw-00001
diff --git a/compose_files/pulp/assets/maven-fixture/foo/bar/1.2.3.rhlw-00002/foo.bar.1.2.3.rhlw-00002.jar b/compose_files/pulp/assets/maven-fixture/foo/bar/1.2.3.rhlw-00002/foo.bar.1.2.3.rhlw-00002.jar
new file mode 100644
index 0000000..518a38a
Binary files /dev/null and b/compose_files/pulp/assets/maven-fixture/foo/bar/1.2.3.rhlw-00002/foo.bar.1.2.3.rhlw-00002.jar differ
diff --git a/compose_files/pulp/assets/maven-fixture/foo/bar/2.0.1/foo.bar.2.0.1.pom b/compose_files/pulp/assets/maven-fixture/foo/bar/1.2.3.rhlw-00002/foo.bar.1.2.3.rhlw-00002.pom
similarity index 83%
rename from compose_files/pulp/assets/maven-fixture/foo/bar/2.0.1/foo.bar.2.0.1.pom
rename to compose_files/pulp/assets/maven-fixture/foo/bar/1.2.3.rhlw-00002/foo.bar.1.2.3.rhlw-00002.pom
index 29f7623..b97e0aa 100644
--- a/compose_files/pulp/assets/maven-fixture/foo/bar/2.0.1/foo.bar.2.0.1.pom
+++ b/compose_files/pulp/assets/maven-fixture/foo/bar/1.2.3.rhlw-00002/foo.bar.1.2.3.rhlw-00002.pom
@@ -3,5 +3,5 @@
4.0.0
foo
bar
- 2.0.1
+ 1.2.3.rhlw-00002
diff --git a/compose_files/pulp/assets/maven-fixture/foo/bar/1.2.3/foo.bar.1.2.3.rhlw-00001.jar b/compose_files/pulp/assets/maven-fixture/foo/bar/1.2.3/foo.bar.1.2.3.rhlw-00001.jar
deleted file mode 100644
index e979a54..0000000
Binary files a/compose_files/pulp/assets/maven-fixture/foo/bar/1.2.3/foo.bar.1.2.3.rhlw-00001.jar and /dev/null differ
diff --git a/compose_files/pulp/assets/maven-fixture/foo/bar/1.2.3/foo.bar.1.2.3.rhlw-00002.jar b/compose_files/pulp/assets/maven-fixture/foo/bar/1.2.3/foo.bar.1.2.3.rhlw-00002.jar
deleted file mode 100644
index e979a54..0000000
Binary files a/compose_files/pulp/assets/maven-fixture/foo/bar/1.2.3/foo.bar.1.2.3.rhlw-00002.jar and /dev/null differ
diff --git a/compose_files/pulp/assets/maven-fixture/foo/bar/2.0.1.rhlw-00001/foo.bar.2.0.1.rhlw-00001.jar b/compose_files/pulp/assets/maven-fixture/foo/bar/2.0.1.rhlw-00001/foo.bar.2.0.1.rhlw-00001.jar
new file mode 100644
index 0000000..97203b3
Binary files /dev/null and b/compose_files/pulp/assets/maven-fixture/foo/bar/2.0.1.rhlw-00001/foo.bar.2.0.1.rhlw-00001.jar differ
diff --git a/compose_files/pulp/assets/maven-fixture/foo/bar/2.0.1.rhlw-00001/foo.bar.2.0.1.rhlw-00001.pom b/compose_files/pulp/assets/maven-fixture/foo/bar/2.0.1.rhlw-00001/foo.bar.2.0.1.rhlw-00001.pom
new file mode 100644
index 0000000..c82bb4b
--- /dev/null
+++ b/compose_files/pulp/assets/maven-fixture/foo/bar/2.0.1.rhlw-00001/foo.bar.2.0.1.rhlw-00001.pom
@@ -0,0 +1,7 @@
+
+
+ 4.0.0
+ foo
+ bar
+ 2.0.1.rhlw-00001
+
diff --git a/compose_files/pulp/assets/maven-fixture/foo/bar/2.0.1/foo.bar.2.0.1.rhlw-00001.jar b/compose_files/pulp/assets/maven-fixture/foo/bar/2.0.1/foo.bar.2.0.1.rhlw-00001.jar
deleted file mode 100644
index e979a54..0000000
Binary files a/compose_files/pulp/assets/maven-fixture/foo/bar/2.0.1/foo.bar.2.0.1.rhlw-00001.jar and /dev/null differ
diff --git a/internal/test/integration/maven_test.go b/internal/test/integration/maven_test.go
index 99dd24a..8534b79 100644
--- a/internal/test/integration/maven_test.go
+++ b/internal/test/integration/maven_test.go
@@ -22,16 +22,18 @@ const (
testMavenContentOrigin = "http://localhost:8088"
testMavenGroupID = "foo"
testMavenArtifactID = "bar"
- testMavenVersion123 = "1.2.3"
- testMavenVersion201 = "2.0.1"
+ testMavenBuildVersion123R1 = "1.2.3.rhlw-00001"
+ testMavenBuildVersion123R2 = "1.2.3.rhlw-00002"
+ testMavenBuildVersion201R1 = "2.0.1.rhlw-00001"
)
var testMavenArtifactPaths = []string{
- "foo/bar/1.2.3/foo.bar.1.2.3.pom",
- "foo/bar/1.2.3/foo.bar.1.2.3.rhlw-00001.jar",
- "foo/bar/1.2.3/foo.bar.1.2.3.rhlw-00002.jar",
- "foo/bar/2.0.1/foo.bar.2.0.1.pom",
- "foo/bar/2.0.1/foo.bar.2.0.1.rhlw-00001.jar",
+ "foo/bar/1.2.3.rhlw-00001/foo.bar.1.2.3.rhlw-00001.pom",
+ "foo/bar/1.2.3.rhlw-00001/foo.bar.1.2.3.rhlw-00001.jar",
+ "foo/bar/1.2.3.rhlw-00002/foo.bar.1.2.3.rhlw-00002.pom",
+ "foo/bar/1.2.3.rhlw-00002/foo.bar.1.2.3.rhlw-00002.jar",
+ "foo/bar/2.0.1.rhlw-00001/foo.bar.2.0.1.rhlw-00001.pom",
+ "foo/bar/2.0.1.rhlw-00001/foo.bar.2.0.1.rhlw-00001.jar",
}
type MavenSuite struct {
@@ -105,8 +107,9 @@ func (m *MavenSuite) TestMavenPackageList() {
pkg := response.Results[0]
assert.Equal(m.T(), testMavenGroupID, pkg.GroupID)
assert.Equal(m.T(), testMavenArtifactID, pkg.ArtifactID)
- assert.Contains(m.T(), pkg.Versions, testMavenVersion123)
- assert.Contains(m.T(), pkg.Versions, testMavenVersion201)
+ assert.Contains(m.T(), pkg.Versions, testMavenBuildVersion123R1)
+ assert.Contains(m.T(), pkg.Versions, testMavenBuildVersion123R2)
+ assert.Contains(m.T(), pkg.Versions, testMavenBuildVersion201R1)
require.NotEmpty(m.T(), pkg.LatestReleases)
foundVersions := make(map[string]bool)
@@ -114,8 +117,9 @@ func (m *MavenSuite) TestMavenPackageList() {
foundVersions[latest.Version] = true
assert.NotEmpty(m.T(), latest.CreatedAt)
}
- assert.True(m.T(), foundVersions[testMavenVersion123])
- assert.True(m.T(), foundVersions[testMavenVersion201])
+ assert.True(m.T(), foundVersions[testMavenBuildVersion123R1])
+ assert.True(m.T(), foundVersions[testMavenBuildVersion123R2])
+ assert.True(m.T(), foundVersions[testMavenBuildVersion201R1])
}
func (m *MavenSuite) TestMavenPackageListSearchFilter() {
@@ -169,7 +173,7 @@ func (m *MavenSuite) TestMavenBuildList() {
m.repositoryHref,
testMavenGroupID,
testMavenArtifactID,
- testMavenVersion123,
+ testMavenBuildVersion123R1,
tangy.PageOptions{Offset: 0, Limit: 10},
)
require.NoError(m.T(), err)
@@ -180,7 +184,7 @@ func (m *MavenSuite) TestMavenBuildList() {
build := response.Results[0]
assert.Equal(m.T(), testMavenGroupID, build.GroupID)
assert.Equal(m.T(), testMavenArtifactID, build.ArtifactID)
- assert.Equal(m.T(), testMavenVersion123, build.Version)
+ assert.Equal(m.T(), testMavenBuildVersion123R1, build.Version)
assert.True(m.T(), strings.HasSuffix(build.Filename, ".pom"), build.Filename)
assert.NotEmpty(m.T(), build.CreatedAt)
}
@@ -191,7 +195,7 @@ func (m *MavenSuite) TestMavenBuildListPagination() {
m.repositoryHref,
testMavenGroupID,
testMavenArtifactID,
- testMavenVersion123,
+ testMavenBuildVersion123R1,
tangy.PageOptions{Offset: 0, Limit: 1},
)
require.NoError(m.T(), err)
@@ -203,7 +207,7 @@ func (m *MavenSuite) TestMavenBuildListPagination() {
m.repositoryHref,
testMavenGroupID,
testMavenArtifactID,
- testMavenVersion123,
+ testMavenBuildVersion123R1,
tangy.PageOptions{Offset: 1, Limit: 10},
)
require.NoError(m.T(), err)
@@ -212,7 +216,7 @@ func (m *MavenSuite) TestMavenBuildListPagination() {
}
func (m *MavenSuite) TestMavenBuildListEmptyHref() {
- response, err := m.tangy.MavenBuildList(context.Background(), "", testMavenGroupID, testMavenArtifactID, testMavenVersion123, tangy.PageOptions{Limit: 10})
+ response, err := m.tangy.MavenBuildList(context.Background(), "", testMavenGroupID, testMavenArtifactID, testMavenBuildVersion123R1, tangy.PageOptions{Limit: 10})
require.NoError(m.T(), err)
assert.Empty(m.T(), response.Results)
assert.Zero(m.T(), response.Total)
@@ -229,7 +233,7 @@ func (m *MavenSuite) TestMavenBuildListOptionalFilters() {
)
require.NoError(m.T(), err)
require.NotEmpty(m.T(), response.Results)
- assert.Equal(m.T(), 2, response.Total)
+ assert.Equal(m.T(), 3, response.Total)
build := response.Results[0]
assert.Equal(m.T(), testMavenGroupID, build.GroupID)
@@ -244,8 +248,8 @@ func (m *MavenSuite) TestMavenBuildListOptionalFilters() {
tangy.PageOptions{Offset: 0, Limit: 10},
)
require.NoError(m.T(), err)
- require.Len(m.T(), filtered.Results, 2)
- assert.Equal(m.T(), 2, filtered.Total)
+ require.Len(m.T(), filtered.Results, 3)
+ assert.Equal(m.T(), 3, filtered.Total)
filtered, err = m.tangy.MavenBuildList(
context.Background(),
@@ -256,8 +260,8 @@ func (m *MavenSuite) TestMavenBuildListOptionalFilters() {
tangy.PageOptions{Offset: 0, Limit: 10},
)
require.NoError(m.T(), err)
- require.Len(m.T(), filtered.Results, 2)
- assert.Equal(m.T(), 2, filtered.Total)
+ require.Len(m.T(), filtered.Results, 3)
+ assert.Equal(m.T(), 3, filtered.Total)
}
func (m *MavenSuite) TestMavenRepositoryMetrics() {
diff --git a/pkg/tangy/maven.go b/pkg/tangy/maven.go
index c433170..7a16267 100644
--- a/pkg/tangy/maven.go
+++ b/pkg/tangy/maven.go
@@ -243,13 +243,26 @@ func (t *tangyImpl) MavenPackageList(ctx context.Context, repositoryHref string,
}, nil
}
+const mavenReleaseQualifierPattern = `[a-zA-Z]+-\d+`
+
+const mavenReleaseVersionSuffixPattern = `\.` + mavenReleaseQualifierPattern + `$`
+
+const mavenReleaseFilenamePattern = `\.(` + mavenReleaseQualifierPattern + `)\.pom$`
+
+var mavenReleaseVersionSuffixRegexp = regexp.MustCompile(mavenReleaseVersionSuffixPattern)
+
+var mavenReleaseFilenameRegexp = regexp.MustCompile(mavenReleaseFilenamePattern)
+
+// stripMavenReleaseVersion removes a trailing release qualifier from a Maven version string.
+// Example: 5.3.18.rhlw-00003 -> 5.3.18
+func stripMavenReleaseVersion(version string) string {
+ return mavenReleaseVersionSuffixRegexp.ReplaceAllString(version, "")
+}
+
// extractRelease extracts the release version from a filename
// Example: smallrye-mutiny-vertx-core-3.16.0.rhlw-3002.pom -> rhlw-3002
func extractRelease(filename string) string {
- // Pattern to match .rhlw-XXXX or similar release patterns before .pom
- // Looks for a dot followed by alphanumeric+dash, then .pom
- re := regexp.MustCompile(`\.([a-zA-Z]+-\d+)\.pom$`)
- matches := re.FindStringSubmatch(filename)
+ matches := mavenReleaseFilenameRegexp.FindStringSubmatch(filename)
if len(matches) > 1 {
return matches[1]
}
@@ -411,7 +424,8 @@ func (t *tangyImpl) MavenBuildList(ctx context.Context, repositoryHref, groupID,
}
// MavenRepositoryMetrics returns package, build, and version counts for the latest version of a repository.
-// Packages are distinct group_id/artifact_id pairs from .pom artifacts; builds and versions are counted from .jar artifacts.
+// All counts are based on .jar artifacts. Builds are distinct full versions (e.g. 5.3.18.rhlw-00003);
+// versions are distinct base versions with release qualifiers stripped (e.g. 5.3.18).
func (t *tangyImpl) MavenRepositoryMetrics(ctx context.Context, repositoryHref string) (MavenRepositoryMetrics, error) {
if repositoryHref == "" {
return MavenRepositoryMetrics{}, nil
@@ -444,11 +458,7 @@ func (t *tangyImpl) MavenRepositoryMetrics(ctx context.Context, repositoryHref s
return MavenRepositoryMetrics{}, err
}
- pomFilter := ` AND rp.filename LIKE '%.pom'`
jarFilter := ` AND rp.filename LIKE '%.jar'`
- pomFrom := `
- FROM maven_mavenartifact rp
- ` + innerUnion + pomFilter
jarFrom := `
FROM maven_mavenartifact rp
` + innerUnion + jarFilter
@@ -456,10 +466,14 @@ func (t *tangyImpl) MavenRepositoryMetrics(ctx context.Context, repositoryHref s
metricsQuery := `
SELECT
(SELECT COUNT(DISTINCT (rp.group_id, rp.artifact_id))
- ` + pomFrom + `) AS package_count,
- (SELECT COUNT(*)
- ` + jarFrom + `) AS build_count,
+ ` + jarFrom + `) AS package_count,
(SELECT COUNT(DISTINCT (rp.group_id, rp.artifact_id, rp.version))
+ ` + jarFrom + `) AS build_count,
+ (SELECT COUNT(DISTINCT (
+ rp.group_id,
+ rp.artifact_id,
+ regexp_replace(rp.version, '` + mavenReleaseVersionSuffixPattern + `', '')
+ ))
` + jarFrom + `) AS version_count`
var metrics MavenRepositoryMetrics
diff --git a/pkg/tangy/maven_test.go b/pkg/tangy/maven_test.go
index 40853bc..3bf5be3 100644
--- a/pkg/tangy/maven_test.go
+++ b/pkg/tangy/maven_test.go
@@ -50,6 +50,115 @@ func TestParseRepositoryHref(t *testing.T) {
}
}
+func TestStripMavenReleaseVersion(t *testing.T) {
+ t.Parallel()
+
+ tests := []struct {
+ name string
+ version string
+ want string
+ }{
+ {
+ name: "release suffix in version",
+ version: "5.3.18.rhlw-00003",
+ want: "5.3.18",
+ },
+ {
+ name: "plain version",
+ version: "1.2.3",
+ want: "1.2.3",
+ },
+ {
+ name: "final qualifier version",
+ version: "4.1.114.Final",
+ want: "4.1.114.Final",
+ },
+ {
+ name: "empty version",
+ version: "",
+ want: "",
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ t.Parallel()
+ assert.Equal(t, tt.want, stripMavenReleaseVersion(tt.version))
+ })
+ }
+}
+
+func TestMavenRepositoryMetricsCounting(t *testing.T) {
+ t.Parallel()
+
+ type artifact struct {
+ group string
+ artifact string
+ version string
+ }
+
+ countMetrics := func(artifacts []artifact) (packageCount, buildCount, versionCount int) {
+ packages := make(map[[2]string]struct{})
+ builds := make(map[[3]string]struct{})
+ versions := make(map[[3]string]struct{})
+
+ for _, a := range artifacts {
+ packages[[2]string{a.group, a.artifact}] = struct{}{}
+ builds[[3]string{a.group, a.artifact, a.version}] = struct{}{}
+ baseVersion := stripMavenReleaseVersion(a.version)
+ versions[[3]string{a.group, a.artifact, baseVersion}] = struct{}{}
+ }
+
+ return len(packages), len(builds), len(versions)
+ }
+
+ springCoreVersions := []string{
+ "5.3.18.rhlw-00003",
+ "5.3.18.rhlw-00004",
+ "5.3.18.rhlw-00005",
+ "5.3.18.rhlw-00006",
+ "5.3.18.rhlw-00007",
+ }
+ springCoreArtifacts := make([]artifact, 0, len(springCoreVersions)*3)
+ for _, version := range springCoreVersions {
+ for range 3 {
+ springCoreArtifacts = append(springCoreArtifacts, artifact{
+ group: "org.springframework",
+ artifact: "spring-core",
+ version: version,
+ })
+ }
+ }
+
+ nettyVersions := []string{
+ "4.1.114.Final",
+ "4.1.127.Final",
+ "4.1.128.Final",
+ "4.1.130.Final",
+ "4.1.133.Final",
+ }
+ nettyArtifacts := make([]artifact, 0, len(nettyVersions)*5)
+ for _, version := range nettyVersions {
+ for range 5 {
+ nettyArtifacts = append(nettyArtifacts, artifact{
+ group: "io.netty",
+ artifact: "netty-codec",
+ version: version,
+ })
+ }
+ }
+
+ packageCount, buildCount, versionCount := countMetrics(springCoreArtifacts)
+ assert.Equal(t, 1, packageCount)
+ assert.Equal(t, 5, buildCount)
+ assert.Equal(t, 1, versionCount)
+
+ packageCount, buildCount, versionCount = countMetrics(nettyArtifacts)
+ assert.Equal(t, 1, packageCount)
+ assert.Equal(t, 5, buildCount)
+ assert.Equal(t, 5, versionCount)
+}
+
func TestExtractRelease(t *testing.T) {
t.Parallel()