Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Package registry changes #19305

Merged
merged 21 commits into from
Apr 6, 2022
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions integrations/api_packages_container_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"net/http"
"strings"
"testing"
"time"

"code.gitea.io/gitea/models/db"
packages_model "code.gitea.io/gitea/models/packages"
Expand All @@ -20,6 +21,7 @@ import (
container_module "code.gitea.io/gitea/modules/packages/container"
"code.gitea.io/gitea/modules/packages/container/oci"
"code.gitea.io/gitea/modules/setting"
packages_service "code.gitea.io/gitea/services/packages"

"github.com/stretchr/testify/assert"
)
Expand Down Expand Up @@ -531,4 +533,19 @@ func TestPackageContainer(t *testing.T) {
})
})
}

t.Run("Cleanup", func(t *testing.T) {
for _, image := range images {
_, err := packages_model.GetInternalVersionByNameAndVersion(db.DefaultContext, user.ID, packages_model.TypeContainer, image, container_model.UploadVersion)
assert.NoError(t, err)
}

err := packages_service.Cleanup(nil, time.Duration(0))
assert.NoError(t, err)

for _, image := range images {
_, err := packages_model.GetInternalVersionByNameAndVersion(db.DefaultContext, user.ID, packages_model.TypeContainer, image, container_model.UploadVersion)
assert.ErrorIs(t, err, packages_model.ErrPackageNotExist)
}
})
}
2 changes: 1 addition & 1 deletion models/packages/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ func GetPackagesByType(ctx context.Context, ownerID int64, packageType Type) ([]
// DeletePackagesIfUnreferenced deletes a package if there are no associated versions
func DeletePackagesIfUnreferenced(ctx context.Context) error {
in := builder.
Select("package_version.package_id").
Select("package.id").
lunny marked this conversation as resolved.
Show resolved Hide resolved
From("package").
Join("LEFT", "package_version", "package_version.package_id = package.id").
Where(builder.Expr("package_version.id IS NULL"))
Expand Down
157 changes: 67 additions & 90 deletions models/packages/package_version.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,13 @@ import (

"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"

"xorm.io/builder"
)

var (
// ErrDuplicatePackageVersion indicates a duplicated package version error
ErrDuplicatePackageVersion = errors.New("Package version does exist already")
// ErrPackageVersionNotExist indicates a package version not exist error
ErrPackageVersionNotExist = errors.New("Package version does not exist")
)
// ErrDuplicatePackageVersion indicates a duplicated package version error
var ErrDuplicatePackageVersion = errors.New("Package version does exist already")
KN4CK3R marked this conversation as resolved.
Show resolved Hide resolved

func init() {
db.RegisterModel(new(PackageVersion))
Expand Down Expand Up @@ -99,75 +96,43 @@ func GetInternalVersionByNameAndVersion(ctx context.Context, ownerID int64, pack
}

func getVersionByNameAndVersion(ctx context.Context, ownerID int64, packageType Type, name, version string, isInternal bool) (*PackageVersion, error) {
var cond builder.Cond = builder.Eq{
"package.owner_id": ownerID,
"package.type": packageType,
"package.lower_name": strings.ToLower(name),
"package_version.is_internal": isInternal,
}
pv := &PackageVersion{
LowerVersion: strings.ToLower(version),
}
has, err := db.GetEngine(ctx).
Join("INNER", "package", "package.id = package_version.package_id").
Where(cond).
Get(pv)
pvs, _, err := SearchVersions(ctx, &PackageSearchOptions{
OwnerID: ownerID,
Type: packageType,
NameExactMatch: true,
QueryName: name,
VersionExactMatch: true,
QueryVersion: version,
IsInternal: isInternal,
Paginator: db.NewAbsoluteListOptions(0, 1),
})
if err != nil {
return nil, err
}
if !has {
if len(pvs) == 0 {
return nil, ErrPackageNotExist
}

return pv, nil
return pvs[0], nil
}

// GetVersionsByPackageType gets all versions of a specific type
func GetVersionsByPackageType(ctx context.Context, ownerID int64, packageType Type) ([]*PackageVersion, error) {
var cond builder.Cond = builder.Eq{
"package.owner_id": ownerID,
"package.type": packageType,
"package_version.is_internal": false,
}

pvs := make([]*PackageVersion, 0, 10)
return pvs, db.GetEngine(ctx).
Where(cond).
Join("INNER", "package", "package.id = package_version.package_id").
Find(&pvs)
pvs, _, err := SearchVersions(ctx, &PackageSearchOptions{
OwnerID: ownerID,
Type: packageType,
})
return pvs, err
}

// GetVersionsByPackageName gets all versions of a specific package
func GetVersionsByPackageName(ctx context.Context, ownerID int64, packageType Type, name string) ([]*PackageVersion, error) {
var cond builder.Cond = builder.Eq{
"package.owner_id": ownerID,
"package.type": packageType,
"package.lower_name": strings.ToLower(name),
"package_version.is_internal": false,
}

pvs := make([]*PackageVersion, 0, 10)
return pvs, db.GetEngine(ctx).
Where(cond).
Join("INNER", "package", "package.id = package_version.package_id").
Find(&pvs)
}

// GetVersionsByFilename gets all versions which are linked to a filename
func GetVersionsByFilename(ctx context.Context, ownerID int64, packageType Type, filename string) ([]*PackageVersion, error) {
var cond builder.Cond = builder.Eq{
"package.owner_id": ownerID,
"package.type": packageType,
"package_file.lower_name": strings.ToLower(filename),
"package_version.is_internal": false,
}

pvs := make([]*PackageVersion, 0, 10)
return pvs, db.GetEngine(ctx).
Where(cond).
Join("INNER", "package_file", "package_file.version_id = package_version.id").
Join("INNER", "package", "package.id = package_version.package_id").
Find(&pvs)
pvs, _, err := SearchVersions(ctx, &PackageSearchOptions{
OwnerID: ownerID,
Type: packageType,
NameExactMatch: true,
QueryName: name,
})
return pvs, err
}

// DeleteVersionByID deletes a version by id
Expand All @@ -185,19 +150,24 @@ func HasVersionFileReferences(ctx context.Context, versionID int64) (bool, error

// PackageSearchOptions are options for SearchXXX methods
type PackageSearchOptions struct {
OwnerID int64
RepoID int64
Type string
PackageID int64
QueryName string
QueryVersion string
Properties map[string]string
Sort string
OwnerID int64
RepoID int64
Type Type
PackageID int64
NameExactMatch bool
QueryName string
VersionExactMatch bool
QueryVersion string
Properties map[string]string
IsInternal bool
HasFileWithName string
HasFiles util.OptionalBool
Sort string
6543 marked this conversation as resolved.
Show resolved Hide resolved
db.Paginator
}

func (opts *PackageSearchOptions) toConds() builder.Cond {
var cond builder.Cond = builder.Eq{"package_version.is_internal": false}
var cond builder.Cond = builder.Eq{"package_version.is_internal": opts.IsInternal}

if opts.OwnerID != 0 {
cond = cond.And(builder.Eq{"package.owner_id": opts.OwnerID})
Expand All @@ -212,10 +182,18 @@ func (opts *PackageSearchOptions) toConds() builder.Cond {
cond = cond.And(builder.Eq{"package.id": opts.PackageID})
}
if opts.QueryName != "" {
cond = cond.And(builder.Like{"package.lower_name", strings.ToLower(opts.QueryName)})
if opts.NameExactMatch {
cond = cond.And(builder.Eq{"package.lower_name": strings.ToLower(opts.QueryName)})
} else {
cond = cond.And(builder.Like{"package.lower_name", strings.ToLower(opts.QueryName)})
}
}
if opts.QueryVersion != "" {
cond = cond.And(builder.Like{"package_version.lower_version", strings.ToLower(opts.QueryVersion)})
if opts.VersionExactMatch {
cond = cond.And(builder.Eq{"package_version.lower_version": strings.ToLower(opts.QueryVersion)})
} else {
cond = cond.And(builder.Like{"package_version.lower_version", strings.ToLower(opts.QueryVersion)})
}
}

if len(opts.Properties) != 0 {
Expand All @@ -238,6 +216,22 @@ func (opts *PackageSearchOptions) toConds() builder.Cond {
})
}

if opts.HasFileWithName != "" {
fileCond := builder.Expr("package_file.version_id = package_version.id").And(builder.Eq{"package_file.lower_name": strings.ToLower(opts.HasFileWithName)})

cond = cond.And(builder.Exists(builder.Select("package_file.id").From("package_file").Where(fileCond)))
}

if !opts.HasFiles.IsNone() {
var filesCond builder.Cond = builder.Exists(builder.Select("package_file.id").From("package_file").Where(builder.Expr("package_file.version_id = package_version.id")))

if opts.HasFiles.IsFalse() {
filesCond = builder.Not{filesCond}
}

cond = cond.And(filesCond)
}

return cond
}

Expand Down Expand Up @@ -297,20 +291,3 @@ func SearchLatestVersions(ctx context.Context, opts *PackageSearchOptions) ([]*P
count, err := sess.FindAndCount(&pvs)
return pvs, count, err
}

// FindVersionsByPropertyNameAndValue gets all package versions which are associated with a specific property + value
func FindVersionsByPropertyNameAndValue(ctx context.Context, packageID int64, name, value string) ([]*PackageVersion, error) {
var cond builder.Cond = builder.Eq{
"package_property.ref_type": PropertyTypeVersion,
"package_property.name": name,
"package_property.value": value,
"package_version.package_id": packageID,
"package_version.is_internal": false,
}

pvs := make([]*PackageVersion, 0, 5)
return pvs, db.GetEngine(ctx).
Where(cond).
Join("INNER", "package_property", "package_property.ref_id = package_version.id").
Find(&pvs)
}
2 changes: 1 addition & 1 deletion routers/api/packages/composer/composer.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func SearchPackages(ctx *context.Context) {

opts := &packages_model.PackageSearchOptions{
OwnerID: ctx.Package.Owner.ID,
Type: string(packages_model.TypeComposer),
Type: packages_model.TypeComposer,
QueryName: ctx.FormTrim("q"),
Paginator: &paginator,
}
Expand Down
7 changes: 6 additions & 1 deletion routers/api/packages/npm/npm.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,12 @@ func setPackageTag(tag string, pv *packages_model.PackageVersion, deleteOnly boo
}
defer committer.Close()

pvs, err := packages_model.FindVersionsByPropertyNameAndValue(ctx, pv.PackageID, npm_module.TagProperty, tag)
pvs, _, err := packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{
PackageID: pv.PackageID,
Properties: map[string]string{
npm_module.TagProperty: tag,
},
})
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion routers/api/packages/nuget/nuget.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func ServiceIndex(ctx *context.Context) {
func SearchService(ctx *context.Context) {
pvs, count, err := packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{
OwnerID: ctx.Package.Owner.ID,
Type: string(packages_model.TypeNuGet),
Type: packages_model.TypeNuGet,
QueryName: ctx.FormTrim("q"),
Paginator: db.NewAbsoluteListOptions(
ctx.FormInt("skip"),
Expand Down
15 changes: 12 additions & 3 deletions routers/api/packages/rubygems/rubygems.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func EnumeratePackages(ctx *context.Context) {
func EnumeratePackagesLatest(ctx *context.Context) {
pvs, _, err := packages_model.SearchLatestVersions(ctx, &packages_model.PackageSearchOptions{
OwnerID: ctx.Package.Owner.ID,
Type: string(packages_model.TypeRubyGems),
Type: packages_model.TypeRubyGems,
})
if err != nil {
apiError(ctx, http.StatusInternalServerError, err)
Expand Down Expand Up @@ -96,7 +96,7 @@ func ServePackageSpecification(ctx *context.Context) {
return
}

pvs, err := packages_model.GetVersionsByFilename(ctx, ctx.Package.Owner.ID, packages_model.TypeRubyGems, filename[:len(filename)-10]+"gem")
pvs, err := getVersionsByFilename(ctx, filename[:len(filename)-10]+"gem")
if err != nil {
apiError(ctx, http.StatusInternalServerError, err)
return
Expand Down Expand Up @@ -158,7 +158,7 @@ func ServePackageSpecification(ctx *context.Context) {
func DownloadPackageFile(ctx *context.Context) {
filename := ctx.Params("filename")

pvs, err := packages_model.GetVersionsByFilename(ctx, ctx.Package.Owner.ID, packages_model.TypeRubyGems, filename)
pvs, err := getVersionsByFilename(ctx, filename)
if err != nil {
apiError(ctx, http.StatusInternalServerError, err)
return
Expand Down Expand Up @@ -283,3 +283,12 @@ func DeletePackage(ctx *context.Context) {
apiError(ctx, http.StatusInternalServerError, err)
}
}

func getVersionsByFilename(ctx *context.Context, filename string) ([]*packages_model.PackageVersion, error) {
pvs, _, err := packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{
OwnerID: ctx.Package.Owner.ID,
Type: packages_model.TypeRubyGems,
HasFileWithName: filename,
})
return pvs, err
}
2 changes: 1 addition & 1 deletion routers/api/v1/packages/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func ListPackages(ctx *context.APIContext) {

pvs, count, err := packages.SearchVersions(ctx, &packages.PackageSearchOptions{
OwnerID: ctx.Package.Owner.ID,
Type: packageType,
Type: packages.Type(packageType),
QueryName: query,
Paginator: &listOptions,
})
Expand Down
2 changes: 1 addition & 1 deletion routers/web/admin/packages.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func Packages(ctx *context.Context) {

pvs, total, err := packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{
QueryName: query,
Type: packageType,
Type: packages_model.Type(packageType),
Sort: sort,
Paginator: &db.ListOptions{
PageSize: setting.UI.PackagesPagingNum,
Expand Down
2 changes: 1 addition & 1 deletion routers/web/repo/packages.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func Packages(ctx *context.Context) {
OwnerID: ctx.ContextUser.ID,
RepoID: ctx.Repo.Repository.ID,
QueryName: query,
Type: packageType,
Type: packages.Type(packageType),
})
if err != nil {
ctx.ServerError("SearchLatestVersions", err)
Expand Down
2 changes: 1 addition & 1 deletion routers/web/user/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func ListPackages(ctx *context.Context) {
Page: page,
},
OwnerID: ctx.ContextUser.ID,
Type: packageType,
Type: packages_model.Type(packageType),
QueryName: query,
})
if err != nil {
Expand Down
Loading