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.

282 lines
6.3 KiB

  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 models
  5. import (
  6. "fmt"
  7. "strings"
  8. "code.gitea.io/gitea/modules/log"
  9. "code.gitea.io/gitea/modules/setting"
  10. )
  11. // UnitType is Unit's Type
  12. type UnitType int
  13. // Enumerate all the unit types
  14. const (
  15. UnitTypeCode UnitType = iota + 1 // 1 code
  16. UnitTypeIssues // 2 issues
  17. UnitTypePullRequests // 3 PRs
  18. UnitTypeReleases // 4 Releases
  19. UnitTypeWiki // 5 Wiki
  20. UnitTypeExternalWiki // 6 ExternalWiki
  21. UnitTypeExternalTracker // 7 ExternalTracker
  22. UnitTypeProjects // 8 Kanban board
  23. )
  24. // Value returns integer value for unit type
  25. func (u UnitType) Value() int {
  26. return int(u)
  27. }
  28. func (u UnitType) String() string {
  29. switch u {
  30. case UnitTypeCode:
  31. return "UnitTypeCode"
  32. case UnitTypeIssues:
  33. return "UnitTypeIssues"
  34. case UnitTypePullRequests:
  35. return "UnitTypePullRequests"
  36. case UnitTypeReleases:
  37. return "UnitTypeReleases"
  38. case UnitTypeWiki:
  39. return "UnitTypeWiki"
  40. case UnitTypeExternalWiki:
  41. return "UnitTypeExternalWiki"
  42. case UnitTypeExternalTracker:
  43. return "UnitTypeExternalTracker"
  44. case UnitTypeProjects:
  45. return "UnitTypeProjects"
  46. }
  47. return fmt.Sprintf("Unknown UnitType %d", u)
  48. }
  49. // ColorFormat provides a ColorFormatted version of this UnitType
  50. func (u UnitType) ColorFormat(s fmt.State) {
  51. log.ColorFprintf(s, "%d:%s",
  52. log.NewColoredIDValue(u),
  53. u)
  54. }
  55. var (
  56. // AllRepoUnitTypes contains all the unit types
  57. AllRepoUnitTypes = []UnitType{
  58. UnitTypeCode,
  59. UnitTypeIssues,
  60. UnitTypePullRequests,
  61. UnitTypeReleases,
  62. UnitTypeWiki,
  63. UnitTypeExternalWiki,
  64. UnitTypeExternalTracker,
  65. UnitTypeProjects,
  66. }
  67. // DefaultRepoUnits contains the default unit types
  68. DefaultRepoUnits = []UnitType{
  69. UnitTypeCode,
  70. UnitTypeIssues,
  71. UnitTypePullRequests,
  72. UnitTypeReleases,
  73. UnitTypeWiki,
  74. UnitTypeProjects,
  75. }
  76. // NotAllowedDefaultRepoUnits contains units that can't be default
  77. NotAllowedDefaultRepoUnits = []UnitType{
  78. UnitTypeExternalWiki,
  79. UnitTypeExternalTracker,
  80. }
  81. // MustRepoUnits contains the units could not be disabled currently
  82. MustRepoUnits = []UnitType{
  83. UnitTypeCode,
  84. UnitTypeReleases,
  85. }
  86. // DisabledRepoUnits contains the units that have been globally disabled
  87. DisabledRepoUnits = []UnitType{}
  88. )
  89. func loadUnitConfig() {
  90. setDefaultRepoUnits := FindUnitTypes(setting.Repository.DefaultRepoUnits...)
  91. // Default repo units set if setting is not empty
  92. if len(setDefaultRepoUnits) > 0 {
  93. // MustRepoUnits required as default
  94. DefaultRepoUnits = make([]UnitType, len(MustRepoUnits))
  95. copy(DefaultRepoUnits, MustRepoUnits)
  96. for _, defaultU := range setDefaultRepoUnits {
  97. if !defaultU.CanBeDefault() {
  98. log.Warn("Not allowed as default unit: %s", defaultU.String())
  99. continue
  100. }
  101. // MustRepoUnits already added
  102. if defaultU.CanDisable() {
  103. DefaultRepoUnits = append(DefaultRepoUnits, defaultU)
  104. }
  105. }
  106. }
  107. DisabledRepoUnits = FindUnitTypes(setting.Repository.DisabledRepoUnits...)
  108. // Check that must units are not disabled
  109. for i, disabledU := range DisabledRepoUnits {
  110. if !disabledU.CanDisable() {
  111. log.Warn("Not allowed to global disable unit %s", disabledU.String())
  112. DisabledRepoUnits = append(DisabledRepoUnits[:i], DisabledRepoUnits[i+1:]...)
  113. }
  114. }
  115. // Remove disabled units from default units
  116. for _, disabledU := range DisabledRepoUnits {
  117. for i, defaultU := range DefaultRepoUnits {
  118. if defaultU == disabledU {
  119. DefaultRepoUnits = append(DefaultRepoUnits[:i], DefaultRepoUnits[i+1:]...)
  120. }
  121. }
  122. }
  123. }
  124. // UnitGlobalDisabled checks if unit type is global disabled
  125. func (u UnitType) UnitGlobalDisabled() bool {
  126. for _, ud := range DisabledRepoUnits {
  127. if u == ud {
  128. return true
  129. }
  130. }
  131. return false
  132. }
  133. // CanDisable checks if this unit type can be disabled.
  134. func (u *UnitType) CanDisable() bool {
  135. for _, mu := range MustRepoUnits {
  136. if *u == mu {
  137. return false
  138. }
  139. }
  140. return true
  141. }
  142. // CanBeDefault checks if the unit type can be a default repo unit
  143. func (u *UnitType) CanBeDefault() bool {
  144. for _, nadU := range NotAllowedDefaultRepoUnits {
  145. if *u == nadU {
  146. return false
  147. }
  148. }
  149. return true
  150. }
  151. // Unit is a section of one repository
  152. type Unit struct {
  153. Type UnitType
  154. NameKey string
  155. URI string
  156. DescKey string
  157. Idx int
  158. }
  159. // CanDisable returns if this unit could be disabled.
  160. func (u *Unit) CanDisable() bool {
  161. return u.Type.CanDisable()
  162. }
  163. // IsLessThan compares order of two units
  164. func (u Unit) IsLessThan(unit Unit) bool {
  165. if (u.Type == UnitTypeExternalTracker || u.Type == UnitTypeExternalWiki) && unit.Type != UnitTypeExternalTracker && unit.Type != UnitTypeExternalWiki {
  166. return false
  167. }
  168. return u.Idx < unit.Idx
  169. }
  170. // Enumerate all the units
  171. var (
  172. UnitCode = Unit{
  173. UnitTypeCode,
  174. "repo.code",
  175. "/",
  176. "repo.code.desc",
  177. 0,
  178. }
  179. UnitIssues = Unit{
  180. UnitTypeIssues,
  181. "repo.issues",
  182. "/issues",
  183. "repo.issues.desc",
  184. 1,
  185. }
  186. UnitExternalTracker = Unit{
  187. UnitTypeExternalTracker,
  188. "repo.ext_issues",
  189. "/issues",
  190. "repo.ext_issues.desc",
  191. 1,
  192. }
  193. UnitPullRequests = Unit{
  194. UnitTypePullRequests,
  195. "repo.pulls",
  196. "/pulls",
  197. "repo.pulls.desc",
  198. 2,
  199. }
  200. UnitReleases = Unit{
  201. UnitTypeReleases,
  202. "repo.releases",
  203. "/releases",
  204. "repo.releases.desc",
  205. 3,
  206. }
  207. UnitWiki = Unit{
  208. UnitTypeWiki,
  209. "repo.wiki",
  210. "/wiki",
  211. "repo.wiki.desc",
  212. 4,
  213. }
  214. UnitExternalWiki = Unit{
  215. UnitTypeExternalWiki,
  216. "repo.ext_wiki",
  217. "/wiki",
  218. "repo.ext_wiki.desc",
  219. 4,
  220. }
  221. UnitProjects = Unit{
  222. UnitTypeProjects,
  223. "repo.projects",
  224. "/projects",
  225. "repo.projects.desc",
  226. 5,
  227. }
  228. // Units contains all the units
  229. Units = map[UnitType]Unit{
  230. UnitTypeCode: UnitCode,
  231. UnitTypeIssues: UnitIssues,
  232. UnitTypeExternalTracker: UnitExternalTracker,
  233. UnitTypePullRequests: UnitPullRequests,
  234. UnitTypeReleases: UnitReleases,
  235. UnitTypeWiki: UnitWiki,
  236. UnitTypeExternalWiki: UnitExternalWiki,
  237. UnitTypeProjects: UnitProjects,
  238. }
  239. )
  240. // FindUnitTypes give the unit key name and return unit
  241. func FindUnitTypes(nameKeys ...string) (res []UnitType) {
  242. for _, key := range nameKeys {
  243. for t, u := range Units {
  244. if strings.EqualFold(key, u.NameKey) {
  245. res = append(res, t)
  246. break
  247. }
  248. }
  249. }
  250. return
  251. }