mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 10:56:10 +01:00 
			
		
		
		
	Improve nuget/rubygems package registries (#34741)
1. Add some missing (optional) fields for nuget v2, and sort the fields to make it easier to maintain 2. Add missing "platform" for rubygems: `VERSION-PLATFORM` and `VERSION_PLATFORM` Co-authored-by: Giteabot <teabot@gitea.io>
This commit is contained in:
		| @@ -44,7 +44,7 @@ func (opts *BlobSearchOptions) toConds() builder.Cond { | |||||||
| 		cond = cond.And(builder.Eq{"package_version.lower_version": strings.ToLower(opts.Tag)}) | 		cond = cond.And(builder.Eq{"package_version.lower_version": strings.ToLower(opts.Tag)}) | ||||||
| 	} | 	} | ||||||
| 	if opts.IsManifest { | 	if opts.IsManifest { | ||||||
| 		cond = cond.And(builder.Eq{"package_file.lower_name": ManifestFilename}) | 		cond = cond.And(builder.Eq{"package_file.lower_name": container_module.ManifestFilename}) | ||||||
| 	} | 	} | ||||||
| 	if opts.OnlyLead { | 	if opts.OnlyLead { | ||||||
| 		cond = cond.And(builder.Eq{"package_file.is_lead": true}) | 		cond = cond.And(builder.Eq{"package_file.is_lead": true}) | ||||||
| @@ -235,7 +235,7 @@ func SearchImageTags(ctx context.Context, opts *ImageTagsSearchOptions) ([]*pack | |||||||
| func SearchExpiredUploadedBlobs(ctx context.Context, olderThan time.Duration) ([]*packages.PackageFile, error) { | func SearchExpiredUploadedBlobs(ctx context.Context, olderThan time.Duration) ([]*packages.PackageFile, error) { | ||||||
| 	var cond builder.Cond = builder.Eq{ | 	var cond builder.Cond = builder.Eq{ | ||||||
| 		"package_version.is_internal":   true, | 		"package_version.is_internal":   true, | ||||||
| 		"package_version.lower_version": UploadVersion, | 		"package_version.lower_version": container_module.UploadVersion, | ||||||
| 		"package.type":                  packages.TypeContainer, | 		"package.type":                  packages.TypeContainer, | ||||||
| 	} | 	} | ||||||
| 	cond = cond.And(builder.Lt{"package_file.created_unix": time.Now().Add(-olderThan).Unix()}) | 	cond = cond.And(builder.Lt{"package_file.created_unix": time.Now().Add(-olderThan).Unix()}) | ||||||
|   | |||||||
| @@ -103,10 +103,10 @@ func (pd *PackageDescriptor) CalculateBlobSize() int64 { | |||||||
|  |  | ||||||
| // GetPackageDescriptor gets the package description for a version | // GetPackageDescriptor gets the package description for a version | ||||||
| func GetPackageDescriptor(ctx context.Context, pv *PackageVersion) (*PackageDescriptor, error) { | func GetPackageDescriptor(ctx context.Context, pv *PackageVersion) (*PackageDescriptor, error) { | ||||||
| 	return getPackageDescriptor(ctx, pv, cache.NewEphemeralCache()) | 	return GetPackageDescriptorWithCache(ctx, pv, cache.NewEphemeralCache()) | ||||||
| } | } | ||||||
|  |  | ||||||
| func getPackageDescriptor(ctx context.Context, pv *PackageVersion, c *cache.EphemeralCache) (*PackageDescriptor, error) { | func GetPackageDescriptorWithCache(ctx context.Context, pv *PackageVersion, c *cache.EphemeralCache) (*PackageDescriptor, error) { | ||||||
| 	p, err := cache.GetWithEphemeralCache(ctx, c, "package", pv.PackageID, GetPackageByID) | 	p, err := cache.GetWithEphemeralCache(ctx, c, "package", pv.PackageID, GetPackageByID) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| @@ -270,7 +270,7 @@ func GetPackageDescriptors(ctx context.Context, pvs []*PackageVersion) ([]*Packa | |||||||
| func getPackageDescriptors(ctx context.Context, pvs []*PackageVersion, c *cache.EphemeralCache) ([]*PackageDescriptor, error) { | func getPackageDescriptors(ctx context.Context, pvs []*PackageVersion, c *cache.EphemeralCache) ([]*PackageDescriptor, error) { | ||||||
| 	pds := make([]*PackageDescriptor, 0, len(pvs)) | 	pds := make([]*PackageDescriptor, 0, len(pvs)) | ||||||
| 	for _, pv := range pvs { | 	for _, pv := range pvs { | ||||||
| 		pd, err := getPackageDescriptor(ctx, pv, c) | 		pd, err := GetPackageDescriptorWithCache(ctx, pv, c) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -57,14 +57,24 @@ type Package struct { | |||||||
|  |  | ||||||
| // Metadata represents the metadata of a Nuget package | // Metadata represents the metadata of a Nuget package | ||||||
| type Metadata struct { | type Metadata struct { | ||||||
| 	Description              string                  `json:"description,omitempty"` | 	Authors                  string `json:"authors,omitempty"` | ||||||
| 	ReleaseNotes             string                  `json:"release_notes,omitempty"` | 	Copyright                string `json:"copyright,omitempty"` | ||||||
| 	Readme                   string                  `json:"readme,omitempty"` | 	Description              string `json:"description,omitempty"` | ||||||
| 	Authors                  string                  `json:"authors,omitempty"` | 	DevelopmentDependency    bool   `json:"development_dependency,omitempty"` | ||||||
| 	ProjectURL               string                  `json:"project_url,omitempty"` | 	IconURL                  string `json:"icon_url,omitempty"` | ||||||
| 	RepositoryURL            string                  `json:"repository_url,omitempty"` | 	Language                 string `json:"language,omitempty"` | ||||||
| 	RequireLicenseAcceptance bool                    `json:"require_license_acceptance"` | 	LicenseURL               string `json:"license_url,omitempty"` | ||||||
| 	Dependencies             map[string][]Dependency `json:"dependencies,omitempty"` | 	MinClientVersion         string `json:"min_client_version,omitempty"` | ||||||
|  | 	Owners                   string `json:"owners,omitempty"` | ||||||
|  | 	ProjectURL               string `json:"project_url,omitempty"` | ||||||
|  | 	Readme                   string `json:"readme,omitempty"` | ||||||
|  | 	ReleaseNotes             string `json:"release_notes,omitempty"` | ||||||
|  | 	RepositoryURL            string `json:"repository_url,omitempty"` | ||||||
|  | 	RequireLicenseAcceptance bool   `json:"require_license_acceptance"` | ||||||
|  | 	Tags                     string `json:"tags,omitempty"` | ||||||
|  | 	Title                    string `json:"title,omitempty"` | ||||||
|  |  | ||||||
|  | 	Dependencies map[string][]Dependency `json:"dependencies,omitempty"` | ||||||
| } | } | ||||||
|  |  | ||||||
| // Dependency represents a dependency of a Nuget package | // Dependency represents a dependency of a Nuget package | ||||||
| @@ -74,24 +84,30 @@ type Dependency struct { | |||||||
| } | } | ||||||
|  |  | ||||||
| // https://learn.microsoft.com/en-us/nuget/reference/nuspec | // https://learn.microsoft.com/en-us/nuget/reference/nuspec | ||||||
|  | // https://github.com/NuGet/NuGet.Client/blob/dev/src/NuGet.Core/NuGet.Packaging/compiler/resources/nuspec.xsd | ||||||
| type nuspecPackage struct { | type nuspecPackage struct { | ||||||
| 	Metadata struct { | 	Metadata struct { | ||||||
| 		ID                       string `xml:"id"` | 		// required fields | ||||||
| 		Version                  string `xml:"version"` | 		Authors     string `xml:"authors"` | ||||||
| 		Authors                  string `xml:"authors"` | 		Description string `xml:"description"` | ||||||
| 		RequireLicenseAcceptance bool   `xml:"requireLicenseAcceptance"` | 		ID          string `xml:"id"` | ||||||
|  | 		Version     string `xml:"version"` | ||||||
|  |  | ||||||
|  | 		// optional fields | ||||||
|  | 		Copyright                string `xml:"copyright"` | ||||||
|  | 		DevelopmentDependency    bool   `xml:"developmentDependency"` | ||||||
|  | 		IconURL                  string `xml:"iconUrl"` | ||||||
|  | 		Language                 string `xml:"language"` | ||||||
|  | 		LicenseURL               string `xml:"licenseUrl"` | ||||||
|  | 		MinClientVersion         string `xml:"minClientVersion,attr"` | ||||||
|  | 		Owners                   string `xml:"owners"` | ||||||
| 		ProjectURL               string `xml:"projectUrl"` | 		ProjectURL               string `xml:"projectUrl"` | ||||||
| 		Description              string `xml:"description"` |  | ||||||
| 		ReleaseNotes             string `xml:"releaseNotes"` |  | ||||||
| 		Readme                   string `xml:"readme"` | 		Readme                   string `xml:"readme"` | ||||||
| 		PackageTypes             struct { | 		ReleaseNotes             string `xml:"releaseNotes"` | ||||||
| 			PackageType []struct { | 		RequireLicenseAcceptance bool   `xml:"requireLicenseAcceptance"` | ||||||
| 				Name string `xml:"name,attr"` | 		Tags                     string `xml:"tags"` | ||||||
| 			} `xml:"packageType"` | 		Title                    string `xml:"title"` | ||||||
| 		} `xml:"packageTypes"` |  | ||||||
| 		Repository struct { |  | ||||||
| 			URL string `xml:"url,attr"` |  | ||||||
| 		} `xml:"repository"` |  | ||||||
| 		Dependencies struct { | 		Dependencies struct { | ||||||
| 			Dependency []struct { | 			Dependency []struct { | ||||||
| 				ID      string `xml:"id,attr"` | 				ID      string `xml:"id,attr"` | ||||||
| @@ -107,6 +123,14 @@ type nuspecPackage struct { | |||||||
| 				} `xml:"dependency"` | 				} `xml:"dependency"` | ||||||
| 			} `xml:"group"` | 			} `xml:"group"` | ||||||
| 		} `xml:"dependencies"` | 		} `xml:"dependencies"` | ||||||
|  | 		PackageTypes struct { | ||||||
|  | 			PackageType []struct { | ||||||
|  | 				Name string `xml:"name,attr"` | ||||||
|  | 			} `xml:"packageType"` | ||||||
|  | 		} `xml:"packageTypes"` | ||||||
|  | 		Repository struct { | ||||||
|  | 			URL string `xml:"url,attr"` | ||||||
|  | 		} `xml:"repository"` | ||||||
| 	} `xml:"metadata"` | 	} `xml:"metadata"` | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -167,13 +191,23 @@ func ParseNuspecMetaData(archive *zip.Reader, r io.Reader) (*Package, error) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	m := &Metadata{ | 	m := &Metadata{ | ||||||
| 		Description:              p.Metadata.Description, |  | ||||||
| 		ReleaseNotes:             p.Metadata.ReleaseNotes, |  | ||||||
| 		Authors:                  p.Metadata.Authors, | 		Authors:                  p.Metadata.Authors, | ||||||
|  | 		Copyright:                p.Metadata.Copyright, | ||||||
|  | 		Description:              p.Metadata.Description, | ||||||
|  | 		DevelopmentDependency:    p.Metadata.DevelopmentDependency, | ||||||
|  | 		IconURL:                  p.Metadata.IconURL, | ||||||
|  | 		Language:                 p.Metadata.Language, | ||||||
|  | 		LicenseURL:               p.Metadata.LicenseURL, | ||||||
|  | 		MinClientVersion:         p.Metadata.MinClientVersion, | ||||||
|  | 		Owners:                   p.Metadata.Owners, | ||||||
| 		ProjectURL:               p.Metadata.ProjectURL, | 		ProjectURL:               p.Metadata.ProjectURL, | ||||||
|  | 		ReleaseNotes:             p.Metadata.ReleaseNotes, | ||||||
| 		RepositoryURL:            p.Metadata.Repository.URL, | 		RepositoryURL:            p.Metadata.Repository.URL, | ||||||
| 		RequireLicenseAcceptance: p.Metadata.RequireLicenseAcceptance, | 		RequireLicenseAcceptance: p.Metadata.RequireLicenseAcceptance, | ||||||
| 		Dependencies:             make(map[string][]Dependency), | 		Tags:                     p.Metadata.Tags, | ||||||
|  | 		Title:                    p.Metadata.Title, | ||||||
|  |  | ||||||
|  | 		Dependencies: make(map[string][]Dependency), | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if p.Metadata.Readme != "" { | 	if p.Metadata.Readme != "" { | ||||||
| @@ -227,13 +261,13 @@ func ParseNuspecMetaData(archive *zip.Reader, r io.Reader) (*Package, error) { | |||||||
| func toNormalizedVersion(v *version.Version) string { | func toNormalizedVersion(v *version.Version) string { | ||||||
| 	var buf bytes.Buffer | 	var buf bytes.Buffer | ||||||
| 	segments := v.Segments64() | 	segments := v.Segments64() | ||||||
| 	fmt.Fprintf(&buf, "%d.%d.%d", segments[0], segments[1], segments[2]) | 	_, _ = fmt.Fprintf(&buf, "%d.%d.%d", segments[0], segments[1], segments[2]) | ||||||
| 	if len(segments) > 3 && segments[3] > 0 { | 	if len(segments) > 3 && segments[3] > 0 { | ||||||
| 		fmt.Fprintf(&buf, ".%d", segments[3]) | 		_, _ = fmt.Fprintf(&buf, ".%d", segments[3]) | ||||||
| 	} | 	} | ||||||
| 	pre := v.Prerelease() | 	pre := v.Prerelease() | ||||||
| 	if pre != "" { | 	if pre != "" { | ||||||
| 		fmt.Fprint(&buf, "-", pre) | 		_, _ = fmt.Fprint(&buf, "-", pre) | ||||||
| 	} | 	} | ||||||
| 	return buf.String() | 	return buf.String() | ||||||
| } | } | ||||||
|   | |||||||
| @@ -12,44 +12,62 @@ import ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| const ( | const ( | ||||||
| 	id                = "System.Gitea" | 	authors                  = "Gitea Authors" | ||||||
| 	semver            = "1.0.1" | 	copyright                = "Package Copyright" | ||||||
| 	authors           = "Gitea Authors" | 	dependencyID             = "System.Text.Json" | ||||||
| 	projectURL        = "https://gitea.io" | 	dependencyVersion        = "5.0.0" | ||||||
| 	description       = "Package Description" | 	developmentDependency    = true | ||||||
| 	releaseNotes      = "Package Release Notes" | 	description              = "Package Description" | ||||||
| 	readme            = "Readme" | 	iconURL                  = "https://gitea.io/favicon.png" | ||||||
| 	repositoryURL     = "https://gitea.io/gitea/gitea" | 	id                       = "System.Gitea" | ||||||
| 	targetFramework   = ".NETStandard2.1" | 	language                 = "Package Language" | ||||||
| 	dependencyID      = "System.Text.Json" | 	licenseURL               = "https://gitea.io/license" | ||||||
| 	dependencyVersion = "5.0.0" | 	minClientVersion         = "1.0.0.0" | ||||||
|  | 	owners                   = "Package Owners" | ||||||
|  | 	projectURL               = "https://gitea.io" | ||||||
|  | 	readme                   = "Readme" | ||||||
|  | 	releaseNotes             = "Package Release Notes" | ||||||
|  | 	repositoryURL            = "https://gitea.io/gitea/gitea" | ||||||
|  | 	requireLicenseAcceptance = true | ||||||
|  | 	tags                     = "tag_1 tag_2 tag_3" | ||||||
|  | 	targetFramework          = ".NETStandard2.1" | ||||||
|  | 	title                    = "Package Title" | ||||||
|  | 	versionStr               = "1.0.1" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const nuspecContent = `<?xml version="1.0" encoding="utf-8"?> | const nuspecContent = `<?xml version="1.0" encoding="utf-8"?> | ||||||
| <package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd"> | <package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd"> | ||||||
|   <metadata> | 	<metadata minClientVersion="` + minClientVersion + `"> | ||||||
|     <id>` + id + `</id> | 		<authors>` + authors + `</authors> | ||||||
|     <version>` + semver + `</version> | 		<copyright>` + copyright + `</copyright> | ||||||
|     <authors>` + authors + `</authors> | 		<description>` + description + `</description> | ||||||
|     <requireLicenseAcceptance>true</requireLicenseAcceptance> | 		<developmentDependency>true</developmentDependency> | ||||||
|     <projectUrl>` + projectURL + `</projectUrl> | 		<iconUrl>` + iconURL + `</iconUrl> | ||||||
|     <description>` + description + `</description> | 		<id>` + id + `</id> | ||||||
|     <releaseNotes>` + releaseNotes + `</releaseNotes> | 		<language>` + language + `</language> | ||||||
|     <repository url="` + repositoryURL + `" /> | 		<licenseUrl>` + licenseURL + `</licenseUrl> | ||||||
|     <readme>README.md</readme> | 		<owners>` + owners + `</owners> | ||||||
|     <dependencies> | 		<projectUrl>` + projectURL + `</projectUrl> | ||||||
|       <group targetFramework="` + targetFramework + `"> | 		<readme>README.md</readme> | ||||||
|         <dependency id="` + dependencyID + `" version="` + dependencyVersion + `" exclude="Build,Analyzers" /> | 		<releaseNotes>` + releaseNotes + `</releaseNotes> | ||||||
|       </group> | 		<repository url="` + repositoryURL + `" /> | ||||||
|     </dependencies> | 		<requireLicenseAcceptance>true</requireLicenseAcceptance> | ||||||
|   </metadata> | 		<tags>` + tags + `</tags> | ||||||
|  | 		<title>` + title + `</title> | ||||||
|  | 		<version>` + versionStr + `</version> | ||||||
|  | 		<dependencies> | ||||||
|  | 			<group targetFramework="` + targetFramework + `"> | ||||||
|  | 				<dependency id="` + dependencyID + `" version="` + dependencyVersion + `" exclude="Build,Analyzers" /> | ||||||
|  | 			</group> | ||||||
|  | 		</dependencies> | ||||||
|  | 	</metadata> | ||||||
| </package>` | </package>` | ||||||
|  |  | ||||||
| const symbolsNuspecContent = `<?xml version="1.0" encoding="utf-8"?> | const symbolsNuspecContent = `<?xml version="1.0" encoding="utf-8"?> | ||||||
| <package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd"> | <package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd"> | ||||||
|   <metadata> |   <metadata> | ||||||
|     <id>` + id + `</id> |     <id>` + id + `</id> | ||||||
|     <version>` + semver + `</version> |     <version>` + versionStr + `</version> | ||||||
|     <description>` + description + `</description> |     <description>` + description + `</description> | ||||||
|     <packageTypes> |     <packageTypes> | ||||||
|       <packageType name="SymbolsPackage" /> |       <packageType name="SymbolsPackage" /> | ||||||
| @@ -140,14 +158,26 @@ func TestParsePackageMetaData(t *testing.T) { | |||||||
| 		assert.NotNil(t, np) | 		assert.NotNil(t, np) | ||||||
| 		assert.Equal(t, DependencyPackage, np.PackageType) | 		assert.Equal(t, DependencyPackage, np.PackageType) | ||||||
|  |  | ||||||
| 		assert.Equal(t, id, np.ID) |  | ||||||
| 		assert.Equal(t, semver, np.Version) |  | ||||||
| 		assert.Equal(t, authors, np.Metadata.Authors) | 		assert.Equal(t, authors, np.Metadata.Authors) | ||||||
| 		assert.Equal(t, projectURL, np.Metadata.ProjectURL) |  | ||||||
| 		assert.Equal(t, description, np.Metadata.Description) | 		assert.Equal(t, description, np.Metadata.Description) | ||||||
| 		assert.Equal(t, releaseNotes, np.Metadata.ReleaseNotes) | 		assert.Equal(t, id, np.ID) | ||||||
|  | 		assert.Equal(t, versionStr, np.Version) | ||||||
|  |  | ||||||
|  | 		assert.Equal(t, copyright, np.Metadata.Copyright) | ||||||
|  | 		assert.Equal(t, developmentDependency, np.Metadata.DevelopmentDependency) | ||||||
|  | 		assert.Equal(t, iconURL, np.Metadata.IconURL) | ||||||
|  | 		assert.Equal(t, language, np.Metadata.Language) | ||||||
|  | 		assert.Equal(t, licenseURL, np.Metadata.LicenseURL) | ||||||
|  | 		assert.Equal(t, minClientVersion, np.Metadata.MinClientVersion) | ||||||
|  | 		assert.Equal(t, owners, np.Metadata.Owners) | ||||||
|  | 		assert.Equal(t, projectURL, np.Metadata.ProjectURL) | ||||||
| 		assert.Equal(t, readme, np.Metadata.Readme) | 		assert.Equal(t, readme, np.Metadata.Readme) | ||||||
|  | 		assert.Equal(t, releaseNotes, np.Metadata.ReleaseNotes) | ||||||
| 		assert.Equal(t, repositoryURL, np.Metadata.RepositoryURL) | 		assert.Equal(t, repositoryURL, np.Metadata.RepositoryURL) | ||||||
|  | 		assert.Equal(t, requireLicenseAcceptance, np.Metadata.RequireLicenseAcceptance) | ||||||
|  | 		assert.Equal(t, tags, np.Metadata.Tags) | ||||||
|  | 		assert.Equal(t, title, np.Metadata.Title) | ||||||
|  |  | ||||||
| 		assert.Len(t, np.Metadata.Dependencies, 1) | 		assert.Len(t, np.Metadata.Dependencies, 1) | ||||||
| 		assert.Contains(t, np.Metadata.Dependencies, targetFramework) | 		assert.Contains(t, np.Metadata.Dependencies, targetFramework) | ||||||
| 		deps := np.Metadata.Dependencies[targetFramework] | 		deps := np.Metadata.Dependencies[targetFramework] | ||||||
| @@ -180,7 +210,7 @@ func TestParsePackageMetaData(t *testing.T) { | |||||||
| 		assert.Equal(t, SymbolsPackage, np.PackageType) | 		assert.Equal(t, SymbolsPackage, np.PackageType) | ||||||
|  |  | ||||||
| 		assert.Equal(t, id, np.ID) | 		assert.Equal(t, id, np.ID) | ||||||
| 		assert.Equal(t, semver, np.Version) | 		assert.Equal(t, versionStr, np.Version) | ||||||
| 		assert.Equal(t, description, np.Metadata.Description) | 		assert.Equal(t, description, np.Metadata.Description) | ||||||
| 		assert.Empty(t, np.Metadata.Dependencies) | 		assert.Empty(t, np.Metadata.Dependencies) | ||||||
| 	}) | 	}) | ||||||
|   | |||||||
| @@ -34,7 +34,7 @@ type PortablePdbList []*PortablePdb | |||||||
|  |  | ||||||
| func (l PortablePdbList) Close() { | func (l PortablePdbList) Close() { | ||||||
| 	for _, pdb := range l { | 	for _, pdb := range l { | ||||||
| 		pdb.Content.Close() | 		_ = pdb.Content.Close() | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -65,7 +65,7 @@ func ExtractPortablePdb(r io.ReaderAt, size int64) (PortablePdbList, error) { | |||||||
|  |  | ||||||
| 				buf, err := packages.CreateHashedBufferFromReader(f) | 				buf, err := packages.CreateHashedBufferFromReader(f) | ||||||
|  |  | ||||||
| 				f.Close() | 				_ = f.Close() | ||||||
|  |  | ||||||
| 				if err != nil { | 				if err != nil { | ||||||
| 					return err | 					return err | ||||||
| @@ -73,12 +73,12 @@ func ExtractPortablePdb(r io.ReaderAt, size int64) (PortablePdbList, error) { | |||||||
|  |  | ||||||
| 				id, err := ParseDebugHeaderID(buf) | 				id, err := ParseDebugHeaderID(buf) | ||||||
| 				if err != nil { | 				if err != nil { | ||||||
| 					buf.Close() | 					_ = buf.Close() | ||||||
| 					return fmt.Errorf("Invalid PDB file: %w", err) | 					return fmt.Errorf("Invalid PDB file: %w", err) | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				if _, err := buf.Seek(0, io.SeekStart); err != nil { | 				if _, err := buf.Seek(0, io.SeekStart); err != nil { | ||||||
| 					buf.Close() | 					_ = buf.Close() | ||||||
| 					return err | 					return err | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -24,14 +24,14 @@ func TestExtractPortablePdb(t *testing.T) { | |||||||
| 		var buf bytes.Buffer | 		var buf bytes.Buffer | ||||||
| 		archive := zip.NewWriter(&buf) | 		archive := zip.NewWriter(&buf) | ||||||
| 		w, _ := archive.Create(name) | 		w, _ := archive.Create(name) | ||||||
| 		w.Write(content) | 		_, _ = w.Write(content) | ||||||
| 		archive.Close() | 		_ = archive.Close() | ||||||
| 		return buf.Bytes() | 		return buf.Bytes() | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	t.Run("MissingPdbFiles", func(t *testing.T) { | 	t.Run("MissingPdbFiles", func(t *testing.T) { | ||||||
| 		var buf bytes.Buffer | 		var buf bytes.Buffer | ||||||
| 		zip.NewWriter(&buf).Close() | 		_ = zip.NewWriter(&buf).Close() | ||||||
|  |  | ||||||
| 		pdbs, err := ExtractPortablePdb(bytes.NewReader(buf.Bytes()), int64(buf.Len())) | 		pdbs, err := ExtractPortablePdb(bytes.NewReader(buf.Bytes()), int64(buf.Len())) | ||||||
| 		assert.ErrorIs(t, err, ErrMissingPdbFiles) | 		assert.ErrorIs(t, err, ErrMissingPdbFiles) | ||||||
|   | |||||||
| @@ -130,8 +130,8 @@ func getOrCreateUploadVersion(ctx context.Context, pi *packages_service.PackageI | |||||||
| 		pv := &packages_model.PackageVersion{ | 		pv := &packages_model.PackageVersion{ | ||||||
| 			PackageID:    p.ID, | 			PackageID:    p.ID, | ||||||
| 			CreatorID:    pi.Owner.ID, | 			CreatorID:    pi.Owner.ID, | ||||||
| 			Version:      container_model.UploadVersion, | 			Version:      container_module.UploadVersion, | ||||||
| 			LowerVersion: container_model.UploadVersion, | 			LowerVersion: container_module.UploadVersion, | ||||||
| 			IsInternal:   true, | 			IsInternal:   true, | ||||||
| 			MetadataJSON: "null", | 			MetadataJSON: "null", | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -151,7 +151,7 @@ func processOciImageManifest(ctx context.Context, mci *manifestCreationInfo, buf | |||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		uploadVersion, err := packages_model.GetInternalVersionByNameAndVersion(ctx, mci.Owner.ID, packages_model.TypeContainer, mci.Image, container_model.UploadVersion) | 		uploadVersion, err := packages_model.GetInternalVersionByNameAndVersion(ctx, mci.Owner.ID, packages_model.TypeContainer, mci.Image, container_module.UploadVersion) | ||||||
| 		if err != nil && err != packages_model.ErrPackageNotExist { | 		if err != nil && err != packages_model.ErrPackageNotExist { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| @@ -492,7 +492,7 @@ func createManifestBlob(ctx context.Context, mci *manifestCreationInfo, pv *pack | |||||||
| 	pf, err := createFileFromBlobReference(ctx, pv, nil, &blobReference{ | 	pf, err := createFileFromBlobReference(ctx, pv, nil, &blobReference{ | ||||||
| 		Digest:       digest.Digest(manifestDigest), | 		Digest:       digest.Digest(manifestDigest), | ||||||
| 		MediaType:    mci.MediaType, | 		MediaType:    mci.MediaType, | ||||||
| 		Name:         container_model.ManifestFilename, | 		Name:         container_module.ManifestFilename, | ||||||
| 		File:         &packages_model.PackageFileDescriptor{Blob: pb}, | 		File:         &packages_model.PackageFileDescriptor{Blob: pb}, | ||||||
| 		ExpectedSize: pb.Size, | 		ExpectedSize: pb.Size, | ||||||
| 		IsLead:       true, | 		IsLead:       true, | ||||||
| @@ -505,7 +505,7 @@ func createManifestBlob(ctx context.Context, mci *manifestCreationInfo, pv *pack | |||||||
| 		OwnerID:     mci.Owner.ID, | 		OwnerID:     mci.Owner.ID, | ||||||
| 		PackageType: packages_model.TypeContainer, | 		PackageType: packages_model.TypeContainer, | ||||||
| 		VersionID:   pv.ID, | 		VersionID:   pv.ID, | ||||||
| 		Query:       container_model.ManifestFilename, | 		Query:       container_module.ManifestFilename, | ||||||
| 	}) | 	}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, false, "", err | 		return nil, false, "", err | ||||||
|   | |||||||
| @@ -246,21 +246,30 @@ type TypedValue[T any] struct { | |||||||
| } | } | ||||||
|  |  | ||||||
| type FeedEntryProperties struct { | type FeedEntryProperties struct { | ||||||
| 	Version                  string                `xml:"d:Version"` |  | ||||||
| 	NormalizedVersion        string                `xml:"d:NormalizedVersion"` |  | ||||||
| 	Authors                  string                `xml:"d:Authors"` | 	Authors                  string                `xml:"d:Authors"` | ||||||
|  | 	Copyright                string                `xml:"d:Copyright,omitempty"` | ||||||
|  | 	Created                  TypedValue[time.Time] `xml:"d:Created"` | ||||||
| 	Dependencies             string                `xml:"d:Dependencies"` | 	Dependencies             string                `xml:"d:Dependencies"` | ||||||
| 	Description              string                `xml:"d:Description"` | 	Description              string                `xml:"d:Description"` | ||||||
| 	VersionDownloadCount     TypedValue[int64]     `xml:"d:VersionDownloadCount"` | 	DevelopmentDependency    TypedValue[bool]      `xml:"d:DevelopmentDependency"` | ||||||
| 	DownloadCount            TypedValue[int64]     `xml:"d:DownloadCount"` | 	DownloadCount            TypedValue[int64]     `xml:"d:DownloadCount"` | ||||||
| 	PackageSize              TypedValue[int64]     `xml:"d:PackageSize"` | 	ID                       string                `xml:"d:Id"` | ||||||
| 	Created                  TypedValue[time.Time] `xml:"d:Created"` | 	IconURL                  string                `xml:"d:IconUrl,omitempty"` | ||||||
|  | 	Language                 string                `xml:"d:Language,omitempty"` | ||||||
| 	LastUpdated              TypedValue[time.Time] `xml:"d:LastUpdated"` | 	LastUpdated              TypedValue[time.Time] `xml:"d:LastUpdated"` | ||||||
| 	Published                TypedValue[time.Time] `xml:"d:Published"` | 	LicenseURL               string                `xml:"d:LicenseUrl,omitempty"` | ||||||
|  | 	MinClientVersion         string                `xml:"d:MinClientVersion,omitempty"` | ||||||
|  | 	NormalizedVersion        string                `xml:"d:NormalizedVersion"` | ||||||
|  | 	Owners                   string                `xml:"d:Owners,omitempty"` | ||||||
|  | 	PackageSize              TypedValue[int64]     `xml:"d:PackageSize"` | ||||||
| 	ProjectURL               string                `xml:"d:ProjectUrl,omitempty"` | 	ProjectURL               string                `xml:"d:ProjectUrl,omitempty"` | ||||||
|  | 	Published                TypedValue[time.Time] `xml:"d:Published"` | ||||||
| 	ReleaseNotes             string                `xml:"d:ReleaseNotes,omitempty"` | 	ReleaseNotes             string                `xml:"d:ReleaseNotes,omitempty"` | ||||||
| 	RequireLicenseAcceptance TypedValue[bool]      `xml:"d:RequireLicenseAcceptance"` | 	RequireLicenseAcceptance TypedValue[bool]      `xml:"d:RequireLicenseAcceptance"` | ||||||
| 	Title                    string                `xml:"d:Title"` | 	Tags                     string                `xml:"d:Tags,omitempty"` | ||||||
|  | 	Title                    string                `xml:"d:Title,omitempty"` | ||||||
|  | 	Version                  string                `xml:"d:Version"` | ||||||
|  | 	VersionDownloadCount     TypedValue[int64]     `xml:"d:VersionDownloadCount"` | ||||||
| } | } | ||||||
|  |  | ||||||
| type FeedEntry struct { | type FeedEntry struct { | ||||||
| @@ -353,21 +362,30 @@ func createEntry(l *linkBuilder, pd *packages_model.PackageDescriptor, withNames | |||||||
| 		Author:  metadata.Authors, | 		Author:  metadata.Authors, | ||||||
| 		Content: content, | 		Content: content, | ||||||
| 		Properties: &FeedEntryProperties{ | 		Properties: &FeedEntryProperties{ | ||||||
| 			Version:                  pd.Version.Version, |  | ||||||
| 			NormalizedVersion:        pd.Version.Version, |  | ||||||
| 			Authors:                  metadata.Authors, | 			Authors:                  metadata.Authors, | ||||||
|  | 			Copyright:                metadata.Copyright, | ||||||
|  | 			Created:                  createdValue, | ||||||
| 			Dependencies:             buildDependencyString(metadata), | 			Dependencies:             buildDependencyString(metadata), | ||||||
| 			Description:              metadata.Description, | 			Description:              metadata.Description, | ||||||
| 			VersionDownloadCount:     TypedValue[int64]{Type: "Edm.Int64", Value: pd.Version.DownloadCount}, | 			DevelopmentDependency:    TypedValue[bool]{Type: "Edm.Boolean", Value: metadata.DevelopmentDependency}, | ||||||
| 			DownloadCount:            TypedValue[int64]{Type: "Edm.Int64", Value: pd.Version.DownloadCount}, | 			DownloadCount:            TypedValue[int64]{Type: "Edm.Int64", Value: pd.Version.DownloadCount}, | ||||||
| 			PackageSize:              TypedValue[int64]{Type: "Edm.Int64", Value: pd.CalculateBlobSize()}, | 			ID:                       pd.Package.Name, | ||||||
| 			Created:                  createdValue, | 			IconURL:                  metadata.IconURL, | ||||||
|  | 			Language:                 metadata.Language, | ||||||
| 			LastUpdated:              createdValue, | 			LastUpdated:              createdValue, | ||||||
| 			Published:                createdValue, | 			LicenseURL:               metadata.LicenseURL, | ||||||
|  | 			MinClientVersion:         metadata.MinClientVersion, | ||||||
|  | 			NormalizedVersion:        pd.Version.Version, | ||||||
|  | 			Owners:                   metadata.Owners, | ||||||
|  | 			PackageSize:              TypedValue[int64]{Type: "Edm.Int64", Value: pd.CalculateBlobSize()}, | ||||||
| 			ProjectURL:               metadata.ProjectURL, | 			ProjectURL:               metadata.ProjectURL, | ||||||
|  | 			Published:                createdValue, | ||||||
| 			ReleaseNotes:             metadata.ReleaseNotes, | 			ReleaseNotes:             metadata.ReleaseNotes, | ||||||
| 			RequireLicenseAcceptance: TypedValue[bool]{Type: "Edm.Boolean", Value: metadata.RequireLicenseAcceptance}, | 			RequireLicenseAcceptance: TypedValue[bool]{Type: "Edm.Boolean", Value: metadata.RequireLicenseAcceptance}, | ||||||
| 			Title:                    pd.Package.Name, | 			Tags:                     metadata.Tags, | ||||||
|  | 			Title:                    metadata.Title, | ||||||
|  | 			Version:                  pd.Version.Version, | ||||||
|  | 			VersionDownloadCount:     TypedValue[int64]{Type: "Edm.Int64", Value: pd.Version.DownloadCount}, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -14,6 +14,7 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
|  |  | ||||||
| 	packages_model "code.gitea.io/gitea/models/packages" | 	packages_model "code.gitea.io/gitea/models/packages" | ||||||
|  | 	"code.gitea.io/gitea/modules/cache" | ||||||
| 	"code.gitea.io/gitea/modules/optional" | 	"code.gitea.io/gitea/modules/optional" | ||||||
| 	packages_module "code.gitea.io/gitea/modules/packages" | 	packages_module "code.gitea.io/gitea/modules/packages" | ||||||
| 	rubygems_module "code.gitea.io/gitea/modules/packages/rubygems" | 	rubygems_module "code.gitea.io/gitea/modules/packages/rubygems" | ||||||
| @@ -309,7 +310,7 @@ func GetPackageInfo(ctx *context.Context) { | |||||||
| 		apiError(ctx, http.StatusNotFound, nil) | 		apiError(ctx, http.StatusNotFound, nil) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	infoContent, err := makePackageInfo(ctx, versions) | 	infoContent, err := makePackageInfo(ctx, versions, cache.NewEphemeralCache()) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		apiError(ctx, http.StatusInternalServerError, err) | 		apiError(ctx, http.StatusInternalServerError, err) | ||||||
| 		return | 		return | ||||||
| @@ -317,7 +318,7 @@ func GetPackageInfo(ctx *context.Context) { | |||||||
| 	ctx.PlainText(http.StatusOK, infoContent) | 	ctx.PlainText(http.StatusOK, infoContent) | ||||||
| } | } | ||||||
|  |  | ||||||
| // GetAllPackagesVersions returns a custom text based format containing information about all versions of all rubygems. | // GetAllPackagesVersions returns a custom text-based format containing information about all versions of all rubygems. | ||||||
| // ref: https://guides.rubygems.org/rubygems-org-compact-index-api/ | // ref: https://guides.rubygems.org/rubygems-org-compact-index-api/ | ||||||
| func GetAllPackagesVersions(ctx *context.Context) { | func GetAllPackagesVersions(ctx *context.Context) { | ||||||
| 	packages, err := packages_model.GetPackagesByType(ctx, ctx.Package.Owner.ID, packages_model.TypeRubyGems) | 	packages, err := packages_model.GetPackagesByType(ctx, ctx.Package.Owner.ID, packages_model.TypeRubyGems) | ||||||
| @@ -326,6 +327,7 @@ func GetAllPackagesVersions(ctx *context.Context) { | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	ephemeralCache := cache.NewEphemeralCache() | ||||||
| 	out := &strings.Builder{} | 	out := &strings.Builder{} | ||||||
| 	out.WriteString("---\n") | 	out.WriteString("---\n") | ||||||
| 	for _, pkg := range packages { | 	for _, pkg := range packages { | ||||||
| @@ -338,7 +340,7 @@ func GetAllPackagesVersions(ctx *context.Context) { | |||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		info, err := makePackageInfo(ctx, versions) | 		info, err := makePackageInfo(ctx, versions, ephemeralCache) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			apiError(ctx, http.StatusInternalServerError, err) | 			apiError(ctx, http.StatusInternalServerError, err) | ||||||
| 			return | 			return | ||||||
| @@ -348,7 +350,14 @@ func GetAllPackagesVersions(ctx *context.Context) { | |||||||
| 		_, _ = fmt.Fprintf(out, "%s ", pkg.Name) | 		_, _ = fmt.Fprintf(out, "%s ", pkg.Name) | ||||||
| 		for i, v := range versions { | 		for i, v := range versions { | ||||||
| 			sep := util.Iif(i == len(versions)-1, "", ",") | 			sep := util.Iif(i == len(versions)-1, "", ",") | ||||||
| 			_, _ = fmt.Fprintf(out, "%s%s", v.Version, sep) | 			pd, err := packages_model.GetPackageDescriptorWithCache(ctx, v, ephemeralCache) | ||||||
|  | 			if errors.Is(err, util.ErrNotExist) { | ||||||
|  | 				continue | ||||||
|  | 			} else if err != nil { | ||||||
|  | 				apiError(ctx, http.StatusInternalServerError, err) | ||||||
|  | 				return | ||||||
|  | 			} | ||||||
|  | 			writePackageVersionForList(pd.Metadata, v.Version, sep, out) | ||||||
| 		} | 		} | ||||||
| 		_, _ = fmt.Fprintf(out, " %x\n", md5.Sum([]byte(info))) | 		_, _ = fmt.Fprintf(out, " %x\n", md5.Sum([]byte(info))) | ||||||
| 	} | 	} | ||||||
| @@ -356,6 +365,16 @@ func GetAllPackagesVersions(ctx *context.Context) { | |||||||
| 	ctx.PlainText(http.StatusOK, out.String()) | 	ctx.PlainText(http.StatusOK, out.String()) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func writePackageVersionForList(metadata any, version, sep string, out *strings.Builder) { | ||||||
|  | 	if metadata, _ := metadata.(*rubygems_module.Metadata); metadata != nil && metadata.Platform != "" && metadata.Platform != "ruby" { | ||||||
|  | 		// VERSION_PLATFORM (see comment above in GetAllPackagesVersions) | ||||||
|  | 		_, _ = fmt.Fprintf(out, "%s_%s%s", version, metadata.Platform, sep) | ||||||
|  | 	} else { | ||||||
|  | 		// VERSION only | ||||||
|  | 		_, _ = fmt.Fprintf(out, "%s%s", version, sep) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| func writePackageVersionRequirements(prefix string, reqs []rubygems_module.VersionRequirement, out *strings.Builder) { | func writePackageVersionRequirements(prefix string, reqs []rubygems_module.VersionRequirement, out *strings.Builder) { | ||||||
| 	out.WriteString(prefix) | 	out.WriteString(prefix) | ||||||
| 	if len(reqs) == 0 { | 	if len(reqs) == 0 { | ||||||
| @@ -367,11 +386,21 @@ func writePackageVersionRequirements(prefix string, reqs []rubygems_module.Versi | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func makePackageVersionDependency(ctx *context.Context, version *packages_model.PackageVersion) (string, error) { | func writePackageVersionForDependency(version, platform string, out *strings.Builder) { | ||||||
|  | 	if platform != "" && platform != "ruby" { | ||||||
|  | 		// VERSION-PLATFORM (see comment below in makePackageVersionDependency) | ||||||
|  | 		_, _ = fmt.Fprintf(out, "%s-%s ", version, platform) | ||||||
|  | 	} else { | ||||||
|  | 		// VERSION only | ||||||
|  | 		_, _ = fmt.Fprintf(out, "%s ", version) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func makePackageVersionDependency(ctx *context.Context, version *packages_model.PackageVersion, c *cache.EphemeralCache) (string, error) { | ||||||
| 	// format: VERSION[-PLATFORM] [DEPENDENCY[,DEPENDENCY,...]]|REQUIREMENT[,REQUIREMENT,...] | 	// format: VERSION[-PLATFORM] [DEPENDENCY[,DEPENDENCY,...]]|REQUIREMENT[,REQUIREMENT,...] | ||||||
| 	// DEPENDENCY: GEM:CONSTRAINT[&CONSTRAINT] | 	// DEPENDENCY: GEM:CONSTRAINT[&CONSTRAINT] | ||||||
| 	// REQUIREMENT: KEY:VALUE (always contains "checksum") | 	// REQUIREMENT: KEY:VALUE (always contains "checksum") | ||||||
| 	pd, err := packages_model.GetPackageDescriptor(ctx, version) | 	pd, err := packages_model.GetPackageDescriptorWithCache(ctx, version, c) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return "", err | 		return "", err | ||||||
| 	} | 	} | ||||||
| @@ -388,8 +417,7 @@ func makePackageVersionDependency(ctx *context.Context, version *packages_model. | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	buf := &strings.Builder{} | 	buf := &strings.Builder{} | ||||||
| 	buf.WriteString(version.Version) | 	writePackageVersionForDependency(version.Version, metadata.Platform, buf) | ||||||
| 	buf.WriteByte(' ') |  | ||||||
| 	for i, dep := range metadata.RuntimeDependencies { | 	for i, dep := range metadata.RuntimeDependencies { | ||||||
| 		sep := util.Iif(i == 0, "", ",") | 		sep := util.Iif(i == 0, "", ",") | ||||||
| 		writePackageVersionRequirements(fmt.Sprintf("%s%s:", sep, dep.Name), dep.Version, buf) | 		writePackageVersionRequirements(fmt.Sprintf("%s%s:", sep, dep.Name), dep.Version, buf) | ||||||
| @@ -404,10 +432,10 @@ func makePackageVersionDependency(ctx *context.Context, version *packages_model. | |||||||
| 	return buf.String(), nil | 	return buf.String(), nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func makePackageInfo(ctx *context.Context, versions []*packages_model.PackageVersion) (string, error) { | func makePackageInfo(ctx *context.Context, versions []*packages_model.PackageVersion, c *cache.EphemeralCache) (string, error) { | ||||||
| 	ret := "---\n" | 	ret := "---\n" | ||||||
| 	for _, v := range versions { | 	for _, v := range versions { | ||||||
| 		dep, err := makePackageVersionDependency(ctx, v) | 		dep, err := makePackageVersionDependency(ctx, v, c) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return "", err | 			return "", err | ||||||
| 		} | 		} | ||||||
|   | |||||||
							
								
								
									
										41
									
								
								routers/api/packages/rubygems/rubygems_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								routers/api/packages/rubygems/rubygems_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | |||||||
|  | // Copyright 2025 The Gitea Authors. All rights reserved. | ||||||
|  | // SPDX-License-Identifier: MIT | ||||||
|  |  | ||||||
|  | package rubygems | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"strings" | ||||||
|  | 	"testing" | ||||||
|  |  | ||||||
|  | 	rubygems_module "code.gitea.io/gitea/modules/packages/rubygems" | ||||||
|  |  | ||||||
|  | 	"github.com/stretchr/testify/assert" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func TestWritePackageVersion(t *testing.T) { | ||||||
|  | 	buf := &strings.Builder{} | ||||||
|  |  | ||||||
|  | 	writePackageVersionForList(nil, "1.0", " ", buf) | ||||||
|  | 	assert.Equal(t, "1.0 ", buf.String()) | ||||||
|  | 	buf.Reset() | ||||||
|  |  | ||||||
|  | 	writePackageVersionForList(&rubygems_module.Metadata{Platform: "ruby"}, "1.0", " ", buf) | ||||||
|  | 	assert.Equal(t, "1.0 ", buf.String()) | ||||||
|  | 	buf.Reset() | ||||||
|  |  | ||||||
|  | 	writePackageVersionForList(&rubygems_module.Metadata{Platform: "linux"}, "1.0", " ", buf) | ||||||
|  | 	assert.Equal(t, "1.0_linux ", buf.String()) | ||||||
|  | 	buf.Reset() | ||||||
|  |  | ||||||
|  | 	writePackageVersionForDependency("1.0", "", buf) | ||||||
|  | 	assert.Equal(t, "1.0 ", buf.String()) | ||||||
|  | 	buf.Reset() | ||||||
|  |  | ||||||
|  | 	writePackageVersionForDependency("1.0", "ruby", buf) | ||||||
|  | 	assert.Equal(t, "1.0 ", buf.String()) | ||||||
|  | 	buf.Reset() | ||||||
|  |  | ||||||
|  | 	writePackageVersionForDependency("1.0", "os", buf) | ||||||
|  | 	assert.Equal(t, "1.0-os ", buf.String()) | ||||||
|  | 	buf.Reset() | ||||||
|  | } | ||||||
| @@ -57,7 +57,7 @@ func cleanupExpiredUploadedBlobs(ctx context.Context, olderThan time.Duration) e | |||||||
| 		Type: packages_model.TypeContainer, | 		Type: packages_model.TypeContainer, | ||||||
| 		Version: packages_model.SearchValue{ | 		Version: packages_model.SearchValue{ | ||||||
| 			ExactMatch: true, | 			ExactMatch: true, | ||||||
| 			Value:      container_model.UploadVersion, | 			Value:      container_module.UploadVersion, | ||||||
| 		}, | 		}, | ||||||
| 		IsInternal: optional.Some(true), | 		IsInternal: optional.Some(true), | ||||||
| 		HasFiles:   optional.Some(false), | 		HasFiles:   optional.Some(false), | ||||||
|   | |||||||
| @@ -18,7 +18,6 @@ import ( | |||||||
| 	auth_model "code.gitea.io/gitea/models/auth" | 	auth_model "code.gitea.io/gitea/models/auth" | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	packages_model "code.gitea.io/gitea/models/packages" | 	packages_model "code.gitea.io/gitea/models/packages" | ||||||
| 	container_model "code.gitea.io/gitea/models/packages/container" |  | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| 	container_module "code.gitea.io/gitea/modules/packages/container" | 	container_module "code.gitea.io/gitea/modules/packages/container" | ||||||
| @@ -71,8 +70,8 @@ func TestPackageContainer(t *testing.T) { | |||||||
| 	configContent := `{"architecture":"amd64","config":{"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/true"],"ArgsEscaped":true,"Image":"sha256:9bd8b88dc68b80cffe126cc820e4b52c6e558eb3b37680bfee8e5f3ed7b8c257"},"container":"b89fe92a887d55c0961f02bdfbfd8ac3ddf66167db374770d2d9e9fab3311510","container_config":{"Hostname":"b89fe92a887d","Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh","-c","#(nop) ","CMD [\"/true\"]"],"ArgsEscaped":true,"Image":"sha256:9bd8b88dc68b80cffe126cc820e4b52c6e558eb3b37680bfee8e5f3ed7b8c257"},"created":"2022-01-01T00:00:00.000000000Z","docker_version":"20.10.12","history":[{"created":"2022-01-01T00:00:00.000000000Z","created_by":"/bin/sh -c #(nop) COPY file:0e7589b0c800daaf6fa460d2677101e4676dd9491980210cb345480e513f3602 in /true "},{"created":"2022-01-01T00:00:00.000000001Z","created_by":"/bin/sh -c #(nop)  CMD [\"/true\"]","empty_layer":true}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:0ff3b91bdf21ecdf2f2f3d4372c2098a14dbe06cd678e8f0a85fd4902d00e2e2"]}}` | 	configContent := `{"architecture":"amd64","config":{"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/true"],"ArgsEscaped":true,"Image":"sha256:9bd8b88dc68b80cffe126cc820e4b52c6e558eb3b37680bfee8e5f3ed7b8c257"},"container":"b89fe92a887d55c0961f02bdfbfd8ac3ddf66167db374770d2d9e9fab3311510","container_config":{"Hostname":"b89fe92a887d","Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh","-c","#(nop) ","CMD [\"/true\"]"],"ArgsEscaped":true,"Image":"sha256:9bd8b88dc68b80cffe126cc820e4b52c6e558eb3b37680bfee8e5f3ed7b8c257"},"created":"2022-01-01T00:00:00.000000000Z","docker_version":"20.10.12","history":[{"created":"2022-01-01T00:00:00.000000000Z","created_by":"/bin/sh -c #(nop) COPY file:0e7589b0c800daaf6fa460d2677101e4676dd9491980210cb345480e513f3602 in /true "},{"created":"2022-01-01T00:00:00.000000001Z","created_by":"/bin/sh -c #(nop)  CMD [\"/true\"]","empty_layer":true}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:0ff3b91bdf21ecdf2f2f3d4372c2098a14dbe06cd678e8f0a85fd4902d00e2e2"]}}` | ||||||
|  |  | ||||||
| 	manifestDigest := "sha256:4f10484d1c1bb13e3956b4de1cd42db8e0f14a75be1617b60f2de3cd59c803c6" | 	manifestDigest := "sha256:4f10484d1c1bb13e3956b4de1cd42db8e0f14a75be1617b60f2de3cd59c803c6" | ||||||
| 	manifestContent := `{"schemaVersion":2,"mediaType":"` + container_model.ContentTypeDockerDistributionManifestV2 + `","config":{"mediaType":"application/vnd.docker.container.image.v1+json","digest":"sha256:4607e093bec406eaadb6f3a340f63400c9d3a7038680744c406903766b938f0d","size":1069},"layers":[{"mediaType":"application/vnd.docker.image.rootfs.diff.tar.gzip","digest":"sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4","size":32}]}` | 	manifestContent := `{"schemaVersion":2,"mediaType":"` + container_module.ContentTypeDockerDistributionManifestV2 + `","config":{"mediaType":"application/vnd.docker.container.image.v1+json","digest":"sha256:4607e093bec406eaadb6f3a340f63400c9d3a7038680744c406903766b938f0d","size":1069},"layers":[{"mediaType":"application/vnd.docker.image.rootfs.diff.tar.gzip","digest":"sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4","size":32}]}` | ||||||
| 	manifestContentType := container_model.ContentTypeDockerDistributionManifestV2 | 	manifestContentType := container_module.ContentTypeDockerDistributionManifestV2 | ||||||
|  |  | ||||||
| 	untaggedManifestDigest := "sha256:4305f5f5572b9a426b88909b036e52ee3cf3d7b9c1b01fac840e90747f56623d" | 	untaggedManifestDigest := "sha256:4305f5f5572b9a426b88909b036e52ee3cf3d7b9c1b01fac840e90747f56623d" | ||||||
| 	untaggedManifestContent := `{"schemaVersion":2,"mediaType":"` + oci.MediaTypeImageManifest + `","config":{"mediaType":"application/vnd.docker.container.image.v1+json","digest":"sha256:4607e093bec406eaadb6f3a340f63400c9d3a7038680744c406903766b938f0d","size":1069},"layers":[{"mediaType":"application/vnd.docker.image.rootfs.diff.tar.gzip","digest":"sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4","size":32}]}` | 	untaggedManifestContent := `{"schemaVersion":2,"mediaType":"` + oci.MediaTypeImageManifest + `","config":{"mediaType":"application/vnd.docker.container.image.v1+json","digest":"sha256:4607e093bec406eaadb6f3a340f63400c9d3a7038680744c406903766b938f0d","size":1069},"layers":[{"mediaType":"application/vnd.docker.image.rootfs.diff.tar.gzip","digest":"sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4","size":32}]}` | ||||||
| @@ -252,7 +251,7 @@ func TestPackageContainer(t *testing.T) { | |||||||
| 				assert.Equal(t, fmt.Sprintf("/v2/%s/%s/blobs/%s", user.Name, image, blobDigest), resp.Header().Get("Location")) | 				assert.Equal(t, fmt.Sprintf("/v2/%s/%s/blobs/%s", user.Name, image, blobDigest), resp.Header().Get("Location")) | ||||||
| 				assert.Equal(t, blobDigest, resp.Header().Get("Docker-Content-Digest")) | 				assert.Equal(t, blobDigest, resp.Header().Get("Docker-Content-Digest")) | ||||||
|  |  | ||||||
| 				pv, err := packages_model.GetInternalVersionByNameAndVersion(db.DefaultContext, user.ID, packages_model.TypeContainer, image, container_model.UploadVersion) | 				pv, err := packages_model.GetInternalVersionByNameAndVersion(db.DefaultContext, user.ID, packages_model.TypeContainer, image, container_module.UploadVersion) | ||||||
| 				assert.NoError(t, err) | 				assert.NoError(t, err) | ||||||
|  |  | ||||||
| 				pfs, err := packages_model.GetFilesByVersionID(db.DefaultContext, pv.ID) | 				pfs, err := packages_model.GetFilesByVersionID(db.DefaultContext, pv.ID) | ||||||
| @@ -432,7 +431,7 @@ func TestPackageContainer(t *testing.T) { | |||||||
| 						assert.Len(t, pd.Files, 3) | 						assert.Len(t, pd.Files, 3) | ||||||
| 						for _, pfd := range pd.Files { | 						for _, pfd := range pd.Files { | ||||||
| 							switch pfd.File.Name { | 							switch pfd.File.Name { | ||||||
| 							case container_model.ManifestFilename: | 							case container_module.ManifestFilename: | ||||||
| 								assert.True(t, pfd.File.IsLead) | 								assert.True(t, pfd.File.IsLead) | ||||||
| 								assert.Equal(t, "application/vnd.docker.distribution.manifest.v2+json", pfd.Properties.GetByName(container_module.PropertyMediaType)) | 								assert.Equal(t, "application/vnd.docker.distribution.manifest.v2+json", pfd.Properties.GetByName(container_module.PropertyMediaType)) | ||||||
| 								assert.Equal(t, manifestDigest, pfd.Properties.GetByName(container_module.PropertyDigest)) | 								assert.Equal(t, manifestDigest, pfd.Properties.GetByName(container_module.PropertyDigest)) | ||||||
| @@ -534,7 +533,7 @@ func TestPackageContainer(t *testing.T) { | |||||||
|  |  | ||||||
| 				assert.Len(t, pd.Files, 3) | 				assert.Len(t, pd.Files, 3) | ||||||
| 				for _, pfd := range pd.Files { | 				for _, pfd := range pd.Files { | ||||||
| 					if pfd.File.Name == container_model.ManifestFilename { | 					if pfd.File.Name == container_module.ManifestFilename { | ||||||
| 						assert.True(t, pfd.File.IsLead) | 						assert.True(t, pfd.File.IsLead) | ||||||
| 						assert.Equal(t, oci.MediaTypeImageManifest, pfd.Properties.GetByName(container_module.PropertyMediaType)) | 						assert.Equal(t, oci.MediaTypeImageManifest, pfd.Properties.GetByName(container_module.PropertyMediaType)) | ||||||
| 						assert.Equal(t, untaggedManifestDigest, pfd.Properties.GetByName(container_module.PropertyDigest)) | 						assert.Equal(t, untaggedManifestDigest, pfd.Properties.GetByName(container_module.PropertyDigest)) | ||||||
|   | |||||||
| @@ -46,21 +46,30 @@ func TestPackageNuGet(t *testing.T) { | |||||||
| 	defer tests.PrepareTestEnv(t)() | 	defer tests.PrepareTestEnv(t)() | ||||||
|  |  | ||||||
| 	type FeedEntryProperties struct { | 	type FeedEntryProperties struct { | ||||||
| 		Version                  string                      `xml:"Version"` |  | ||||||
| 		NormalizedVersion        string                      `xml:"NormalizedVersion"` |  | ||||||
| 		Authors                  string                      `xml:"Authors"` | 		Authors                  string                      `xml:"Authors"` | ||||||
|  | 		Copyright                string                      `xml:"Copyright,omitempty"` | ||||||
|  | 		Created                  nuget.TypedValue[time.Time] `xml:"Created"` | ||||||
| 		Dependencies             string                      `xml:"Dependencies"` | 		Dependencies             string                      `xml:"Dependencies"` | ||||||
| 		Description              string                      `xml:"Description"` | 		Description              string                      `xml:"Description"` | ||||||
| 		VersionDownloadCount     nuget.TypedValue[int64]     `xml:"VersionDownloadCount"` | 		DevelopmentDependency    nuget.TypedValue[bool]      `xml:"DevelopmentDependency"` | ||||||
| 		DownloadCount            nuget.TypedValue[int64]     `xml:"DownloadCount"` | 		DownloadCount            nuget.TypedValue[int64]     `xml:"DownloadCount"` | ||||||
| 		PackageSize              nuget.TypedValue[int64]     `xml:"PackageSize"` | 		ID                       string                      `xml:"Id"` | ||||||
| 		Created                  nuget.TypedValue[time.Time] `xml:"Created"` | 		IconURL                  string                      `xml:"IconUrl,omitempty"` | ||||||
|  | 		Language                 string                      `xml:"Language,omitempty"` | ||||||
| 		LastUpdated              nuget.TypedValue[time.Time] `xml:"LastUpdated"` | 		LastUpdated              nuget.TypedValue[time.Time] `xml:"LastUpdated"` | ||||||
| 		Published                nuget.TypedValue[time.Time] `xml:"Published"` | 		LicenseURL               string                      `xml:"LicenseUrl,omitempty"` | ||||||
|  | 		MinClientVersion         string                      `xml:"MinClientVersion,omitempty"` | ||||||
|  | 		NormalizedVersion        string                      `xml:"NormalizedVersion"` | ||||||
|  | 		Owners                   string                      `xml:"Owners,omitempty"` | ||||||
|  | 		PackageSize              nuget.TypedValue[int64]     `xml:"PackageSize"` | ||||||
| 		ProjectURL               string                      `xml:"ProjectUrl,omitempty"` | 		ProjectURL               string                      `xml:"ProjectUrl,omitempty"` | ||||||
|  | 		Published                nuget.TypedValue[time.Time] `xml:"Published"` | ||||||
| 		ReleaseNotes             string                      `xml:"ReleaseNotes,omitempty"` | 		ReleaseNotes             string                      `xml:"ReleaseNotes,omitempty"` | ||||||
| 		RequireLicenseAcceptance nuget.TypedValue[bool]      `xml:"RequireLicenseAcceptance"` | 		RequireLicenseAcceptance nuget.TypedValue[bool]      `xml:"RequireLicenseAcceptance"` | ||||||
|  | 		Tags                     string                      `xml:"Tags,omitempty"` | ||||||
| 		Title                    string                      `xml:"Title"` | 		Title                    string                      `xml:"Title"` | ||||||
|  | 		Version                  string                      `xml:"Version"` | ||||||
|  | 		VersionDownloadCount     nuget.TypedValue[int64]     `xml:"VersionDownloadCount"` | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	type FeedEntry struct { | 	type FeedEntry struct { | ||||||
| @@ -86,28 +95,54 @@ func TestPackageNuGet(t *testing.T) { | |||||||
| 	readToken := getUserToken(t, user.Name, auth_model.AccessTokenScopeReadPackage) | 	readToken := getUserToken(t, user.Name, auth_model.AccessTokenScopeReadPackage) | ||||||
| 	badToken := getUserToken(t, user.Name, auth_model.AccessTokenScopeReadNotification) | 	badToken := getUserToken(t, user.Name, auth_model.AccessTokenScopeReadNotification) | ||||||
|  |  | ||||||
| 	packageName := "test.package" | 	packageName := "test.package" // id | ||||||
|  | 	packageID := packageName | ||||||
| 	packageVersion := "1.0.3" | 	packageVersion := "1.0.3" | ||||||
| 	packageAuthors := "KN4CK3R" | 	packageAuthors := "KN4CK3R" | ||||||
| 	packageDescription := "Gitea Test Package" | 	packageDescription := "Gitea Test Package" | ||||||
|  |  | ||||||
| 	symbolFilename := "test.pdb" | 	symbolFilename := "test.pdb" | ||||||
| 	symbolID := "d910bb6948bd4c6cb40155bcf52c3c94" | 	symbolID := "d910bb6948bd4c6cb40155bcf52c3c94" | ||||||
|  |  | ||||||
|  | 	packageCopyright := "Package Copyright" | ||||||
|  | 	packageIconURL := "https://gitea.io/favicon.png" | ||||||
|  | 	packageLanguage := "Package Language" | ||||||
|  | 	packageLicenseURL := "https://gitea.io/license" | ||||||
|  | 	packageMinClientVersion := "1.0.0.0" | ||||||
|  | 	packageOwners := "Package Owners" | ||||||
|  | 	packageProjectURL := "https://gitea.io" | ||||||
|  | 	packageReleaseNotes := "Package Release Notes" | ||||||
|  | 	packageTags := "tag_1 tag_2 tag_3" | ||||||
|  | 	packageTitle := "Package Title" | ||||||
|  | 	packageDevelopmentDependency := true | ||||||
|  | 	packageRequireLicenseAcceptance := true | ||||||
|  |  | ||||||
| 	createNuspec := func(id, version string) string { | 	createNuspec := func(id, version string) string { | ||||||
| 		return `<?xml version="1.0" encoding="utf-8"?> | 		return `<?xml version="1.0" encoding="utf-8"?> | ||||||
| <package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd"> | 		<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd"> | ||||||
| 	<metadata> | 			<metadata minClientVersion="` + packageMinClientVersion + `"> | ||||||
| 		<id>` + id + `</id> | 				<authors>` + packageAuthors + `</authors> | ||||||
| 		<version>` + version + `</version> | 				<copyright>` + packageCopyright + `</copyright> | ||||||
| 		<authors>` + packageAuthors + `</authors> | 				<description>` + packageDescription + `</description> | ||||||
| 		<description>` + packageDescription + `</description> | 				<developmentDependency>true</developmentDependency> | ||||||
| 		<dependencies> | 				<iconUrl>` + packageIconURL + `</iconUrl> | ||||||
| 			<group targetFramework=".NETStandard2.0"> | 				<id>` + id + `</id> | ||||||
| 				<dependency id="Microsoft.CSharp" version="4.5.0" /> | 				<language>` + packageLanguage + `</language> | ||||||
| 			</group> | 				<licenseUrl>` + packageLicenseURL + `</licenseUrl> | ||||||
| 		</dependencies> | 				<owners>` + packageOwners + `</owners> | ||||||
| 	</metadata> | 				<projectUrl>` + packageProjectURL + `</projectUrl> | ||||||
| </package>` | 				<releaseNotes>` + packageReleaseNotes + `</releaseNotes> | ||||||
|  | 				<requireLicenseAcceptance>true</requireLicenseAcceptance> | ||||||
|  | 				<tags>` + packageTags + `</tags> | ||||||
|  | 				<title>` + packageTitle + `</title> | ||||||
|  | 				<version>` + version + `</version> | ||||||
|  | 				<dependencies> | ||||||
|  | 					<group targetFramework=".NETStandard2.0"> | ||||||
|  | 						<dependency id="Microsoft.CSharp" version="4.5.0" /> | ||||||
|  | 					</group> | ||||||
|  | 				</dependencies> | ||||||
|  | 			</metadata> | ||||||
|  | 		</package>` | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	createPackage := func(id, version string) *bytes.Buffer { | 	createPackage := func(id, version string) *bytes.Buffer { | ||||||
| @@ -393,7 +428,7 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`) | |||||||
|  |  | ||||||
| 					pb, err := packages.GetBlobByID(db.DefaultContext, pf.BlobID) | 					pb, err := packages.GetBlobByID(db.DefaultContext, pf.BlobID) | ||||||
| 					assert.NoError(t, err) | 					assert.NoError(t, err) | ||||||
| 					assert.Equal(t, int64(412), pb.Size) | 					assert.Equal(t, int64(610), pb.Size) | ||||||
| 				case fmt.Sprintf("%s.%s.snupkg", packageName, packageVersion): | 				case fmt.Sprintf("%s.%s.snupkg", packageName, packageVersion): | ||||||
| 					assert.False(t, pf.IsLead) | 					assert.False(t, pf.IsLead) | ||||||
|  |  | ||||||
| @@ -405,7 +440,7 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`) | |||||||
|  |  | ||||||
| 					pb, err := packages.GetBlobByID(db.DefaultContext, pf.BlobID) | 					pb, err := packages.GetBlobByID(db.DefaultContext, pf.BlobID) | ||||||
| 					assert.NoError(t, err) | 					assert.NoError(t, err) | ||||||
| 					assert.Equal(t, int64(427), pb.Size) | 					assert.Equal(t, int64(996), pb.Size) | ||||||
| 				case symbolFilename: | 				case symbolFilename: | ||||||
| 					assert.False(t, pf.IsLead) | 					assert.False(t, pf.IsLead) | ||||||
|  |  | ||||||
| @@ -736,10 +771,24 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`) | |||||||
| 				var result FeedEntry | 				var result FeedEntry | ||||||
| 				decodeXML(t, resp, &result) | 				decodeXML(t, resp, &result) | ||||||
|  |  | ||||||
| 				assert.Equal(t, packageName, result.Properties.Title) |  | ||||||
| 				assert.Equal(t, packageVersion, result.Properties.Version) |  | ||||||
| 				assert.Equal(t, packageAuthors, result.Properties.Authors) | 				assert.Equal(t, packageAuthors, result.Properties.Authors) | ||||||
| 				assert.Equal(t, packageDescription, result.Properties.Description) | 				assert.Equal(t, packageDescription, result.Properties.Description) | ||||||
|  | 				assert.Equal(t, packageID, result.Properties.ID) | ||||||
|  | 				assert.Equal(t, packageVersion, result.Properties.Version) | ||||||
|  |  | ||||||
|  | 				assert.Equal(t, packageCopyright, result.Properties.Copyright) | ||||||
|  | 				assert.Equal(t, packageDevelopmentDependency, result.Properties.DevelopmentDependency.Value) | ||||||
|  | 				assert.Equal(t, packageIconURL, result.Properties.IconURL) | ||||||
|  | 				assert.Equal(t, packageLanguage, result.Properties.Language) | ||||||
|  | 				assert.Equal(t, packageLicenseURL, result.Properties.LicenseURL) | ||||||
|  | 				assert.Equal(t, packageMinClientVersion, result.Properties.MinClientVersion) | ||||||
|  | 				assert.Equal(t, packageOwners, result.Properties.Owners) | ||||||
|  | 				assert.Equal(t, packageProjectURL, result.Properties.ProjectURL) | ||||||
|  | 				assert.Equal(t, packageReleaseNotes, result.Properties.ReleaseNotes) | ||||||
|  | 				assert.Equal(t, packageRequireLicenseAcceptance, result.Properties.RequireLicenseAcceptance.Value) | ||||||
|  | 				assert.Equal(t, packageTags, result.Properties.Tags) | ||||||
|  | 				assert.Equal(t, packageTitle, result.Properties.Title) | ||||||
|  |  | ||||||
| 				assert.Equal(t, "Microsoft.CSharp:4.5.0:.NETStandard2.0", result.Properties.Dependencies) | 				assert.Equal(t, "Microsoft.CSharp:4.5.0:.NETStandard2.0", result.Properties.Dependencies) | ||||||
| 			}) | 			}) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -15,9 +15,9 @@ import ( | |||||||
| 	auth_model "code.gitea.io/gitea/models/auth" | 	auth_model "code.gitea.io/gitea/models/auth" | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	packages_model "code.gitea.io/gitea/models/packages" | 	packages_model "code.gitea.io/gitea/models/packages" | ||||||
| 	container_model "code.gitea.io/gitea/models/packages/container" |  | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
|  | 	container_module "code.gitea.io/gitea/modules/packages/container" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	api "code.gitea.io/gitea/modules/structs" | 	api "code.gitea.io/gitea/modules/structs" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/util" | ||||||
| @@ -538,7 +538,7 @@ func TestPackageCleanup(t *testing.T) { | |||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
| 		assert.NotEmpty(t, pbs) | 		assert.NotEmpty(t, pbs) | ||||||
|  |  | ||||||
| 		_, err = packages_model.GetInternalVersionByNameAndVersion(db.DefaultContext, user.ID, packages_model.TypeContainer, "cleanup-test", container_model.UploadVersion) | 		_, err = packages_model.GetInternalVersionByNameAndVersion(db.DefaultContext, user.ID, packages_model.TypeContainer, "cleanup-test", container_module.UploadVersion) | ||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
|  |  | ||||||
| 		err = packages_cleanup_service.CleanupTask(db.DefaultContext, duration) | 		err = packages_cleanup_service.CleanupTask(db.DefaultContext, duration) | ||||||
| @@ -548,7 +548,7 @@ func TestPackageCleanup(t *testing.T) { | |||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
| 		assert.Empty(t, pbs) | 		assert.Empty(t, pbs) | ||||||
|  |  | ||||||
| 		_, err = packages_model.GetInternalVersionByNameAndVersion(db.DefaultContext, user.ID, packages_model.TypeContainer, "cleanup-test", container_model.UploadVersion) | 		_, err = packages_model.GetInternalVersionByNameAndVersion(db.DefaultContext, user.ID, packages_model.TypeContainer, "cleanup-test", container_module.UploadVersion) | ||||||
| 		assert.ErrorIs(t, err, packages_model.ErrPackageNotExist) | 		assert.ErrorIs(t, err, packages_model.ErrPackageNotExist) | ||||||
| 	}) | 	}) | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user