package common import ( "errors" "fmt" "io" "os" "path/filepath" "regexp" "strings" transport "github.com/go-openapi/runtime/client" apiclient "src.opensuse.org/autogits/common/gitea-generated/client" "src.opensuse.org/autogits/common/gitea-generated/client/organization" "src.opensuse.org/autogits/common/gitea-generated/client/repository" "src.opensuse.org/autogits/common/gitea-generated/models" ) func (h *RequestHandler) allocateGiteaTransport() (*transport.Runtime, *apiclient.GiteaAPI) { r := transport.New("src.opensuse.org", apiclient.DefaultBasePath, [](string){"https"}) r.DefaultAuthentication = transport.BearerToken(giteaToken) r.SetDebug(true) return r, apiclient.New(r, nil) } func (h *RequestHandler) CreateRepositoryIfNotExist(org Organization, repoName string) *models.Repository { if h.HasError() { return nil } transport, client := h.allocateGiteaTransport() repo, err := client.Repository.RepoGet( repository.NewRepoGetParams().WithDefaults().WithOwner(org.Username).WithRepo(repoName), transport.DefaultAuthentication) if err != nil { switch err.(type) { case *repository.RepoGetNotFound: h.Log("repo '%s' does not exist. Trying to create it ....", repoName) repo, err := client.Organization.CreateOrgRepo( organization.NewCreateOrgRepoParams().WithDefaults().WithBody( &models.CreateRepoOption{ AutoInit: false, Name: &repoName, ObjectFormatName: models.CreateRepoOptionObjectFormatNameSha256, }, ).WithOrg(org.Username), nil, ) if err != nil { switch err.(type) { case *organization.CreateOrgRepoCreated: h.Log("repo '%s' created, with notification error?", repoName) default: h.Error = err h.LogError("error creating repo '%s' under '%s': %s", repoName, org.Username, err.Error()) return nil } } else { h.Log("repo '%s' created", repoName) } // initialize repository h.Error = os.Mkdir(filepath.Join(h.GitPath, DefaultGitPrj), 0700) if h.HasError() { return nil } h.GitExec(DefaultGitPrj, "init", "--object-format="+repo.Payload.ObjectFormatName) h.GitExec(DefaultGitPrj, "checkout", "-b", repo.Payload.DefaultBranch) if h.HasError() { return nil } readmeFilename := filepath.Join(h.GitPath, DefaultGitPrj, "README.md") { file, _ := os.Create(readmeFilename) defer file.Close() io.WriteString(file, ReadmeBoilerplate) } h.GitExec(DefaultGitPrj, "add", "README.md") h.GitExec(DefaultGitPrj, "commit", "-m", "Automatic devel project creation") h.GitExec(DefaultGitPrj, "remote", "add", "origin", repo.Payload.SSHURL) return repo.Payload default: h.Error = err h.LogError("cannot fetch repo data for '%s' / '%s' : %w", org.Username, repoName, err) } } return repo.Payload } func (h *RequestHandler) CreatePullRequest(repo *models.Repository, srcId, targetId, title, body string) *models.PullRequest { if h.HasError() { return nil } transport, client := h.allocateGiteaTransport() prOptions := models.CreatePullRequestOption{ Base: repo.DefaultBranch, Head: srcId, Title: title, Body: body, } pr, err := client.Repository.RepoCreatePullRequest( repository. NewRepoCreatePullRequestParams(). WithDefaults(). WithOwner(repo.Owner.UserName). WithRepo(repo.Name). WithBody(&prOptions), transport.DefaultAuthentication, ) if err != nil { h.LogError("Cannot create pull request: %v", err) h.Error = err return nil } if !pr.IsSuccess() { h.LogError("PR creation failed: %s", pr.Error()) h.Error = errors.New(pr.Error()) return nil } return pr.GetPayload() } func (h *RequestHandler) RequestReviews(pr *models.PullRequest, reviewer string) []*models.PullReview { if h.HasError() { return nil } transport, client := h.allocateGiteaTransport() reviewOptions := models.PullReviewRequestOptions{ Reviewers: []string{reviewer}, } review, err := client.Repository.RepoCreatePullReviewRequests( repository. NewRepoCreatePullReviewRequestsParams(). WithOwner(pr.Base.Repo.Owner.UserName). WithRepo(pr.Base.Repo.Name). WithIndex(pr.Index). WithBody(&reviewOptions), transport.DefaultAuthentication, ) if err != nil { h.LogError("Cannot create pull request: %v", err) h.Error = err return nil } if !review.IsSuccess() { h.LogError("PR creation failed: %s", review.Error()) h.Error = errors.New(review.Error()) return nil } return review.GetPayload() } func (h *RequestHandler) GetAssociatedPrjGitPR(pr *PullRequest) *models.PullRequest { if h.HasError() { return nil } transport, client := h.allocateGiteaTransport() var page, maxSize int64; page = 1 maxSize = 10000 state := "open" prs, err := client.Repository.RepoListPullRequests( repository. NewRepoListPullRequestsParams(). WithDefaults(). WithOwner(pr.Repo.Owner.Username). WithRepo(DefaultGitPrj). WithState(&state). WithLimit(&maxSize). WithPage(&page), transport.DefaultAuthentication) if err != nil { h.Error = fmt.Errorf("cannot fetch PR list for %s / %s : %v", pr.Repo.Owner.Username, pr.Repo.Name, err) return nil } if !prs.IsSuccess() { h.Error = fmt.Errorf("cannot fetch PR list for %s / %s : %s", pr.Repo.Owner.Username, pr.Repo.Name, prs.Error()) } payload_processing: for _, pr := range prs.Payload { lines := strings.Split(pr.Body, "\n") for _, line := range lines { r := regexp.MustCompile(`^PullRequest: ([^/]+)/([^/]+)#(\d+)$`) if m := r.FindSubmatch([]byte(line)); m != nil { h.Log("match: %#v", m) break payload_processing } else { h.Log("not matched: '%s'", line) } } } return nil }