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.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  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. "code.gitea.io/gitea/modules/migrations"
  12. "code.gitea.io/gitea/modules/migrations/base"
  13. "code.gitea.io/gitea/modules/setting"
  14. "code.gitea.io/gitea/modules/structs"
  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. if err := initDB(); err != nil {
  74. return err
  75. }
  76. log.Trace("AppPath: %s", setting.AppPath)
  77. log.Trace("AppWorkPath: %s", setting.AppWorkPath)
  78. log.Trace("Custom path: %s", setting.CustomPath)
  79. log.Trace("Log path: %s", setting.LogRootPath)
  80. setting.InitDBConfig()
  81. var (
  82. serviceType structs.GitServiceType
  83. cloneAddr = ctx.String("clone_addr")
  84. serviceStr = ctx.String("git_service")
  85. )
  86. if strings.HasPrefix(strings.ToLower(cloneAddr), "https://github.com/") {
  87. serviceStr = "github"
  88. } else if strings.HasPrefix(strings.ToLower(cloneAddr), "https://gitlab.com/") {
  89. serviceStr = "gitlab"
  90. } else if strings.HasPrefix(strings.ToLower(cloneAddr), "https://gitea.com/") {
  91. serviceStr = "gitea"
  92. }
  93. if serviceStr == "" {
  94. return errors.New("git_service missed or clone_addr cannot be recognized")
  95. }
  96. serviceType = convert.ToGitServiceType(serviceStr)
  97. var opts = base.MigrateOptions{
  98. GitServiceType: serviceType,
  99. CloneAddr: cloneAddr,
  100. AuthUsername: ctx.String("auth_username"),
  101. AuthPassword: ctx.String("auth_password"),
  102. AuthToken: ctx.String("auth_token"),
  103. RepoName: ctx.String("repo_name"),
  104. }
  105. if len(ctx.String("units")) == 0 {
  106. opts.Wiki = true
  107. opts.Issues = true
  108. opts.Milestones = true
  109. opts.Labels = true
  110. opts.Releases = true
  111. opts.Comments = true
  112. opts.PullRequests = true
  113. opts.ReleaseAssets = true
  114. } else {
  115. units := strings.Split(ctx.String("units"), ",")
  116. for _, unit := range units {
  117. switch strings.ToLower(unit) {
  118. case "wiki":
  119. opts.Wiki = true
  120. case "issues":
  121. opts.Issues = true
  122. case "milestones":
  123. opts.Milestones = true
  124. case "labels":
  125. opts.Labels = true
  126. case "releases":
  127. opts.Releases = true
  128. case "release_assets":
  129. opts.ReleaseAssets = true
  130. case "comments":
  131. opts.Comments = true
  132. case "pull_requests":
  133. opts.PullRequests = true
  134. }
  135. }
  136. }
  137. if err := migrations.DumpRepository(
  138. context.Background(),
  139. ctx.String("repo_dir"),
  140. ctx.String("owner_name"),
  141. opts,
  142. ); err != nil {
  143. log.Fatal("Failed to dump repository: %v", err)
  144. return err
  145. }
  146. log.Trace("Dump finished!!!")
  147. return nil
  148. }