From 8c6180a8cf2619eb5dd3a055ae0bdef518a629e36d1bcd51d30f7268be1dc3c4 Mon Sep 17 00:00:00 2001 From: Adam Majer Date: Sun, 15 Dec 2024 13:00:20 +0100 Subject: [PATCH] . --- bots-common/git_utils.go | 74 +++++++++++++++++-------- bots-common/git_utils_test.go | 6 +- bots-common/gitea_utils.go | 8 +-- workflow-pr/main_test.go | 8 +-- workflow-pr/pr_processor.go | 2 +- workflow-pr/pr_processor_closed.go | 2 +- workflow-pr/pr_processor_closed_test.go | 2 +- workflow-pr/pr_processor_opened.go | 2 +- workflow-pr/pr_processor_opened_test.go | 2 +- workflow-pr/pr_processor_sync.go | 4 +- workflow-pr/pr_processor_sync_test.go | 2 +- workflow-pr/pr_processor_test.go | 2 +- workflow-pr/repo_check.go | 2 +- workflow-pr/repo_check_test.go | 12 ++-- 14 files changed, 81 insertions(+), 47 deletions(-) diff --git a/bots-common/git_utils.go b/bots-common/git_utils.go index 755fd2d..71d7a8d 100644 --- a/bots-common/git_utils.go +++ b/bots-common/git_utils.go @@ -32,7 +32,27 @@ import ( //go:generate mockgen -source=git_utils.go -destination=mock/git_utils.go -typed -type GitHandler struct { +type GitSubmoduleLister interface { + GitSubmoduleList(gitPath, commitId string) (submoduleList map[string]string, err error) + GitSubmoduleCommitId(cwd, packageName, commitId string) (subCommitId string, valid bool) +} + +type Git interface { + GetPath() string + + CloneDevel(gitDir, outName, urlString string) error + GitBranchHead(gitDir, branchName string) (string, error) + io.Closer + + GitSubmoduleLister + + GitExecWithOutputOrPanic(cwd string, params ...string) string + GitExecOrPanic(cwd string, params ...string) + GitExec(cwd string, params ...string) error + GitExecWithOutput(cwd string, params ...string) (string, error) +} + +type GitHandlerImpl struct { DebugLogger bool GitPath string @@ -40,26 +60,36 @@ type GitHandler struct { GitEmail string } -type GitHandlerGenerator interface { - CreateGitHandler(git_author, email, prj_name string) (*GitHandler, error) +func (s *GitHandlerImpl) GetPath() string { + return s.GitPath } -type GitHandlerImpl struct{} +type GitHandlerGenerator interface { + CreateGitHandler(git_author, email, prjName string) (Git, error) + ReadExistingPath(git_author, email, gitPath string) (Git, error) +} -func (*GitHandlerImpl) CreateGitHandler(git_author, email, prj_name string) (*GitHandler, error) { - var err error +type GitHandlerGeneratorImpl struct{} - git := new(GitHandler) - git.GitCommiter = git_author - git.GitPath, err = os.MkdirTemp("", prj_name) +func (s *GitHandlerGeneratorImpl) CreateGitHandler(git_author, email, prj_name string) (Git, error) { + gitPath, err := os.MkdirTemp("", prj_name) if err != nil { return nil, fmt.Errorf("Cannot create temp dir: %w", err) } - if err = os.Chmod(git.GitPath, 0700); err != nil { + if err = os.Chmod(gitPath, 0700); err != nil { return nil, fmt.Errorf("Cannot fix permissions of temp dir: %w", err) } + return s.ReadExistingPath(git_author, email, gitPath) +} + +func (*GitHandlerGeneratorImpl) ReadExistingPath(git_author, email, gitPath string) (Git, error) { + git := &GitHandlerImpl{ + GitCommiter: git_author, + GitPath: gitPath, + } + return git, nil } @@ -101,7 +131,7 @@ func (refs *GitReferences) addReference(id, branch string) { refs.refs = append(refs.refs, GitReference{Branch: branch, Id: id}) } -func (e *GitHandler) CloneDevel(gitDir, outName, urlString string) error { +func (e *GitHandlerImpl) CloneDevel(gitDir, outName, urlString string) error { url, err := url.Parse(urlString) branch := url.Fragment url.Fragment = "" @@ -122,7 +152,7 @@ func (e *GitHandler) CloneDevel(gitDir, outName, urlString string) error { return nil } -func (e *GitHandler) GitBranchHead(gitDir, branchName string) (string, error) { +func (e *GitHandlerImpl) GitBranchHead(gitDir, branchName string) (string, error) { id, err := e.GitExecWithOutput(gitDir, "rev-list", "-1", branchName) if err != nil { return "", fmt.Errorf("Can't find default remote branch: %s", branchName) @@ -131,7 +161,7 @@ func (e *GitHandler) GitBranchHead(gitDir, branchName string) (string, error) { return strings.TrimSpace(id), nil } -func (e *GitHandler) Close() error { +func (e *GitHandlerImpl) Close() error { if err := os.RemoveAll(e.GitPath); err != nil { return err } @@ -155,7 +185,7 @@ func (h writeFunc) Close() error { return err } -func (e *GitHandler) GitExecWithOutputOrPanic(cwd string, params ...string) string { +func (e *GitHandlerImpl) GitExecWithOutputOrPanic(cwd string, params ...string) string { out, err := e.GitExecWithOutput(cwd, params...) if err != nil { log.Panicln("git command failed:", params, "@", cwd, "err:", err) @@ -163,20 +193,20 @@ func (e *GitHandler) GitExecWithOutputOrPanic(cwd string, params ...string) stri return out } -func (e *GitHandler) GitExecOrPanic(cwd string, params ...string) { +func (e *GitHandlerImpl) GitExecOrPanic(cwd string, params ...string) { if err := e.GitExec(cwd, params...); err != nil { log.Panicln("git command failed:", params, "@", cwd, "err:", err) } } -func (e *GitHandler) GitExec(cwd string, params ...string) error { +func (e *GitHandlerImpl) GitExec(cwd string, params ...string) error { _, err := e.GitExecWithOutput(cwd, params...) return err } var ExtraGitParams []string -func (e *GitHandler) GitExecWithOutput(cwd string, params ...string) (string, error) { +func (e *GitHandlerImpl) GitExecWithOutput(cwd string, params ...string) (string, error) { cmd := exec.Command("/usr/bin/git", params...) cmd.Env = []string{ "GIT_CEILING_DIRECTORIES=" + e.GitPath, @@ -485,7 +515,7 @@ func parseGitBlob(data <-chan byte) ([]byte, error) { return d, nil } -func (e *GitHandler) GitParseCommits(cwd string, commitIDs []string) (parsedCommits []commit, err error) { +func (e *GitHandlerImpl) GitParseCommits(cwd string, commitIDs []string) (parsedCommits []commit, err error) { var done sync.Mutex done.Lock() @@ -533,7 +563,7 @@ func (e *GitHandler) GitParseCommits(cwd string, commitIDs []string) (parsedComm } // TODO: support sub-trees -func (e *GitHandler) GitCatFile(cwd, commitId, filename string) (data []byte, err error) { +func (e *GitHandlerImpl) GitCatFile(cwd, commitId, filename string) (data []byte, err error) { var done sync.Mutex done.Lock() @@ -598,7 +628,7 @@ func (e *GitHandler) GitCatFile(cwd, commitId, filename string) (data []byte, er // return (filename) -> (hash) map for all submodules // TODO: recursive? map different orgs, not just assume '.' for path -func (e *GitHandler) GitSubmoduleList(cwd, commitId string) (submoduleList map[string]string, err error) { +func (e *GitHandlerImpl) GitSubmoduleList(gitPath, commitId string) (submoduleList map[string]string, err error) { var done sync.Mutex submoduleList = make(map[string]string) @@ -639,7 +669,7 @@ func (e *GitHandler) GitSubmoduleList(cwd, commitId string) (submoduleList map[s "GIT_CEILING_DIRECTORIES=" + e.GitPath, "GIT_CONFIG_GLOBAL=/dev/null", } - cmd.Dir = filepath.Join(e.GitPath, cwd) + cmd.Dir = filepath.Join(e.GitPath, gitPath) cmd.Stdout = &data_in cmd.Stdin = &data_out cmd.Stderr = writeFunc(func(data []byte) (int, error) { @@ -657,7 +687,7 @@ func (e *GitHandler) GitSubmoduleList(cwd, commitId string) (submoduleList map[s return submoduleList, err } -func (e *GitHandler) GitSubmoduleCommitId(cwd, packageName, commitId string) (subCommitId string, valid bool) { +func (e *GitHandlerImpl) GitSubmoduleCommitId(cwd, packageName, commitId string) (subCommitId string, valid bool) { defer func() { if recover() != nil { commitId = "" diff --git a/bots-common/git_utils_test.go b/bots-common/git_utils_test.go index af0f6ab..093c35e 100644 --- a/bots-common/git_utils_test.go +++ b/bots-common/git_utils_test.go @@ -259,7 +259,7 @@ func TestCommitTreeParsingOfHead(t *testing.T) { t.Run("reads HEAD and parses the tree", func(t *testing.T) { const nodejs21 = "c678c57007d496a98bec668ae38f2c26a695f94af78012f15d044ccf066ccb41" - h := GitHandler{ + h := GitHandlerImpl{ GitPath: gitDir, } id, ok := h.GitSubmoduleCommitId("", "nodejs21", commitId) @@ -272,7 +272,7 @@ func TestCommitTreeParsingOfHead(t *testing.T) { }) t.Run("reads README.md", func(t *testing.T) { - h := GitHandler{ + h := GitHandlerImpl{ GitPath: gitDir, } data, err := h.GitCatFile("", commitId, "README.md") @@ -285,7 +285,7 @@ func TestCommitTreeParsingOfHead(t *testing.T) { }) t.Run("read HEAD", func(t *testing.T) { - h := GitHandler{ + h := GitHandlerImpl{ GitPath: gitDir, } diff --git a/bots-common/gitea_utils.go b/bots-common/gitea_utils.go index 3a9aefb..507f857 100644 --- a/bots-common/gitea_utils.go +++ b/bots-common/gitea_utils.go @@ -70,7 +70,7 @@ type Gitea interface { SetNotificationRead(notificationId int64) error GetOrganization(orgName string) (*models.Organization, error) GetOrganizationRepositories(orgName string) ([]*models.Repository, error) - CreateRepositoryIfNotExist(git *GitHandler, org Organization, repoName string) (*models.Repository, error) + CreateRepositoryIfNotExist(git Git, org Organization, repoName string) (*models.Repository, error) CreatePullRequestIfNotExist(repo *models.Repository, srcId, targetId, title, body string) (*models.PullRequest, error) RequestReviews(pr *models.PullRequest, reviewer string) ([]*models.PullReview, error) AddReviewComment(pr *models.PullRequest, state models.ReviewStateType, comment string) (*models.PullReview, error) @@ -210,7 +210,7 @@ func (gitea *GiteaTransport) GetOrganizationRepositories(orgName string) ([]*mod return repos, nil } -func (gitea *GiteaTransport) CreateRepositoryIfNotExist(git *GitHandler, org Organization, repoName string) (*models.Repository, error) { +func (gitea *GiteaTransport) CreateRepositoryIfNotExist(git Git, org Organization, repoName string) (*models.Repository, error) { repo, err := gitea.client.Repository.RepoGet( repository.NewRepoGetParams().WithDefaults().WithOwner(org.Username).WithRepo(repoName), gitea.transport.DefaultAuthentication) @@ -239,7 +239,7 @@ func (gitea *GiteaTransport) CreateRepositoryIfNotExist(git *GitHandler, org Org } // initialize repository - if err = os.Mkdir(filepath.Join(git.GitPath, DefaultGitPrj), 0700); err != nil { + if err = os.Mkdir(filepath.Join(git.GetPath(), DefaultGitPrj), 0700); err != nil { return nil, err } if err = git.GitExec(DefaultGitPrj, "init", "--object-format="+repo.Payload.ObjectFormatName); err != nil { @@ -248,7 +248,7 @@ func (gitea *GiteaTransport) CreateRepositoryIfNotExist(git *GitHandler, org Org if err = git.GitExec(DefaultGitPrj, "checkout", "-b", repo.Payload.DefaultBranch); err != nil { return nil, err } - readmeFilename := filepath.Join(git.GitPath, DefaultGitPrj, "README.md") + readmeFilename := filepath.Join(git.GetPath(), DefaultGitPrj, "README.md") { file, _ := os.Create(readmeFilename) defer file.Close() diff --git a/workflow-pr/main_test.go b/workflow-pr/main_test.go index 0e6476e..d6c188c 100644 --- a/workflow-pr/main_test.go +++ b/workflow-pr/main_test.go @@ -43,7 +43,7 @@ func TestProjctGitSync(t *testing.T) { const LocalCMD = "---" -func gitExecs(t *testing.T, git *common.GitHandler, cmds [][]string) { +func gitExecs(t *testing.T, git *common.GitHandlerImpl, cmds [][]string) { for _, cmd := range cmds { if cmd[0] == LocalCMD { command := exec.Command(cmd[2], cmd[3:]...) @@ -86,7 +86,7 @@ func commandsForPackages(dir, prefix string, startN, endN int) [][]string { return commands } -func setupGitForTests(t *testing.T, git *common.GitHandler) { +func setupGitForTests(t *testing.T, git *common.GitHandlerImpl) { common.ExtraGitParams = []string{ "GIT_CONFIG_COUNT=1", "GIT_CONFIG_KEY_0=protocol.file.allow", @@ -131,7 +131,7 @@ func TestUpdatePrBranch(t *testing.T) { Pull_Request: &common.PullRequest{}, } - git := &common.GitHandler{ + git := &common.GitHandlerImpl{ DebugLogger: true, GitCommiter: "TestCommiter", GitEmail: "test@testing", @@ -167,7 +167,7 @@ func TestCreatePrBranch(t *testing.T) { Pull_Request: &common.PullRequest{}, } - git := &common.GitHandler{ + git := &common.GitHandlerImpl{ DebugLogger: true, GitCommiter: "TestCommiter", GitEmail: "test@testing", diff --git a/workflow-pr/pr_processor.go b/workflow-pr/pr_processor.go index b08459c..7c3b3d7 100644 --- a/workflow-pr/pr_processor.go +++ b/workflow-pr/pr_processor.go @@ -9,7 +9,7 @@ import ( ) type PullRequestProcessor interface { - Process(req *common.PullRequestWebhookEvent, git *common.GitHandler, config *common.AutogitConfig) error + Process(req *common.PullRequestWebhookEvent, git common.Git, config *common.AutogitConfig) error } type RequestProcessor struct { diff --git a/workflow-pr/pr_processor_closed.go b/workflow-pr/pr_processor_closed.go index edd110d..db4e067 100644 --- a/workflow-pr/pr_processor_closed.go +++ b/workflow-pr/pr_processor_closed.go @@ -10,7 +10,7 @@ type PullRequestClosed struct { gitea common.Gitea } -func (*PullRequestClosed) Process(req *common.PullRequestWebhookEvent, git *common.GitHandler, config *common.AutogitConfig) error { +func (*PullRequestClosed) Process(req *common.PullRequestWebhookEvent, git common.Git, config *common.AutogitConfig) error { if req.Repository.Name != config.GitProjectName { return nil } diff --git a/workflow-pr/pr_processor_closed_test.go b/workflow-pr/pr_processor_closed_test.go index dc0c7dc..1fb8cf7 100644 --- a/workflow-pr/pr_processor_closed_test.go +++ b/workflow-pr/pr_processor_closed_test.go @@ -47,7 +47,7 @@ func TestClosePR(t *testing.T) { }, } - git := &common.GitHandler{ + git := &common.GitHandlerImpl{ GitCommiter: "tester", GitEmail: "test@suse.com", } diff --git a/workflow-pr/pr_processor_opened.go b/workflow-pr/pr_processor_opened.go index b953ba4..bcc3f79 100644 --- a/workflow-pr/pr_processor_opened.go +++ b/workflow-pr/pr_processor_opened.go @@ -10,7 +10,7 @@ type PullRequestOpened struct { gitea common.Gitea } -func (o *PullRequestOpened) Process(req *common.PullRequestWebhookEvent, git *common.GitHandler, config *common.AutogitConfig) error { +func (o *PullRequestOpened) Process(req *common.PullRequestWebhookEvent, git common.Git, config *common.AutogitConfig) error { // requests against project are not handled here if req.Repository.Name == config.GitProjectName { return nil diff --git a/workflow-pr/pr_processor_opened_test.go b/workflow-pr/pr_processor_opened_test.go index 6dfca21..d6f60ed 100644 --- a/workflow-pr/pr_processor_opened_test.go +++ b/workflow-pr/pr_processor_opened_test.go @@ -49,7 +49,7 @@ func TestOpenPR(t *testing.T) { }, } - git := &common.GitHandler{ + git := &common.GitHandlerImpl{ GitCommiter: "tester", GitEmail: "test@suse.com", } diff --git a/workflow-pr/pr_processor_sync.go b/workflow-pr/pr_processor_sync.go index 0636fb0..97ad2b8 100644 --- a/workflow-pr/pr_processor_sync.go +++ b/workflow-pr/pr_processor_sync.go @@ -12,7 +12,7 @@ func prGitBranchNameForPR(req *common.PullRequestWebhookEvent) string { return fmt.Sprintf("PR_%s#%d", req.Repository.Name, req.Pull_Request.Number) } -func updateOrCreatePRBranch(req *common.PullRequestWebhookEvent, git *common.GitHandler, commitMsg, branchName string) { +func updateOrCreatePRBranch(req *common.PullRequestWebhookEvent, git common.Git, commitMsg, branchName string) { common.PanicOnError(git.GitExec(common.DefaultGitPrj, "submodule", "update", "--init", "--checkout", "--depth", "1", req.Repository.Name)) common.PanicOnError(git.GitExec(path.Join(common.DefaultGitPrj, req.Repository.Name), "fetch", "--depth", "1", "origin", req.Pull_Request.Head.Sha)) common.PanicOnError(git.GitExec(path.Join(common.DefaultGitPrj, req.Repository.Name), "checkout", req.Pull_Request.Head.Sha)) @@ -30,7 +30,7 @@ type PullRequestSynced struct { gitea common.Gitea } -func (o *PullRequestSynced) Process(req *common.PullRequestWebhookEvent, git *common.GitHandler, config *common.AutogitConfig) error { +func (o *PullRequestSynced) Process(req *common.PullRequestWebhookEvent, git common.Git, config *common.AutogitConfig) error { if req.Repository.Name == config.GitProjectName { return processPrjGitPullRequestSync(req) } diff --git a/workflow-pr/pr_processor_sync_test.go b/workflow-pr/pr_processor_sync_test.go index 223164f..75522c0 100644 --- a/workflow-pr/pr_processor_sync_test.go +++ b/workflow-pr/pr_processor_sync_test.go @@ -65,7 +65,7 @@ func TestSyncPR(t *testing.T) { }, } - git := &common.GitHandler{ + git := &common.GitHandlerImpl{ GitCommiter: "tester", GitEmail: "test@suse.com", } diff --git a/workflow-pr/pr_processor_test.go b/workflow-pr/pr_processor_test.go index 1683559..eb7b916 100644 --- a/workflow-pr/pr_processor_test.go +++ b/workflow-pr/pr_processor_test.go @@ -28,7 +28,7 @@ func TestPRProcessor(t *testing.T) { req := &RequestProcessor{ configuredRepos: testConfiguration, - git: &common.GitHandlerImpl{}, + git: &common.GitHandlerGeneratorImpl{}, } event := &common.PullRequestWebhookEvent{ diff --git a/workflow-pr/repo_check.go b/workflow-pr/repo_check.go index d5f6f86..46a2aaf 100644 --- a/workflow-pr/repo_check.go +++ b/workflow-pr/repo_check.go @@ -33,7 +33,7 @@ type DefaultStateChecker struct { func CreateDefaultStateChecker(checkOnStart bool, processor *RequestProcessor, gitea common.Gitea, interval time.Duration) *DefaultStateChecker { var s = &DefaultStateChecker{ - git: &common.GitHandlerImpl{}, + git: &common.GitHandlerGeneratorImpl{}, gitea: gitea, checkInterval: interval, checkOnStart: checkOnStart, diff --git a/workflow-pr/repo_check_test.go b/workflow-pr/repo_check_test.go index ecfe335..a8d7535 100644 --- a/workflow-pr/repo_check_test.go +++ b/workflow-pr/repo_check_test.go @@ -137,13 +137,17 @@ func TestRepoCheck(t *testing.T) { } type testGit struct { - git *common.GitHandler + git *common.GitHandlerImpl } -func (s *testGit) CreateGitHandler(a, b, c string) (*common.GitHandler, error) { +func (s *testGit) CreateGitHandler(a, b, c string) (common.Git, error) { return s.git, nil } +func (s *testGit) ReadExistingPath(a,b,c string) (common.Git, error) { + return nil, errors.New("should not be called") +} + func TestVerifyProjectState(t *testing.T) { var logBuf bytes.Buffer oldOut := log.Writer() @@ -154,7 +158,7 @@ func TestVerifyProjectState(t *testing.T) { ctl := gomock.NewController(t) gitea := mock_common.NewMockGitea(ctl) - git := &common.GitHandler{ + git := &common.GitHandlerImpl{ DebugLogger: true, GitCommiter: "TestCommiter", GitEmail: "test@testing", @@ -200,7 +204,7 @@ func TestVerifyProjectState(t *testing.T) { gitea := mock_common.NewMockGitea(ctl) process := mock_main.NewMockPullRequestProcessor(ctl) - git := &common.GitHandler{ + git := &common.GitHandlerImpl{ DebugLogger: true, GitCommiter: "TestCommiter", GitEmail: "test@testing",