From 8d1aabf6e53bced20e5bdb1b3c9e93495829edc7 Mon Sep 17 00:00:00 2001 From: Akhan Zhakiyanov Date: Fri, 5 Sep 2025 16:21:16 +0800 Subject: [PATCH 1/5] fix: Add author.name field to Swift Package Registry API response 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 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. --- modules/packages/swift/metadata.go | 1 + routers/api/packages/swift/swift.go | 1 + 2 files changed, 2 insertions(+) diff --git a/modules/packages/swift/metadata.go b/modules/packages/swift/metadata.go index 85beb57607a26..e5f27f56b4afd 100644 --- a/modules/packages/swift/metadata.go +++ b/modules/packages/swift/metadata.go @@ -82,6 +82,7 @@ type ProgrammingLanguage struct { // https://schema.org/Person type Person struct { Type string `json:"@type,omitempty"` + Name string `json:"name,omitempty"` // inherited from https://schema.org/Thing GivenName string `json:"givenName,omitempty"` MiddleName string `json:"middleName,omitempty"` FamilyName string `json:"familyName,omitempty"` diff --git a/routers/api/packages/swift/swift.go b/routers/api/packages/swift/swift.go index e1c3b368345d1..d84f79a0a8e68 100644 --- a/routers/api/packages/swift/swift.go +++ b/routers/api/packages/swift/swift.go @@ -227,6 +227,7 @@ func PackageVersionMetadata(ctx *context.Context) { }, Author: swift_module.Person{ Type: "Person", + Name: metadata.Author.String(), GivenName: metadata.Author.GivenName, MiddleName: metadata.Author.MiddleName, FamilyName: metadata.Author.FamilyName, From aa8b073a65fc8405ba279b2cef3f51f9de7e10d6 Mon Sep 17 00:00:00 2001 From: Akhan Zhakiyanov Date: Fri, 5 Sep 2025 16:37:19 +0800 Subject: [PATCH 2/5] fix: fmt --- modules/packages/swift/metadata.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/packages/swift/metadata.go b/modules/packages/swift/metadata.go index e5f27f56b4afd..9a57741f27145 100644 --- a/modules/packages/swift/metadata.go +++ b/modules/packages/swift/metadata.go @@ -82,7 +82,7 @@ type ProgrammingLanguage struct { // https://schema.org/Person type Person struct { Type string `json:"@type,omitempty"` - Name string `json:"name,omitempty"` // inherited from https://schema.org/Thing + Name string `json:"name,omitempty"` // inherited from https://schema.org/Thing GivenName string `json:"givenName,omitempty"` MiddleName string `json:"middleName,omitempty"` FamilyName string `json:"familyName,omitempty"` From dca121c0bac37faeaad4fccce131e3bfb6a91de9 Mon Sep 17 00:00:00 2001 From: Akhan Zhakiyanov Date: Sat, 6 Sep 2025 14:12:06 +0800 Subject: [PATCH 3/5] fix: test Name field --- tests/integration/api_packages_swift_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/integration/api_packages_swift_test.go b/tests/integration/api_packages_swift_test.go index 59e1470632266..ddc3cb63f3b56 100644 --- a/tests/integration/api_packages_swift_test.go +++ b/tests/integration/api_packages_swift_test.go @@ -354,6 +354,7 @@ func TestPackageSwift(t *testing.T) { assert.Equal(t, packageVersion, result.Metadata.Version) assert.Equal(t, packageDescription, result.Metadata.Description) assert.Equal(t, "Swift", result.Metadata.ProgrammingLanguage.Name) + assert.Equal(t, packageAuthor, result.Metadata.Author.Name) assert.Equal(t, packageAuthor, result.Metadata.Author.GivenName) req = NewRequest(t, "GET", fmt.Sprintf("%s/%s/%s/%s.json", url, packageScope, packageName, packageVersion)). From ae689172e2979db69d6c5f5f3cf52b17ffee4fb6 Mon Sep 17 00:00:00 2001 From: Akhan Zhakiyanov Date: Sat, 6 Sep 2025 14:12:48 +0800 Subject: [PATCH 4/5] fix: autogenerate author name if it's not explicitly provided --- modules/packages/swift/metadata.go | 8 ++- modules/packages/swift/metadata_test.go | 79 +++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 1 deletion(-) diff --git a/modules/packages/swift/metadata.go b/modules/packages/swift/metadata.go index 9a57741f27145..b8ef82f48fd87 100644 --- a/modules/packages/swift/metadata.go +++ b/modules/packages/swift/metadata.go @@ -185,11 +185,17 @@ func ParsePackage(sr io.ReaderAt, size int64, mr io.Reader) (*Package, error) { p.Metadata.Description = ssc.Description p.Metadata.Keywords = ssc.Keywords p.Metadata.License = ssc.License - p.Metadata.Author = Person{ + author := Person{ + Name: ssc.Author.Name, GivenName: ssc.Author.GivenName, MiddleName: ssc.Author.MiddleName, FamilyName: ssc.Author.FamilyName, } + // If Name is not provided but individual name components are, generate it + if author.Name == "" && (author.GivenName != "" || author.MiddleName != "" || author.FamilyName != "") { + author.Name = author.String() + } + p.Metadata.Author = author p.Metadata.RepositoryURL = ssc.CodeRepository if !validation.IsValidURL(p.Metadata.RepositoryURL) { diff --git a/modules/packages/swift/metadata_test.go b/modules/packages/swift/metadata_test.go index 3913c2355ba21..461773cbfce07 100644 --- a/modules/packages/swift/metadata_test.go +++ b/modules/packages/swift/metadata_test.go @@ -97,10 +97,49 @@ func TestParsePackage(t *testing.T) { assert.Equal(t, packageDescription, p.Metadata.Description) assert.ElementsMatch(t, []string{"swift", "package"}, p.Metadata.Keywords) assert.Equal(t, packageLicense, p.Metadata.License) + assert.Equal(t, packageAuthor, p.Metadata.Author.Name) assert.Equal(t, packageAuthor, p.Metadata.Author.GivenName) assert.Equal(t, packageRepositoryURL, p.Metadata.RepositoryURL) assert.ElementsMatch(t, []string{packageRepositoryURL}, p.RepositoryURLs) }) + + t.Run("WithExplicitNameField", func(t *testing.T) { + data := createArchive(map[string][]byte{ + "Package.swift": []byte("// swift-tools-version:5.7\n//\n// Package.swift"), + }) + + authorName := "John Doe" + p, err := ParsePackage( + data, + data.Size(), + strings.NewReader(`{"name":"`+packageName+`","version":"`+packageVersion+`","description":"`+packageDescription+`","author":{"name":"`+authorName+`","givenName":"John","familyName":"Doe"}}`), + ) + assert.NotNil(t, p) + assert.NoError(t, err) + + assert.Equal(t, authorName, p.Metadata.Author.Name) + assert.Equal(t, "John", p.Metadata.Author.GivenName) + assert.Equal(t, "Doe", p.Metadata.Author.FamilyName) + }) + + t.Run("NameFieldGeneration", func(t *testing.T) { + data := createArchive(map[string][]byte{ + "Package.swift": []byte("// swift-tools-version:5.7\n//\n// Package.swift"), + }) + + // Test with only individual name components - Name should be auto-generated + p, err := ParsePackage( + data, + data.Size(), + strings.NewReader(`{"author":{"givenName":"John","middleName":"Q","familyName":"Doe"}}`), + ) + assert.NotNil(t, p) + assert.NoError(t, err) + assert.Equal(t, "John Q Doe", p.Metadata.Author.Name) + assert.Equal(t, "John", p.Metadata.Author.GivenName) + assert.Equal(t, "Q", p.Metadata.Author.MiddleName) + assert.Equal(t, "Doe", p.Metadata.Author.FamilyName) + }) } func TestTrimmedVersionString(t *testing.T) { @@ -142,3 +181,43 @@ func TestTrimmedVersionString(t *testing.T) { assert.Equal(t, c.Expected, TrimmedVersionString(c.Version)) } } + +func TestPersonNameString(t *testing.T) { + cases := []struct { + Name string + Person Person + Expected string + }{ + { + Name: "GivenNameOnly", + Person: Person{GivenName: "John"}, + Expected: "John", + }, + { + Name: "GivenAndFamily", + Person: Person{GivenName: "John", FamilyName: "Doe"}, + Expected: "John Doe", + }, + { + Name: "FullName", + Person: Person{GivenName: "John", MiddleName: "Q", FamilyName: "Doe"}, + Expected: "John Q Doe", + }, + { + Name: "MiddleAndFamily", + Person: Person{MiddleName: "Q", FamilyName: "Doe"}, + Expected: "Q Doe", + }, + { + Name: "Empty", + Person: Person{}, + Expected: "", + }, + } + + for _, c := range cases { + t.Run(c.Name, func(t *testing.T) { + assert.Equal(t, c.Expected, c.Person.String()) + }) + } +} From b9dcca117ece0a6070c116888159a99f94bf6376 Mon Sep 17 00:00:00 2001 From: Akhan Zhakiyanov Date: Sun, 7 Sep 2025 18:09:12 +0800 Subject: [PATCH 5/5] fix: simplify name check --- modules/packages/swift/metadata.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/packages/swift/metadata.go b/modules/packages/swift/metadata.go index b8ef82f48fd87..78925c6e6d9c4 100644 --- a/modules/packages/swift/metadata.go +++ b/modules/packages/swift/metadata.go @@ -191,8 +191,8 @@ func ParsePackage(sr io.ReaderAt, size int64, mr io.Reader) (*Package, error) { MiddleName: ssc.Author.MiddleName, FamilyName: ssc.Author.FamilyName, } - // If Name is not provided but individual name components are, generate it - if author.Name == "" && (author.GivenName != "" || author.MiddleName != "" || author.FamilyName != "") { + // If Name is not provided, generate it from individual name components + if author.Name == "" { author.Name = author.String() } p.Metadata.Author = author