A fork of Gitea (see branch `mj`) adding Majority Judgment Polls 𐄷 over Issues and Merge Requests. https://git.mieuxvoter.fr
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.

276 lines
8.7 KiB

  1. // Copyright 2020 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 doctor
  5. import (
  6. "context"
  7. "code.gitea.io/gitea/models"
  8. "code.gitea.io/gitea/models/migrations"
  9. "code.gitea.io/gitea/modules/log"
  10. "code.gitea.io/gitea/modules/setting"
  11. )
  12. func checkDBConsistency(logger log.Logger, autofix bool) error {
  13. // make sure DB version is uptodate
  14. if err := models.NewEngine(context.Background(), migrations.EnsureUpToDate); err != nil {
  15. logger.Critical("Model version on the database does not match the current Gitea version. Model consistency will not be checked until the database is upgraded")
  16. return err
  17. }
  18. // find labels without existing repo or org
  19. count, err := models.CountOrphanedLabels()
  20. if err != nil {
  21. logger.Critical("Error: %v whilst counting orphaned labels", err)
  22. return err
  23. }
  24. if count > 0 {
  25. if autofix {
  26. if err = models.DeleteOrphanedLabels(); err != nil {
  27. logger.Critical("Error: %v whilst deleting orphaned labels", err)
  28. return err
  29. }
  30. logger.Info("%d labels without existing repository/organisation deleted", count)
  31. } else {
  32. logger.Warn("%d labels without existing repository/organisation", count)
  33. }
  34. }
  35. // find IssueLabels without existing label
  36. count, err = models.CountOrphanedIssueLabels()
  37. if err != nil {
  38. logger.Critical("Error: %v whilst counting orphaned issue_labels", err)
  39. return err
  40. }
  41. if count > 0 {
  42. if autofix {
  43. if err = models.DeleteOrphanedIssueLabels(); err != nil {
  44. logger.Critical("Error: %v whilst deleting orphaned issue_labels", err)
  45. return err
  46. }
  47. logger.Info("%d issue_labels without existing label deleted", count)
  48. } else {
  49. logger.Warn("%d issue_labels without existing label", count)
  50. }
  51. }
  52. // find issues without existing repository
  53. count, err = models.CountOrphanedIssues()
  54. if err != nil {
  55. logger.Critical("Error: %v whilst counting orphaned issues", err)
  56. return err
  57. }
  58. if count > 0 {
  59. if autofix {
  60. if err = models.DeleteOrphanedIssues(); err != nil {
  61. logger.Critical("Error: %v whilst deleting orphaned issues", err)
  62. return err
  63. }
  64. logger.Info("%d issues without existing repository deleted", count)
  65. } else {
  66. logger.Warn("%d issues without existing repository", count)
  67. }
  68. }
  69. // find pulls without existing issues
  70. count, err = models.CountOrphanedObjects("pull_request", "issue", "pull_request.issue_id=issue.id")
  71. if err != nil {
  72. logger.Critical("Error: %v whilst counting orphaned objects", err)
  73. return err
  74. }
  75. if count > 0 {
  76. if autofix {
  77. if err = models.DeleteOrphanedObjects("pull_request", "issue", "pull_request.issue_id=issue.id"); err != nil {
  78. logger.Critical("Error: %v whilst deleting orphaned objects", err)
  79. return err
  80. }
  81. logger.Info("%d pull requests without existing issue deleted", count)
  82. } else {
  83. logger.Warn("%d pull requests without existing issue", count)
  84. }
  85. }
  86. // find tracked times without existing issues/pulls
  87. count, err = models.CountOrphanedObjects("tracked_time", "issue", "tracked_time.issue_id=issue.id")
  88. if err != nil {
  89. logger.Critical("Error: %v whilst counting orphaned objects", err)
  90. return err
  91. }
  92. if count > 0 {
  93. if autofix {
  94. if err = models.DeleteOrphanedObjects("tracked_time", "issue", "tracked_time.issue_id=issue.id"); err != nil {
  95. logger.Critical("Error: %v whilst deleting orphaned objects", err)
  96. return err
  97. }
  98. logger.Info("%d tracked times without existing issue deleted", count)
  99. } else {
  100. logger.Warn("%d tracked times without existing issue", count)
  101. }
  102. }
  103. // find null archived repositories
  104. count, err = models.CountNullArchivedRepository()
  105. if err != nil {
  106. logger.Critical("Error: %v whilst counting null archived repositories", err)
  107. return err
  108. }
  109. if count > 0 {
  110. if autofix {
  111. updatedCount, err := models.FixNullArchivedRepository()
  112. if err != nil {
  113. logger.Critical("Error: %v whilst fixing null archived repositories", err)
  114. return err
  115. }
  116. logger.Info("%d repositories with null is_archived updated", updatedCount)
  117. } else {
  118. logger.Warn("%d repositories with null is_archived", count)
  119. }
  120. }
  121. // find label comments with empty labels
  122. count, err = models.CountCommentTypeLabelWithEmptyLabel()
  123. if err != nil {
  124. logger.Critical("Error: %v whilst counting label comments with empty labels", err)
  125. return err
  126. }
  127. if count > 0 {
  128. if autofix {
  129. updatedCount, err := models.FixCommentTypeLabelWithEmptyLabel()
  130. if err != nil {
  131. logger.Critical("Error: %v whilst removing label comments with empty labels", err)
  132. return err
  133. }
  134. logger.Info("%d label comments with empty labels removed", updatedCount)
  135. } else {
  136. logger.Warn("%d label comments with empty labels", count)
  137. }
  138. }
  139. // find label comments with labels from outside the repository
  140. count, err = models.CountCommentTypeLabelWithOutsideLabels()
  141. if err != nil {
  142. logger.Critical("Error: %v whilst counting label comments with outside labels", err)
  143. return err
  144. }
  145. if count > 0 {
  146. if autofix {
  147. updatedCount, err := models.FixCommentTypeLabelWithOutsideLabels()
  148. if err != nil {
  149. logger.Critical("Error: %v whilst removing label comments with outside labels", err)
  150. return err
  151. }
  152. log.Info("%d label comments with outside labels removed", updatedCount)
  153. } else {
  154. log.Warn("%d label comments with outside labels", count)
  155. }
  156. }
  157. // find issue_label with labels from outside the repository
  158. count, err = models.CountIssueLabelWithOutsideLabels()
  159. if err != nil {
  160. logger.Critical("Error: %v whilst counting issue_labels from outside the repository or organisation", err)
  161. return err
  162. }
  163. if count > 0 {
  164. if autofix {
  165. updatedCount, err := models.FixIssueLabelWithOutsideLabels()
  166. if err != nil {
  167. logger.Critical("Error: %v whilst removing issue_labels from outside the repository or organisation", err)
  168. return err
  169. }
  170. logger.Info("%d issue_labels from outside the repository or organisation removed", updatedCount)
  171. } else {
  172. logger.Warn("%d issue_labels from outside the repository or organisation", count)
  173. }
  174. }
  175. // TODO: function to recalc all counters
  176. if setting.Database.UsePostgreSQL {
  177. count, err = models.CountBadSequences()
  178. if err != nil {
  179. logger.Critical("Error: %v whilst checking sequence values", err)
  180. return err
  181. }
  182. if count > 0 {
  183. if autofix {
  184. err := models.FixBadSequences()
  185. if err != nil {
  186. logger.Critical("Error: %v whilst attempting to fix sequences", err)
  187. return err
  188. }
  189. logger.Info("%d sequences updated", count)
  190. } else {
  191. logger.Warn("%d sequences with incorrect values", count)
  192. }
  193. }
  194. }
  195. // find protected branches without existing repository
  196. count, err = models.CountOrphanedObjects("protected_branch", "repository", "protected_branch.repo_id=repository.id")
  197. if err != nil {
  198. logger.Critical("Error: %v whilst counting orphaned objects", err)
  199. return err
  200. }
  201. if count > 0 {
  202. if autofix {
  203. if err = models.DeleteOrphanedObjects("protected_branch", "repository", "protected_branch.repo_id=repository.id"); err != nil {
  204. logger.Critical("Error: %v whilst deleting orphaned objects", err)
  205. return err
  206. }
  207. logger.Info("%d protected branches without existing repository deleted", count)
  208. } else {
  209. logger.Warn("%d protected branches without existing repository", count)
  210. }
  211. }
  212. // find deleted branches without existing repository
  213. count, err = models.CountOrphanedObjects("deleted_branch", "repository", "deleted_branch.repo_id=repository.id")
  214. if err != nil {
  215. logger.Critical("Error: %v whilst counting orphaned objects", err)
  216. return err
  217. }
  218. if count > 0 {
  219. if autofix {
  220. if err = models.DeleteOrphanedObjects("deleted_branch", "repository", "deleted_branch.repo_id=repository.id"); err != nil {
  221. logger.Critical("Error: %v whilst deleting orphaned objects", err)
  222. return err
  223. }
  224. logger.Info("%d deleted branches without existing repository deleted", count)
  225. } else {
  226. logger.Warn("%d deleted branches without existing repository", count)
  227. }
  228. }
  229. // find LFS locks without existing repository
  230. count, err = models.CountOrphanedObjects("lfs_lock", "repository", "lfs_lock.repo_id=repository.id")
  231. if err != nil {
  232. logger.Critical("Error: %v whilst counting orphaned objects", err)
  233. return err
  234. }
  235. if count > 0 {
  236. if autofix {
  237. if err = models.DeleteOrphanedObjects("lfs_lock", "repository", "lfs_lock.repo_id=repository.id"); err != nil {
  238. logger.Critical("Error: %v whilst deleting orphaned objects", err)
  239. return err
  240. }
  241. logger.Info("%d LFS locks without existing repository deleted", count)
  242. } else {
  243. logger.Warn("%d LFS locks without existing repository", count)
  244. }
  245. }
  246. return nil
  247. }
  248. func init() {
  249. Register(&Check{
  250. Title: "Check consistency of database",
  251. Name: "check-db-consistency",
  252. IsDefault: false,
  253. Run: checkDBConsistency,
  254. Priority: 3,
  255. })
  256. }