Skip to content

Commit 2e613ad

Browse files
committed
Some NuGet package enhancements
- go-gitea/gitea#30280
1 parent ceba1ab commit 2e613ad

File tree

3 files changed

+73
-32
lines changed

3 files changed

+73
-32
lines changed

modules/packages/nuget/metadata.go

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ type Package struct {
5959
type Metadata struct {
6060
Description string `json:"description,omitempty"`
6161
ReleaseNotes string `json:"release_notes,omitempty"`
62+
Readme string `json:"readme,omitempty"`
6263
Authors string `json:"authors,omitempty"`
6364
ProjectURL string `json:"project_url,omitempty"`
6465
RepositoryURL string `json:"repository_url,omitempty"`
@@ -72,6 +73,7 @@ type Dependency struct {
7273
Version string `json:"version"`
7374
}
7475

76+
// https://learn.microsoft.com/en-us/nuget/reference/nuspec
7577
type nuspecPackage struct {
7678
Metadata struct {
7779
ID string `xml:"id"`
@@ -81,6 +83,7 @@ type nuspecPackage struct {
8183
ProjectURL string `xml:"projectUrl"`
8284
Description string `xml:"description"`
8385
ReleaseNotes string `xml:"releaseNotes"`
86+
Readme string `xml:"readme"`
8487
PackageTypes struct {
8588
PackageType []struct {
8689
Name string `xml:"name,attr"`
@@ -90,6 +93,11 @@ type nuspecPackage struct {
9093
URL string `xml:"url,attr"`
9194
} `xml:"repository"`
9295
Dependencies struct {
96+
Dependency []struct {
97+
ID string `xml:"id,attr"`
98+
Version string `xml:"version,attr"`
99+
Exclude string `xml:"exclude,attr"`
100+
} `xml:"dependency"`
93101
Group []struct {
94102
TargetFramework string `xml:"targetFramework,attr"`
95103
Dependency []struct {
@@ -123,14 +131,14 @@ func ParsePackageMetaData(r io.ReaderAt, size int64) (*Package, error) {
123131
}
124132
defer f.Close()
125133

126-
return ParseNuspecMetaData(f)
134+
return ParseNuspecMetaData(archive, f)
127135
}
128136
}
129137
return nil, ErrMissingNuspecFile
130138
}
131139

132140
// ParseNuspecMetaData parses a Nuspec file to retrieve the metadata of a Nuget package
133-
func ParseNuspecMetaData(r io.Reader) (*Package, error) {
141+
func ParseNuspecMetaData(archive *zip.Reader, r io.Reader) (*Package, error) {
134142
var nuspecBuf bytes.Buffer
135143
var p nuspecPackage
136144
if err := xml.NewDecoder(io.TeeReader(r, &nuspecBuf)).Decode(&p); err != nil {
@@ -168,6 +176,28 @@ func ParseNuspecMetaData(r io.Reader) (*Package, error) {
168176
Dependencies: make(map[string][]Dependency),
169177
}
170178

179+
if p.Metadata.Readme != "" {
180+
f, err := archive.Open(p.Metadata.Readme)
181+
if err == nil {
182+
buf, _ := io.ReadAll(f)
183+
m.Readme = string(buf)
184+
_ = f.Close()
185+
}
186+
}
187+
188+
if len(p.Metadata.Dependencies.Dependency) > 0 {
189+
deps := make([]Dependency, 0, len(p.Metadata.Dependencies.Dependency))
190+
for _, dep := range p.Metadata.Dependencies.Dependency {
191+
if dep.ID == "" || dep.Version == "" {
192+
continue
193+
}
194+
deps = append(deps, Dependency{
195+
ID: dep.ID,
196+
Version: dep.Version,
197+
})
198+
}
199+
m.Dependencies[""] = deps
200+
}
171201
for _, group := range p.Metadata.Dependencies.Group {
172202
deps := make([]Dependency, 0, len(group.Dependency))
173203
for _, dep := range group.Dependency {

modules/packages/nuget/metadata_test.go

Lines changed: 37 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ package nuget
66
import (
77
"archive/zip"
88
"bytes"
9-
"strings"
109
"testing"
1110

1211
"github.com/stretchr/testify/assert"
@@ -19,6 +18,7 @@ const (
1918
projectURL = "https://gitea.io"
2019
description = "Package Description"
2120
releaseNotes = "Package Release Notes"
21+
readme = "Readme"
2222
repositoryURL = "https://gitea.io/gitea/gitea"
2323
targetFramework = ".NETStandard2.1"
2424
dependencyID = "System.Text.Json"
@@ -36,6 +36,7 @@ const nuspecContent = `<?xml version="1.0" encoding="utf-8"?>
3636
<description>` + description + `</description>
3737
<releaseNotes>` + releaseNotes + `</releaseNotes>
3838
<repository url="` + repositoryURL + `" />
39+
<readme>README.md</readme>
3940
<dependencies>
4041
<group targetFramework="` + targetFramework + `">
4142
<dependency id="` + dependencyID + `" version="` + dependencyVersion + `" exclude="Build,Analyzers" />
@@ -60,75 +61,81 @@ const symbolsNuspecContent = `<?xml version="1.0" encoding="utf-8"?>
6061
</package>`
6162

6263
func TestParsePackageMetaData(t *testing.T) {
63-
createArchive := func(name, content string) []byte {
64+
createArchive := func(files map[string]string) []byte {
6465
var buf bytes.Buffer
6566
archive := zip.NewWriter(&buf)
66-
w, _ := archive.Create(name)
67-
w.Write([]byte(content))
67+
for name, content := range files {
68+
w, _ := archive.Create(name)
69+
w.Write([]byte(content))
70+
}
6871
archive.Close()
6972
return buf.Bytes()
7073
}
7174

7275
t.Run("MissingNuspecFile", func(t *testing.T) {
73-
data := createArchive("dummy.txt", "")
76+
data := createArchive(map[string]string{"dummy.txt": ""})
7477

7578
np, err := ParsePackageMetaData(bytes.NewReader(data), int64(len(data)))
7679
assert.Nil(t, np)
7780
assert.ErrorIs(t, err, ErrMissingNuspecFile)
7881
})
7982

8083
t.Run("MissingNuspecFileInRoot", func(t *testing.T) {
81-
data := createArchive("sub/package.nuspec", "")
84+
data := createArchive(map[string]string{"sub/package.nuspec": ""})
8285

8386
np, err := ParsePackageMetaData(bytes.NewReader(data), int64(len(data)))
8487
assert.Nil(t, np)
8588
assert.ErrorIs(t, err, ErrMissingNuspecFile)
8689
})
8790

8891
t.Run("InvalidNuspecFile", func(t *testing.T) {
89-
data := createArchive("package.nuspec", "")
92+
data := createArchive(map[string]string{"package.nuspec": ""})
9093

9194
np, err := ParsePackageMetaData(bytes.NewReader(data), int64(len(data)))
9295
assert.Nil(t, np)
9396
assert.Error(t, err)
9497
})
9598

9699
t.Run("InvalidPackageId", func(t *testing.T) {
97-
data := createArchive("package.nuspec", `<?xml version="1.0" encoding="utf-8"?>
100+
data := createArchive(map[string]string{"package.nuspec": `<?xml version="1.0" encoding="utf-8"?>
98101
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
99102
<metadata></metadata>
100-
</package>`)
103+
</package>`})
101104

102105
np, err := ParsePackageMetaData(bytes.NewReader(data), int64(len(data)))
103106
assert.Nil(t, np)
104107
assert.ErrorIs(t, err, ErrNuspecInvalidID)
105108
})
106109

107110
t.Run("InvalidPackageVersion", func(t *testing.T) {
108-
data := createArchive("package.nuspec", `<?xml version="1.0" encoding="utf-8"?>
111+
data := createArchive(map[string]string{"package.nuspec": `<?xml version="1.0" encoding="utf-8"?>
109112
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
110113
<metadata>
111-
<id>`+id+`</id>
114+
<id>` + id + `</id>
112115
</metadata>
113-
</package>`)
116+
</package>`})
114117

115118
np, err := ParsePackageMetaData(bytes.NewReader(data), int64(len(data)))
116119
assert.Nil(t, np)
117120
assert.ErrorIs(t, err, ErrNuspecInvalidVersion)
118121
})
119122

120-
t.Run("Valid", func(t *testing.T) {
121-
data := createArchive("package.nuspec", nuspecContent)
123+
t.Run("MissingReadme", func(t *testing.T) {
124+
data := createArchive(map[string]string{"package.nuspec": nuspecContent})
122125

123126
np, err := ParsePackageMetaData(bytes.NewReader(data), int64(len(data)))
124127
assert.NoError(t, err)
125128
assert.NotNil(t, np)
129+
assert.Empty(t, np.Metadata.Readme)
126130
})
127-
}
128131

129-
func TestParseNuspecMetaData(t *testing.T) {
130132
t.Run("Dependency Package", func(t *testing.T) {
131-
np, err := ParseNuspecMetaData(strings.NewReader(nuspecContent))
133+
data := createArchive(map[string]string{
134+
"package.nuspec": nuspecContent,
135+
"README.md": readme,
136+
})
137+
138+
np, err := ParsePackageMetaData(bytes.NewReader(data), int64(len(data)))
132139
assert.NoError(t, err)
133140
assert.NotNil(t, np)
134141
assert.Equal(t, DependencyPackage, np.PackageType)
@@ -139,6 +146,7 @@ func TestParseNuspecMetaData(t *testing.T) {
139146
assert.Equal(t, projectURL, np.Metadata.ProjectURL)
140147
assert.Equal(t, description, np.Metadata.Description)
141148
assert.Equal(t, releaseNotes, np.Metadata.ReleaseNotes)
149+
assert.Equal(t, readme, np.Metadata.Readme)
142150
assert.Equal(t, repositoryURL, np.Metadata.RepositoryURL)
143151
assert.Len(t, np.Metadata.Dependencies, 1)
144152
assert.Contains(t, np.Metadata.Dependencies, targetFramework)
@@ -148,21 +156,25 @@ func TestParseNuspecMetaData(t *testing.T) {
148156
assert.Equal(t, dependencyVersion, deps[0].Version)
149157

150158
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>`))
159+
data := createArchive(map[string]string{"package.nuspec": `<?xml version="1.0" encoding="utf-8"?>
160+
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
161+
<metadata>
162+
<id>test</id>
163+
<version>1.04.5.2.5-rc.1+metadata</version>
164+
</metadata>
165+
</package>`})
166+
167+
np, err := ParsePackageMetaData(bytes.NewReader(data), int64(len(data)))
158168
assert.NoError(t, err)
159169
assert.NotNil(t, np)
160170
assert.Equal(t, "1.4.5.2-rc.1", np.Version)
161171
})
162172
})
163173

164174
t.Run("Symbols Package", func(t *testing.T) {
165-
np, err := ParseNuspecMetaData(strings.NewReader(symbolsNuspecContent))
175+
data := createArchive(map[string]string{"package.nuspec": symbolsNuspecContent})
176+
177+
np, err := ParsePackageMetaData(bytes.NewReader(data), int64(len(data)))
166178
assert.NoError(t, err)
167179
assert.NotNil(t, np)
168180
assert.Equal(t, SymbolsPackage, np.PackageType)

templates/package/content/nuget.tmpl

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,11 @@
1616
</div>
1717
</div>
1818

19-
{{if or .PackageDescriptor.Metadata.Description .PackageDescriptor.Metadata.ReleaseNotes}}
19+
{{if or .PackageDescriptor.Metadata.Description .PackageDescriptor.Metadata.ReleaseNotes .PackageDescriptor.Metadata.Readme}}
2020
<h4 class="ui top attached header">{{ctx.Locale.Tr "packages.about"}}</h4>
21-
<div class="ui attached segment">
22-
{{if .PackageDescriptor.Metadata.Description}}{{.PackageDescriptor.Metadata.Description}}{{end}}
23-
{{if .PackageDescriptor.Metadata.ReleaseNotes}}{{.PackageDescriptor.Metadata.ReleaseNotes}}{{end}}
24-
</div>
21+
{{if .PackageDescriptor.Metadata.Description}}<div class="ui attached segment">{{RenderMarkdownToHtml $.Context .PackageDescriptor.Metadata.Description}}</div>{{end}}
22+
{{if .PackageDescriptor.Metadata.Readme}}<div class="ui attached segment markup markdown">{{RenderMarkdownToHtml $.Context .PackageDescriptor.Metadata.Readme}}</div>{{end}}
23+
{{if .PackageDescriptor.Metadata.ReleaseNotes}}<div class="ui attached segment">{{RenderMarkdownToHtml $.Context .PackageDescriptor.Metadata.ReleaseNotes}}</div>{{end}}
2524
{{end}}
2625

2726
{{if .PackageDescriptor.Metadata.Dependencies}}

0 commit comments

Comments
 (0)