gitea源码

reference.go 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. // Copyright 2022 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package conan
  4. import (
  5. "fmt"
  6. "regexp"
  7. "strings"
  8. "code.gitea.io/gitea/modules/log"
  9. "code.gitea.io/gitea/modules/util"
  10. )
  11. const (
  12. // taken from https://github.com/conan-io/conan/blob/develop/conans/model/ref.py
  13. minChars = 2
  14. maxChars = 51
  15. // DefaultRevision if no revision is specified
  16. DefaultRevision = "0"
  17. )
  18. var (
  19. namePattern = regexp.MustCompile(fmt.Sprintf(`^[a-zA-Z0-9_][a-zA-Z0-9_\+\.-]{%d,%d}$`, minChars-1, maxChars-1))
  20. revisionPattern = regexp.MustCompile(fmt.Sprintf(`^[a-zA-Z0-9]{1,%d}$`, maxChars))
  21. ErrValidation = util.NewInvalidArgumentErrorf("could not validate one or more reference fields")
  22. )
  23. // RecipeReference represents a recipe <Name>/<Version>@<User>/<Channel>#<Revision>
  24. type RecipeReference struct {
  25. Name string
  26. Version string
  27. User string
  28. Channel string
  29. Revision string
  30. }
  31. func NewRecipeReference(name, version, user, channel, revision string) (*RecipeReference, error) {
  32. log.Trace("Conan Recipe: %s/%s(@%s/%s(#%s))", name, version, user, channel, revision)
  33. if user == "_" {
  34. user = ""
  35. }
  36. if channel == "_" {
  37. channel = ""
  38. }
  39. if (user != "" && channel == "") || (user == "" && channel != "") {
  40. return nil, ErrValidation
  41. }
  42. if !namePattern.MatchString(name) {
  43. return nil, ErrValidation
  44. }
  45. v := strings.TrimSpace(version)
  46. if v == "" {
  47. return nil, ErrValidation
  48. }
  49. if user != "" && !namePattern.MatchString(user) {
  50. return nil, ErrValidation
  51. }
  52. if channel != "" && !namePattern.MatchString(channel) {
  53. return nil, ErrValidation
  54. }
  55. if revision != "" && !revisionPattern.MatchString(revision) {
  56. return nil, ErrValidation
  57. }
  58. return &RecipeReference{name, v, user, channel, revision}, nil
  59. }
  60. func (r *RecipeReference) RevisionOrDefault() string {
  61. if r.Revision == "" {
  62. return DefaultRevision
  63. }
  64. return r.Revision
  65. }
  66. func (r *RecipeReference) String() string {
  67. rev := ""
  68. if r.Revision != "" {
  69. rev = "#" + r.Revision
  70. }
  71. if r.User == "" || r.Channel == "" {
  72. return fmt.Sprintf("%s/%s%s", r.Name, r.Version, rev)
  73. }
  74. return fmt.Sprintf("%s/%s@%s/%s%s", r.Name, r.Version, r.User, r.Channel, rev)
  75. }
  76. func (r *RecipeReference) LinkName() string {
  77. user := r.User
  78. if user == "" {
  79. user = "_"
  80. }
  81. channel := r.Channel
  82. if channel == "" {
  83. channel = "_"
  84. }
  85. return fmt.Sprintf("%s/%s/%s/%s/%s", r.Name, r.Version, user, channel, r.RevisionOrDefault())
  86. }
  87. func (r *RecipeReference) WithRevision(revision string) *RecipeReference {
  88. return &RecipeReference{r.Name, r.Version, r.User, r.Channel, revision}
  89. }
  90. // AsKey builds the additional key for the package file
  91. func (r *RecipeReference) AsKey() string {
  92. return fmt.Sprintf("%s|%s|%s", r.User, r.Channel, r.RevisionOrDefault())
  93. }
  94. // PackageReference represents a package of a recipe <Name>/<Version>@<User>/<Channel>#<Revision> <Reference>#<Revision>
  95. type PackageReference struct {
  96. Recipe *RecipeReference
  97. Reference string
  98. Revision string
  99. }
  100. func NewPackageReference(recipe *RecipeReference, reference, revision string) (*PackageReference, error) {
  101. log.Trace("Conan Package: %v %s(#%s)", recipe, reference, revision)
  102. if recipe == nil {
  103. return nil, ErrValidation
  104. }
  105. if reference == "" || !revisionPattern.MatchString(reference) {
  106. return nil, ErrValidation
  107. }
  108. if revision != "" && !revisionPattern.MatchString(revision) {
  109. return nil, ErrValidation
  110. }
  111. return &PackageReference{recipe, reference, revision}, nil
  112. }
  113. func (r *PackageReference) RevisionOrDefault() string {
  114. if r.Revision == "" {
  115. return DefaultRevision
  116. }
  117. return r.Revision
  118. }
  119. func (r *PackageReference) LinkName() string {
  120. return fmt.Sprintf("%s/%s", r.Reference, r.RevisionOrDefault())
  121. }
  122. func (r *PackageReference) WithRevision(revision string) *PackageReference {
  123. return &PackageReference{r.Recipe, r.Reference, revision}
  124. }
  125. // AsKey builds the additional key for the package file
  126. func (r *PackageReference) AsKey() string {
  127. return fmt.Sprintf("%s|%s|%s|%s|%s", r.Recipe.User, r.Recipe.Channel, r.Recipe.RevisionOrDefault(), r.Reference, r.RevisionOrDefault())
  128. }