Skip to content

Commit 89c99a4

Browse files
GiteaBotahanoff
andauthored
fix: add author.name field to Swift Package Registry API response (#35410) (#35431)
Backport #35410 by ahanoff Fixes #35159 Swift Package Manager expects an 'author.name' field in package metadata, but Gitea was only providing schema.org format fields (givenName, middleName, familyName). This caused SPM to fail with keyNotFound error when fetching package metadata. Changes: - Add 'name' field to Person struct (inherited from https://schema.org/Thing) - Populate 'name' field in API response using existing String() method - Maintains backward compatibility with existing schema.org fields - Provides both formats for maximum compatibility The fix ensures Swift Package Manager can successfully resolve packages while preserving full schema.org compliance. Co-authored-by: Akhan Zhakiyanov <[email protected]>
1 parent 3c7e7a1 commit 89c99a4

File tree

4 files changed

+89
-1
lines changed

4 files changed

+89
-1
lines changed

modules/packages/swift/metadata.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ type ProgrammingLanguage struct {
8282
// https://schema.org/Person
8383
type Person struct {
8484
Type string `json:"@type,omitempty"`
85+
Name string `json:"name,omitempty"` // inherited from https://schema.org/Thing
8586
GivenName string `json:"givenName,omitempty"`
8687
MiddleName string `json:"middleName,omitempty"`
8788
FamilyName string `json:"familyName,omitempty"`
@@ -184,11 +185,17 @@ func ParsePackage(sr io.ReaderAt, size int64, mr io.Reader) (*Package, error) {
184185
p.Metadata.Description = ssc.Description
185186
p.Metadata.Keywords = ssc.Keywords
186187
p.Metadata.License = ssc.License
187-
p.Metadata.Author = Person{
188+
author := Person{
189+
Name: ssc.Author.Name,
188190
GivenName: ssc.Author.GivenName,
189191
MiddleName: ssc.Author.MiddleName,
190192
FamilyName: ssc.Author.FamilyName,
191193
}
194+
// If Name is not provided, generate it from individual name components
195+
if author.Name == "" {
196+
author.Name = author.String()
197+
}
198+
p.Metadata.Author = author
192199

193200
p.Metadata.RepositoryURL = ssc.CodeRepository
194201
if !validation.IsValidURL(p.Metadata.RepositoryURL) {

modules/packages/swift/metadata_test.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,49 @@ func TestParsePackage(t *testing.T) {
9797
assert.Equal(t, packageDescription, p.Metadata.Description)
9898
assert.ElementsMatch(t, []string{"swift", "package"}, p.Metadata.Keywords)
9999
assert.Equal(t, packageLicense, p.Metadata.License)
100+
assert.Equal(t, packageAuthor, p.Metadata.Author.Name)
100101
assert.Equal(t, packageAuthor, p.Metadata.Author.GivenName)
101102
assert.Equal(t, packageRepositoryURL, p.Metadata.RepositoryURL)
102103
assert.ElementsMatch(t, []string{packageRepositoryURL}, p.RepositoryURLs)
103104
})
105+
106+
t.Run("WithExplicitNameField", func(t *testing.T) {
107+
data := createArchive(map[string][]byte{
108+
"Package.swift": []byte("// swift-tools-version:5.7\n//\n// Package.swift"),
109+
})
110+
111+
authorName := "John Doe"
112+
p, err := ParsePackage(
113+
data,
114+
data.Size(),
115+
strings.NewReader(`{"name":"`+packageName+`","version":"`+packageVersion+`","description":"`+packageDescription+`","author":{"name":"`+authorName+`","givenName":"John","familyName":"Doe"}}`),
116+
)
117+
assert.NotNil(t, p)
118+
assert.NoError(t, err)
119+
120+
assert.Equal(t, authorName, p.Metadata.Author.Name)
121+
assert.Equal(t, "John", p.Metadata.Author.GivenName)
122+
assert.Equal(t, "Doe", p.Metadata.Author.FamilyName)
123+
})
124+
125+
t.Run("NameFieldGeneration", func(t *testing.T) {
126+
data := createArchive(map[string][]byte{
127+
"Package.swift": []byte("// swift-tools-version:5.7\n//\n// Package.swift"),
128+
})
129+
130+
// Test with only individual name components - Name should be auto-generated
131+
p, err := ParsePackage(
132+
data,
133+
data.Size(),
134+
strings.NewReader(`{"author":{"givenName":"John","middleName":"Q","familyName":"Doe"}}`),
135+
)
136+
assert.NotNil(t, p)
137+
assert.NoError(t, err)
138+
assert.Equal(t, "John Q Doe", p.Metadata.Author.Name)
139+
assert.Equal(t, "John", p.Metadata.Author.GivenName)
140+
assert.Equal(t, "Q", p.Metadata.Author.MiddleName)
141+
assert.Equal(t, "Doe", p.Metadata.Author.FamilyName)
142+
})
104143
}
105144

106145
func TestTrimmedVersionString(t *testing.T) {
@@ -142,3 +181,43 @@ func TestTrimmedVersionString(t *testing.T) {
142181
assert.Equal(t, c.Expected, TrimmedVersionString(c.Version))
143182
}
144183
}
184+
185+
func TestPersonNameString(t *testing.T) {
186+
cases := []struct {
187+
Name string
188+
Person Person
189+
Expected string
190+
}{
191+
{
192+
Name: "GivenNameOnly",
193+
Person: Person{GivenName: "John"},
194+
Expected: "John",
195+
},
196+
{
197+
Name: "GivenAndFamily",
198+
Person: Person{GivenName: "John", FamilyName: "Doe"},
199+
Expected: "John Doe",
200+
},
201+
{
202+
Name: "FullName",
203+
Person: Person{GivenName: "John", MiddleName: "Q", FamilyName: "Doe"},
204+
Expected: "John Q Doe",
205+
},
206+
{
207+
Name: "MiddleAndFamily",
208+
Person: Person{MiddleName: "Q", FamilyName: "Doe"},
209+
Expected: "Q Doe",
210+
},
211+
{
212+
Name: "Empty",
213+
Person: Person{},
214+
Expected: "",
215+
},
216+
}
217+
218+
for _, c := range cases {
219+
t.Run(c.Name, func(t *testing.T) {
220+
assert.Equal(t, c.Expected, c.Person.String())
221+
})
222+
}
223+
}

routers/api/packages/swift/swift.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ func PackageVersionMetadata(ctx *context.Context) {
230230
},
231231
Author: swift_module.Person{
232232
Type: "Person",
233+
Name: metadata.Author.String(),
233234
GivenName: metadata.Author.GivenName,
234235
MiddleName: metadata.Author.MiddleName,
235236
FamilyName: metadata.Author.FamilyName,

tests/integration/api_packages_swift_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,7 @@ func TestPackageSwift(t *testing.T) {
355355
assert.Equal(t, packageVersion, result.Metadata.Version)
356356
assert.Equal(t, packageDescription, result.Metadata.Description)
357357
assert.Equal(t, "Swift", result.Metadata.ProgrammingLanguage.Name)
358+
assert.Equal(t, packageAuthor, result.Metadata.Author.Name)
358359
assert.Equal(t, packageAuthor, result.Metadata.Author.GivenName)
359360

360361
req = NewRequest(t, "GET", fmt.Sprintf("%s/%s/%s/%s.json", url, packageScope, packageName, packageVersion)).

0 commit comments

Comments
 (0)