Skip to content

Commit 86ace4b

Browse files
KN4CK3Rlunny
andauthored
Normalize NuGet package version on upload (#22186)
Fixes #22178 After this change upload versions with different semver metadata are treated as the same version and trigger a duplicated version error. Co-authored-by: Lunny Xiao <[email protected]>
1 parent fe6608f commit 86ace4b

File tree

4 files changed

+36
-21
lines changed

4 files changed

+36
-21
lines changed

modules/packages/nuget/metadata.go

+19-1
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ package nuget
55

66
import (
77
"archive/zip"
8+
"bytes"
89
"encoding/xml"
910
"errors"
11+
"fmt"
1012
"io"
1113
"path/filepath"
1214
"regexp"
@@ -182,7 +184,23 @@ func ParseNuspecMetaData(r io.Reader) (*Package, error) {
182184
return &Package{
183185
PackageType: packageType,
184186
ID: p.Metadata.ID,
185-
Version: v.String(),
187+
Version: toNormalizedVersion(v),
186188
Metadata: m,
187189
}, nil
188190
}
191+
192+
// https://learn.microsoft.com/en-us/nuget/concepts/package-versioning#normalized-version-numbers
193+
// https://github.com/NuGet/NuGet.Client/blob/dccbd304b11103e08b97abf4cf4bcc1499d9235a/src/NuGet.Core/NuGet.Versioning/VersionFormatter.cs#L121
194+
func toNormalizedVersion(v *version.Version) string {
195+
var buf bytes.Buffer
196+
segments := v.Segments64()
197+
fmt.Fprintf(&buf, "%d.%d.%d", segments[0], segments[1], segments[2])
198+
if len(segments) > 3 && segments[3] > 0 {
199+
fmt.Fprintf(&buf, ".%d", segments[3])
200+
}
201+
pre := v.Prerelease()
202+
if pre != "" {
203+
fmt.Fprint(&buf, "-", pre)
204+
}
205+
return buf.String()
206+
}

modules/packages/nuget/metadata_test.go

+13
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,19 @@ func TestParseNuspecMetaData(t *testing.T) {
146146
assert.Len(t, deps, 1)
147147
assert.Equal(t, dependencyID, deps[0].ID)
148148
assert.Equal(t, dependencyVersion, deps[0].Version)
149+
150+
t.Run("NormalizedVersion", func(t *testing.T) {
151+
np, err := ParseNuspecMetaData(strings.NewReader(`<?xml version="1.0" encoding="utf-8"?>
152+
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
153+
<metadata>
154+
<id>test</id>
155+
<version>1.04.5.2.5-rc.1+metadata</version>
156+
</metadata>
157+
</package>`))
158+
assert.NoError(t, err)
159+
assert.NotNil(t, np)
160+
assert.Equal(t, "1.4.5.2-rc.1", np.Version)
161+
})
149162
})
150163

151164
t.Run("Symbols Package", func(t *testing.T) {

routers/api/packages/nuget/api_v2.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ func createEntry(l *linkBuilder, pd *packages_model.PackageDescriptor, withNames
344344
Content: content,
345345
Properties: &FeedEntryProperties{
346346
Version: pd.Version.Version,
347-
NormalizedVersion: normalizeVersion(pd.SemVer),
347+
NormalizedVersion: pd.Version.Version,
348348
Authors: metadata.Authors,
349349
Dependencies: buildDependencyString(metadata),
350350
Description: metadata.Description,

routers/api/packages/nuget/api_v3.go

+3-19
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,11 @@
44
package nuget
55

66
import (
7-
"bytes"
8-
"fmt"
97
"sort"
108
"time"
119

1210
packages_model "code.gitea.io/gitea/models/packages"
1311
nuget_module "code.gitea.io/gitea/modules/packages/nuget"
14-
15-
"github.com/hashicorp/go-version"
1612
)
1713

1814
// https://docs.microsoft.com/en-us/nuget/api/service-index#resources
@@ -95,8 +91,8 @@ func createRegistrationIndexResponse(l *linkBuilder, pds []*packages_model.Packa
9591
{
9692
RegistrationPageURL: l.GetRegistrationIndexURL(pds[0].Package.Name),
9793
Count: len(pds),
98-
Lower: normalizeVersion(pds[0].SemVer),
99-
Upper: normalizeVersion(pds[len(pds)-1].SemVer),
94+
Lower: pds[0].Version.Version,
95+
Upper: pds[len(pds)-1].Version.Version,
10096
Items: items,
10197
},
10298
},
@@ -173,7 +169,7 @@ type PackageVersionsResponse struct {
173169
func createPackageVersionsResponse(pds []*packages_model.PackageDescriptor) *PackageVersionsResponse {
174170
versions := make([]string, 0, len(pds))
175171
for _, pd := range pds {
176-
versions = append(versions, normalizeVersion(pd.SemVer))
172+
versions = append(versions, pd.Version.Version)
177173
}
178174

179175
return &PackageVersionsResponse{
@@ -248,15 +244,3 @@ func createSearchResult(l *linkBuilder, pds []*packages_model.PackageDescriptor)
248244
RegistrationIndexURL: l.GetRegistrationIndexURL(latest.Package.Name),
249245
}
250246
}
251-
252-
// normalizeVersion removes the metadata
253-
func normalizeVersion(v *version.Version) string {
254-
var buf bytes.Buffer
255-
segments := v.Segments64()
256-
fmt.Fprintf(&buf, "%d.%d.%d", segments[0], segments[1], segments[2])
257-
pre := v.Prerelease()
258-
if pre != "" {
259-
fmt.Fprintf(&buf, "-%s", pre)
260-
}
261-
return buf.String()
262-
}

0 commit comments

Comments
 (0)