aboutsummaryrefslogtreecommitdiff
path: root/services/projectbase/projectbase.go
diff options
context:
space:
mode:
Diffstat (limited to 'services/projectbase/projectbase.go')
-rw-r--r--services/projectbase/projectbase.go120
1 files changed, 120 insertions, 0 deletions
diff --git a/services/projectbase/projectbase.go b/services/projectbase/projectbase.go
new file mode 100644
index 000000000..eb86a65ef
--- /dev/null
+++ b/services/projectbase/projectbase.go
@@ -0,0 +1,120 @@
+// Copyright 2021 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package projectbase
+
+import (
+ "context"
+ "fmt"
+ "os"
+ "path/filepath"
+
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/services/migrations"
+ files_service "code.gitea.io/gitea/services/repository/files"
+)
+
+// InitProjectBase function
+func InitProjectBase(ctx context.Context, repo *repo_model.Repository) error {
+ if repo.HasProjectBase() {
+ return nil
+ }
+
+ if err := git.InitRepository(ctx, repo.ProjectBasePath(), true); err != nil {
+ return fmt.Errorf("InitRepository: %v", err)
+ } else if _, err = git.NewCommand(ctx, "symbolic-ref", "HEAD", git.BranchPrefix+"master").RunInDir(repo.ProjectBasePath()); err != nil {
+ return fmt.Errorf("unable to set default branch to master: %v", err)
+ }
+ return nil
+}
+
+// UpdateProjectBase function
+func UpdateProjectBase(ctx context.Context, token string, repo *repo_model.Repository) error {
+ //
+ // Checkout repository
+ //
+ temp, err := files_service.NewTemporaryUploadRepository(ctx, repo)
+ if err != nil {
+ return err
+ }
+ basePath := temp.BasePath()
+ defer temp.Close()
+ if stdout, err := git.NewCommand(ctx, "clone", "--no-checkout", "--shared", "--depth=1", repo.ProjectBasePath(), basePath).Run(); err != nil {
+ log.Error("Failed to clone projectbase repository: %s %s (%v)", repo.FullName(), stdout, err)
+ return fmt.Errorf("Failed to clone projectbase repository: %s %s (%v)", repo.FullName(), stdout, err)
+ }
+
+ //
+ // Create downloader & uploader
+ //
+ opts := migrations.MigrateOptions{
+ GitServiceType: structs.GiteaService,
+ Issues: true,
+ Comments: true,
+ AuthToken: token,
+ CloneAddr: repo.CloneLink().HTTPS,
+ }
+ downloaderFactory := &migrations.GiteaDownloaderFactory{}
+ downloader, err := downloaderFactory.New(ctx, opts)
+ if err != nil {
+ return err
+ }
+ uploader, err := migrations.NewRepositoryDumper(ctx, basePath, repo.OwnerName, repo.Name, opts)
+ if err != nil {
+ return err
+ }
+
+ //
+ // Perform the migration
+ //
+ if err := migrations.InternalMigrateRepository(downloader, uploader, opts); err != nil {
+ if err1 := uploader.Rollback(); err1 != nil {
+ log.Error("rollback failed: %v", err1)
+ }
+ return err
+ }
+ d := filepath.Join(basePath, repo.OwnerName, repo.Name)
+ for _, f := range []string{"repo.yml", "topic.yml", "issue.yml", "comments"} {
+ if err := os.Rename(filepath.Join(d, f), filepath.Join(basePath, f)); err != nil {
+ return err
+ }
+ }
+ if err := util.RemoveAll(filepath.Join(basePath, repo.OwnerName)); err != nil {
+ return err
+ }
+
+ //
+ // Commit the migration to the repository & push it
+ //
+ if stdout, err := git.NewCommand(ctx, "add", ".").RunInDir(basePath); err != nil {
+ log.Error("Failed to git add. : %s %s (%v)", repo.FullName(), stdout, err)
+ return fmt.Errorf("Failed to git add .: %s %s (%v)", repo.FullName(), stdout, err)
+ }
+ owner, err := user_model.GetUserByName(repo.OwnerName)
+ if err != nil {
+ log.Error("GetUserByName(repo.OwnerName=%s) (%v)", repo.OwnerName, err)
+ return err
+ }
+ author := owner.NewGitSig()
+ env := append(os.Environ(),
+ "GIT_AUTHOR_NAME="+author.Name,
+ "GIT_AUTHOR_EMAIL="+author.Email,
+ "GIT_COMMITTER_NAME="+author.Name,
+ "GIT_COMMITTER_EMAIL="+author.Email,
+ )
+ if stdout, err := git.NewCommand(ctx, "commit", "-m", "project info").RunInDirWithEnv(basePath, env); err != nil {
+ log.Error("Failed to git add . : %s %s (%v)", repo.FullName(), stdout, err)
+ return fmt.Errorf("Failed to git add .: %s %s (%v)", repo.FullName(), stdout, err)
+ }
+ if stdout, err := git.NewCommand(ctx, "push").RunInDir(basePath); err != nil {
+ log.Error("Failed to git push: %s %s (%v)", repo.FullName(), stdout, err)
+ return fmt.Errorf("Failed to git push: %s %s (%v)", repo.FullName(), stdout, err)
+ }
+ return nil
+}