Skip to content

Commit 4130feb

Browse files
committed
feat: new generic package version/file enumeration api endpoint
1 parent cddff73 commit 4130feb

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed

routers/api/packages/api.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@ func CommonRoutes() *web.Router {
336336
})
337337
}, reqPackageAccess(perm.AccessModeRead))
338338
r.Group("/generic", func() {
339+
r.Get("/{packagename}/list", generic.EnumeratePackageVersions)
339340
r.Group("/{packagename}/{packageversion}", func() {
340341
r.Delete("", reqPackageAccess(perm.AccessModeWrite), generic.DeletePackage)
341342
r.Group("/{filename}", func() {

routers/api/packages/generic/generic.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212

1313
packages_model "code.gitea.io/gitea/models/packages"
1414
packages_module "code.gitea.io/gitea/modules/packages"
15+
"code.gitea.io/gitea/modules/timeutil"
1516
"code.gitea.io/gitea/routers/api/packages/helper"
1617
"code.gitea.io/gitea/services/context"
1718
packages_service "code.gitea.io/gitea/services/packages"
@@ -22,11 +23,70 @@ var (
2223
filenameRegex = regexp.MustCompile(`\A[-_+=:;.()\[\]{}~!@#$%^& \w]+\z`)
2324
)
2425

26+
// GenericPackageFileInfo represents information about an existing package file
27+
// swagger:model
28+
type GenericPackageFileInfo struct {
29+
// Name of package file
30+
Name string `json:"name"`
31+
// swagger:strfmt date-time
32+
// Date when package file was created/uploaded
33+
CreatedUnix timeutil.TimeStamp `json:"created"`
34+
}
35+
36+
// GenericPackageInfo represents information about an existing package file
37+
// swagger:model
38+
type GenericPackageInfo struct {
39+
/// Version linked to package information
40+
Version string `json:"version"`
41+
/// Download count for files within version
42+
DownloadCount int64 `json:"downloads"`
43+
/// Files uploaded for package version
44+
Files []GenericPackageFileInfo `json:"files"`
45+
}
46+
2547
func apiError(ctx *context.Context, status int, obj any) {
2648
message := helper.ProcessErrorForUser(ctx, status, obj)
2749
ctx.PlainText(status, message)
2850
}
2951

52+
// EnumeratePackageVersions lists upload versions and their associated files
53+
func EnumeratePackageVersions(ctx *context.Context) {
54+
pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeGeneric, ctx.PathParam("packagename"))
55+
if err != nil {
56+
apiError(ctx, http.StatusInternalServerError, err)
57+
return
58+
}
59+
if len(pvs) == 0 {
60+
apiError(ctx, http.StatusNotFound, err)
61+
return
62+
}
63+
64+
var info []GenericPackageInfo
65+
for _, pv := range pvs {
66+
packageFiles, err := packages_model.GetFilesByVersionID(ctx, pv.ID)
67+
if err != nil {
68+
apiError(ctx, http.StatusInternalServerError, err)
69+
return
70+
}
71+
72+
var files []GenericPackageFileInfo
73+
for _, file := range packageFiles {
74+
files = append(files, GenericPackageFileInfo{
75+
Name: file.Name,
76+
CreatedUnix: file.CreatedUnix,
77+
})
78+
}
79+
80+
info = append(info, GenericPackageInfo{
81+
Version: pv.Version,
82+
DownloadCount: pv.DownloadCount,
83+
Files: files,
84+
})
85+
}
86+
87+
ctx.JSON(http.StatusOK, info)
88+
}
89+
3090
// DownloadPackageFile serves the specific generic package.
3191
func DownloadPackageFile(ctx *context.Context) {
3292
s, u, pf, err := packages_service.OpenFileForDownloadByPackageNameAndVersion(

0 commit comments

Comments
 (0)