fix: maven use groupId:artifactId for package name concatenation (#6352)
Some checks are pending
/ release (push) Waiting to run
testing / test-unit (push) Blocked by required conditions
testing / test-e2e (push) Blocked by required conditions
testing / backend-checks (push) Waiting to run
testing / frontend-checks (push) Waiting to run
testing / test-remote-cacher (redis) (push) Blocked by required conditions
testing / test-remote-cacher (valkey) (push) Blocked by required conditions
testing / test-remote-cacher (garnet) (push) Blocked by required conditions
testing / test-remote-cacher (redict) (push) Blocked by required conditions
testing / test-mysql (push) Blocked by required conditions
testing / test-pgsql (push) Blocked by required conditions
testing / test-sqlite (push) Blocked by required conditions
testing / security-check (push) Blocked by required conditions

Second part of #6327 to fix the Maven package naming. This pull request includes:
* Changing the group and artifact IDs from being separated by `-` to `:` as suggested by [Maven](https://maven.apache.org/pom.html#Maven_Coordinates).
* Making Maven package names case-sensitive
* Migrating the database to:
  * Handle collisions of package names (e.g., groupId: foo- with artifactId: bar and groupId: foo with artifactId: -bar) by moving them into their own packages.
  * Fix the missing group ID issue (#6329).
  * Update  lower_name to match the name value for maven pkgs to make it case-sensetive.

## Checklist

The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org).

### Tests

- I added test coverage for Go changes...
  - [x] in their respective `*_test.go` for unit tests.
  - [x] in the `tests/integration` directory if it involves interactions with a live Forgejo server.
- I added test coverage for JavaScript changes...
  - [ ] in `web_src/js/*.test.js` if it can be unit tested.
  - [ ] in `tests/e2e/*.test.e2e.js` if it requires interactions with a live Forgejo server (see also the [developer guide for JavaScript testing](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/tests/e2e/README.md#end-to-end-tests)).

### Documentation

- [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change.
- [x] I did not document these changes and I do not expect someone else to do it.

### Release notes

- [ ] I do not want this change to show in the release notes.
- [x] I want the title to show in the release notes with a link to this pull request.
- [ ] I want the content of the `release-notes/<pull request number>.md` to be be used for the release notes instead of the title.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6352
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Co-authored-by: Julian Schlarb <julian.schlarb@denktmit.de>
Co-committed-by: Julian Schlarb <julian.schlarb@denktmit.de>
This commit is contained in:
Julian Schlarb 2025-06-01 09:02:29 +02:00 committed by Earl Warren
parent baa93ec66e
commit 21151ea5ce
14 changed files with 2522 additions and 27 deletions

View file

@ -101,6 +101,8 @@ var migrations = []*Migration{
NewMigration("Migrate `User.NormalizedFederatedURI` column to extract port & schema into FederatedHost", MigrateNormalizedFederatedURI), NewMigration("Migrate `User.NormalizedFederatedURI` column to extract port & schema into FederatedHost", MigrateNormalizedFederatedURI),
// v30 -> v31 // v30 -> v31
NewMigration("Normalize repository.topics to empty slice instead of null", SetTopicsAsEmptySlice), NewMigration("Normalize repository.topics to empty slice instead of null", SetTopicsAsEmptySlice),
// v31 -> v32
NewMigration("Migrate maven package name concatenation", ChangeMavenArtifactConcatenation),
} }
// GetCurrentDBVersion returns the current Forgejo database version. // GetCurrentDBVersion returns the current Forgejo database version.

View file

@ -0,0 +1,414 @@
// Copyright 2025 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: GPL-3.0-or-later
package forgejo_migrations //nolint:revive
import (
"encoding/xml"
"fmt"
"regexp"
"slices"
"sort"
"strconv"
"strings"
"forgejo.org/models/packages"
"forgejo.org/modules/json"
"forgejo.org/modules/log"
"forgejo.org/modules/packages/maven"
packages_service "forgejo.org/services/packages"
"golang.org/x/net/context"
"xorm.io/xorm"
)
var getPackage = packages_service.GetPackageFileStream
type Snapshot struct {
baseVersion string
date string
time string
build int
}
type Metadata struct {
XMLName xml.Name `xml:"metadata"`
ModelVersion string `xml:"modelVersion,attr"`
GroupID string `xml:"groupId"`
ArtifactID string `xml:"artifactId"`
Version string `xml:"version"`
}
type mavenPackageResult struct {
PackageFile *packages.PackageFile `xorm:"extends"`
PackageVersion *packages.PackageVersion `xorm:"extends"`
Package *packages.Package `xorm:"extends"`
PackageName string `xorm:"-"`
Snapshot *Snapshot `xorm:"-"`
GroupID string `xorm:"-"`
ArtifactID string `xorm:"-"`
}
// ChangeMavenArtifactConcatenation resolves old dash-concatenated Maven coordinates and regenerates metadata.
// Note: runs per-owner in a single transaction; failures roll back all owners.
func ChangeMavenArtifactConcatenation(x *xorm.Engine) error {
sess := x.NewSession()
defer sess.Close()
if err := sess.Begin(); err != nil {
return err
}
// get unique owner IDs of Maven packages
var ownerIDs []*int64
if err := sess.
Table("package").
Select("package.owner_id").
Where("package.type = 'maven'").
GroupBy("package.owner_id").
OrderBy("package.owner_id DESC").
Find(&ownerIDs); err != nil {
return err
}
for _, id := range ownerIDs {
if err := fixMavenArtifactPerOwner(sess, id); err != nil {
log.Error("owner %d migration failed: %v", id, err)
return err // rollback all
}
}
return sess.Commit()
}
func fixMavenArtifactPerOwner(sess *xorm.Session, ownerID *int64) error {
results, err := getMavenPackageResultsToUpdate(sess, ownerID)
if err != nil {
return err
}
if err = resolvePackageCollisions(results, sess); err != nil {
return err
}
if err = processPackageVersions(results, sess); err != nil {
return err
}
return processPackageFiles(results, sess)
}
// processPackageFiles updates Maven package files and versions in the database
// Returns an error if any database or processing operation fails.
func processPackageFiles(results []*mavenPackageResult, sess *xorm.Session) error {
processedVersion := make(map[string][]*mavenPackageResult)
for _, r := range results {
if r.Snapshot != nil {
key := fmt.Sprintf("%s:%s", r.PackageName, r.PackageVersion.LowerVersion)
processedVersion[key] = append(processedVersion[key], r)
}
// Only update version_id when it differs
if r.PackageVersion.ID != r.PackageFile.VersionID {
pattern := strings.TrimSuffix(r.PackageFile.Name, ".pom") + "%"
// Per routers/api/packages/maven/maven.go:338, POM files already have the `IsLead`, so no update needed for this prop
if _, err := sess.Exec("UPDATE package_file SET version_id = ? WHERE version_id = ? and name like ?", r.PackageVersion.ID, r.PackageFile.VersionID, pattern); err != nil {
return err
}
}
}
// If maven-metadata.xml is missing (snapshot path collision), skip regeneration
// Without this metadata, Maven cannot resolve snapshot details
for _, packageResults := range processedVersion {
sort.Slice(packageResults, func(i, j int) bool {
return packageResults[i].Snapshot.build > packageResults[j].Snapshot.build
})
rs := packageResults[0]
pf, md, err := parseMetadata(sess, rs)
if err != nil {
return err
}
if pf != nil && md != nil && md.GroupID == rs.GroupID && md.ArtifactID == rs.ArtifactID {
if pf.VersionID != rs.PackageFile.VersionID {
if _, err := sess.ID(pf.ID).Cols("version_id").Update(pf); err != nil {
return err
}
}
continue
}
log.Warn("no maven-metadata.xml found for (id: %d) [%s:%s]", rs.PackageVersion.ID, rs.PackageName, rs.PackageVersion.Version)
}
return nil
}
// parseMetadata retrieves metadata for a Maven package file from the database and decodes it into a Metadata object.
// Returns the associated PackageFile, Metadata, and any error encountered during processing.
func parseMetadata(sess *xorm.Session, snapshot *mavenPackageResult) (*packages.PackageFile, *Metadata, error) {
ctx := context.Background()
var pf packages.PackageFile
found, err := sess.Table(pf).
Where("version_id = ?", snapshot.PackageFile.VersionID). // still the old id
And("lower_name = ?", "maven-metadata.xml").
Get(&pf)
if err != nil {
return nil, nil, err
}
if !found {
return nil, nil, nil
}
s, _, _, err := getPackage(ctx, &pf)
if err != nil {
return nil, nil, err
}
defer s.Close()
dec := xml.NewDecoder(s)
var m Metadata
if err := dec.Decode(&m); err != nil {
return nil, nil, err
}
return &pf, &m, nil
}
// processPackageVersions processes Maven package versions by updating metadata or inserting new records as necessary.
// It avoids redundant updates by tracking already processed versions using a map. Returns an error on failure.
func processPackageVersions(results []*mavenPackageResult, sess *xorm.Session) error {
processedVersion := make(map[string]int64)
for _, r := range results {
key := fmt.Sprintf("%s:%s", r.PackageName, r.PackageVersion.Version)
if id, ok := processedVersion[key]; ok {
r.PackageVersion.ID = id
continue
}
// for non collisions, just update the metadata
if r.PackageVersion.PackageID == r.Package.ID {
if _, err := sess.ID(r.PackageVersion.ID).Cols("metadata_json").Update(r.PackageVersion); err != nil {
return err
}
} else {
log.Info("Create new maven package version for %s:%s", r.PackageName, r.PackageVersion.Version)
r.PackageVersion.ID = 0
r.PackageVersion.PackageID = r.Package.ID
if _, err := sess.Insert(r.PackageVersion); err != nil {
return err
}
}
processedVersion[key] = r.PackageVersion.ID
}
return nil
}
// getMavenPackageResultsToUpdate retrieves Maven package results that need updates based on the owner ID.
// It processes POM metadata, fixes package inconsistencies, and filters corrupted package versions.
func getMavenPackageResultsToUpdate(sess *xorm.Session, ownerID *int64) ([]*mavenPackageResult, error) {
ctx := context.Background()
var candidates []*mavenPackageResult
if err := sess.
Table("package_file").
Select("package_file.*, package_version.*, package.*").
Join("INNER", "package_version", "package_version.id = package_file.version_id").
Join("INNER", "package", "package.id = package_version.package_id").
Where("package_file.lower_name LIKE ?", "%.pom").
And("package.type = ?", "maven").
And("package.owner_id = ?", ownerID).
OrderBy("package_version.id DESC, package_file.id DESC").
Find(&candidates); err != nil {
return nil, err
}
var results []*mavenPackageResult
var corruptedVersionIDs []int64
// fetch actual metadata from blob as all packages needs to be fixed following the new string concatenation
for _, r := range candidates {
if err := processPomMetadata(ctx, r); err != nil {
// Skip corrupted versions; admin intervention may be needed to repair these files.
log.Warn("Failed to process package file [id: %d] ignoring package version[%d]: %v", r.PackageFile.ID, r.PackageVersion.ID, err)
corruptedVersionIDs = append(corruptedVersionIDs, r.PackageVersion.ID)
continue
}
results = append(results, r)
log.Debug("Resolved id [%d] from [%s:%s] to [%s:%s] [Snapshot: %v]", r.Package.ID, r.Package.Name, r.PackageVersion.Version, r.PackageName, r.PackageVersion.Version, r.Snapshot)
}
for _, corruptedVersionID := range corruptedVersionIDs {
for i := 0; i < len(results); {
if corruptedVersionID == results[i].PackageVersion.ID {
results = append(results[:i], results[i+1:]...)
} else {
i++
}
}
}
return results, nil
}
// resolvePackageCollisions handles name collisions by keeping the first existing record and inserting new Package records for subsequent collisions.
// Returns a map from PackageName to its resolved Package.ID.
func resolvePackageCollisions(results []*mavenPackageResult, sess *xorm.Session) error {
// Group new names by lowerName
collisions := make(map[string][]string)
for _, r := range results {
names := collisions[r.Package.LowerName]
if !slices.Contains(names, r.PackageName) {
collisions[r.Package.LowerName] = append(names, r.PackageName)
}
}
pkgIDByName := make(map[string]int64)
var err error
for _, r := range results {
list := collisions[r.Package.LowerName]
// update to the upcoming package name which is colon separated
r.Package.Name = r.PackageName
r.Package.LowerName = r.PackageName
// exiting entry
if id, ok := pkgIDByName[r.PackageName]; ok {
r.Package.ID = id
// first package kept the current id
} else if list[0] == r.PackageName {
pkgIDByName[r.PackageName] = r.Package.ID
if _, err = sess.ID(r.Package.ID).Cols("name", "lower_name").Update(r.Package); err != nil {
return err
}
// create a new entry
} else {
log.Info("Create new maven package for %s", r.Package.Name)
r.Package.ID = 0
if _, err = sess.Insert(r.Package); err != nil {
return err
}
pkgIDByName[r.PackageName] = r.Package.ID
}
}
return nil
}
// processPomMetadata processes a Maven package file, parses its POM metadata, and updates PackageVersion information.
func processPomMetadata(ctx context.Context, mpr *mavenPackageResult) error {
s, _, _, err := getPackage(ctx, mpr.PackageFile)
if err != nil {
return fmt.Errorf("unable to get package stream: %v", err)
}
defer s.Close()
actualPom, err := maven.ParsePackageMetaData(s)
if err != nil {
return fmt.Errorf("failed to parse POM metadata: %v", err)
}
raw, err := json.Marshal(actualPom)
if err != nil {
return fmt.Errorf("failed to marshal metadata: %v", err)
}
var currentPom *maven.Metadata
if err = json.Unmarshal([]byte(mpr.PackageVersion.MetadataJSON), &currentPom); err != nil {
return fmt.Errorf("failed to unmarshal metadata: %v", err)
}
// since the rest api can also be (ab)used to upload artifacts wrong, just ignore them
if isInvalidMatch(currentPom, actualPom) {
return fmt.Errorf("artifact mismatch: actual [%s] expected [%s]", actualPom.ArtifactID, currentPom.ArtifactID)
}
// this will also fix packages that missed its groupID
// Ref: https://codeberg.org/forgejo/forgejo/pulls/6329
mpr.PackageVersion.MetadataJSON = string(raw)
// Since Maven packages are case-sensitive, avoid potential clashes and clean-ups
// by enforcing consistent case handling similar to RPM packages.
mpr.PackageName = fmt.Sprintf("%s:%s", actualPom.GroupID, actualPom.ArtifactID)
mpr.GroupID = actualPom.GroupID
mpr.ArtifactID = actualPom.ArtifactID
if strings.HasSuffix(mpr.PackageVersion.Version, "-SNAPSHOT") {
snap, err := extraSnapshotDetails(currentPom, actualPom, mpr)
if err != nil {
return err
}
mpr.Snapshot = snap
} else {
// only snapshots are affected but kept in case of not complete fixtures
expectedFileName := fmt.Sprintf("%s-%s.pom", actualPom.ArtifactID, mpr.PackageVersion.Version)
if mpr.PackageFile.Name != expectedFileName {
log.Warn("invalid package file name - this is a collision which needs to be resolved expected [%s], actual [%s]", expectedFileName, mpr.PackageFile.Name)
}
}
return nil
}
// extraSnapshotDetails extracts detailed snapshot information
// Returns a Snapshot object encapsulating the extracted details or an error if the filename is invalid or parsing fails.
func extraSnapshotDetails(currentPom, actualPom *maven.Metadata, mpr *mavenPackageResult) (*Snapshot, error) {
pattern := `^%s-` +
`(?P<baseVersion>[\d\.]+)-` +
`(?P<date>\d{8})\.` +
`(?P<time>\d{6})-` +
`(?P<build>\d+)\.pom$`
re := regexp.MustCompile(fmt.Sprintf(pattern, regexp.QuoteMeta(currentPom.ArtifactID)))
if re.FindStringSubmatch(mpr.PackageFile.Name) == nil {
log.Warn("invalid package file name - this is a collision which needs to be resolved %s", mpr.PackageFile.Name)
}
re = regexp.MustCompile(fmt.Sprintf(pattern, regexp.QuoteMeta(actualPom.ArtifactID)))
match := re.FindStringSubmatch(mpr.PackageFile.Name)
if match == nil {
return nil, fmt.Errorf("invalid snapshot filename: %s", mpr.PackageFile.Name)
}
baseIdx := re.SubexpIndex("baseVersion")
dateIdx := re.SubexpIndex("date")
timeIdx := re.SubexpIndex("time")
buildIdx := re.SubexpIndex("build")
buildNum, _ := strconv.Atoi(match[buildIdx])
return &Snapshot{
baseVersion: match[baseIdx],
date: match[dateIdx],
time: match[timeIdx],
build: buildNum,
}, nil
}
// isInvalidMatch returns true if the stored metadatas groupID:artifactID
// differs from actual values—accounting for an earlier bug that sometimes omitted the groupID.
func isInvalidMatch(current, actual *maven.Metadata) bool {
bare := fmt.Sprintf("-%s", actual.ArtifactID)
full := fmt.Sprintf("%s-%s", actual.GroupID, actual.ArtifactID)
currentID := fmt.Sprintf("%s-%s", current.GroupID, current.ArtifactID)
return currentID != full && currentID != bare
}

View file

@ -0,0 +1,369 @@
// Copyright 2025 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: GPL-3.0-or-later
package forgejo_migrations //nolint:revive
import (
"bytes"
"context"
"io"
"net/url"
"strings"
"testing"
migration_tests "forgejo.org/models/migrations/test"
"forgejo.org/models/packages"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
type readSeekCloser struct {
*bytes.Reader
}
func (rsc readSeekCloser) Close() error {
// No resources to close, so we simply provide a no-op implementation.
return nil
}
func StringToReadSeekCloser(s string) io.ReadSeekCloser {
return readSeekCloser{Reader: bytes.NewReader([]byte(s))}
}
func Test_ChangeMavenArtifactConcatenation(t *testing.T) {
getPackage = func(ctx context.Context, pf *packages.PackageFile) (io.ReadSeekCloser, *url.URL, *packages.PackageFile, error) {
var data string
switch pf.BlobID {
case 1:
data = `<project><modelVersion>4.0.0</modelVersion><packaging>pom</packaging><groupId>com.example</groupId><artifactId>parent-project</artifactId><version>1.0-SNAPSHOT</version></project>`
case 3:
data = `<project><modelVersion>4.0.0</modelVersion><packaging></packaging><parent><groupId>com.example</groupId><artifactId>parent-project</artifactId></parent><groupId></groupId><artifactId>sub-module</artifactId><version>1.0-SNAPSHOT</version></project>`
case 6:
data = `<project><modelVersion>4.0.0</modelVersion><packaging>pom</packaging><groupId>com.example</groupId><artifactId>parent-project</artifactId><version>7.0.0</version></project>`
case 7:
data = `<project><modelVersion>4.0.0</modelVersion><packaging></packaging><parent><groupId>com.example</groupId><artifactId>parent-project</artifactId></parent><groupId></groupId><artifactId>sub-module</artifactId><version>7.0.0</version></project>`
case 9:
data = `<project><modelVersion>4.0.0</modelVersion><packaging>pom</packaging><groupId>com.example</groupId><artifactId>parent-project</artifactId><version>7.0.0</version></project>`
case 11:
data = `<project><modelVersion>4.0.0</modelVersion><packaging>pom</packaging><groupId>foo-</groupId><artifactId>bar</artifactId><version>1.0-SNAPSHOT</version></project>`
case 13:
data = `<project><modelVersion>4.0.0</modelVersion><packaging>pom</packaging><groupId>foo-</groupId><artifactId>bar</artifactId><version>7.0.0</version></project>`
case 14:
data = `<project><modelVersion>4.0.0</modelVersion><packaging>pom</packaging><groupId>foo</groupId><artifactId>-bar</artifactId><version>1.0-SNAPSHOT</version></project>`
case 16:
data = `<project><modelVersion>4.0.0</modelVersion><packaging>pom</packaging><groupId>foo</groupId><artifactId>-bar</artifactId><version>7.0.0</version></project>`
case 20:
data = `<project><modelVersion>4.0.0</modelVersion><packaging>pom</packaging><groupId>com.example</groupId><artifactId>parent-project</artifactId><version>8.0.0</version></project>`
case 21:
data = `<project><modelVersion>4.0.0</modelVersion><packaging></packaging><parent><groupId>com.example</groupId><artifactId>parent-project</artifactId></parent><groupId></groupId><artifactId>sub-module</artifactId><version>8.0.0</version></project>`
case 23:
data = `<project><modelVersion>4.0.0</modelVersion><packaging>pom</packaging><groupId>com.example</groupId><artifactId>parent-project</artifactId><version>8.0.0</version></project>`
case 26:
data = `<project><modelVersion>4.0.0</modelVersion><packaging>pom</packaging><groupId>foo-</groupId><artifactId>bar</artifactId><version>8.0.0</version></project>`
case 28:
data = `<project><modelVersion>4.0.0</modelVersion><packaging>pom</packaging><groupId>foo</groupId><artifactId>-bar</artifactId><version>8.0.0</version></project>`
case 32:
data = `<project><modelVersion>4.0.0</modelVersion><packaging>pom</packaging><groupId>com.example</groupId><artifactId>parent-project</artifactId><version>9.0.0</version></project>`
case 33:
data = `<project><modelVersion>4.0.0</modelVersion><packaging></packaging><parent><groupId>com.example</groupId><artifactId>parent-project</artifactId></parent><groupId></groupId><artifactId>sub-module</artifactId><version>9.0.0</version></project>`
case 35:
data = `<project><modelVersion>4.0.0</modelVersion><packaging>pom</packaging><groupId>com.example</groupId><artifactId>parent-project</artifactId><version>9.0.0</version></project>`
case 38:
data = `<project><modelVersion>4.0.0</modelVersion><packaging>pom</packaging><groupId>foo-</groupId><artifactId>bar</artifactId><version>9.0.0</version></project>`
case 40:
data = `<project><modelVersion>4.0.0</modelVersion><packaging>pom</packaging><groupId>foo</groupId><artifactId>-bar</artifactId><version>9.0.0</version></project>`
case 44:
data = `<project><modelVersion>4.0.0</modelVersion><packaging>pom</packaging><groupId>com.example</groupId><artifactId>parent-project</artifactId><version>10.0.0</version></project>`
case 45:
data = `<project><modelVersion>4.0.0</modelVersion><packaging></packaging><parent><groupId>com.example</groupId><artifactId>parent-project</artifactId></parent><groupId></groupId><artifactId>sub-module</artifactId><version>10.0.0</version></project>`
case 47:
data = `<project><modelVersion>4.0.0</modelVersion><packaging>pom</packaging><groupId>com.example</groupId><artifactId>parent-project</artifactId><version>10.0.0</version></project>`
case 50:
data = `<project><modelVersion>4.0.0</modelVersion><packaging>pom</packaging><groupId>foo-</groupId><artifactId>bar</artifactId><version>10.0.0</version></project>`
case 52:
data = `<project><modelVersion>4.0.0</modelVersion><packaging>pom</packaging><groupId>foo</groupId><artifactId>-bar</artifactId><version>10.0.0</version></project>`
case 56:
data = `<project><modelVersion>4.0.0</modelVersion><packaging>pom</packaging><groupId>com.example</groupId><artifactId>parent-project</artifactId><version>11.0.0</version></project>`
case 57:
data = `<project><modelVersion>4.0.0</modelVersion><packaging></packaging><parent><groupId>com.example</groupId><artifactId>parent-project</artifactId></parent><groupId></groupId><artifactId>sub-module</artifactId><version>11.0.0</version></project>`
case 59:
data = `<project><modelVersion>4.0.0</modelVersion><packaging>pom</packaging><groupId>com.example</groupId><artifactId>parent-project</artifactId><version>11.0.0</version></project>`
case 62:
data = `<project><modelVersion>4.0.0</modelVersion><packaging>pom</packaging><groupId>foo-</groupId><artifactId>bar</artifactId><version>11.0.0</version></project>`
case 64:
data = `<project><modelVersion>4.0.0</modelVersion><packaging>pom</packaging><groupId>foo</groupId><artifactId>-bar</artifactId><version>11.0.0</version></project>`
case 66:
data = `<project><modelVersion>4.0.0</modelVersion><packaging></packaging><parent><groupId>com.broken</groupId><artifactId>br-parent</artifactId></parent><groupId></groupId><artifactId>br-rest-webmvc</artifactId><version></version></project>`
case 68:
data = `<project><modelVersion>4.0.0</modelVersion><packaging></packaging><parent><groupId>com.broken</groupId><artifactId>br-parent</artifactId></parent><groupId></groupId><artifactId>br-openapi-base</artifactId><version></version></project>`
case 72:
data = `<project><modelVersion>4.0.0</modelVersion><packaging>pom</packaging><parent><groupId>de.loosetie</groupId><artifactId>lt-parent-kotlin</artifactId></parent><groupId>com.broken</groupId><artifactId>br-root</artifactId><version>1.2.4</version></project>`
case 74:
data = `<project><modelVersion>4.0.0</modelVersion><packaging></packaging><parent><groupId>com.broken</groupId><artifactId>br-parent</artifactId></parent><groupId></groupId><artifactId>br-repo-jooq</artifactId><version></version></project>`
case 76:
data = `<project><modelVersion>4.0.0</modelVersion><packaging></packaging><parent><groupId>com.broken</groupId><artifactId>br-parent</artifactId></parent><groupId></groupId><artifactId>br-repo-in-memory</artifactId><version></version></project>`
case 78:
data = `<project><modelVersion>4.0.0</modelVersion><packaging>pom</packaging><parent><groupId>com.broken</groupId><artifactId>br-root</artifactId></parent><groupId></groupId><artifactId>br-parent</artifactId><version></version></project>`
case 79:
data = `<project><modelVersion>4.0.0</modelVersion><packaging>pom</packaging><groupId>group</groupId><artifactId>bar-art</artifactId><version>11.0.0</version></project>`
case 80:
data = `<project><modelVersion>4.0.0</modelVersion><packaging>pom</packaging><groupId>group-bar</groupId><artifactId>art</artifactId><version>11.0.0</version></project>`
case 55:
data = `<?xml version="1.0" encoding="UTF-8"?><metadata modelVersion="1.1.0"><groupId>com.example</groupId><artifactId>sub-module</artifactId><version>1.0-SNAPSHOT</version></metadata>`
case 53:
data = `<?xml version="1.0" encoding="UTF-8"?><metadata modelVersion="1.1.0"><groupId>com.example</groupId><artifactId>parent-project</artifactId><version>1.0-SNAPSHOT</version></metadata>`
case 63:
data = `<?xml version="1.0" encoding="UTF-8"?><metadata modelVersion="1.1.0"><groupId>foo</groupId><artifactId>-bar</artifactId><version>1.0-SNAPSHOT</version></metadata>`
default:
t.Fatalf("Unknown package file type: %d", pf.BlobID)
}
return StringToReadSeekCloser(data), nil, nil, nil
}
x, deferable := migration_tests.PrepareTestEnv(t, 0, new(packages.Package), new(packages.PackageFile), new(packages.PackageVersion), new(packages.PackageBlob))
defer deferable()
if x == nil || t.Failed() {
return
}
cnt, err := x.Table("package").Count()
require.NoError(t, err)
assert.EqualValues(t, 8, cnt)
cnt, err = x.Table("package_file").Count()
require.NoError(t, err)
assert.EqualValues(t, 87, cnt)
cnt, err = x.Table("package_version").Count()
require.NoError(t, err)
assert.EqualValues(t, 31, cnt)
cnt, err = x.Table("package_blob").Count()
require.NoError(t, err)
assert.EqualValues(t, 80, cnt)
require.NoError(t, ChangeMavenArtifactConcatenation(x))
var pks []*packages.Package
require.NoError(t, x.OrderBy("id").Find(&pks))
validatePackages(t, pks)
var pvs []*packages.PackageVersion
require.NoError(t, x.OrderBy("id").Find(&pvs))
validatePackageVersions(t, pvs)
var pfs []*packages.PackageFile
require.NoError(t, x.OrderBy("id").Find(&pfs))
validatePackageFiles(t, pfs)
}
func validatePackages(t *testing.T, pbs []*packages.Package) {
assertPackage := func(id, ownerID, repoID int64, name string) {
pb := pbs[id-1]
require.Equal(t, id, pb.ID)
require.Equal(t, ownerID, pb.OwnerID)
require.Equal(t, repoID, pb.RepoID)
require.Equal(t, name, pb.Name)
require.Equal(t, name, pb.LowerName)
require.Equal(t, packages.TypeMaven, pb.Type)
}
require.Len(t, pbs, 10)
assertPackage(1, 2, 0, "com.example:parent-project")
assertPackage(2, 2, 0, "com.example:sub-module")
assertPackage(3, 1, 0, "com.example:parent-project")
assertPackage(4, 1, 0, "com.example:sub-module")
assertPackage(5, 1, 0, "foo:-bar")
assertPackage(6, 8, 54, "com.broken:br-rest-webmvc")
// broken poms completely ignored as it is impossible to look up the correct metadata
assertPackage(7, 8, 54, "com.broken-br-openapi-base")
assertPackage(8, 1, 0, "group-bar:art")
// new created entries
assertPackage(9, 1, 0, "group:bar-art")
assertPackage(10, 1, 0, "foo-:bar")
}
func validatePackageVersions(t *testing.T, pvs []*packages.PackageVersion) {
require.Len(t, pvs, 38)
assertPackageVersion := func(id, packageId, creatorId, createdUnix int64, version, metadata string) {
pv := pvs[id-1]
require.Equal(t, id, pv.ID)
require.Equal(t, packageId, pv.PackageID)
require.Equal(t, creatorId, pv.CreatorID)
require.Equal(t, version, pv.Version)
require.Equal(t, strings.ToLower(version), pv.LowerVersion)
require.JSONEq(t, metadata, pv.MetadataJSON)
}
assertPackageVersion(1, 1, 1, 1746256357, "1.0-SNAPSHOT", `{"artifact_id":"parent-project","group_id":"com.example"}`)
assertPackageVersion(2, 2, 1, 1746256358, "1.0-SNAPSHOT", `{"artifact_id":"sub-module","group_id":"com.example"}`)
assertPackageVersion(3, 1, 1, 1746256360, "7.0.0", `{"artifact_id":"parent-project","group_id":"com.example"}`)
// added groupId
assertPackageVersion(4, 2, 1, 1746256361, "7.0.0", `{"artifact_id":"sub-module","group_id":"com.example"}`)
assertPackageVersion(5, 3, 1, 1746256364, "7.0.0", `{"artifact_id":"parent-project","group_id":"com.example"}`)
// added groupId
assertPackageVersion(6, 4, 1, 1746256365, "7.0.0", `{"artifact_id":"sub-module","group_id":"com.example"}`)
assertPackageVersion(7, 5, 1, 1746256367, "1.0-SNAPSHOT", `{"artifact_id":"-bar","group_id":"foo"}`)
assertPackageVersion(8, 5, 1, 1746256370, "7.0.0", `{"artifact_id":"-bar","group_id":"foo"}`)
assertPackageVersion(9, 1, 1, 1746256389, "8.0.0", `{"artifact_id":"parent-project","group_id":"com.example"}`)
// added groupId
assertPackageVersion(10, 2, 1, 1746256390, "8.0.0", `{"artifact_id":"sub-module","group_id":"com.example"}`)
assertPackageVersion(11, 3, 1, 1746256393, "8.0.0", `{"artifact_id":"parent-project","group_id":"com.example"}`)
// added groupId
assertPackageVersion(12, 4, 1, 1746256394, "8.0.0", `{"artifact_id":"sub-module","group_id":"com.example"}`)
assertPackageVersion(13, 5, 1, 1746256399, "8.0.0", `{"artifact_id":"-bar","group_id":"foo"}`)
assertPackageVersion(14, 1, 1, 1746256419, "9.0.0", `{"artifact_id":"parent-project","group_id":"com.example"}`)
// added groupId
assertPackageVersion(15, 2, 1, 1746256420, "9.0.0", `{"artifact_id":"sub-module","group_id":"com.example"}`)
assertPackageVersion(16, 3, 1, 1746256423, "9.0.0", `{"artifact_id":"parent-project","group_id":"com.example"}`)
// added groupId
assertPackageVersion(17, 4, 1, 1746256424, "9.0.0", `{"artifact_id":"sub-module","group_id":"com.example"}`)
assertPackageVersion(18, 5, 1, 1746256429, "9.0.0", `{"artifact_id":"-bar","group_id":"foo"}`)
assertPackageVersion(19, 1, 1, 1746256449, "10.0.0", `{"artifact_id":"parent-project","group_id":"com.example"}`)
assertPackageVersion(20, 2, 1, 1746256450, "10.0.0", `{"artifact_id":"sub-module","group_id":"com.example"}`)
assertPackageVersion(21, 3, 1, 1746256452, "10.0.0", `{"artifact_id":"parent-project","group_id":"com.example"}`)
assertPackageVersion(22, 4, 1, 1746256453, "10.0.0", `{"artifact_id":"sub-module","group_id":"com.example"}`)
assertPackageVersion(23, 5, 1, 1746256459, "10.0.0", `{"artifact_id":"-bar","group_id":"foo"}`)
assertPackageVersion(24, 1, 1, 1746256478, "11.0.0", `{"artifact_id":"parent-project","group_id":"com.example"}`)
assertPackageVersion(25, 2, 1, 1746256479, "11.0.0", `{"artifact_id":"sub-module","group_id":"com.example"}`)
assertPackageVersion(26, 3, 1, 1746256482, "11.0.0", `{"artifact_id":"parent-project","group_id":"com.example"}`)
assertPackageVersion(27, 4, 1, 1746256483, "11.0.0", `{"artifact_id":"sub-module","group_id":"com.example"}`)
assertPackageVersion(28, 5, 1, 1746256488, "11.0.0", `{"artifact_id":"-bar","group_id":"foo"}`)
// should be untouched at all. fixtures doesn't contain names
assertPackageVersion(29, 7, 6, 1746256488, "1.2.4", `{"group_id":"com.broken","artifact_id":"br-root","name":"Foo"}`)
// added group name
assertPackageVersion(30, 6, 6, 1746256488, "1.2.4", `{"artifact_id":"br-rest-webmvc", "group_id":"com.broken"}`)
assertPackageVersion(31, 8, 1, 1746256488, "11.0.0", `{"artifact_id":"art","group_id":"group-bar"}`)
// new entries
assertPackageVersion(32, 9, 1, 1746256488, "11.0.0", `{"artifact_id":"bar-art","group_id":"group"}`)
assertPackageVersion(33, 10, 1, 1746256488, "11.0.0", `{"artifact_id":"bar","group_id":"foo-"}`)
assertPackageVersion(34, 10, 1, 1746256488, "10.0.0", `{"artifact_id":"bar","group_id":"foo-"}`)
assertPackageVersion(35, 10, 1, 1746256488, "9.0.0", `{"artifact_id":"bar","group_id":"foo-"}`)
assertPackageVersion(36, 10, 1, 1746256488, "8.0.0", `{"artifact_id":"bar","group_id":"foo-"}`)
assertPackageVersion(37, 10, 1, 1746256488, "7.0.0", `{"artifact_id":"bar","group_id":"foo-"}`)
assertPackageVersion(38, 10, 1, 1746256488, "1.0-SNAPSHOT", `{"artifact_id":"bar","group_id":"foo-"}`)
}
func validatePackageFiles(t *testing.T, pfs []*packages.PackageFile) {
assertPackageVersion := func(pos, id, versionId, blobId, createdUnix int64, name string, isLead bool) {
pf := pfs[pos]
require.Equal(t, id, pf.ID)
require.Equal(t, versionId, pf.VersionID)
require.Equal(t, blobId, pf.BlobID)
require.Equal(t, name, pf.Name)
require.Equal(t, strings.ToLower(name), pf.LowerName)
require.Empty(t, pf.CompositeKey)
require.Equal(t, isLead, pf.IsLead)
require.EqualValues(t, createdUnix, pf.CreatedUnix)
require.Empty(t, pf.CompositeKey)
}
assertPackageVersion(0, 1, 1, 1, 1746256357, "parent-project-1.0-20250503.071237-1.pom", true)
assertPackageVersion(1, 3, 2, 3, 1746256358, "sub-module-1.0-20250503.071237-1.pom", true)
assertPackageVersion(2, 4, 2, 4, 1746256358, "sub-module-1.0-20250503.071237-1.jar", false)
assertPackageVersion(3, 6, 3, 6, 1746256360, "parent-project-7.0.0.pom", true)
assertPackageVersion(4, 7, 4, 7, 1746256361, "sub-module-7.0.0.pom", true)
assertPackageVersion(5, 8, 4, 8, 1746256361, "sub-module-7.0.0.jar", false)
assertPackageVersion(6, 9, 5, 9, 1746256364, "parent-project-7.0.0.pom", true)
assertPackageVersion(7, 10, 6, 7, 1746256365, "sub-module-7.0.0.pom", true)
assertPackageVersion(8, 11, 6, 10, 1746256365, "sub-module-7.0.0.jar", false)
// new versionId 7 -> 38
assertPackageVersion(9, 12, 38, 11, 1746256367, "bar-1.0-20250503.071248-1.pom", true)
// new versionId 37
assertPackageVersion(10, 14, 37, 13, 1746256370, "bar-7.0.0.pom", true)
assertPackageVersion(11, 15, 7, 14, 1746256373, "-bar-1.0-20250503.071253-2.pom", true)
assertPackageVersion(12, 17, 8, 16, 1746256375, "-bar-7.0.0.pom", true)
assertPackageVersion(13, 18, 1, 1, 1746256385, "parent-project-1.0-20250503.071306-2.pom", true)
assertPackageVersion(14, 20, 2, 3, 1746256386, "sub-module-1.0-20250503.071306-2.pom", true)
assertPackageVersion(15, 21, 2, 18, 1746256386, "sub-module-1.0-20250503.071306-2.jar", false)
assertPackageVersion(16, 23, 9, 20, 1746256389, "parent-project-8.0.0.pom", true)
assertPackageVersion(17, 24, 10, 21, 1746256390, "sub-module-8.0.0.pom", true)
assertPackageVersion(18, 25, 10, 22, 1746256390, "sub-module-8.0.0.jar", false)
assertPackageVersion(19, 26, 11, 23, 1746256393, "parent-project-8.0.0.pom", true)
assertPackageVersion(20, 27, 12, 21, 1746256394, "sub-module-8.0.0.pom", true)
assertPackageVersion(21, 28, 12, 24, 1746256394, "sub-module-8.0.0.jar", false)
// new versionId 7 -> 38
assertPackageVersion(22, 29, 38, 11, 1746256397, "bar-1.0-20250503.071317-3.pom", true)
assertPackageVersion(23, 31, 36, 26, 1746256399, "bar-8.0.0.pom", true)
assertPackageVersion(24, 32, 7, 14, 1746256402, "-bar-1.0-20250503.071323-4.pom", true)
assertPackageVersion(25, 34, 13, 28, 1746256405, "-bar-8.0.0.pom", true)
assertPackageVersion(26, 35, 1, 1, 1746256415, "parent-project-1.0-20250503.071335-3.pom", true)
assertPackageVersion(27, 37, 2, 3, 1746256416, "sub-module-1.0-20250503.071335-3.pom", true)
assertPackageVersion(28, 38, 2, 30, 1746256416, "sub-module-1.0-20250503.071335-3.jar", false)
assertPackageVersion(29, 40, 14, 32, 1746256419, "parent-project-9.0.0.pom", true)
assertPackageVersion(30, 41, 15, 33, 1746256420, "sub-module-9.0.0.pom", true)
assertPackageVersion(31, 42, 15, 34, 1746256420, "sub-module-9.0.0.jar", false)
assertPackageVersion(32, 43, 16, 35, 1746256423, "parent-project-9.0.0.pom", true)
assertPackageVersion(33, 44, 17, 33, 1746256424, "sub-module-9.0.0.pom", true)
assertPackageVersion(34, 45, 17, 36, 1746256424, "sub-module-9.0.0.jar", false)
// new versionId 7 -> 38
assertPackageVersion(35, 46, 38, 11, 1746256427, "bar-1.0-20250503.071347-5.pom", true)
// new versionId 18 -> 35
assertPackageVersion(36, 48, 35, 38, 1746256429, "bar-9.0.0.pom", true)
assertPackageVersion(37, 49, 7, 14, 1746256432, "-bar-1.0-20250503.071353-6.pom", true)
assertPackageVersion(38, 51, 18, 40, 1746256435, "-bar-9.0.0.pom", true)
assertPackageVersion(39, 52, 1, 1, 1746256445, "parent-project-1.0-20250503.071405-4.pom", true)
assertPackageVersion(40, 54, 2, 3, 1746256446, "sub-module-1.0-20250503.071405-4.pom", true)
assertPackageVersion(41, 55, 2, 42, 1746256446, "sub-module-1.0-20250503.071405-4.jar", false)
assertPackageVersion(42, 57, 19, 44, 1746256449, "parent-project-10.0.0.pom", true)
assertPackageVersion(43, 58, 20, 45, 1746256450, "sub-module-10.0.0.pom", true)
assertPackageVersion(44, 59, 20, 46, 1746256450, "sub-module-10.0.0.jar", false)
assertPackageVersion(45, 60, 21, 47, 1746256452, "parent-project-10.0.0.pom", true)
assertPackageVersion(46, 61, 22, 45, 1746256453, "sub-module-10.0.0.pom", true)
assertPackageVersion(47, 62, 22, 48, 1746256453, "sub-module-10.0.0.jar", false)
// new versionId 7 -> 38
assertPackageVersion(48, 63, 38, 11, 1746256456, "bar-1.0-20250503.071416-7.pom", true)
// new versionId 34
assertPackageVersion(49, 65, 34, 50, 1746256459, "bar-10.0.0.pom", true)
assertPackageVersion(50, 66, 7, 14, 1746256461, "-bar-1.0-20250503.071422-8.pom", true)
assertPackageVersion(51, 68, 23, 52, 1746256464, "-bar-10.0.0.pom", true)
assertPackageVersion(52, 69, 1, 1, 1746256474, "parent-project-1.0-20250503.071435-5.pom", true)
assertPackageVersion(53, 70, 1, 53, 1746256474, "maven-metadata.xml", false)
assertPackageVersion(54, 71, 2, 3, 1746256475, "sub-module-1.0-20250503.071435-5.pom", true)
assertPackageVersion(55, 72, 2, 54, 1746256475, "sub-module-1.0-20250503.071435-5.jar", false)
assertPackageVersion(56, 73, 2, 55, 1746256476, "maven-metadata.xml", false)
assertPackageVersion(57, 74, 24, 56, 1746256478, "parent-project-11.0.0.pom", true)
assertPackageVersion(58, 75, 25, 57, 1746256479, "sub-module-11.0.0.pom", true)
assertPackageVersion(59, 76, 25, 58, 1746256479, "sub-module-11.0.0.jar", false)
assertPackageVersion(60, 77, 26, 59, 1746256482, "parent-project-11.0.0.pom", true)
assertPackageVersion(61, 78, 27, 57, 1746256483, "sub-module-11.0.0.pom", true)
assertPackageVersion(62, 79, 27, 60, 1746256483, "sub-module-11.0.0.jar", false)
// new versionId 7 -> 38
assertPackageVersion(63, 80, 38, 11, 1746256486, "bar-1.0-20250503.071446-9.pom", true)
// new versionId 33
assertPackageVersion(64, 82, 33, 62, 1746256488, "bar-11.0.0.pom", true)
assertPackageVersion(65, 83, 7, 14, 1746256491, "-bar-1.0-20250503.071451-10.pom", true)
assertPackageVersion(66, 84, 7, 63, 1746256491, "maven-metadata.xml", false)
assertPackageVersion(67, 85, 28, 64, 1746256494, "-bar-11.0.0.pom", true)
assertPackageVersion(68, 86, 29, 75, 174625649444986, "br-repo-jooq-1.2.4-sources.jar", false)
assertPackageVersion(69, 87, 29, 65, 174625649446161, "br-rest-webmvc-1.2.4.jar", false)
assertPackageVersion(70, 88, 29, 68, 174625649444734, "br-openapi-base-1.2.4.pom", true)
assertPackageVersion(71, 89, 29, 69, 174625649444746, "br-openapi-base-1.2.4.jar", false)
assertPackageVersion(72, 90, 29, 70, 174625649444775, "br-openapi-base-1.2.4-sources.jar", false)
assertPackageVersion(73, 91, 29, 78, 174625649444852, "br-parent-1.2.4.pom", true)
assertPackageVersion(74, 92, 29, 76, 174625649444900, "br-repo-in-memory-1.2.4.pom", true)
assertPackageVersion(75, 93, 29, 73, 174625649444911, "br-repo-in-memory-1.2.4.jar", false)
assertPackageVersion(76, 94, 29, 77, 174625649444922, "br-repo-in-memory-1.2.4-sources.jar", false)
assertPackageVersion(77, 95, 29, 74, 174625649444953, "br-repo-jooq-1.2.4.pom", true)
assertPackageVersion(78, 96, 29, 67, 174625649444969, "br-repo-jooq-1.2.4.jar", false)
assertPackageVersion(79, 97, 29, 71, 174625649446161, "br-rest-webmvc-1.2.4-sources.jar", false)
assertPackageVersion(80, 98, 29, 66, 174625649446195, "br-rest-webmvc-1.2.4.pom", true)
assertPackageVersion(81, 99, 29, 72, 174625649446217, "br-root-1.2.4.pom", true)
assertPackageVersion(82, 100, 30, 66, 174625649446311, "br-rest-webmvc-1.2.4.pom", true)
assertPackageVersion(83, 101, 30, 65, 174625649446312, "br-rest-webmvc-1.2.4.jar", false)
assertPackageVersion(84, 102, 30, 71, 174625649446312, "br-rest-webmvc-1.2.4-sources.jar", false)
// new versionId 31 -> 32
assertPackageVersion(85, 103, 32, 79, 1746280832, "bar-art-11.0.0.pom", true)
assertPackageVersion(86, 104, 31, 80, 1746280843, "art-11.0.0.pom", true)
}

View file

@ -0,0 +1,66 @@
- id: 1
owner_id: 2
repo_id: 0
type: maven
name: com.example-parent-project
lower_name: com.example-parent-project
semver_compatible: 0
is_internal: 0
- id: 2
owner_id: 2
repo_id: 0
type: maven
name: com.example-sub-module
lower_name: com.example-sub-module
semver_compatible: 0
is_internal: 0
- id: 3
owner_id: 1
repo_id: 0
type: maven
name: com.example-parent-project
lower_name: com.example-parent-project
semver_compatible: 0
is_internal: 0
- id: 4
owner_id: 1
repo_id: 0
type: maven
name: com.example-sub-module
lower_name: com.example-sub-module
semver_compatible: 0
is_internal: 0
- id: 5
owner_id: 1
repo_id: 0
type: maven
name: foo--bar
lower_name: foo--bar
semver_compatible: 0
is_internal: 0
# broken uploads
- id: 6
owner_id: 8
repo_id: 54
type: maven
name: com.broken-br-rest-webmvc
lower_name: com.broken-br-rest-webmvc
semver_compatible: 0
is_internal: 0
- id: 7
owner_id: 8
repo_id: 54
type: maven
name: com.broken-br-openapi-base
lower_name: com.broken-br-openapi-base
semver_compatible: 0
is_internal: 0
# collision
- id: 8
owner_id: 1
repo_id: 0
type: maven
name: group-bar-art
lower_name: group-bar-art
semver_compatible: 0
is_internal: 0

View file

@ -0,0 +1,641 @@
- id: 1
size: 1038
hash_md5: 6096f13928b6de3103a2bd4857fcf1fa
hash_sha1: bbdfeca76d178834b5750cd8d14b8a698847c554
hash_sha256: 82d2245520562132935dc1d0caa181df125587917de9f14ed9dfeb2f2f88f0f0
hash_sha512: 898896789a69a87252b44e13c253ecadfbe04867c8319931eccddf4fef57b04b066061792b515c17d4480e3bbafc82590781a0c3fd43c6a64abe0e5cff05e057
created_unix: 1746256357
hash_blake2b: null
- id: 2
size: 598
hash_md5: 390df8dad491a0aba1b5098801735d5b
hash_sha1: e96e2d1909a9dc88f6a34cdd2e34e2308d9a0283
hash_sha256: a292499ce09f7ec89fbcf97d7816dd7f9c90e3deb0163be5704a28e3eb0dc819
hash_sha512: 8ddb3201adbdb4bdf97d27f563db097a032f910fefcf64de1b09d533aaa44affb8622b037143ea620df1010bdba56e5206dff6bd9de4450e43ba214ac2bf67d9
created_unix: 1746256357
hash_blake2b: null
- id: 3
size: 763
hash_md5: bb4f70724a5c4197d91f9bf1e36e49c3
hash_sha1: 6fd741578f83b0f1d10dbc0a53f339e790d93c16
hash_sha256: e6e07ed923d3c316d4174449be423171bc46a8c6dad0c864d3d2b916eda5bb5f
hash_sha512: 773336c44e8cd5aa92c3b3c921418392661ae5a4c51305341e2766d39ad978e3dfdf4f4992bbcc88bdce3fb824b6a75b1e86a161211940d55e6a4715dab924c6
created_unix: 1746256358
hash_blake2b: null
- id: 4
size: 2099
hash_md5: 72dbbe63f0c475783e53cc8760183dbc
hash_sha1: c1f6bff52587f6cc11dd26549873e5dd4bfdf4df
hash_sha256: d79571250439111a13090e69b5dd5e3ba02f980fcf6aca46943f854a0762145f
hash_sha512: bda94c619b66d9c01e75385b2e77be630b38e70d8a4163894c059550d9c6bd8300656f9dbf6c81c06112061b18c4bdc32102019ed1dd151556bd02ba433175d4
created_unix: 1746256358
hash_blake2b: null
- id: 5
size: 765
hash_md5: dba88ff4468713b2de10b2151115a3cd
hash_sha1: f2ba30eda8fd818a8e435a720c242acd77db4498
hash_sha256: 5fc713fca3c8daeef084fc9bebc08c0dc49dfccbbd6da774180f6b57dab2a0b1
hash_sha512: 5b494fffce128d83a5a5891c2615709efa8ed2ab7bf557ba33c4d6cc4cc2386af11e74e0db28c162bb402a6e9cdfd270f2dadb033832e9cf313c6ac5ee5493b9
created_unix: 1746256358
hash_blake2b: null
- id: 6
size: 1031
hash_md5: 32aec2cc3a9369dbd7fd062267ddc0de
hash_sha1: 611b0d7b0e10574a87ca3fee6172f3b77b3fc824
hash_sha256: d53eaadc924150a5e5b7be4a0fdbbf20d2c996b01bb01f4388570815166fbabd
hash_sha512: f1b516945b8faf99e4943171c9b149114753b7cbe53707f901c7fa07f810662a8e2fe1a9dd4a7b1ee8989c4c26499c3e4ce5e233cadf5ee897dc5b4839353071
created_unix: 1746256360
hash_blake2b: null
- id: 7
size: 749
hash_md5: dadab7af17fffd4ba67b2161f0573840
hash_sha1: 8438861bf54c263273cfb3d85bd4aa060d983cfe
hash_sha256: 28acf9ad32b66ee2e02fe58e6c61aafd12fc299fdb9add83a6043244a5e211a6
hash_sha512: bf009a26ab2f863fe4571840fd5ea3586ceb02270e1d52319ae65a96709aa0b81cbbf95cbd28add5b8803e20431579a1e61cd98dc089febf4f471d309efb124a
created_unix: 1746256361
hash_blake2b: null
- id: 8
size: 2081
hash_md5: 65f26423829a7cda51535dfd8649927e
hash_sha1: c9436ace1e28aca3c546be746e8986f66a3beafd
hash_sha256: 9c2c053ac72e9fb571b6cd7a31019759126b5fae331753d8594cb8a0aa210e58
hash_sha512: 185728651b566828e8ee69cbd4d9fb331403c0f2e01bbf2e5be65d8e70a049390c78a08e5eff5ead7c070efaff7e3e7b4d13e8ca48d94f9b7a714be954259d94
created_unix: 1746256361
hash_blake2b: null
- id: 9
size: 1016
hash_md5: 8c19574fa57e395ce6f35d8d5644048d
hash_sha1: 0dea7bcebea9d4f506da68a5c3a592ab6bbb8150
hash_sha256: c31fcee243ed68fa575c7ffbacfacfdcb24001bd86e261475220d91603d4995c
hash_sha512: eb92ec4f81e9beba3473f4504f8bb387aeac632a70a5016b27b6527ac70dcc4c940fb940a225452892701b8e6ecfdcd3858b6bd74b87f94a3b5f5bb1de369645
created_unix: 1746256364
hash_blake2b: null
- id: 10
size: 2081
hash_md5: 42e97d6c79d8c7dfa4f80c90534a3a7e
hash_sha1: edeb74a2a1a05ad4851629b90b65463559976995
hash_sha256: 228213798b1af7033aed779446cb5a657b765f72dc47626ca2a0ad7aaca846e6
hash_sha512: 65d83d6a96e8b59ec0ae35a184a8bbe844e572eb7b2c66b022f92925dc31edcad02312e59d1312d944ee1ace163729e6d0ec95b1c97163c61a19b40b18156cca
created_unix: 1746256365
hash_blake2b: null
- id: 11
size: 947
hash_md5: a1aa1f55f9579b5b81d2b2c797677d3a
hash_sha1: 27f82af8e6580ad7fecad111665666cb08f90274
hash_sha256: ec8b8d74a0074f391e5b9fb25f4924c5dc30e8767df07096f7ea9b4f038fe0a2
hash_sha512: eb59b7154f208bfbc5da207b7fbe8288917d637bd2ad09f60e525d1208ab41a5a312d349715b527012f46b32351494bff7f5c6510b4521fda0c9164afc87b50c
created_unix: 1746256367
hash_blake2b: null
- id: 12
size: 580
hash_md5: a4e26488fa83b5945d1c0373fe07d6c0
hash_sha1: 891cde56160342b16e4e3eab187487b1e7d4c155
hash_sha256: 8d27bf11781cad6d864da15e7b04080a6b1c4f8908d2e5baba79b855f6049194
hash_sha512: ea05ff7b6e8566609063f3492c0b2551ae1275912b8c370c5345fadda9e3a408d0879c749a94160e180161eb7727a93d7a3a8aaa1dde892f75748fc4d62fece5
created_unix: 1746256368
hash_blake2b: null
- id: 13
size: 940
hash_md5: 2b1ec34161144a7100b6988347f80e4c
hash_sha1: 29e71c96e109efccb8a7f756c1828e16b19d5303
hash_sha256: 97b8e8d2bf656e30a60328054fe47cb901ebe3aa7a4c30fa7f4cdbe1b2600663
hash_sha512: 8fb46a5898cb29eebac4a73b7c02dbcfe5c596c8f273b8e4483ea5778a3475718e792ec50b031879146e6072e396b022fdc6ee1cbf83369acdc0ee341cc9090c
created_unix: 1746256370
hash_blake2b: null
- id: 14
size: 947
hash_md5: 086cba5b2139e72ea02ba0ba40bb1cef
hash_sha1: e62e69071a629c0c46465e132b530b33da90a49d
hash_sha256: 51c4395507768e97e7e6426f6acf0b054eb64fcdb5cff64b78680a013c8dbe14
hash_sha512: ced379957d362b70a60f188d6c8c24ef2b3bc9828b32314a629574dea760c17225f1ef91875e9906ba4063fcff522fcd1d8c47d0a9a1ee9c6fe6d28d35219aa3
created_unix: 1746256373
hash_blake2b: null
- id: 15
size: 580
hash_md5: 4091fac7a4f1754f86ddcc52734d5628
hash_sha1: 5478354b11895f4495337e6c1ffd1480a05c4558
hash_sha256: 930a7c95b67d8f6bcef5587a522b945f16840d7466ca45408b43a320ae28ec11
hash_sha512: 93b69bc6c84fd03e66d42c49620d1efed6f3354598b82937528347b67088ed4042705b85989cbb9ce59c256cfc9fef8a706c3f149511643ceafbc88d660404fb
created_unix: 1746256373
hash_blake2b: null
- id: 16
size: 940
hash_md5: 0714ceb54fbe397bd632a61e66498265
hash_sha1: d66dc74c7f5a092c266aaa18d236840e2ab1b7e7
hash_sha256: 6a8557a171e8808ed59b3e2c95f9499851e4a222654fa7320d3658c094bbc40d
hash_sha512: a6b34065742e12611f3df651d7b3c859d7f4d058bfb7aee3901e69755aa13342720530a8d4a8253f2696389db0d2df6ecb0d4068d7c747d7f480ec2fcb3846c1
created_unix: 1746256375
hash_blake2b: null
- id: 17
size: 598
hash_md5: 65e94a8db881efaf0944e26c8c8262f0
hash_sha1: 60b143474f8dd311ccdd3eb08a1589a3f8b757df
hash_sha256: 9ffad7e3c4c868a02c08b5956e67a4ae86b3a516ef56ca3345d6e8416e7585fd
hash_sha512: 1441415dce05f8f2d44027bc5c78133e8a757454d3b26171e576d154c23b81d97ae8ed59861ee072e15ece88dfb187d53cd052972af46d35880cabc9fe31d670
created_unix: 1746256385
hash_blake2b: null
- id: 18
size: 2099
hash_md5: 8e3ec93159d2190db2f80778756d33af
hash_sha1: 65a0719f6c8a19768852a7314fc3672c6f992347
hash_sha256: 2bdd4a5ebe1a6ac3043cb56485051a8b3332a16b6461899c3fd298156ebae4e6
hash_sha512: e33122f943f62ba64bdf16c9249495e643b836c756252de9d001069de6367792bfdfe22e00f689663b88e661309cd5d1af2a7dc6ab24a96e5542db065dfa5230
created_unix: 1746256386
hash_blake2b: null
- id: 19
size: 765
hash_md5: 823b9b5f66afb761bfd3db0d5f7e7b35
hash_sha1: 822357b0ba18bb302272bd77227361beaac414d8
hash_sha256: 255da7936e3a5df32cd3ef0d8af7ecb9b273aee15d08932806ffa3feb0a15368
hash_sha512: ef0a455f0c7eb01403c51d85676a95d912622af4ea428fbf44818bcfd1b0a06d628decd27079f77d7913255ebfa0837411dbabf1b87d08caee3ca950a752f04a
created_unix: 1746256386
hash_blake2b: null
- id: 20
size: 1031
hash_md5: a3952027a659d6199f4b5f6534465bd4
hash_sha1: e14f78cd8cf1561cce5dabbee03778be99f298f1
hash_sha256: 1bc987782dc3aa48b2fedca48c13bbc752d7e55c642d5b2194db88940652cef0
hash_sha512: 34298f6f1cccddd5489d6bee98a3bb16efdfe78edf38c71c2641aa49e316bc8efc1fda3423026343336d1e76211ac535678c7f0b144b6580cb3eae8c9dcd37f2
created_unix: 1746256389
hash_blake2b: null
- id: 21
size: 749
hash_md5: 35decba84a82a8b52e9b81c29574ed82
hash_sha1: 1397366dbecb13de99f8caf9eb758afd23951824
hash_sha256: 060fb4fddb2d6b85cc5d49c531aedebdafd10638447ec7582122c2d6a05874bf
hash_sha512: 4dad39a4cf8d99f866492181bbda829a58123d1e5c70df06f83b2dc9690ccec149795f493ff814a7f2e32003033b47ea8d37ddbcce970f1a248a92b1ed791769
created_unix: 1746256390
hash_blake2b: null
- id: 22
size: 2081
hash_md5: 8f02a5a705e82c7b4cd279714095f43e
hash_sha1: 0cd14ac45ee96a739e74921b11fd39145240be23
hash_sha256: bbc981db64f0cb352740e76df76452ccc1c0a5c0bc73929d63cbd12033976cf3
hash_sha512: 66bb3adec4666246c27844f89eaed600863a6e93143064d4edba1494efc474e095997e462480bd928680f090639205b8917486815181f3399115f21ce1233ad4
created_unix: 1746256390
hash_blake2b: null
- id: 23
size: 1016
hash_md5: 9f446caee85b293c8b7aafadf38973d4
hash_sha1: 446a2c6fc2dda6ad2e00818afdff8771211ed08d
hash_sha256: 1379abf81c435e90cc4e9658bd7d6fad4437bf92bbc8610c2e0ed12e57e03150
hash_sha512: ed7a09670cd9cc74ce977c2a24f6ed98e2d72de7abc37ccf077c56f78320bcb37fdc702743837ded3d25d8b4dcab75e0559649486ba589a657a1b72954c2d8fb
created_unix: 1746256393
hash_blake2b: null
- id: 24
size: 2081
hash_md5: 799454b1553262175f9f151a037e922e
hash_sha1: d56f9adcd116fd93d11d3692440bd6bd033c9e5a
hash_sha256: 4c6051a3051e44e747f38cc3fe96d20a2bc4272dc25cc0c374eca4d3bd45884b
hash_sha512: 7243936532054ee059bf8bc996a23e80ff5ec90ce5724235ec91e13ed501693dfe881f78e70dde01cb2f3ad1de428fdf0c86a740dc473f7401159bb1719ad59a
created_unix: 1746256394
hash_blake2b: null
- id: 25
size: 580
hash_md5: 7ca05a7b4ef9c35504122ea71260a7ac
hash_sha1: dc9091893ec24b36d8e88ec1d64e58fed315744c
hash_sha256: f6cb7d1d54e02ddf93e1f1d9a9131f12770d19cc2432982f4af33a42f9d2f8ea
hash_sha512: d011cb7f41761ec032fa1c0ecd5733fe152d07a498f7d048e7ff0fe9e04cbc472594795ee427c86d71e104cc36bb4765fe652457bf02f6cfafb39bce1554e9e5
created_unix: 1746256397
hash_blake2b: null
- id: 26
size: 940
hash_md5: 979ff1d9d17988d15d74a9125f2ec53f
hash_sha1: aa540f051f67d77d27edc2468addd77f50a9e134
hash_sha256: 1983f79e2cc3b39feada90a938d6b06772e87ec74a40540a347bad3f367824fb
hash_sha512: 2c8b53b796990c028cafe26d20183b4a3ddb0221274756d68a81c8cd3f00dc1de2e8346a9e9f83ccc119e94bc058576f96bc633be6a6499806877c42912d1208
created_unix: 1746256399
hash_blake2b: null
- id: 27
size: 580
hash_md5: e8c6c698b114078242994350e2c59cfe
hash_sha1: 965f728ce742af25f364f840e05b9cd8c21e4505
hash_sha256: b83a283c38737abcbb23462117ef35e6ee4a4d86513a2440bb4d41fa0e117dc9
hash_sha512: 418aaf3bcd26cf63856e36ddba8c972ea99a764c25ed9fcfe6003236f6cc1e812885bf153d6f8a1b9fe712a3af04d4d99ea4d87a57ce06663f285cc1388a34b5
created_unix: 1746256402
hash_blake2b: null
- id: 28
size: 940
hash_md5: 4831302596f19f696b56d59564d1991d
hash_sha1: 92e6531a2e7bc42727d4ff455efa8f1408c38c55
hash_sha256: b24b3aeb82d6dd3d532f6047e0b697b062fb10f2c4e1849b11eb1a7494450578
hash_sha512: ef61c607cec6ab378cbf2522c985fe699ab2843072068e0809f06ae02c7d9b8476663104ffded3af3c96335d0db817bb78dbbc062dc48ed84b104826cb4642a6
created_unix: 1746256405
hash_blake2b: null
- id: 29
size: 598
hash_md5: 56a57f536a07cfd465c022e69bfc064d
hash_sha1: 4fd298455cddb9a0381410e5e05bcebb54d66639
hash_sha256: e8b37be762d1ab0fc8bbc297ba1b27c507d0098a287973c3b7003772839d81ce
hash_sha512: e1ed956616b3314eb247cf24586b36ce90435635ae40b57814c7a6cf0ef92c38bf13fbc2f07895ca6f67dfb9c3b9c0b4cf5556d69320b424dca989d1e4f74856
created_unix: 1746256415
hash_blake2b: null
- id: 30
size: 2099
hash_md5: 4bc4c156c6a6a6d421e6b2a0f9bad601
hash_sha1: 7c8746c62bb8418d1570fd0884cf9f846e055ffa
hash_sha256: 3f56bd9d542d9b944c47fb946277d72445ef2d34dfee108ea3a8c2d06dbca50b
hash_sha512: 7b47cc1e588c8e358cc29aa2135bcccb0f919bfbd9bc26b8342a352f4fdde3f3d2b5ad935c1efd6fc2d9e7cec5b1dc5c3e6630c9b3b979e47ff4fbce7863ea3d
created_unix: 1746256416
hash_blake2b: null
- id: 31
size: 765
hash_md5: 5c30fe5aa7e261d6c6575cc8265697a1
hash_sha1: cdc6f4ed95e723af264f3b6aae46bd0a98deacea
hash_sha256: fc9e302e423b982dad68720d5f940452a312cf3c287a96dc66582460265a1b01
hash_sha512: 079c9cdc9a919dac4225f42c26ffb34d4d115db8ab5e51cbcdd2b248f06935dfcb169f0a9e04f49b143615dafd5a6742ed231a1be13bc5c814af75ae173bd0e0
created_unix: 1746256416
hash_blake2b: null
- id: 32
size: 1031
hash_md5: 0a379e399f7918290e303348c8cd6b07
hash_sha1: ab53de2814344cfd8998d209c6927a415df147ff
hash_sha256: 2267f735bd581417efae14f797ece94779fcea40ab28ac700734c0ee38b284e2
hash_sha512: 967ebc462c40ecda18ad36abba96534459d8c653c14628ea2d8a2f1e18b313b2cf07d36080cce0aed921780b7717913ab1a77063632845d0daebb4d93bee595e
created_unix: 1746256419
hash_blake2b: null
- id: 33
size: 749
hash_md5: 861a7d2013e965382bb9404175aa4f44
hash_sha1: caf88fc255776f9460c5bd689973a66f528d447f
hash_sha256: 9c592110208bcd6624661c36180ce96f238dbe6c6f9ad9749a0d3df828172743
hash_sha512: f7a6a16bf8c972fc12871030e3b681c1341b2eccc047f64904b2e6139f8f41015387d517e1ae0e9a19fde8dd0c3d9188db3e433120618f096e7894d3646c765e
created_unix: 1746256420
hash_blake2b: null
- id: 34
size: 2081
hash_md5: d05558896004f742e8bbe6bbb318deda
hash_sha1: 2537f2f2127f5bfeb43ab064aaabb8278ad4bc08
hash_sha256: 4e931208c50f458bd523ef5ef55c5367335c62d558be4e24615dd200a75c378d
hash_sha512: 8a4fece3a1dd51c870c160d526e58fc96c3282dd770a1e9ce38b39492cda676dd48ecf258ba3282ed081997142503967a7114646481cde6d5b7eb7be49fcff37
created_unix: 1746256420
hash_blake2b: null
- id: 35
size: 1016
hash_md5: 835a5a3fe19145a134e4a0508fbb9411
hash_sha1: 707c30bed611042d57c52d0db2bcd0f609016a5a
hash_sha256: 650248c779adbb13c81316902d4b7b27ef294530b0bbd484a3f3a1d369ca995b
hash_sha512: 81810ccaf38ad57a9e384336f872d2f39da9474abd648024e8da6733c9d0fd214757563cc7c8a7dcff12cd3e64ba4b694afa6854a6f55bd4e5a53152eef6a7f2
created_unix: 1746256423
hash_blake2b: null
- id: 36
size: 2081
hash_md5: 599464902943b0e7499180d1c2547754
hash_sha1: cab101f1bb3a73e91c3d75f7897067fb29c7747a
hash_sha256: 5e960e634845737a49b2bf758496e2a42cfb227ab24455a9d182bde7f597d4a6
hash_sha512: 759dde21a878216a6e629bdbd91e2fa4dcc04b7c56116683b5c7433eba277ca3f17daf918c4575130dd14a6d2dcf453bc7861f7e99b7abf150c3b058a299743e
created_unix: 1746256424
hash_blake2b: null
- id: 37
size: 580
hash_md5: 6e23997166dfb6e2bf3cddb0d7a7f6ff
hash_sha1: a9972937cb840e3c961fa00ed8512c45fa9d75a3
hash_sha256: c95111d06b75e32cf4d507b818544dbb5245bc0b7dd8b3a1f5d8479772a06b1e
hash_sha512: ca549fae977e7fcda088e3211d362a3636c47bd914e2c5ce08ddff2703e60b06dbd66339bae819c881425364f679f1839b1e0685f3bced32747a969d00775a8c
created_unix: 1746256427
hash_blake2b: null
- id: 38
size: 940
hash_md5: bda9707822e39ed52a6d0b9bb5e9af96
hash_sha1: f6ea322c0b9c6211747129636a59ff95e5dbb165
hash_sha256: 364f44514fb924cfcddc84c31bbf3dccf9060d9e3ef1e3e6dd28f5789a79e4c6
hash_sha512: 7636858249476a81c886c529997eb55ef8c36c52430f0e98050f628fcd440dc09e57f43f88e272f827f86c95451aa4b1927a8d860f970427d1df8348590e7869
created_unix: 1746256429
hash_blake2b: null
- id: 39
size: 580
hash_md5: 5b373c943e67125442c5a573eece9404
hash_sha1: 84b40e3373b8c172d8c302dd304f792838a3f788
hash_sha256: d6355300d7e51c649efe19b3419d0dec57d42d4c75079e4ca06ea081f8260f5c
hash_sha512: bd926b535bd19f60d69d76a858db2c48f6057223bc23a3575a4fb49fc9ea455250f2bdedad09efdb098c4ac16c6e3d2451a6c182ef191f076276de790448506f
created_unix: 1746256432
hash_blake2b: null
- id: 40
size: 940
hash_md5: e3817ea0b2f58dd5cc570c0d337a2ecd
hash_sha1: 2acc853133cb0ddb46a546fb31f7b4f23df1c676
hash_sha256: 775271730e0c4b923a81f539ce97d1b21a1db78ca201065dc886fd42d4e0251b
hash_sha512: cb28a65b2f5f7e1e9ec45f6151ed322ee751de5266f413940655de7d739ebf2f7ac9168ccd9676e5b1696d3dcfb57d0bbc404141dfb321a2d28c1a6dcf32b0a7
created_unix: 1746256435
hash_blake2b: null
- id: 41
size: 598
hash_md5: fb3df5314eda77cfc0da782d86a1574e
hash_sha1: 874c3e4aeaad0dcb91f955357c008ed3de52883f
hash_sha256: a1f80fc25f3a4cacc21c4ab3e263cc722f7e44bc829a38e7fa927853737cbf9c
hash_sha512: b27519f9792ac72b715ff591895deba46d4c6455ea04a4b416e8c5a13eb234176ebd85a21cee5b473f3baa679c6c03cfb72d6d552dee7baa9e7d75535c776557
created_unix: 1746256445
hash_blake2b: null
- id: 42
size: 2099
hash_md5: f12303e4cfd6cb446c8411f8c2c5c54d
hash_sha1: 74af4b51471a501f0fd65ff19498cda87c8252d3
hash_sha256: 9fde3ad1d6dc79a40d9ef1c41bb22d00db53df558c0f4d305aaddc0dc2cc0bba
hash_sha512: 0f19704ff822157723138bbbf027d418a601cbe0fd21db16478d6e870ad74b80084d5aa35d529a2c6555237cfea19a6c1f955df0c4b00b5ed94f0f1b42465bd6
created_unix: 1746256446
hash_blake2b: null
- id: 43
size: 765
hash_md5: 0ee9f9dbd150f2fba1f2d151243a23ea
hash_sha1: 521db5e9e0e2d25e8b80c9a168ece7263e0b548c
hash_sha256: 034554ebaf63c4c20d9290e86b45375616b4e289a28e480f58e25a791c361639
hash_sha512: 23ba0f0847083365fbbd0c4de0d71a6560e50781f413e1546a11e9d9d4aad7daee1116b5b94844ee0a431f4d70796561a337a648ec052ac3c5e4bad5accf73ea
created_unix: 1746256446
hash_blake2b: null
- id: 44
size: 1032
hash_md5: c4c544a801fb99281c6c473c22e0545b
hash_sha1: 1c686f728522cb8387a8415a259c62c1af8a0fd1
hash_sha256: ce8c82a53d379498784a981f3c69d847947420fb7e1077f5a2b3d9f41fb7c8ed
hash_sha512: d9d1bb2a1bcc7886f8c2fd5a413cd954fe2043d4a81dbb1f9ace06a1676684047a7ef2bdc27c9d3f9b800657dbf7226acc0f32b71fc6dc0c9e2662a5c64f7fea
created_unix: 1746256449
hash_blake2b: null
- id: 45
size: 751
hash_md5: 89b82f20b8be3ea17a068b46e7497428
hash_sha1: 27f1389a68febf6786e0d79c698dd1d66c9abfd2
hash_sha256: db4ea60e526f85e9829a45e2d75c1f48509e7429a79f7a5d24bc536596c66ab5
hash_sha512: b441c6ba00bfcca18adaa976ac37bbf9cab17cac8e7d24e54bc40122dec33781faec7b07db97b3dcaefec7ff8a4251e96728772995d91d196691d8e3494b5768
created_unix: 1746256450
hash_blake2b: null
- id: 46
size: 2081
hash_md5: 96d24b1f1bec73579c5dbf85ee52b332
hash_sha1: 4f407843baaa58116c1022b73f5e411f1c531840
hash_sha256: 6866d5d85796b5fc8576310f8ed1d9d9c85825727007809cfc9ff666f1dbdbf0
hash_sha512: 8c7c62afaeec008d7c6bc8e390f4adbb11c4ca11337aa1c6832ba83de19f0c75d52ea4fd72a822acdc4f567158120119ed121e0b68213db7a7a7a4f3a731f8fb
created_unix: 1746256450
hash_blake2b: null
- id: 47
size: 1017
hash_md5: 71a491bc2a2bbb08ec5b3682d09c3f1f
hash_sha1: a126e70bed9837bf4609f32d74b20d2ca3e47b59
hash_sha256: 2bcacea4eefed11c6f6a23da44ddd575689460262af046a37872e32aa76b79c3
hash_sha512: d647d5f7122d76928ac349bdb147fad8b2cd68b7be75a4f580c768feaf86c5e1f7ec484786b6c81324b9df00329cc89217cb00d379138b40adfc81f74d06e6bb
created_unix: 1746256452
hash_blake2b: null
- id: 48
size: 2081
hash_md5: 26e05a44a2e1989b418aac50feda163e
hash_sha1: 224cefa64086537d1d571644abc2180803128035
hash_sha256: ea09c61dff5dec488b378b2ce0d4dd64891394606aa318dd57d5f2158d7441fd
hash_sha512: 4ca6c77760a11e44f7826b3a23bd5b607ab1e323f47aa76acd9226f1771551fa4dd45c58002c8d3ba6fc4867ed17ad34edb1695a9ab94a31afb8255862633976
created_unix: 1746256453
hash_blake2b: null
- id: 49
size: 580
hash_md5: a9e65f66ed8ba4769f366fc93142ae07
hash_sha1: c170e29851dc3fb44e115a907de7152efd5fb85e
hash_sha256: 8ae9c630848588ab6bafebbc6ebcb3b6fe329350e89894852db5c55cc52a4c2c
hash_sha512: e0bdaf7430a5176640c0fd57910e1b3e98b4dcc0d34a5a4e898be6c30ccd2d3b59c22dcf94619e3349003ba7b7882ab43216d6175471becffd874143d74ace17
created_unix: 1746256456
hash_blake2b: null
- id: 50
size: 941
hash_md5: accc00b46ba0c6abc545ed79c2a2f88b
hash_sha1: 44a47e8601fe1785bbabc21dbc9efc61ff16d47f
hash_sha256: 6f514c55dca294288b5821f415cd24ba11649f001edcfe219e1052d252fd49d8
hash_sha512: 9ee7ebd7280fdb51f46610a7923212236b668e7a62a083bae7f2e2f1472d06cb0a9d0f38069e5537fa3b8689f13abeb3e38a1e8432d55f247a06c0522e74374e
created_unix: 1746256459
hash_blake2b: null
- id: 51
size: 580
hash_md5: 700171de0c83b136769d88af94c1b9b3
hash_sha1: c3baca0fb897aeb9462f3718369a30515a68e415
hash_sha256: 96eec3e81eebd724a3ef0e6215e337543b3979f2a3355a193933dc7489aa4616
hash_sha512: bfb5bb19da1aa65d7cc78ad4f3c57769aefef90ffd5edab3ecd0db5272550bb0666de00acb2a053e03a9473e09d9a77b5026e46bbe18cf669ec4e953b49256c9
created_unix: 1746256462
hash_blake2b: null
- id: 52
size: 941
hash_md5: 613b6c98a027fc929ecdb06482859626
hash_sha1: 39878c4f57ff81bcdc2ce191c44a9a9b31384646
hash_sha256: 78fe74176a46873c6fe0c519270641ea45b3e879b1d4caa595bf67dc69d760b0
hash_sha512: 16c23e52c02fa0d30dd60704299a375eb6ca75c3fb471fa3501720e53118254bc8888dbf44f75c3cdb2a98ac0ff9ae6fff72e9026fa9a241eaa25841f4fbdaaf
created_unix: 1746256464
hash_blake2b: null
- id: 53
size: 598
hash_md5: f3015c6cc30b064cd13392a252b61038
hash_sha1: 5b6a6ba01238ec187d18ed02f080456d9b0d8416
hash_sha256: c331e46fb09c0bcc4aa8019b39d9ed7ddfacbcd139407557f6089f36e5861c57
hash_sha512: 64d91206800c8fcc22e449591952289fb83eff85dcc2bf898f2daab66d40ff4e8f9b665335b7a6bd2c0663d78a2ddf1debef923f3306f6813dae98caf02a0f95
created_unix: 1746256474
hash_blake2b: 1ae012597dbf2d40644c82e06dc6267d88638571b0c669c62e59d15463c289e170f602420e0147da1f9524cea5095f63868bc36ab5630383360e8101b3796d49
- id: 54
size: 2099
hash_md5: 84d83643c58073eb48d88ae591920e50
hash_sha1: ef931c2b87b9e2c10b7bbb2bb592cb5dbe82aed7
hash_sha256: 8b554f322b8fce952f2221bf08be8447b8606e2ce54d8846b5edcc80ec1fbafd
hash_sha512: a2b1a5321f67ed8a324e17903497fac845169cbbb49cc3dfdad9800b164877a7d8f5fcc8f9d6a8e2b394cb13c9a512b27e39149f3b017dd28f26cfcb168fc4c6
created_unix: 1746256475
hash_blake2b: e4ca11cdd35926a89604589782e538c8140911fef2dad8a934685b33ad841e3cc96ea9d36c90ae413147ce2cabe6c5517045320049fbb3b0069f3620df753bfc
- id: 55
size: 765
hash_md5: 1e9a236068db2f888b41ad1737e26764
hash_sha1: 03c5b9eb6e2fea31d3e774c51d3719227810414b
hash_sha256: b117af5eaca1f723b7fc3646853298bbffddbb02c63af5cf09d853f0585afb89
hash_sha512: c24ff96a33c8eb5f96a212923e1381d41e2813be978772f407aac30090c8657558427b40cbc129dc8b43b96c988ab888703ef5d5e139dff32bf727041a90fca5
created_unix: 1746256476
hash_blake2b: f4549d79377a1d01fd8c0a19d4a015dfcc50b58820d57ec7bd14fdc5fbaa8166fdd11432200d728d5f1052e54cab2069c8f80818616377c1baa1013fc7679356
- id: 56
size: 1032
hash_md5: 6cda2dee8f57ccc1730f40917a6ec85c
hash_sha1: 9689d59af6cf615be6ac21106dcbcc79250b2909
hash_sha256: 012e2bbd675130a45b6b6255142254428a86b35c5cffd17546331e9f1bbadb55
hash_sha512: 06b79141428bb93d1ba14a82f132dd068ac4b68db3e55029a25ff4bd2be6274a33898f263dc225eed1186462f7eb3fa4e7a24925e996dda0dd1bdbd265eef6b4
created_unix: 1746256478
hash_blake2b: 0e148046a9984fe45d2109d227ed31b58329afc532eee4817d2113584ff034aa1c5ff09d44240c715d9a80a1a3ea89480bfb425e173df154aedde6398e2ec347
- id: 57
size: 751
hash_md5: 00c8d9ca6462b0e95a30325307a1d855
hash_sha1: 525a79e7dfe6553e5e4b4057e80e090d48b43c84
hash_sha256: 5b74c950ced8330e3dae432f6c5b0330c6c8e3a72f706f2d8128db989640a02a
hash_sha512: 0777a9af5eb936fe5c1a28bb5df26c06db7e290f858cb1ac2e7717236c9be949e8bb214d4007b865ed9d22776b5abd4f8f1e16f862beb9d2db7388f16c9f0ac4
created_unix: 1746256479
hash_blake2b: 65ed24d1a672a0ec358359f0f9b1dcefce0b64fb8ebaf0342dcf5fd9826b3664a95ac54628a9c245ddfac0843ff36f70de3dff288d5782c54539e1a95c0466d4
- id: 58
size: 2082
hash_md5: 610e6b411ad6a885613f3df4e022e8c2
hash_sha1: 5090aa11b88cc5c22895fdcd9e303eb5f89b414f
hash_sha256: b87955056b214c1404e58c6e60d2e8b203c249ed141ba80ef6e2d22e4d62d187
hash_sha512: c70e98ee7f6b22b427aed9232abdab8380385c841cb6d93af25328bc0a4ed0d1aa4342b363850fde06a1c4f68b0b63c2da99fa36e5934aed5314cdcf6e47e830
created_unix: 1746256479
hash_blake2b: e3d37152d65d1874f932f18ad0325b8bad850dd220e6f81f99ce58b3117a7f9ee40a3467992d8be78988af7434a5303f264cb5bdf4d4ab66752904a55fe4ac44
- id: 59
size: 1017
hash_md5: 155aada9969270a2d3cc9e7cbd72398d
hash_sha1: 6f7140f45bbf17a98d8b51f87c6672c30cbfe114
hash_sha256: 3ff912d0c3e4a91d6f5394d8af0a361ca7f183ff6f8a606a32e68e80d4341300
hash_sha512: 04558b2154b25463060f6ac999426e816682c7b6e866bf3b9198b4b6cf41288f762439871858831bee627559906e920b478c21525e3ddf85b9896d55840775c5
created_unix: 1746256482
hash_blake2b: 485c3a16ff1036dfbc05cc55bbb175d5e782b16a97bc4b47fb29b3af824abab016f808fc6cdc96690c4f657b4acadd69bbcf0dec7dc478c91dd09137b7cb3e2f
- id: 60
size: 2082
hash_md5: dc9d45bb32e8f3490634bd513cbf9ece
hash_sha1: ea91296f560ab8eb978b7ed0db8efe2fd0e8b413
hash_sha256: acf6b1fc9b5b93d9832b6c59e58feb352fd8b07e04356b4b60bbc35dd77c3aac
hash_sha512: ff31a45035f8092995bd6ff8e55e6fa35cdcaa4aeaf296da0382657d080541f49687a5adeccbde9ebac0fdbe814ac1e080e7f266bb38acfacd038ce0a6b6a632
created_unix: 1746256483
hash_blake2b: e24f6cd27d8702026d8d750734fd28d36b1621d8bc7bad18b403b61d0390829a31db679aeea559b7b3f7df27212cad968415d67a72c33abf5744cd61e96e8080
- id: 61
size: 580
hash_md5: efddf19ae15f14a76ad89882c5687f1e
hash_sha1: 4241c3e18d179d31a02032e6fbb31014adf9f3f5
hash_sha256: eee31b528413c52085cc0b0aa0245ac472cfd364e80fde1c5386e78e75372890
hash_sha512: cb752b230dd53a380573dcbd2d406a497ad9279b4fff5fe7de493c34d354de35f343788673830f59912651c1eab81da04513f3ecef0ab6a30dc2f1b39fd9701c
created_unix: 1746256486
hash_blake2b: 02729bb20121140d8f8904adc712dd7432fb1117bba8a3d878b86aa59afdb3e6d26e3d597b072b0364666fea48c2c5721d5d3bdabb12241267d7fbed0668c927
- id: 62
size: 941
hash_md5: 0aeb1040c1716c32a6ee5a3da7e4b7ca
hash_sha1: b7cca777ecd4e4d969f2e4c5e91d30fc7cb75070
hash_sha256: e2f0da45a23db0feddb37e44fbf6600e69187530e52234fe1bcc7ce3d1bd2a28
hash_sha512: c3394a2adb2bc062cd0015751b5a0d64c7e2600a9dd15b7153782bc9c45f57a734bd6ef7d12d35f48bf2b281e5949d8846fd61612f162c227d19a8a0de1f2ce9
created_unix: 1746256488
hash_blake2b: 3fe0bc2e796722fa3c26146ab7f5690eba647ce9463e94266998c68cefc2a834092f92ecddd70d98d1e8774808ebd87df429248c61e73144332b8cd8a571b4b0
- id: 63
size: 582
hash_md5: 1262bc37cc2b04b123ae5c1e7a739c4c
hash_sha1: 2990625d65fed9184ea3da0553722c128dc962c4
hash_sha256: 49ef9afc4951add83afa570b9fef916c5bd22d236fd74752dbfb29944dac4db9
hash_sha512: 9012ae4e297da75320c057c78220f34c64889a1905c49467f4fce7400f87b2957ffa9b1f93b7048746d84320081ec7aa69338e2d57422e53cf3c06a5365f87ef
created_unix: 1746256491
hash_blake2b: a822759b7592218d9571f96ed3039dc934aab2b175476530926ff8bd874b94b05a9c6a275d8b3c2b50fc2efa67fd6045edb659bad9aa11e83044e53cc54564ec
- id: 64
size: 941
hash_md5: 53561653378116758da59c1e5682d024
hash_sha1: ac27f3a6e7bd048aaa784273b6bfc92030708065
hash_sha256: 1da9c5d5281b8467a86fe7fb015f3ebf1807d3d975c8555959399b91628d7b8f
hash_sha512: a97b7265b7df742c903d68b2358f0d14cfc2511c20d2c61a8f2a24505a5fbeaff624b2dd47eca988a3466f55ce7910c0831e7c1617b41a5e560dd584f8b8c28d
created_unix: 1746256494
hash_blake2b: b6a911084595fdcddbab8c70e5482a2cf038bfde93b27258978a42465d894b92725f9abc81646d28a9c4b80a773c6347aaf43cf7d2067135a15edc2f1ad40b08
# broken uploads
- id: 65
size: 66356
hash_md5: 298a5b68e9783c9f193f3818b6362c0b
hash_sha1: 20eecad725f7c40a579fd06f438fa366e9dc5887
hash_sha256: 6b6802be078be4c07b38b9d0a156521459c81d2cc742be8cf115398890baf95c
hash_sha512: 983db2a7ccdf88c8765bacaf6da98eaea04aebd42e1e67943172e7e862c8f62a88cfc96adaf59bb3ad65d889c39e7281f55eb7d706b281782e4c9d0690091d2f
created_unix: 1734346161
hash_blake2b: null
- id: 66
size: 2968
hash_md5: fa67973e250e94fb4a888ebdb4fa86d7
hash_sha1: dce5f1b461883dd50f9191d52aaab01a5a06e578
hash_sha256: aae8a7ee5a446ffbb59eb3e3a70ff8809b61cdc235105397e8550b30d12d145b
hash_sha512: 6b2f0e33da8204e72903a8f13f6ab4b77ef6b387453777e308088d8c44b925c1b1d226bd8836e32af89ce96a586de0ac0d7ebd351a9534fde7de73634b2fa802
created_unix: 1734346195
hash_blake2b: null
- id: 67
size: 64135
hash_md5: d9c454fa89301aed28ffc712cd230c56
hash_sha1: 9c4b65d14fda070c3248e9ad6da78ef118cd7bec
hash_sha256: 9a41e5fec8381a75c41c0e4cc5df56546bbc0ac70019e9ec3716bdf3f7c0da0e
hash_sha512: 04e706e34c62602ab129dcb3e817fe4d3b6843b823686c375cebc3cb6adfb758227cf02aca015a808d340a3aeda7424e9ce35de14456d1a8d40874782239f250
created_unix: 1734344969
hash_blake2b: null
- id: 68
size: 1053
hash_md5: d686ee5f6ce4b91cc317354f49cde759
hash_sha1: 8ff8b4d60a1062fe468ff5c310833151932ec628
hash_sha256: fd61ac88b2ad7760fd4798613bae50994a85e5346002409837f221a5120de03f
hash_sha512: d1705bb7dad6b70a6a9041276bfc41e1e265ac0b8ba65f0ee3bd680e3ad681d813f555b82e81ba162eaae37e5453846fb569c9d64498a69efcfbfa42bd75b82e
created_unix: 1734344734
hash_blake2b: null
- id: 69
size: 24995
hash_md5: 555c619b35ccc37ef448e0627e1c91bc
hash_sha1: 2715bef2d294e8ef9bd8142b8cb92b4f20930792
hash_sha256: 90769f198e34910cf842b36e1ae790e801656fa9dc8c072c8ce06a031c195dcb
hash_sha512: 1d1f5f1badc779bb387259dcd6bf4deec7b8d711e67b62b2c6c85c1f2a6aab3ed463c82e7f5c7d2060bddbd6797ffd070b4120a7d66eea8a57ee345de2822c8e
created_unix: 1734344746
hash_blake2b: null
- id: 70
size: 6307
hash_md5: 70833f96aba4e4aae6a66459e1f48640
hash_sha1: e049c72bc8f5990c1e63c0a9ed17c12b0096efe6
hash_sha256: 55f6f783455b4737078b1b7ec9361299ec336ad0982fdc70e8f861c69be847ca
hash_sha512: 8ac7ab63762560227892717c23a1ba2cd6b3f0a59cd8cfcaa86076c65e63dcbac8f0c47213dab21677f7583b672487ddbff28a4aa2446581e25f5d98edc70eca
created_unix: 1734344775
hash_blake2b: null
- id: 71
size: 14826
hash_md5: 426d22a7b0b57a8a00681191c4f22ae6
hash_sha1: 69781f39415518ae823d8745ce4720e743172019
hash_sha256: 0fd63dcc4af83babbdff690441ea9182a640ed9d40b1312cdb1b457b2a03f38f
hash_sha512: 681fa091abad08a33950f6a308f46ead8c9af8529a42032835c03c960f4578a744b44bd4773aef73438b25b42cc51302498424aead7198eff623f96de6914176
created_unix: 1734346161
hash_blake2b: null
- id: 72
size: 863
hash_md5: 9acc0ca46cfe4c2adfe0b6e5062a8a15
hash_sha1: 0d946b74eac616923103506ee350d82f6c9066bd
hash_sha256: f6641da8427411dcf13c15e7e10cabef802383d859301ffc2de0a49b0f213fc3
hash_sha512: 4ca12e3af7ca08d58307c610042c31775683011b47345064f213312211134cfe5919c71ba4211019565052364262ced0d9b7dffd058199a36c741f2fef39e2af
created_unix: 1734346217
hash_blake2b: null
- id: 73
size: 10272
hash_md5: 6a4f701abfb602e3838ba300f9cb6ccc
hash_sha1: 0e30a16b8e1b74c51abd08e33dc5341404b71e3b
hash_sha256: 0c3e7c7143843491b221af0225ad4205b48ab871aa66ff00bce4d3954b9e0987
hash_sha512: b917580c12f09044e117adca76bd1551df5fb92af1860851700b232d07445b2e8293bb73a9c18bfecc6e6d5dbb6df86d954d6a5d93d0442847f6168125fc91be
created_unix: 1734344911
hash_blake2b: null
- id: 74
size: 4229
hash_md5: 260b6982c5690d674ac546b3bcc743dc
hash_sha1: 8e3214aba795ae5849386dac742deb01caf04b8b
hash_sha256: ee2e1fe649bf8fc670b9ea5f34815d66c85ba7f8fcd861a557afb0aa9679f652
hash_sha512: 6c58c7d0eca2943f3a4a5a2785b961e00d18bf1a9d246879b487120e27f986a0364edb842748875f25244df1c9f939fb705086ad437fce4890f7c8e2b31a79ab
created_unix: 1734344953
hash_blake2b: null
- id: 75
size: 12410
hash_md5: c511f1c9b10762bd9f907e834d7d01cb
hash_sha1: 4998c52d0d23dd3d218e2d9d336f24c0c073601e
hash_sha256: cdcf5d6a2c273647885dc4d1a3da4d64922042a4a0bb16beaf561f29b7c59209
hash_sha512: 6db8db82f436cec9066b4174a280e0e5bbd21cc829cb2beaf2071fe6ff1f8c77a5a7e5e8a168a41551a21c98bf03e6441375c87dc64a0ef2646720f348d3927d
created_unix: 1734344986
hash_blake2b: null
- id: 76
size: 770
hash_md5: f123e1549bdb0cf99f89a8944f25d8f0
hash_sha1: 01507b6530a5b134a5c660765e0f552cdb5131d2
hash_sha256: 81bbd81ba91c24024c7d4790fa1cd5c25acfb7b9c7c4fa9814e0d9f399b6b622
hash_sha512: 0738901ad6678a9ab202d5a0356d8bc49c1ed1ec21922718ff706b0990446f78b87adf3bfd25273db8a8910dd7b19f8c232f469b1f65dacffafb6fde29182104
created_unix: 1734344900
hash_blake2b: null
- id: 77
size: 4034
hash_md5: 4bf84ceb6e877a385f40ad51166bfc1a
hash_sha1: eaf6225714366c3a05d4c56c20b034efd8a5f037
hash_sha256: f375ec85318662e1789bd34750e578cb2fcf99c2bf005ecc06fabf64e23daafc
hash_sha512: 470c5ed2bf14a7ed426453ff026ad2269bbd503ba8c2cd767c89793530c77a7e7e503c68ee542d125bbceda3b49cdc5c846931981eac739a865ffb0cabbe4d89
created_unix: 1734344922
hash_blake2b: null
- id: 78
size: 6088
hash_md5: 0a4d805af108af059f9af308168ddcfb
hash_sha1: bef8a000beaec4bbe5d68b008868d76c90f3f25d
hash_sha256: 5b055f5fa634434bdcde8b8174c783d768abb5a253ccef648bb522af603836ae
hash_sha512: 9254409431fa52da3144960c272e7aaa0bb646297601cbc6bf88f6c736903aa70943cb56fdbddfac096c10444de25bfd53084b2cf3139ef5b650aae38dd42c26
created_unix: 1734344852
hash_blake2b: null
- id: 79
size: 946
hash_md5: 3f78acb32897fd77fe467b9776744c12
hash_sha1: 3d70df43777d56ad3388ad0036979fcb77443b4c
hash_sha256: f9b8b7d3050abecc367bc1523cf5ec17282b5d7181ee833ced319cf382f92616
hash_sha512: 2886114ebaef9a77b21d7240591d376a0ef898986882e25e86e0633d465bb9e8096355a4ca6273eb9cf532f02efadd5195b786249986d7c2fafe40f94a8c5ca9
created_unix: 1746280832
hash_blake2b: cef2628cf51cca9907bdcc69f4e6cbc65c121d37eccb9eccc29fb11179a09af67dccbe0eb04fcd2b87b23925f96082f33feae5c9c550307ab6c6f260aa532f8b
- id: 80
size: 946
hash_md5: 222067385a69840b897fb1177a404876
hash_sha1: d56d3378e8492c6ceee3f967f41123fe59082770
hash_sha256: 3710e14622091c60701b5ee6357d80681ad3b236baf639d2f848887f0cf681a4
hash_sha512: 2de5f0f547b60272ce3da6933309f7c967b23a839c0b7321ae952c229241091033e0640c9e64a199b10936ea64bbc3520ff56a5b6cf339856ca3d089bd5d5487
created_unix: 1746280843
hash_blake2b: e7e3034bcbc26fba242f2d1c8ec4f653e175178e303b1d120adfed0eec2f6c674b29d5fec4ac2ecb862f491682af480c7d3234be633ad9b288cfdc29cd020beb

View file

@ -0,0 +1,698 @@
- id: 1
version_id: 1
blob_id: 1
name: parent-project-1.0-20250503.071237-1.pom
lower_name: parent-project-1.0-20250503.071237-1.pom
composite_key: ""
is_lead: 1
created_unix: 1746256357
- id: 3
version_id: 2
blob_id: 3
name: sub-module-1.0-20250503.071237-1.pom
lower_name: sub-module-1.0-20250503.071237-1.pom
composite_key: ""
is_lead: 1
created_unix: 1746256358
- id: 4
version_id: 2
blob_id: 4
name: sub-module-1.0-20250503.071237-1.jar
lower_name: sub-module-1.0-20250503.071237-1.jar
composite_key: ""
is_lead: 0
created_unix: 1746256358
- id: 6
version_id: 3
blob_id: 6
name: parent-project-7.0.0.pom
lower_name: parent-project-7.0.0.pom
composite_key: ""
is_lead: 1
created_unix: 1746256360
- id: 7
version_id: 4
blob_id: 7
name: sub-module-7.0.0.pom
lower_name: sub-module-7.0.0.pom
composite_key: ""
is_lead: 1
created_unix: 1746256361
- id: 8
version_id: 4
blob_id: 8
name: sub-module-7.0.0.jar
lower_name: sub-module-7.0.0.jar
composite_key: ""
is_lead: 0
created_unix: 1746256361
- id: 9
version_id: 5
blob_id: 9
name: parent-project-7.0.0.pom
lower_name: parent-project-7.0.0.pom
composite_key: ""
is_lead: 1
created_unix: 1746256364
- id: 10
version_id: 6
blob_id: 7
name: sub-module-7.0.0.pom
lower_name: sub-module-7.0.0.pom
composite_key: ""
is_lead: 1
created_unix: 1746256365
- id: 11
version_id: 6
blob_id: 10
name: sub-module-7.0.0.jar
lower_name: sub-module-7.0.0.jar
composite_key: ""
is_lead: 0
created_unix: 1746256365
- id: 12
version_id: 7
blob_id: 11
name: bar-1.0-20250503.071248-1.pom
lower_name: bar-1.0-20250503.071248-1.pom
composite_key: ""
is_lead: 1
created_unix: 1746256367
- id: 14
version_id: 8
blob_id: 13
name: bar-7.0.0.pom
lower_name: bar-7.0.0.pom
composite_key: ""
is_lead: 1
created_unix: 1746256370
- id: 15
version_id: 7
blob_id: 14
name: -bar-1.0-20250503.071253-2.pom
lower_name: -bar-1.0-20250503.071253-2.pom
composite_key: ""
is_lead: 1
created_unix: 1746256373
- id: 17
version_id: 8
blob_id: 16
name: -bar-7.0.0.pom
lower_name: -bar-7.0.0.pom
composite_key: ""
is_lead: 1
created_unix: 1746256375
- id: 18
version_id: 1
blob_id: 1
name: parent-project-1.0-20250503.071306-2.pom
lower_name: parent-project-1.0-20250503.071306-2.pom
composite_key: ""
is_lead: 1
created_unix: 1746256385
- id: 20
version_id: 2
blob_id: 3
name: sub-module-1.0-20250503.071306-2.pom
lower_name: sub-module-1.0-20250503.071306-2.pom
composite_key: ""
is_lead: 1
created_unix: 1746256386
- id: 21
version_id: 2
blob_id: 18
name: sub-module-1.0-20250503.071306-2.jar
lower_name: sub-module-1.0-20250503.071306-2.jar
composite_key: ""
is_lead: 0
created_unix: 1746256386
- id: 23
version_id: 9
blob_id: 20
name: parent-project-8.0.0.pom
lower_name: parent-project-8.0.0.pom
composite_key: ""
is_lead: 1
created_unix: 1746256389
- id: 24
version_id: 10
blob_id: 21
name: sub-module-8.0.0.pom
lower_name: sub-module-8.0.0.pom
composite_key: ""
is_lead: 1
created_unix: 1746256390
- id: 25
version_id: 10
blob_id: 22
name: sub-module-8.0.0.jar
lower_name: sub-module-8.0.0.jar
composite_key: ""
is_lead: 0
created_unix: 1746256390
- id: 26
version_id: 11
blob_id: 23
name: parent-project-8.0.0.pom
lower_name: parent-project-8.0.0.pom
composite_key: ""
is_lead: 1
created_unix: 1746256393
- id: 27
version_id: 12
blob_id: 21
name: sub-module-8.0.0.pom
lower_name: sub-module-8.0.0.pom
composite_key: ""
is_lead: 1
created_unix: 1746256394
- id: 28
version_id: 12
blob_id: 24
name: sub-module-8.0.0.jar
lower_name: sub-module-8.0.0.jar
composite_key: ""
is_lead: 0
created_unix: 1746256394
- id: 29
version_id: 7
blob_id: 11
name: bar-1.0-20250503.071317-3.pom
lower_name: bar-1.0-20250503.071317-3.pom
composite_key: ""
is_lead: 1
created_unix: 1746256397
- id: 31
version_id: 13
blob_id: 26
name: bar-8.0.0.pom
lower_name: bar-8.0.0.pom
composite_key: ""
is_lead: 1
created_unix: 1746256399
- id: 32
version_id: 7
blob_id: 14
name: -bar-1.0-20250503.071323-4.pom
lower_name: -bar-1.0-20250503.071323-4.pom
composite_key: ""
is_lead: 1
created_unix: 1746256402
- id: 34
version_id: 13
blob_id: 28
name: -bar-8.0.0.pom
lower_name: -bar-8.0.0.pom
composite_key: ""
is_lead: 1
created_unix: 1746256405
- id: 35
version_id: 1
blob_id: 1
name: parent-project-1.0-20250503.071335-3.pom
lower_name: parent-project-1.0-20250503.071335-3.pom
composite_key: ""
is_lead: 1
created_unix: 1746256415
- id: 37
version_id: 2
blob_id: 3
name: sub-module-1.0-20250503.071335-3.pom
lower_name: sub-module-1.0-20250503.071335-3.pom
composite_key: ""
is_lead: 1
created_unix: 1746256416
- id: 38
version_id: 2
blob_id: 30
name: sub-module-1.0-20250503.071335-3.jar
lower_name: sub-module-1.0-20250503.071335-3.jar
composite_key: ""
is_lead: 0
created_unix: 1746256416
- id: 40
version_id: 14
blob_id: 32
name: parent-project-9.0.0.pom
lower_name: parent-project-9.0.0.pom
composite_key: ""
is_lead: 1
created_unix: 1746256419
- id: 41
version_id: 15
blob_id: 33
name: sub-module-9.0.0.pom
lower_name: sub-module-9.0.0.pom
composite_key: ""
is_lead: 1
created_unix: 1746256420
- id: 42
version_id: 15
blob_id: 34
name: sub-module-9.0.0.jar
lower_name: sub-module-9.0.0.jar
composite_key: ""
is_lead: 0
created_unix: 1746256420
- id: 43
version_id: 16
blob_id: 35
name: parent-project-9.0.0.pom
lower_name: parent-project-9.0.0.pom
composite_key: ""
is_lead: 1
created_unix: 1746256423
- id: 44
version_id: 17
blob_id: 33
name: sub-module-9.0.0.pom
lower_name: sub-module-9.0.0.pom
composite_key: ""
is_lead: 1
created_unix: 1746256424
- id: 45
version_id: 17
blob_id: 36
name: sub-module-9.0.0.jar
lower_name: sub-module-9.0.0.jar
composite_key: ""
is_lead: 0
created_unix: 1746256424
- id: 46
version_id: 7
blob_id: 11
name: bar-1.0-20250503.071347-5.pom
lower_name: bar-1.0-20250503.071347-5.pom
composite_key: ""
is_lead: 1
created_unix: 1746256427
- id: 48
version_id: 18
blob_id: 38
name: bar-9.0.0.pom
lower_name: bar-9.0.0.pom
composite_key: ""
is_lead: 1
created_unix: 1746256429
- id: 49
version_id: 7
blob_id: 14
name: -bar-1.0-20250503.071353-6.pom
lower_name: -bar-1.0-20250503.071353-6.pom
composite_key: ""
is_lead: 1
created_unix: 1746256432
- id: 51
version_id: 18
blob_id: 40
name: -bar-9.0.0.pom
lower_name: -bar-9.0.0.pom
composite_key: ""
is_lead: 1
created_unix: 1746256435
- id: 52
version_id: 1
blob_id: 1
name: parent-project-1.0-20250503.071405-4.pom
lower_name: parent-project-1.0-20250503.071405-4.pom
composite_key: ""
is_lead: 1
created_unix: 1746256445
- id: 54
version_id: 2
blob_id: 3
name: sub-module-1.0-20250503.071405-4.pom
lower_name: sub-module-1.0-20250503.071405-4.pom
composite_key: ""
is_lead: 1
created_unix: 1746256446
- id: 55
version_id: 2
blob_id: 42
name: sub-module-1.0-20250503.071405-4.jar
lower_name: sub-module-1.0-20250503.071405-4.jar
composite_key: ""
is_lead: 0
created_unix: 1746256446
- id: 57
version_id: 19
blob_id: 44
name: parent-project-10.0.0.pom
lower_name: parent-project-10.0.0.pom
composite_key: ""
is_lead: 1
created_unix: 1746256449
- id: 58
version_id: 20
blob_id: 45
name: sub-module-10.0.0.pom
lower_name: sub-module-10.0.0.pom
composite_key: ""
is_lead: 1
created_unix: 1746256450
- id: 59
version_id: 20
blob_id: 46
name: sub-module-10.0.0.jar
lower_name: sub-module-10.0.0.jar
composite_key: ""
is_lead: 0
created_unix: 1746256450
- id: 60
version_id: 21
blob_id: 47
name: parent-project-10.0.0.pom
lower_name: parent-project-10.0.0.pom
composite_key: ""
is_lead: 1
created_unix: 1746256452
- id: 61
version_id: 22
blob_id: 45
name: sub-module-10.0.0.pom
lower_name: sub-module-10.0.0.pom
composite_key: ""
is_lead: 1
created_unix: 1746256453
- id: 62
version_id: 22
blob_id: 48
name: sub-module-10.0.0.jar
lower_name: sub-module-10.0.0.jar
composite_key: ""
is_lead: 0
created_unix: 1746256453
- id: 63
version_id: 7
blob_id: 11
name: bar-1.0-20250503.071416-7.pom
lower_name: bar-1.0-20250503.071416-7.pom
composite_key: ""
is_lead: 1
created_unix: 1746256456
- id: 65
version_id: 23
blob_id: 50
name: bar-10.0.0.pom
lower_name: bar-10.0.0.pom
composite_key: ""
is_lead: 1
created_unix: 1746256459
- id: 66
version_id: 7
blob_id: 14
name: -bar-1.0-20250503.071422-8.pom
lower_name: -bar-1.0-20250503.071422-8.pom
composite_key: ""
is_lead: 1
created_unix: 1746256461
- id: 68
version_id: 23
blob_id: 52
name: -bar-10.0.0.pom
lower_name: -bar-10.0.0.pom
composite_key: ""
is_lead: 1
created_unix: 1746256464
- id: 69
version_id: 1
blob_id: 1
name: parent-project-1.0-20250503.071435-5.pom
lower_name: parent-project-1.0-20250503.071435-5.pom
composite_key: ""
is_lead: 1
created_unix: 1746256474
- id: 70
version_id: 1
blob_id: 53
name: maven-metadata.xml
lower_name: maven-metadata.xml
composite_key: ""
is_lead: 0
created_unix: 1746256474
- id: 71
version_id: 2
blob_id: 3
name: sub-module-1.0-20250503.071435-5.pom
lower_name: sub-module-1.0-20250503.071435-5.pom
composite_key: ""
is_lead: 1
created_unix: 1746256475
- id: 72
version_id: 2
blob_id: 54
name: sub-module-1.0-20250503.071435-5.jar
lower_name: sub-module-1.0-20250503.071435-5.jar
composite_key: ""
is_lead: 0
created_unix: 1746256475
- id: 73
version_id: 2
blob_id: 55
name: maven-metadata.xml
lower_name: maven-metadata.xml
composite_key: ""
is_lead: 0
created_unix: 1746256476
- id: 74
version_id: 24
blob_id: 56
name: parent-project-11.0.0.pom
lower_name: parent-project-11.0.0.pom
composite_key: ""
is_lead: 1
created_unix: 1746256478
- id: 75
version_id: 25
blob_id: 57
name: sub-module-11.0.0.pom
lower_name: sub-module-11.0.0.pom
composite_key: ""
is_lead: 1
created_unix: 1746256479
- id: 76
version_id: 25
blob_id: 58
name: sub-module-11.0.0.jar
lower_name: sub-module-11.0.0.jar
composite_key: ""
is_lead: 0
created_unix: 1746256479
- id: 77
version_id: 26
blob_id: 59
name: parent-project-11.0.0.pom
lower_name: parent-project-11.0.0.pom
composite_key: ""
is_lead: 1
created_unix: 1746256482
- id: 78
version_id: 27
blob_id: 57
name: sub-module-11.0.0.pom
lower_name: sub-module-11.0.0.pom
composite_key: ""
is_lead: 1
created_unix: 1746256483
- id: 79
version_id: 27
blob_id: 60
name: sub-module-11.0.0.jar
lower_name: sub-module-11.0.0.jar
composite_key: ""
is_lead: 0
created_unix: 1746256483
- id: 80
version_id: 7
blob_id: 11
name: bar-1.0-20250503.071446-9.pom
lower_name: bar-1.0-20250503.071446-9.pom
composite_key: ""
is_lead: 1
created_unix: 1746256486
- id: 82
version_id: 28
blob_id: 62
name: bar-11.0.0.pom
lower_name: bar-11.0.0.pom
composite_key: ""
is_lead: 1
created_unix: 1746256488
- id: 83
version_id: 7
blob_id: 14
name: -bar-1.0-20250503.071451-10.pom
lower_name: -bar-1.0-20250503.071451-10.pom
composite_key: ""
is_lead: 1
created_unix: 1746256491
- id: 84
version_id: 7
blob_id: 63
name: maven-metadata.xml
lower_name: maven-metadata.xml
composite_key: ""
is_lead: 0
created_unix: 1746256491
- id: 85
version_id: 28
blob_id: 64
name: -bar-11.0.0.pom
lower_name: -bar-11.0.0.pom
composite_key: ""
is_lead: 1
created_unix: 1746256494
# broken uploads
- id: 86
version_id: 29
blob_id: 75
name: br-repo-jooq-1.2.4-sources.jar
lower_name: br-repo-jooq-1.2.4-sources.jar
composite_key: ""
is_lead: 0
created_unix: 174625649444986
- id: 87
version_id: 29
blob_id: 65
name: br-rest-webmvc-1.2.4.jar
lower_name: br-rest-webmvc-1.2.4.jar
composite_key: ""
is_lead: 0
created_unix: 174625649446161
- id: 88
version_id: 29
blob_id: 68
name: br-openapi-base-1.2.4.pom
lower_name: br-openapi-base-1.2.4.pom
composite_key: ""
is_lead: 1
created_unix: 174625649444734
- id: 89
version_id: 29
blob_id: 69
name: br-openapi-base-1.2.4.jar
lower_name: br-openapi-base-1.2.4.jar
composite_key: ""
is_lead: 0
created_unix: 174625649444746
- id: 90
version_id: 29
blob_id: 70
name: br-openapi-base-1.2.4-sources.jar
lower_name: br-openapi-base-1.2.4-sources.jar
composite_key: ""
is_lead: 0
created_unix: 174625649444775
- id: 91
version_id: 29
blob_id: 78
name: br-parent-1.2.4.pom
lower_name: br-parent-1.2.4.pom
composite_key: ""
is_lead: 1
created_unix: 174625649444852
- id: 92
version_id: 29
blob_id: 76
name: br-repo-in-memory-1.2.4.pom
lower_name: br-repo-in-memory-1.2.4.pom
composite_key: ""
is_lead: 1
created_unix: 174625649444900
- id: 93
version_id: 29
blob_id: 73
name: br-repo-in-memory-1.2.4.jar
lower_name: br-repo-in-memory-1.2.4.jar
composite_key: ""
is_lead: 0
created_unix: 174625649444911
- id: 94
version_id: 29
blob_id: 77
name: br-repo-in-memory-1.2.4-sources.jar
lower_name: br-repo-in-memory-1.2.4-sources.jar
composite_key: ""
is_lead: 0
created_unix: 174625649444922
- id: 95
version_id: 29
blob_id: 74
name: br-repo-jooq-1.2.4.pom
lower_name: br-repo-jooq-1.2.4.pom
composite_key: ""
is_lead: 1
created_unix: 174625649444953
- id: 96
version_id: 29
blob_id: 67
name: br-repo-jooq-1.2.4.jar
lower_name: br-repo-jooq-1.2.4.jar
composite_key: ""
is_lead: 0
created_unix: 174625649444969
- id: 97
version_id: 29
blob_id: 71
name: br-rest-webmvc-1.2.4-sources.jar
lower_name: br-rest-webmvc-1.2.4-sources.jar
composite_key: ""
is_lead: 0
created_unix: 174625649446161
- id: 98
version_id: 29
blob_id: 66
name: br-rest-webmvc-1.2.4.pom
lower_name: br-rest-webmvc-1.2.4.pom
composite_key: ""
is_lead: 1
created_unix: 174625649446195
- id: 99
version_id: 29
blob_id: 72
name: br-root-1.2.4.pom
lower_name: br-root-1.2.4.pom
composite_key: ""
is_lead: 1
created_unix: 174625649446217
- id: 100
version_id: 30
blob_id: 66
name: br-rest-webmvc-1.2.4.pom
lower_name: br-rest-webmvc-1.2.4.pom
composite_key: ""
is_lead: 1
created_unix: 174625649446311
- id: 101
version_id: 30
blob_id: 65
name: br-rest-webmvc-1.2.4.jar
lower_name: br-rest-webmvc-1.2.4.jar
composite_key: ""
is_lead: 0
created_unix: 174625649446312
- id: 102
version_id: 30
blob_id: 71
name: br-rest-webmvc-1.2.4-sources.jar
lower_name: br-rest-webmvc-1.2.4-sources.jar
composite_key: ""
is_lead: 0
created_unix: 174625649446312
# collision
- id: 103
version_id: 31
blob_id: 79
name: bar-art-11.0.0.pom
lower_name: bar-art-11.0.0.pom
composite_key: ""
is_lead: 1
created_unix: 1746280832
- id: 104
version_id: 31
blob_id: 80
name: art-11.0.0.pom
lower_name: art-11.0.0.pom
composite_key: ""
is_lead: 1
created_unix: 1746280843

View file

@ -0,0 +1,281 @@
- id: 1
package_id: 1
creator_id: 1
version: 1.0-SNAPSHOT
lower_version: 1.0-snapshot
created_unix: 1746256357
is_internal: 0
metadata_json: '{"group_id":"com.example","artifact_id":"parent-project","name":"Example :: Parent "}'
download_count: 0
- id: 2
package_id: 2
creator_id: 1
version: 1.0-SNAPSHOT
lower_version: 1.0-snapshot
created_unix: 1746256358
is_internal: 0
metadata_json: '{"group_id":"com.example","artifact_id":"sub-module","name":"Example :: SubModule ","dependencies":[{"group_id":"junit","artifact_id":"junit","version":"3.8.1"}]}'
download_count: 0
- id: 3
package_id: 1
creator_id: 1
version: 7.0.0
lower_version: 7.0.0
created_unix: 1746256360
is_internal: 0
metadata_json: '{"group_id":"com.example","artifact_id":"parent-project","name":"Example :: Parent "}'
download_count: 0
- id: 4
package_id: 2
creator_id: 1
version: 7.0.0
lower_version: 7.0.0
created_unix: 1746256361
is_internal: 0
metadata_json: '{"artifact_id":"sub-module","name":"Example :: SubModule ","dependencies":[{"group_id":"junit","artifact_id":"junit","version":"3.8.1"}]}'
download_count: 0
- id: 5
package_id: 3
creator_id: 1
version: 7.0.0
lower_version: 7.0.0
created_unix: 1746256364
is_internal: 0
metadata_json: '{"group_id":"com.example","artifact_id":"parent-project","name":"Example :: Parent "}'
download_count: 0
- id: 6
package_id: 4
creator_id: 1
version: 7.0.0
lower_version: 7.0.0
created_unix: 1746256365
is_internal: 0
metadata_json: '{"artifact_id":"sub-module","name":"Example :: SubModule ","dependencies":[{"group_id":"junit","artifact_id":"junit","version":"3.8.1"}]}'
download_count: 0
- id: 7
package_id: 5
creator_id: 1
version: 1.0-SNAPSHOT
lower_version: 1.0-snapshot
created_unix: 1746256367
is_internal: 0
metadata_json: '{"group_id":"foo","artifact_id":"-bar","name":"Example :: Parent "}'
download_count: 0
- id: 8
package_id: 5
creator_id: 1
version: 7.0.0
lower_version: 7.0.0
created_unix: 1746256370
is_internal: 0
metadata_json: '{"group_id":"foo","artifact_id":"-bar","name":"Example :: Parent "}'
download_count: 0
- id: 9
package_id: 1
creator_id: 1
version: 8.0.0
lower_version: 8.0.0
created_unix: 1746256389
is_internal: 0
metadata_json: '{"group_id":"com.example","artifact_id":"parent-project","name":"Example :: Parent "}'
download_count: 0
- id: 10
package_id: 2
creator_id: 1
version: 8.0.0
lower_version: 8.0.0
created_unix: 1746256390
is_internal: 0
metadata_json: '{"artifact_id":"sub-module","name":"Example :: SubModule ","dependencies":[{"group_id":"junit","artifact_id":"junit","version":"3.8.1"}]}'
download_count: 0
- id: 11
package_id: 3
creator_id: 1
version: 8.0.0
lower_version: 8.0.0
created_unix: 1746256393
is_internal: 0
metadata_json: '{"group_id":"com.example","artifact_id":"parent-project","name":"Example :: Parent "}'
download_count: 0
- id: 12
package_id: 4
creator_id: 1
version: 8.0.0
lower_version: 8.0.0
created_unix: 1746256394
is_internal: 0
metadata_json: '{"artifact_id":"sub-module","name":"Example :: SubModule ","dependencies":[{"group_id":"junit","artifact_id":"junit","version":"3.8.1"}]}'
download_count: 0
- id: 13
package_id: 5
creator_id: 1
version: 8.0.0
lower_version: 8.0.0
created_unix: 1746256399
is_internal: 0
metadata_json: '{"group_id":"foo","artifact_id":"-bar","name":"Example :: Parent "}'
download_count: 0
- id: 14
package_id: 1
creator_id: 1
version: 9.0.0
lower_version: 9.0.0
created_unix: 1746256419
is_internal: 0
metadata_json: '{"group_id":"com.example","artifact_id":"parent-project","name":"Example :: Parent "}'
download_count: 0
- id: 15
package_id: 2
creator_id: 1
version: 9.0.0
lower_version: 9.0.0
created_unix: 1746256420
is_internal: 0
metadata_json: '{"artifact_id":"sub-module","name":"Example :: SubModule ","dependencies":[{"group_id":"junit","artifact_id":"junit","version":"3.8.1"}]}'
download_count: 0
- id: 16
package_id: 3
creator_id: 1
version: 9.0.0
lower_version: 9.0.0
created_unix: 1746256423
is_internal: 0
metadata_json: '{"group_id":"com.example","artifact_id":"parent-project","name":"Example :: Parent "}'
download_count: 0
- id: 17
package_id: 4
creator_id: 1
version: 9.0.0
lower_version: 9.0.0
created_unix: 1746256424
is_internal: 0
metadata_json: '{"artifact_id":"sub-module","name":"Example :: SubModule ","dependencies":[{"group_id":"junit","artifact_id":"junit","version":"3.8.1"}]}'
download_count: 0
- id: 18
package_id: 5
creator_id: 1
version: 9.0.0
lower_version: 9.0.0
created_unix: 1746256429
is_internal: 0
metadata_json: '{"group_id":"foo","artifact_id":"-bar","name":"Example :: Parent "}'
download_count: 0
- id: 19
package_id: 1
creator_id: 1
version: 10.0.0
lower_version: 10.0.0
created_unix: 1746256449
is_internal: 0
metadata_json: '{"group_id":"com.example","artifact_id":"parent-project","name":"Example :: Parent "}'
download_count: 0
- id: 20
package_id: 2
creator_id: 1
version: 10.0.0
lower_version: 10.0.0
created_unix: 1746256450
is_internal: 0
metadata_json: '{"group_id":"com.example","artifact_id":"sub-module","name":"Example :: SubModule ","dependencies":[{"group_id":"junit","artifact_id":"junit","version":"3.8.1"}]}'
download_count: 0
- id: 21
package_id: 3
creator_id: 1
version: 10.0.0
lower_version: 10.0.0
created_unix: 1746256452
is_internal: 0
metadata_json: '{"group_id":"com.example","artifact_id":"parent-project","name":"Example :: Parent "}'
download_count: 0
- id: 22
package_id: 4
creator_id: 1
version: 10.0.0
lower_version: 10.0.0
created_unix: 1746256453
is_internal: 0
metadata_json: '{"group_id":"com.example","artifact_id":"sub-module","name":"Example :: SubModule ","dependencies":[{"group_id":"junit","artifact_id":"junit","version":"3.8.1"}]}'
download_count: 0
- id: 23
package_id: 5
creator_id: 1
version: 10.0.0
lower_version: 10.0.0
created_unix: 1746256459
is_internal: 0
metadata_json: '{"group_id":"foo","artifact_id":"-bar","name":"Example :: Parent "}'
download_count: 0
- id: 24
package_id: 1
creator_id: 1
version: 11.0.0
lower_version: 11.0.0
created_unix: 1746256478
is_internal: 0
metadata_json: '{"group_id":"com.example","artifact_id":"parent-project","name":"Example :: Parent "}'
download_count: 0
- id: 25
package_id: 2
creator_id: 1
version: 11.0.0
lower_version: 11.0.0
created_unix: 1746256479
is_internal: 0
metadata_json: '{"group_id":"com.example","artifact_id":"sub-module","name":"Example :: SubModule ","dependencies":[{"group_id":"junit","artifact_id":"junit","version":"3.8.1"}]}'
download_count: 0
- id: 26
package_id: 3
creator_id: 1
version: 11.0.0
lower_version: 11.0.0
created_unix: 1746256482
is_internal: 0
metadata_json: '{"group_id":"com.example","artifact_id":"parent-project","name":"Example :: Parent "}'
download_count: 0
- id: 27
package_id: 4
creator_id: 1
version: 11.0.0
lower_version: 11.0.0
created_unix: 1746256483
is_internal: 0
metadata_json: '{"group_id":"com.example","artifact_id":"sub-module","name":"Example :: SubModule ","dependencies":[{"group_id":"junit","artifact_id":"junit","version":"3.8.1"}]}'
download_count: 0
- id: 28
package_id: 5
creator_id: 1
version: 11.0.0
lower_version: 11.0.0
created_unix: 1746256488
is_internal: 0
metadata_json: '{"group_id":"foo","artifact_id":"-bar","name":"Example :: Parent "}'
download_count: 0
# broken uploads
- id: 29
package_id: 7
creator_id: 6
version: 1.2.4
lower_version: 1.2.4
created_unix: 1746256488
is_internal: 0
metadata_json: '{"group_id":"com.broken","artifact_id":"br-root","name":"Foo"}'
download_count: 0
- id: 30
package_id: 6
creator_id: 6
version: 1.2.4
lower_version: 1.2.4
created_unix: 1746256488
is_internal: 0
metadata_json: '{"artifact_id":"br-rest-webmvc","name":"Foo :: REST :: Web MVC","dependencies":[{"group_id":"com.broken","artifact_id":"br-base"},{"group_id":"jakarta.servlet","artifact_id":"jakarta.servlet-api"},{"group_id":"jakarta.validation","artifact_id":"jakarta.validation-api"},{"group_id":"org.springframework","artifact_id":"spring-webmvc"},{"group_id":"org.springframework.hateoas","artifact_id":"spring-hateoas"},{"group_id":"org.springframework.boot","artifact_id":"spring-boot-starter-test"},{"group_id":"com.broken","artifact_id":"br-test"},{"group_id":"com.broken","artifact_id":"br-repo-in-memory"},{"group_id":"org.hibernate.validator","artifact_id":"hibernate-validator"},{"group_id":"org.glassfish.expressly","artifact_id":"expressly"}]}'
download_count: 0
# collision
- id: 31
package_id: 8
creator_id: 1
version: 11.0.0
lower_version: 11.0.0
created_unix: 1746256488
is_internal: 0
metadata_json: '{"group_id":"group-bar","artifact_id":"art","name":"Example :: Parent "}'
download_count: 0

View file

@ -201,6 +201,15 @@ type Package struct {
IsInternal bool `xorm:"NOT NULL DEFAULT false"` IsInternal bool `xorm:"NOT NULL DEFAULT false"`
} }
func ResolvePackageName(name string, t Type) string {
switch t {
case TypeMaven:
return name
default:
return strings.ToLower(name)
}
}
// TryInsertPackage inserts a package. If a package exists already, ErrDuplicatePackage is returned // TryInsertPackage inserts a package. If a package exists already, ErrDuplicatePackage is returned
func TryInsertPackage(ctx context.Context, p *Package) (*Package, error) { func TryInsertPackage(ctx context.Context, p *Package) (*Package, error) {
e := db.GetEngine(ctx) e := db.GetEngine(ctx)
@ -272,7 +281,7 @@ func GetPackageByName(ctx context.Context, ownerID int64, packageType Type, name
var cond builder.Cond = builder.Eq{ var cond builder.Cond = builder.Eq{
"package.owner_id": ownerID, "package.owner_id": ownerID,
"package.type": packageType, "package.type": packageType,
"package.lower_name": strings.ToLower(name), "package.lower_name": ResolvePackageName(name, packageType),
"package.is_internal": false, "package.is_internal": false,
} }

View file

@ -87,8 +87,8 @@ func GetFileForVersionByID(ctx context.Context, versionID, fileID int64) (*Packa
return pf, nil return pf, nil
} }
// GetFileForVersionByName gets a file of a version by name // GetFileForVersionByNameMatchCase gets a file of a version by name
func GetFileForVersionByName(ctx context.Context, versionID int64, name, key string) (*PackageFile, error) { func GetFileForVersionByNameMatchCase(ctx context.Context, versionID int64, name, key string) (*PackageFile, error) {
if name == "" { if name == "" {
return nil, ErrPackageFileNotExist return nil, ErrPackageFileNotExist
} }
@ -97,7 +97,7 @@ func GetFileForVersionByName(ctx context.Context, versionID int64, name, key str
has, err := db.GetEngine(ctx).Where(builder.Eq{ has, err := db.GetEngine(ctx).Where(builder.Eq{
"version_id": versionID, "version_id": versionID,
"lower_name": strings.ToLower(name), "lower_name": name,
"composite_key": key, "composite_key": key,
}).Get(pf) }).Get(pf)
if err != nil { if err != nil {
@ -109,6 +109,11 @@ func GetFileForVersionByName(ctx context.Context, versionID int64, name, key str
return pf, nil return pf, nil
} }
// GetFileForVersionByName gets a file of a version by name
func GetFileForVersionByName(ctx context.Context, versionID int64, name, key string) (*PackageFile, error) {
return GetFileForVersionByNameMatchCase(ctx, versionID, strings.ToLower(name), key)
}
// DeleteFileByID deletes a file // DeleteFileByID deletes a file
func DeleteFileByID(ctx context.Context, fileID int64) error { func DeleteFileByID(ctx context.Context, fileID int64) error {
_, err := db.GetEngine(ctx).ID(fileID).Delete(&PackageFile{}) _, err := db.GetEngine(ctx).ID(fileID).Delete(&PackageFile{})

View file

@ -211,10 +211,13 @@ func (opts *PackageSearchOptions) ToConds() builder.Cond {
cond = cond.And(builder.Eq{"package.id": opts.PackageID}) cond = cond.And(builder.Eq{"package.id": opts.PackageID})
} }
if opts.Name.Value != "" { if opts.Name.Value != "" {
// potential drawback if Type is all / undefined
name := ResolvePackageName(opts.Name.Value, opts.Type)
if opts.Name.ExactMatch { if opts.Name.ExactMatch {
cond = cond.And(builder.Eq{"package.lower_name": strings.ToLower(opts.Name.Value)}) cond = cond.And(builder.Eq{"package.lower_name": name})
} else { } else {
cond = cond.And(builder.Like{"package.lower_name", strings.ToLower(opts.Name.Value)}) cond = cond.And(builder.Like{"package.lower_name", name})
} }
} }
if opts.Version.Value != "" { if opts.Version.Value != "" {

View file

@ -155,7 +155,7 @@ func DeletePackage(ctx *context.Context) {
}, },
) )
if err != nil { if err != nil {
if err == packages_model.ErrPackageNotExist { if errors.Is(err, packages_model.ErrPackageNotExist) {
apiError(ctx, http.StatusNotFound, err) apiError(ctx, http.StatusNotFound, err)
return return
} }
@ -182,7 +182,7 @@ func DeletePackageFile(ctx *context.Context) {
return pv, pf, nil return pv, pf, nil
}() }()
if err != nil { if err != nil {
if err == packages_model.ErrPackageNotExist || err == packages_model.ErrPackageFileNotExist { if errors.Is(err, packages_model.ErrPackageNotExist) || errors.Is(err, packages_model.ErrPackageFileNotExist) {
apiError(ctx, http.StatusNotFound, err) apiError(ctx, http.StatusNotFound, err)
return return
} }

View file

@ -11,6 +11,7 @@ import (
"encoding/hex" "encoding/hex"
"encoding/xml" "encoding/xml"
"errors" "errors"
"fmt"
"io" "io"
"net/http" "net/http"
"path/filepath" "path/filepath"
@ -61,6 +62,12 @@ func apiError(ctx *context.Context, status int, obj any) {
}) })
} }
// buildPackageID creates a package ID from group and artifact ID
// Refer to https://maven.apache.org/pom.html#Maven_Coordinates
func buildPackageID(groupID, artifactID string) string {
return fmt.Sprintf("%s:%s", groupID, artifactID)
}
// DownloadPackageFile serves the content of a package // DownloadPackageFile serves the content of a package
func DownloadPackageFile(ctx *context.Context) { func DownloadPackageFile(ctx *context.Context) {
handlePackageFile(ctx, true) handlePackageFile(ctx, true)
@ -88,7 +95,7 @@ func handlePackageFile(ctx *context.Context, serveContent bool) {
func serveMavenMetadata(ctx *context.Context, params parameters) { func serveMavenMetadata(ctx *context.Context, params parameters) {
// /com/foo/project/maven-metadata.xml[.md5/.sha1/.sha256/.sha512] // /com/foo/project/maven-metadata.xml[.md5/.sha1/.sha256/.sha512]
packageName := params.GroupID + "-" + params.ArtifactID packageName := buildPackageID(params.GroupID, params.ArtifactID)
pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeMaven, packageName) pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeMaven, packageName)
if err != nil { if err != nil {
apiError(ctx, http.StatusInternalServerError, err) apiError(ctx, http.StatusInternalServerError, err)
@ -119,8 +126,8 @@ func serveMavenMetadata(ctx *context.Context, params parameters) {
latest := pds[len(pds)-1] latest := pds[len(pds)-1]
// http.TimeFormat required a UTC time, refer to https://pkg.go.dev/net/http#TimeFormat // http.TimeFormat required a UTC time, refer to https://pkg.go.dev/net/http#TimeFormat
lastModifed := latest.Version.CreatedUnix.AsTime().UTC().Format(http.TimeFormat) lastModified := latest.Version.CreatedUnix.AsTime().UTC().Format(http.TimeFormat)
ctx.Resp.Header().Set("Last-Modified", lastModifed) ctx.Resp.Header().Set("Last-Modified", lastModified)
ext := strings.ToLower(filepath.Ext(params.Filename)) ext := strings.ToLower(filepath.Ext(params.Filename))
if isChecksumExtension(ext) { if isChecksumExtension(ext) {
@ -150,7 +157,7 @@ func serveMavenMetadata(ctx *context.Context, params parameters) {
} }
func servePackageFile(ctx *context.Context, params parameters, serveContent bool) { func servePackageFile(ctx *context.Context, params parameters, serveContent bool) {
packageName := params.GroupID + "-" + params.ArtifactID packageName := buildPackageID(params.GroupID, params.ArtifactID)
pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeMaven, packageName, params.Version) pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeMaven, packageName, params.Version)
if err != nil { if err != nil {
@ -169,9 +176,9 @@ func servePackageFile(ctx *context.Context, params parameters, serveContent bool
filename = filename[:len(filename)-len(ext)] filename = filename[:len(filename)-len(ext)]
} }
pf, err := packages_model.GetFileForVersionByName(ctx, pv.ID, filename, packages_model.EmptyFileKey) pf, err := packages_model.GetFileForVersionByNameMatchCase(ctx, pv.ID, filename, packages_model.EmptyFileKey)
if err != nil { if err != nil {
if err == packages_model.ErrPackageFileNotExist { if errors.Is(err, packages_model.ErrPackageFileNotExist) {
apiError(ctx, http.StatusNotFound, err) apiError(ctx, http.StatusNotFound, err)
} else { } else {
apiError(ctx, http.StatusInternalServerError, err) apiError(ctx, http.StatusInternalServerError, err)
@ -247,7 +254,7 @@ func UploadPackageFile(ctx *context.Context) {
return return
} }
packageName := params.GroupID + "-" + params.ArtifactID packageName := buildPackageID(params.GroupID, params.ArtifactID)
mavenUploadLock.CheckIn(packageName) mavenUploadLock.CheckIn(packageName)
defer mavenUploadLock.CheckOut(packageName) defer mavenUploadLock.CheckOut(packageName)
@ -283,9 +290,9 @@ func UploadPackageFile(ctx *context.Context) {
apiError(ctx, http.StatusInternalServerError, err) apiError(ctx, http.StatusInternalServerError, err)
return return
} }
pf, err := packages_model.GetFileForVersionByName(ctx, pv.ID, params.Filename[:len(params.Filename)-len(ext)], packages_model.EmptyFileKey) pf, err := packages_model.GetFileForVersionByNameMatchCase(ctx, pv.ID, params.Filename[:len(params.Filename)-len(ext)], packages_model.EmptyFileKey)
if err != nil { if err != nil {
if err == packages_model.ErrPackageFileNotExist { if errors.Is(err, packages_model.ErrPackageFileNotExist) {
apiError(ctx, http.StatusNotFound, err) apiError(ctx, http.StatusNotFound, err)
return return
} }
@ -339,7 +346,7 @@ func UploadPackageFile(ctx *context.Context) {
if pvci.Metadata != nil { if pvci.Metadata != nil {
pv, err := packages_model.GetVersionByNameAndVersion(ctx, pvci.Owner.ID, pvci.PackageType, pvci.Name, pvci.Version) pv, err := packages_model.GetVersionByNameAndVersion(ctx, pvci.Owner.ID, pvci.PackageType, pvci.Name, pvci.Version)
if err != nil && err != packages_model.ErrPackageNotExist { if err != nil && !errors.Is(err, packages_model.ErrPackageNotExist) {
apiError(ctx, http.StatusInternalServerError, err) apiError(ctx, http.StatusInternalServerError, err)
return return
} }

View file

@ -127,12 +127,12 @@ func createPackageAndVersion(ctx context.Context, pvci *PackageCreationInfo, all
OwnerID: pvci.Owner.ID, OwnerID: pvci.Owner.ID,
Type: pvci.PackageType, Type: pvci.PackageType,
Name: pvci.Name, Name: pvci.Name,
LowerName: strings.ToLower(pvci.Name), LowerName: packages_model.ResolvePackageName(pvci.Name, pvci.PackageType),
SemverCompatible: pvci.SemverCompatible, SemverCompatible: pvci.SemverCompatible,
} }
var err error var err error
if p, err = packages_model.TryInsertPackage(ctx, p); err != nil { if p, err = packages_model.TryInsertPackage(ctx, p); err != nil {
if err == packages_model.ErrDuplicatePackage { if errors.Is(err, packages_model.ErrDuplicatePackage) {
packageCreated = false packageCreated = false
} else { } else {
log.Error("Error inserting package: %v", err) log.Error("Error inserting package: %v", err)
@ -208,7 +208,7 @@ func AddFileToExistingPackage(ctx context.Context, pvi *PackageInfo, pfci *Packa
// This method skips quota checks and should only be used for system-managed packages. // This method skips quota checks and should only be used for system-managed packages.
func AddFileToPackageVersionInternal(ctx context.Context, pv *packages_model.PackageVersion, pfci *PackageFileCreationInfo) (*packages_model.PackageFile, error) { func AddFileToPackageVersionInternal(ctx context.Context, pv *packages_model.PackageVersion, pfci *PackageFileCreationInfo) (*packages_model.PackageFile, error) {
return addFileToPackageWrapper(ctx, func(ctx context.Context) (*packages_model.PackageFile, *packages_model.PackageBlob, bool, error) { return addFileToPackageWrapper(ctx, func(ctx context.Context) (*packages_model.PackageFile, *packages_model.PackageBlob, bool, error) {
return addFileToPackageVersionUnchecked(ctx, pv, pfci) return addFileToPackageVersionUnchecked(ctx, pv, pfci, "")
}) })
} }
@ -261,10 +261,10 @@ func addFileToPackageVersion(ctx context.Context, pv *packages_model.PackageVers
return nil, nil, false, err return nil, nil, false, err
} }
return addFileToPackageVersionUnchecked(ctx, pv, pfci) return addFileToPackageVersionUnchecked(ctx, pv, pfci, pvi.PackageType)
} }
func addFileToPackageVersionUnchecked(ctx context.Context, pv *packages_model.PackageVersion, pfci *PackageFileCreationInfo) (*packages_model.PackageFile, *packages_model.PackageBlob, bool, error) { func addFileToPackageVersionUnchecked(ctx context.Context, pv *packages_model.PackageVersion, pfci *PackageFileCreationInfo, packageType packages_model.Type) (*packages_model.PackageFile, *packages_model.PackageBlob, bool, error) {
log.Trace("Adding package file: %v, %s", pv.ID, pfci.Filename) log.Trace("Adding package file: %v, %s", pv.ID, pfci.Filename)
pb, exists, err := packages_model.GetOrInsertBlob(ctx, NewPackageBlob(pfci.Data)) pb, exists, err := packages_model.GetOrInsertBlob(ctx, NewPackageBlob(pfci.Data))
@ -304,7 +304,7 @@ func addFileToPackageVersionUnchecked(ctx context.Context, pv *packages_model.Pa
VersionID: pv.ID, VersionID: pv.ID,
BlobID: pb.ID, BlobID: pb.ID,
Name: pfci.Filename, Name: pfci.Filename,
LowerName: strings.ToLower(pfci.Filename), LowerName: packages_model.ResolvePackageName(pfci.Filename, packageType),
CompositeKey: pfci.CompositeKey, CompositeKey: pfci.CompositeKey,
IsLead: pfci.IsLead, IsLead: pfci.IsLead,
} }

View file

@ -29,12 +29,12 @@ func TestPackageMaven(t *testing.T) {
groupID := "com.gitea" groupID := "com.gitea"
artifactID := "test-project" artifactID := "test-project"
packageName := groupID + "-" + artifactID packageName := groupID + ":" + artifactID
packageVersion := "1.0.1" packageVersion := "1.0.1"
packageDescription := "Test Description" packageDescription := "Test Description"
root := fmt.Sprintf("/api/packages/%s/maven/%s/%s", user.Name, strings.ReplaceAll(groupID, ".", "/"), artifactID) root := fmt.Sprintf("/api/packages/%s/maven/%s/%s", user.Name, strings.ReplaceAll(groupID, ".", "/"), artifactID)
filename := fmt.Sprintf("%s-%s.jar", packageName, packageVersion) filename := fmt.Sprintf("%s:%s.jar", packageName, packageVersion)
putFile := func(t *testing.T, path, content string, expectedStatus int) { putFile := func(t *testing.T, path, content string, expectedStatus int) {
req := NewRequestWithBody(t, "PUT", root+path, strings.NewReader(content)). req := NewRequestWithBody(t, "PUT", root+path, strings.NewReader(content)).
@ -249,7 +249,7 @@ func TestPackageMaven(t *testing.T) {
partialVersion := packageVersion + "-PARTIAL" partialVersion := packageVersion + "-PARTIAL"
putFile(t, fmt.Sprintf("/%s/%s", partialVersion, filename), "test", http.StatusCreated) putFile(t, fmt.Sprintf("/%s/%s", partialVersion, filename), "test", http.StatusCreated)
pkgUIURL := fmt.Sprintf("/%s/-/packages/maven/%s-%s/%s", user.Name, groupID, artifactID, partialVersion) pkgUIURL := fmt.Sprintf("/%s/-/packages/maven/%s:%s/%s", user.Name, groupID, artifactID, partialVersion)
req := NewRequest(t, "GET", pkgUIURL) req := NewRequest(t, "GET", pkgUIURL)
resp := MakeRequest(t, req, http.StatusOK) resp := MakeRequest(t, req, http.StatusOK)
assert.NotContains(t, resp.Body.String(), "Internal server error") assert.NotContains(t, resp.Body.String(), "Internal server error")