diff options
Diffstat (limited to 'services/projectbase/projectbase.go')
-rw-r--r-- | services/projectbase/projectbase.go | 120 |
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 +} |