You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

descriptor.go 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. // Copyright 2021 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package packages
  5. import (
  6. "context"
  7. "fmt"
  8. "net/url"
  9. repo_model "code.gitea.io/gitea/models/repo"
  10. user_model "code.gitea.io/gitea/models/user"
  11. "code.gitea.io/gitea/modules/json"
  12. "code.gitea.io/gitea/modules/packages/composer"
  13. "code.gitea.io/gitea/modules/packages/conan"
  14. "code.gitea.io/gitea/modules/packages/container"
  15. "code.gitea.io/gitea/modules/packages/helm"
  16. "code.gitea.io/gitea/modules/packages/maven"
  17. "code.gitea.io/gitea/modules/packages/npm"
  18. "code.gitea.io/gitea/modules/packages/nuget"
  19. "code.gitea.io/gitea/modules/packages/pypi"
  20. "code.gitea.io/gitea/modules/packages/rubygems"
  21. "github.com/hashicorp/go-version"
  22. )
  23. // PackagePropertyList is a list of package properties
  24. type PackagePropertyList []*PackageProperty
  25. // GetByName gets the first property value with the specific name
  26. func (l PackagePropertyList) GetByName(name string) string {
  27. for _, pp := range l {
  28. if pp.Name == name {
  29. return pp.Value
  30. }
  31. }
  32. return ""
  33. }
  34. // PackageDescriptor describes a package
  35. type PackageDescriptor struct {
  36. Package *Package
  37. Owner *user_model.User
  38. Repository *repo_model.Repository
  39. Version *PackageVersion
  40. SemVer *version.Version
  41. Creator *user_model.User
  42. Properties PackagePropertyList
  43. Metadata interface{}
  44. Files []*PackageFileDescriptor
  45. }
  46. // PackageFileDescriptor describes a package file
  47. type PackageFileDescriptor struct {
  48. File *PackageFile
  49. Blob *PackageBlob
  50. Properties PackagePropertyList
  51. }
  52. // PackageWebLink returns the package web link
  53. func (pd *PackageDescriptor) PackageWebLink() string {
  54. return fmt.Sprintf("%s/-/packages/%s/%s", pd.Owner.HTMLURL(), string(pd.Package.Type), url.PathEscape(pd.Package.LowerName))
  55. }
  56. // FullWebLink returns the package version web link
  57. func (pd *PackageDescriptor) FullWebLink() string {
  58. return fmt.Sprintf("%s/%s", pd.PackageWebLink(), url.PathEscape(pd.Version.LowerVersion))
  59. }
  60. // CalculateBlobSize returns the total blobs size in bytes
  61. func (pd *PackageDescriptor) CalculateBlobSize() int64 {
  62. size := int64(0)
  63. for _, f := range pd.Files {
  64. size += f.Blob.Size
  65. }
  66. return size
  67. }
  68. // GetPackageDescriptor gets the package description for a version
  69. func GetPackageDescriptor(ctx context.Context, pv *PackageVersion) (*PackageDescriptor, error) {
  70. p, err := GetPackageByID(ctx, pv.PackageID)
  71. if err != nil {
  72. return nil, err
  73. }
  74. o, err := user_model.GetUserByIDCtx(ctx, p.OwnerID)
  75. if err != nil {
  76. return nil, err
  77. }
  78. repository, err := repo_model.GetRepositoryByIDCtx(ctx, p.RepoID)
  79. if err != nil && !repo_model.IsErrRepoNotExist(err) {
  80. return nil, err
  81. }
  82. creator, err := user_model.GetUserByIDCtx(ctx, pv.CreatorID)
  83. if err != nil {
  84. return nil, err
  85. }
  86. var semVer *version.Version
  87. if p.SemverCompatible {
  88. semVer, err = version.NewVersion(pv.Version)
  89. if err != nil {
  90. return nil, err
  91. }
  92. }
  93. pvps, err := GetProperties(ctx, PropertyTypeVersion, pv.ID)
  94. if err != nil {
  95. return nil, err
  96. }
  97. pfs, err := GetFilesByVersionID(ctx, pv.ID)
  98. if err != nil {
  99. return nil, err
  100. }
  101. pfds := make([]*PackageFileDescriptor, 0, len(pfs))
  102. for _, pf := range pfs {
  103. pfd, err := GetPackageFileDescriptor(ctx, pf)
  104. if err != nil {
  105. return nil, err
  106. }
  107. pfds = append(pfds, pfd)
  108. }
  109. var metadata interface{}
  110. switch p.Type {
  111. case TypeComposer:
  112. metadata = &composer.Metadata{}
  113. case TypeConan:
  114. metadata = &conan.Metadata{}
  115. case TypeContainer:
  116. metadata = &container.Metadata{}
  117. case TypeGeneric:
  118. // generic packages have no metadata
  119. case TypeHelm:
  120. metadata = &helm.Metadata{}
  121. case TypeNuGet:
  122. metadata = &nuget.Metadata{}
  123. case TypeNpm:
  124. metadata = &npm.Metadata{}
  125. case TypeMaven:
  126. metadata = &maven.Metadata{}
  127. case TypePyPI:
  128. metadata = &pypi.Metadata{}
  129. case TypeRubyGems:
  130. metadata = &rubygems.Metadata{}
  131. default:
  132. panic(fmt.Sprintf("unknown package type: %s", string(p.Type)))
  133. }
  134. if metadata != nil {
  135. if err := json.Unmarshal([]byte(pv.MetadataJSON), &metadata); err != nil {
  136. return nil, err
  137. }
  138. }
  139. return &PackageDescriptor{
  140. Package: p,
  141. Owner: o,
  142. Repository: repository,
  143. Version: pv,
  144. SemVer: semVer,
  145. Creator: creator,
  146. Properties: PackagePropertyList(pvps),
  147. Metadata: metadata,
  148. Files: pfds,
  149. }, nil
  150. }
  151. // GetPackageFileDescriptor gets a package file descriptor for a package file
  152. func GetPackageFileDescriptor(ctx context.Context, pf *PackageFile) (*PackageFileDescriptor, error) {
  153. pb, err := GetBlobByID(ctx, pf.BlobID)
  154. if err != nil {
  155. return nil, err
  156. }
  157. pfps, err := GetProperties(ctx, PropertyTypeFile, pf.ID)
  158. if err != nil {
  159. return nil, err
  160. }
  161. return &PackageFileDescriptor{
  162. pf,
  163. pb,
  164. PackagePropertyList(pfps),
  165. }, nil
  166. }
  167. // GetPackageDescriptors gets the package descriptions for the versions
  168. func GetPackageDescriptors(ctx context.Context, pvs []*PackageVersion) ([]*PackageDescriptor, error) {
  169. pds := make([]*PackageDescriptor, 0, len(pvs))
  170. for _, pv := range pvs {
  171. pd, err := GetPackageDescriptor(ctx, pv)
  172. if err != nil {
  173. return nil, err
  174. }
  175. pds = append(pds, pd)
  176. }
  177. return pds, nil
  178. }