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.

repo_unit.go 7.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. // Copyright 2017 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 repo
  5. import (
  6. "context"
  7. "fmt"
  8. "code.gitea.io/gitea/models/db"
  9. "code.gitea.io/gitea/models/unit"
  10. "code.gitea.io/gitea/modules/json"
  11. "code.gitea.io/gitea/modules/timeutil"
  12. "xorm.io/xorm"
  13. "xorm.io/xorm/convert"
  14. )
  15. // ErrUnitTypeNotExist represents a "UnitTypeNotExist" kind of error.
  16. type ErrUnitTypeNotExist struct {
  17. UT unit.Type
  18. }
  19. // IsErrUnitTypeNotExist checks if an error is a ErrUnitNotExist.
  20. func IsErrUnitTypeNotExist(err error) bool {
  21. _, ok := err.(ErrUnitTypeNotExist)
  22. return ok
  23. }
  24. func (err ErrUnitTypeNotExist) Error() string {
  25. return fmt.Sprintf("Unit type does not exist: %s", err.UT.String())
  26. }
  27. // RepoUnit describes all units of a repository
  28. type RepoUnit struct { //revive:disable-line:exported
  29. ID int64
  30. RepoID int64 `xorm:"INDEX(s)"`
  31. Type unit.Type `xorm:"INDEX(s)"`
  32. Config convert.Conversion `xorm:"TEXT"`
  33. CreatedUnix timeutil.TimeStamp `xorm:"INDEX CREATED"`
  34. }
  35. func init() {
  36. db.RegisterModel(new(RepoUnit))
  37. }
  38. // UnitConfig describes common unit config
  39. type UnitConfig struct{}
  40. // FromDB fills up a UnitConfig from serialized format.
  41. func (cfg *UnitConfig) FromDB(bs []byte) error {
  42. return json.UnmarshalHandleDoubleEncode(bs, &cfg)
  43. }
  44. // ToDB exports a UnitConfig to a serialized format.
  45. func (cfg *UnitConfig) ToDB() ([]byte, error) {
  46. return json.Marshal(cfg)
  47. }
  48. // ExternalWikiConfig describes external wiki config
  49. type ExternalWikiConfig struct {
  50. ExternalWikiURL string
  51. }
  52. // FromDB fills up a ExternalWikiConfig from serialized format.
  53. func (cfg *ExternalWikiConfig) FromDB(bs []byte) error {
  54. return json.UnmarshalHandleDoubleEncode(bs, &cfg)
  55. }
  56. // ToDB exports a ExternalWikiConfig to a serialized format.
  57. func (cfg *ExternalWikiConfig) ToDB() ([]byte, error) {
  58. return json.Marshal(cfg)
  59. }
  60. // ExternalTrackerConfig describes external tracker config
  61. type ExternalTrackerConfig struct {
  62. ExternalTrackerURL string
  63. ExternalTrackerFormat string
  64. ExternalTrackerStyle string
  65. }
  66. // FromDB fills up a ExternalTrackerConfig from serialized format.
  67. func (cfg *ExternalTrackerConfig) FromDB(bs []byte) error {
  68. return json.UnmarshalHandleDoubleEncode(bs, &cfg)
  69. }
  70. // ToDB exports a ExternalTrackerConfig to a serialized format.
  71. func (cfg *ExternalTrackerConfig) ToDB() ([]byte, error) {
  72. return json.Marshal(cfg)
  73. }
  74. // IssuesConfig describes issues config
  75. type IssuesConfig struct {
  76. EnableTimetracker bool
  77. AllowOnlyContributorsToTrackTime bool
  78. EnableDependencies bool
  79. }
  80. // FromDB fills up a IssuesConfig from serialized format.
  81. func (cfg *IssuesConfig) FromDB(bs []byte) error {
  82. return json.UnmarshalHandleDoubleEncode(bs, &cfg)
  83. }
  84. // ToDB exports a IssuesConfig to a serialized format.
  85. func (cfg *IssuesConfig) ToDB() ([]byte, error) {
  86. return json.Marshal(cfg)
  87. }
  88. // PullRequestsConfig describes pull requests config
  89. type PullRequestsConfig struct {
  90. IgnoreWhitespaceConflicts bool
  91. AllowMerge bool
  92. AllowRebase bool
  93. AllowRebaseMerge bool
  94. AllowSquash bool
  95. AllowManualMerge bool
  96. AutodetectManualMerge bool
  97. AllowRebaseUpdate bool
  98. DefaultDeleteBranchAfterMerge bool
  99. DefaultMergeStyle MergeStyle
  100. }
  101. // FromDB fills up a PullRequestsConfig from serialized format.
  102. func (cfg *PullRequestsConfig) FromDB(bs []byte) error {
  103. // AllowRebaseUpdate = true as default for existing PullRequestConfig in DB
  104. cfg.AllowRebaseUpdate = true
  105. return json.UnmarshalHandleDoubleEncode(bs, &cfg)
  106. }
  107. // ToDB exports a PullRequestsConfig to a serialized format.
  108. func (cfg *PullRequestsConfig) ToDB() ([]byte, error) {
  109. return json.Marshal(cfg)
  110. }
  111. // IsMergeStyleAllowed returns if merge style is allowed
  112. func (cfg *PullRequestsConfig) IsMergeStyleAllowed(mergeStyle MergeStyle) bool {
  113. return mergeStyle == MergeStyleMerge && cfg.AllowMerge ||
  114. mergeStyle == MergeStyleRebase && cfg.AllowRebase ||
  115. mergeStyle == MergeStyleRebaseMerge && cfg.AllowRebaseMerge ||
  116. mergeStyle == MergeStyleSquash && cfg.AllowSquash ||
  117. mergeStyle == MergeStyleManuallyMerged && cfg.AllowManualMerge
  118. }
  119. // GetDefaultMergeStyle returns the default merge style for this pull request
  120. func (cfg *PullRequestsConfig) GetDefaultMergeStyle() MergeStyle {
  121. if len(cfg.DefaultMergeStyle) != 0 {
  122. return cfg.DefaultMergeStyle
  123. }
  124. return MergeStyleMerge
  125. }
  126. // BeforeSet is invoked from XORM before setting the value of a field of this object.
  127. func (r *RepoUnit) BeforeSet(colName string, val xorm.Cell) {
  128. switch colName {
  129. case "type":
  130. switch unit.Type(db.Cell2Int64(val)) {
  131. case unit.TypeExternalWiki:
  132. r.Config = new(ExternalWikiConfig)
  133. case unit.TypeExternalTracker:
  134. r.Config = new(ExternalTrackerConfig)
  135. case unit.TypePullRequests:
  136. r.Config = new(PullRequestsConfig)
  137. case unit.TypeIssues:
  138. r.Config = new(IssuesConfig)
  139. case unit.TypeCode, unit.TypeReleases, unit.TypeWiki, unit.TypeProjects, unit.TypePackages:
  140. fallthrough
  141. default:
  142. r.Config = new(UnitConfig)
  143. }
  144. }
  145. }
  146. // Unit returns Unit
  147. func (r *RepoUnit) Unit() unit.Unit {
  148. return unit.Units[r.Type]
  149. }
  150. // CodeConfig returns config for unit.TypeCode
  151. func (r *RepoUnit) CodeConfig() *UnitConfig {
  152. return r.Config.(*UnitConfig)
  153. }
  154. // PullRequestsConfig returns config for unit.TypePullRequests
  155. func (r *RepoUnit) PullRequestsConfig() *PullRequestsConfig {
  156. return r.Config.(*PullRequestsConfig)
  157. }
  158. // ReleasesConfig returns config for unit.TypeReleases
  159. func (r *RepoUnit) ReleasesConfig() *UnitConfig {
  160. return r.Config.(*UnitConfig)
  161. }
  162. // ExternalWikiConfig returns config for unit.TypeExternalWiki
  163. func (r *RepoUnit) ExternalWikiConfig() *ExternalWikiConfig {
  164. return r.Config.(*ExternalWikiConfig)
  165. }
  166. // IssuesConfig returns config for unit.TypeIssues
  167. func (r *RepoUnit) IssuesConfig() *IssuesConfig {
  168. return r.Config.(*IssuesConfig)
  169. }
  170. // ExternalTrackerConfig returns config for unit.TypeExternalTracker
  171. func (r *RepoUnit) ExternalTrackerConfig() *ExternalTrackerConfig {
  172. return r.Config.(*ExternalTrackerConfig)
  173. }
  174. func getUnitsByRepoID(ctx context.Context, repoID int64) (units []*RepoUnit, err error) {
  175. var tmpUnits []*RepoUnit
  176. if err := db.GetEngine(ctx).Where("repo_id = ?", repoID).Find(&tmpUnits); err != nil {
  177. return nil, err
  178. }
  179. for _, u := range tmpUnits {
  180. if !u.Type.UnitGlobalDisabled() {
  181. units = append(units, u)
  182. }
  183. }
  184. return units, nil
  185. }
  186. // UpdateRepoUnit updates the provided repo unit
  187. func UpdateRepoUnit(unit *RepoUnit) error {
  188. _, err := db.GetEngine(db.DefaultContext).ID(unit.ID).Update(unit)
  189. return err
  190. }
  191. // UpdateRepositoryUnits updates a repository's units
  192. func UpdateRepositoryUnits(repo *Repository, units []RepoUnit, deleteUnitTypes []unit.Type) (err error) {
  193. ctx, committer, err := db.TxContext()
  194. if err != nil {
  195. return err
  196. }
  197. defer committer.Close()
  198. // Delete existing settings of units before adding again
  199. for _, u := range units {
  200. deleteUnitTypes = append(deleteUnitTypes, u.Type)
  201. }
  202. if _, err = db.GetEngine(ctx).Where("repo_id = ?", repo.ID).In("type", deleteUnitTypes).Delete(new(RepoUnit)); err != nil {
  203. return err
  204. }
  205. if len(units) > 0 {
  206. if err = db.Insert(ctx, units); err != nil {
  207. return err
  208. }
  209. }
  210. return committer.Commit()
  211. }