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.

dump_repo.go 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  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 cmd
  5. import (
  6. "context"
  7. "errors"
  8. "strings"
  9. "code.gitea.io/gitea/modules/convert"
  10. "code.gitea.io/gitea/modules/log"
  11. base "code.gitea.io/gitea/modules/migration"
  12. "code.gitea.io/gitea/modules/setting"
  13. "code.gitea.io/gitea/modules/structs"
  14. "code.gitea.io/gitea/services/migrations"
  15. "github.com/urfave/cli"
  16. )
  17. // CmdDumpRepository represents the available dump repository sub-command.
  18. var CmdDumpRepository = cli.Command{
  19. Name: "dump-repo",
  20. Usage: "Dump the repository from git/github/gitea/gitlab",
  21. Description: "This is a command for dumping the repository data.",
  22. Action: runDumpRepository,
  23. Flags: []cli.Flag{
  24. cli.StringFlag{
  25. Name: "git_service",
  26. Value: "",
  27. Usage: "Git service, git, github, gitea, gitlab. If clone_addr could be recognized, this could be ignored.",
  28. },
  29. cli.StringFlag{
  30. Name: "repo_dir, r",
  31. Value: "./data",
  32. Usage: "Repository dir path to store the data",
  33. },
  34. cli.StringFlag{
  35. Name: "clone_addr",
  36. Value: "",
  37. Usage: "The URL will be clone, currently could be a git/github/gitea/gitlab http/https URL",
  38. },
  39. cli.StringFlag{
  40. Name: "auth_username",
  41. Value: "",
  42. Usage: "The username to visit the clone_addr",
  43. },
  44. cli.StringFlag{
  45. Name: "auth_password",
  46. Value: "",
  47. Usage: "The password to visit the clone_addr",
  48. },
  49. cli.StringFlag{
  50. Name: "auth_token",
  51. Value: "",
  52. Usage: "The personal token to visit the clone_addr",
  53. },
  54. cli.StringFlag{
  55. Name: "owner_name",
  56. Value: "",
  57. Usage: "The data will be stored on a directory with owner name if not empty",
  58. },
  59. cli.StringFlag{
  60. Name: "repo_name",
  61. Value: "",
  62. Usage: "The data will be stored on a directory with repository name if not empty",
  63. },
  64. cli.StringFlag{
  65. Name: "units",
  66. Value: "",
  67. Usage: `Which items will be migrated, one or more units should be separated as comma.
  68. wiki, issues, labels, releases, release_assets, milestones, pull_requests, comments are allowed. Empty means all units.`,
  69. },
  70. },
  71. }
  72. func runDumpRepository(ctx *cli.Context) error {
  73. stdCtx, cancel := installSignals()
  74. defer cancel()
  75. if err := initDB(stdCtx); err != nil {
  76. return err
  77. }
  78. log.Info("AppPath: %s", setting.AppPath)
  79. log.Info("AppWorkPath: %s", setting.AppWorkPath)
  80. log.Info("Custom path: %s", setting.CustomPath)
  81. log.Info("Log path: %s", setting.LogRootPath)
  82. log.Info("Configuration file: %s", setting.CustomConf)
  83. var (
  84. serviceType structs.GitServiceType
  85. cloneAddr = ctx.String("clone_addr")
  86. serviceStr = ctx.String("git_service")
  87. )
  88. if strings.HasPrefix(strings.ToLower(cloneAddr), "https://github.com/") {
  89. serviceStr = "github"
  90. } else if strings.HasPrefix(strings.ToLower(cloneAddr), "https://gitlab.com/") {
  91. serviceStr = "gitlab"
  92. } else if strings.HasPrefix(strings.ToLower(cloneAddr), "https://gitea.com/") {
  93. serviceStr = "gitea"
  94. }
  95. if serviceStr == "" {
  96. return errors.New("git_service missed or clone_addr cannot be recognized")
  97. }
  98. serviceType = convert.ToGitServiceType(serviceStr)
  99. var opts = base.MigrateOptions{
  100. GitServiceType: serviceType,
  101. CloneAddr: cloneAddr,
  102. AuthUsername: ctx.String("auth_username"),
  103. AuthPassword: ctx.String("auth_password"),
  104. AuthToken: ctx.String("auth_token"),
  105. RepoName: ctx.String("repo_name"),
  106. }
  107. if len(ctx.String("units")) == 0 {
  108. opts.Wiki = true
  109. opts.Issues = true
  110. opts.Milestones = true
  111. opts.Labels = true
  112. opts.Releases = true
  113. opts.Comments = true
  114. opts.PullRequests = true
  115. opts.ReleaseAssets = true
  116. } else {
  117. units := strings.Split(ctx.String("units"), ",")
  118. for _, unit := range units {
  119. switch strings.ToLower(unit) {
  120. case "wiki":
  121. opts.Wiki = true
  122. case "issues":
  123. opts.Issues = true
  124. case "milestones":
  125. opts.Milestones = true
  126. case "labels":
  127. opts.Labels = true
  128. case "releases":
  129. opts.Releases = true
  130. case "release_assets":
  131. opts.ReleaseAssets = true
  132. case "comments":
  133. opts.Comments = true
  134. case "pull_requests":
  135. opts.PullRequests = true
  136. }
  137. }
  138. }
  139. if err := migrations.DumpRepository(
  140. context.Background(),
  141. ctx.String("repo_dir"),
  142. ctx.String("owner_name"),
  143. opts,
  144. ); err != nil {
  145. log.Fatal("Failed to dump repository: %v", err)
  146. return err
  147. }
  148. log.Trace("Dump finished!!!")
  149. return nil
  150. }