Skip to content

Commit 3da5ad9

Browse files
author
Earl Warren
committed
Merge pull request '[v7.0/forgejo] feat: improve nuget nuspec api' (go-gitea#3073) from bp-v7.0/forgejo-bc72fd7 into v7.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/3073 Reviewed-by: Gusted <[email protected]>
2 parents d2a7905 + 091400b commit 3da5ad9

File tree

5 files changed

+413
-175
lines changed

5 files changed

+413
-175
lines changed

modules/packages/nuget/metadata.go

Lines changed: 57 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,11 @@ const maxNuspecFileSize = 3 * 1024 * 1024
4848

4949
// Package represents a Nuget package
5050
type Package struct {
51-
PackageType PackageType
52-
ID string
53-
Version string
54-
Metadata *Metadata
51+
PackageType PackageType
52+
ID string
53+
Version string
54+
Metadata *Metadata
55+
NuspecContent *bytes.Buffer
5556
}
5657

5758
// Metadata represents the metadata of a Nuget package
@@ -71,50 +72,34 @@ type Dependency struct {
7172
Version string `json:"version"`
7273
}
7374

74-
type nuspecPackageType struct {
75-
Name string `xml:"name,attr"`
76-
}
77-
78-
type nuspecPackageTypes struct {
79-
PackageType []nuspecPackageType `xml:"packageType"`
80-
}
81-
82-
type nuspecRepository struct {
83-
URL string `xml:"url,attr,omitempty"`
84-
Type string `xml:"type,attr,omitempty"`
85-
}
86-
type nuspecDependency struct {
87-
ID string `xml:"id,attr"`
88-
Version string `xml:"version,attr"`
89-
Exclude string `xml:"exclude,attr,omitempty"`
90-
}
91-
92-
type nuspecGroup struct {
93-
TargetFramework string `xml:"targetFramework,attr"`
94-
Dependency []nuspecDependency `xml:"dependency"`
95-
}
96-
97-
type nuspecDependencies struct {
98-
Group []nuspecGroup `xml:"group"`
99-
}
100-
101-
type nuspeceMetadata struct {
102-
ID string `xml:"id"`
103-
Version string `xml:"version"`
104-
Authors string `xml:"authors"`
105-
RequireLicenseAcceptance bool `xml:"requireLicenseAcceptance,omitempty"`
106-
ProjectURL string `xml:"projectUrl,omitempty"`
107-
Description string `xml:"description"`
108-
ReleaseNotes string `xml:"releaseNotes,omitempty"`
109-
PackageTypes *nuspecPackageTypes `xml:"packageTypes,omitempty"`
110-
Repository *nuspecRepository `xml:"repository,omitempty"`
111-
Dependencies *nuspecDependencies `xml:"dependencies,omitempty"`
112-
}
113-
11475
type nuspecPackage struct {
115-
XMLName xml.Name `xml:"package"`
116-
Xmlns string `xml:"xmlns,attr"`
117-
Metadata nuspeceMetadata `xml:"metadata"`
76+
Metadata struct {
77+
ID string `xml:"id"`
78+
Version string `xml:"version"`
79+
Authors string `xml:"authors"`
80+
RequireLicenseAcceptance bool `xml:"requireLicenseAcceptance"`
81+
ProjectURL string `xml:"projectUrl"`
82+
Description string `xml:"description"`
83+
ReleaseNotes string `xml:"releaseNotes"`
84+
PackageTypes struct {
85+
PackageType []struct {
86+
Name string `xml:"name,attr"`
87+
} `xml:"packageType"`
88+
} `xml:"packageTypes"`
89+
Repository struct {
90+
URL string `xml:"url,attr"`
91+
} `xml:"repository"`
92+
Dependencies struct {
93+
Group []struct {
94+
TargetFramework string `xml:"targetFramework,attr"`
95+
Dependency []struct {
96+
ID string `xml:"id,attr"`
97+
Version string `xml:"version,attr"`
98+
Exclude string `xml:"exclude,attr"`
99+
} `xml:"dependency"`
100+
} `xml:"group"`
101+
} `xml:"dependencies"`
102+
} `xml:"metadata"`
118103
}
119104

120105
// ParsePackageMetaData parses the metadata of a Nuget package file
@@ -146,8 +131,9 @@ func ParsePackageMetaData(r io.ReaderAt, size int64) (*Package, error) {
146131

147132
// ParseNuspecMetaData parses a Nuspec file to retrieve the metadata of a Nuget package
148133
func ParseNuspecMetaData(r io.Reader) (*Package, error) {
134+
var nuspecBuf bytes.Buffer
149135
var p nuspecPackage
150-
if err := xml.NewDecoder(r).Decode(&p); err != nil {
136+
if err := xml.NewDecoder(io.TeeReader(r, &nuspecBuf)).Decode(&p); err != nil {
151137
return nil, err
152138
}
153139

@@ -165,12 +151,10 @@ func ParseNuspecMetaData(r io.Reader) (*Package, error) {
165151
}
166152

167153
packageType := DependencyPackage
168-
if p.Metadata.PackageTypes != nil {
169-
for _, pt := range p.Metadata.PackageTypes.PackageType {
170-
if pt.Name == "SymbolsPackage" {
171-
packageType = SymbolsPackage
172-
break
173-
}
154+
for _, pt := range p.Metadata.PackageTypes.PackageType {
155+
if pt.Name == "SymbolsPackage" {
156+
packageType = SymbolsPackage
157+
break
174158
}
175159
}
176160

@@ -179,34 +163,32 @@ func ParseNuspecMetaData(r io.Reader) (*Package, error) {
179163
ReleaseNotes: p.Metadata.ReleaseNotes,
180164
Authors: p.Metadata.Authors,
181165
ProjectURL: p.Metadata.ProjectURL,
166+
RepositoryURL: p.Metadata.Repository.URL,
182167
RequireLicenseAcceptance: p.Metadata.RequireLicenseAcceptance,
183168
Dependencies: make(map[string][]Dependency),
184169
}
185-
if p.Metadata.Repository != nil {
186-
m.RepositoryURL = p.Metadata.Repository.URL
187-
}
188-
if p.Metadata.Dependencies != nil {
189-
for _, group := range p.Metadata.Dependencies.Group {
190-
deps := make([]Dependency, 0, len(group.Dependency))
191-
for _, dep := range group.Dependency {
192-
if dep.ID == "" || dep.Version == "" {
193-
continue
194-
}
195-
deps = append(deps, Dependency{
196-
ID: dep.ID,
197-
Version: dep.Version,
198-
})
199-
}
200-
if len(deps) > 0 {
201-
m.Dependencies[group.TargetFramework] = deps
170+
171+
for _, group := range p.Metadata.Dependencies.Group {
172+
deps := make([]Dependency, 0, len(group.Dependency))
173+
for _, dep := range group.Dependency {
174+
if dep.ID == "" || dep.Version == "" {
175+
continue
202176
}
177+
deps = append(deps, Dependency{
178+
ID: dep.ID,
179+
Version: dep.Version,
180+
})
181+
}
182+
if len(deps) > 0 {
183+
m.Dependencies[group.TargetFramework] = deps
203184
}
204185
}
205186
return &Package{
206-
PackageType: packageType,
207-
ID: p.Metadata.ID,
208-
Version: toNormalizedVersion(v),
209-
Metadata: m,
187+
PackageType: packageType,
188+
ID: p.Metadata.ID,
189+
Version: toNormalizedVersion(v),
190+
Metadata: m,
191+
NuspecContent: &nuspecBuf,
210192
}, nil
211193
}
212194

@@ -225,51 +207,3 @@ func toNormalizedVersion(v *version.Version) string {
225207
}
226208
return buf.String()
227209
}
228-
229-
// returning any here because we use a private type and we don't need the type for xml marshalling
230-
func GenerateNuspec(pd *Package) any {
231-
m := nuspeceMetadata{
232-
ID: pd.ID,
233-
Version: pd.Version,
234-
Authors: pd.Metadata.Authors,
235-
Description: pd.Metadata.Description,
236-
ProjectURL: pd.Metadata.ProjectURL,
237-
RequireLicenseAcceptance: pd.Metadata.RequireLicenseAcceptance,
238-
}
239-
240-
if pd.Metadata.RepositoryURL != "" {
241-
m.Repository = &nuspecRepository{
242-
URL: pd.Metadata.RepositoryURL,
243-
}
244-
}
245-
246-
groups := len(pd.Metadata.Dependencies)
247-
if groups > 0 {
248-
m.Dependencies = &nuspecDependencies{
249-
Group: make([]nuspecGroup, 0, groups),
250-
}
251-
252-
for tgf, deps := range pd.Metadata.Dependencies {
253-
if len(deps) == 0 {
254-
continue
255-
}
256-
gDeps := make([]nuspecDependency, 0, len(deps))
257-
for _, dep := range deps {
258-
gDeps = append(gDeps, nuspecDependency{
259-
ID: dep.ID,
260-
Version: dep.Version,
261-
})
262-
}
263-
264-
m.Dependencies.Group = append(m.Dependencies.Group, nuspecGroup{
265-
TargetFramework: tgf,
266-
Dependency: gDeps,
267-
})
268-
}
269-
}
270-
271-
return &nuspecPackage{
272-
Xmlns: "http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd",
273-
Metadata: m,
274-
}
275-
}

routers/api/packages/nuget/nuget.go

Lines changed: 46 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -395,49 +395,28 @@ func DownloadPackageFile(ctx *context.Context) {
395395
packageVersion := ctx.Params("version")
396396
filename := ctx.Params("filename")
397397

398-
if filename == fmt.Sprintf("%s.nuspec", packageName) {
399-
pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeNuGet, packageName, packageVersion)
400-
if err != nil {
398+
s, u, pf, err := packages_service.GetFileStreamByPackageNameAndVersion(
399+
ctx,
400+
&packages_service.PackageInfo{
401+
Owner: ctx.Package.Owner,
402+
PackageType: packages_model.TypeNuGet,
403+
Name: packageName,
404+
Version: packageVersion,
405+
},
406+
&packages_service.PackageFileInfo{
407+
Filename: filename,
408+
},
409+
)
410+
if err != nil {
411+
if err == packages_model.ErrPackageNotExist || err == packages_model.ErrPackageFileNotExist {
401412
apiError(ctx, http.StatusNotFound, err)
402413
return
403414
}
404-
405-
pd, err := packages_model.GetPackageDescriptor(ctx, pv)
406-
if err != nil {
407-
apiError(ctx, http.StatusInternalServerError, err)
408-
return
409-
}
410-
pkg := &nuget_module.Package{
411-
ID: pd.Package.Name,
412-
Version: packageVersion,
413-
Metadata: pd.Metadata.(*nuget_module.Metadata),
414-
}
415-
416-
xmlResponse(ctx, http.StatusOK, nuget_module.GenerateNuspec(pkg))
417-
} else {
418-
s, u, pf, err := packages_service.GetFileStreamByPackageNameAndVersion(
419-
ctx,
420-
&packages_service.PackageInfo{
421-
Owner: ctx.Package.Owner,
422-
PackageType: packages_model.TypeNuGet,
423-
Name: packageName,
424-
Version: packageVersion,
425-
},
426-
&packages_service.PackageFileInfo{
427-
Filename: filename,
428-
},
429-
)
430-
if err != nil {
431-
if err == packages_model.ErrPackageNotExist || err == packages_model.ErrPackageFileNotExist {
432-
apiError(ctx, http.StatusNotFound, err)
433-
return
434-
}
435-
apiError(ctx, http.StatusInternalServerError, err)
436-
return
437-
}
438-
439-
helper.ServePackageFile(ctx, s, u, pf)
415+
apiError(ctx, http.StatusInternalServerError, err)
416+
return
440417
}
418+
419+
helper.ServePackageFile(ctx, s, u, pf)
441420
}
442421

443422
// UploadPackage creates a new package with the metadata contained in the uploaded nupgk file
@@ -453,7 +432,7 @@ func UploadPackage(ctx *context.Context) {
453432
return
454433
}
455434

456-
_, _, err := packages_service.CreatePackageAndAddFile(
435+
pv, _, err := packages_service.CreatePackageAndAddFile(
457436
ctx,
458437
&packages_service.PackageCreationInfo{
459438
PackageInfo: packages_service.PackageInfo{
@@ -487,6 +466,33 @@ func UploadPackage(ctx *context.Context) {
487466
return
488467
}
489468

469+
nuspecBuf, err := packages_module.CreateHashedBufferFromReaderWithSize(np.NuspecContent, np.NuspecContent.Len())
470+
if err != nil {
471+
apiError(ctx, http.StatusInternalServerError, err)
472+
return
473+
}
474+
defer nuspecBuf.Close()
475+
476+
_, err = packages_service.AddFileToPackageVersionInternal(
477+
ctx,
478+
pv,
479+
&packages_service.PackageFileCreationInfo{
480+
PackageFileInfo: packages_service.PackageFileInfo{
481+
Filename: strings.ToLower(fmt.Sprintf("%s.nuspec", np.ID)),
482+
},
483+
Data: nuspecBuf,
484+
},
485+
)
486+
if err != nil {
487+
switch err {
488+
case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize:
489+
apiError(ctx, http.StatusForbidden, err)
490+
default:
491+
apiError(ctx, http.StatusInternalServerError, err)
492+
}
493+
return
494+
}
495+
490496
ctx.Status(http.StatusCreated)
491497
}
492498

0 commit comments

Comments
 (0)