github.com/emmahsax/go-git-helper@v0.0.8-0.20240519163017-907b9de0fa52/internal/githubPullRequest/githubPullRequest.go (about) 1 package githubPullRequest 2 3 import ( 4 "errors" 5 "fmt" 6 "os" 7 "path/filepath" 8 "strconv" 9 "strings" 10 11 "github.com/emmahsax/go-git-helper/internal/commandline" 12 "github.com/emmahsax/go-git-helper/internal/github" 13 "github.com/emmahsax/go-git-helper/internal/utils" 14 go_github "github.com/google/go-github/v60/github" 15 ) 16 17 type GitHubPullRequest struct { 18 BaseBranch string 19 Debug bool 20 Draft string 21 GitRootDir string 22 LocalBranch string 23 LocalRepo string 24 NewPrTitle string 25 } 26 27 func NewGitHubPullRequest(options map[string]string, debug bool) *GitHubPullRequest { 28 return &GitHubPullRequest{ 29 BaseBranch: options["baseBranch"], 30 Debug: debug, 31 Draft: options["draft"], 32 GitRootDir: options["gitRootDir"], 33 LocalBranch: options["localBranch"], 34 LocalRepo: options["localRepo"], 35 NewPrTitle: options["newPrTitle"], 36 } 37 } 38 39 func (pr *GitHubPullRequest) Create() { 40 d, _ := strconv.ParseBool(pr.Draft) 41 options := go_github.NewPullRequest{ 42 Base: go_github.String(pr.BaseBranch), 43 Body: go_github.String(pr.newPrBody()), 44 Draft: go_github.Bool(d), 45 Head: go_github.String(pr.LocalBranch), 46 MaintainerCanModify: go_github.Bool(true), 47 Title: go_github.String(pr.NewPrTitle), 48 } 49 50 repo := strings.Split(pr.LocalRepo, "/") 51 52 fmt.Println("Creating pull request:", pr.NewPrTitle) 53 resp, err := pr.github().CreatePullRequest(repo[0], repo[1], &options) 54 if err != nil { 55 customErr := errors.New("could not create pull request: " + err.Error()) 56 utils.HandleError(customErr, pr.Debug, nil) 57 return 58 } 59 60 fmt.Println("Pull request successfully created:", *resp.HTMLURL) 61 } 62 63 func (pr *GitHubPullRequest) newPrBody() string { 64 templateName := pr.templateNameToApply() 65 if templateName != "" { 66 content, err := os.ReadFile(templateName) 67 if err != nil { 68 utils.HandleError(err, pr.Debug, nil) 69 return "" 70 } 71 72 return string(content) 73 } 74 return "" 75 } 76 77 func (pr *GitHubPullRequest) templateNameToApply() string { 78 templateName := "" 79 if len(pr.prTemplateOptions()) > 0 { 80 templateName = pr.determineTemplate() 81 } 82 83 return templateName 84 } 85 86 func (pr *GitHubPullRequest) determineTemplate() string { 87 if len(pr.prTemplateOptions()) == 1 { 88 applySingleTemplate := commandline.AskYesNoQuestion( 89 fmt.Sprintf("Apply the pull request template from %s?", strings.TrimPrefix(pr.prTemplateOptions()[0], pr.GitRootDir+"/")), 90 ) 91 if applySingleTemplate { 92 return pr.prTemplateOptions()[0] 93 } 94 } else { 95 temp := []string{} 96 for _, str := range pr.prTemplateOptions() { 97 modifiedStr := strings.TrimPrefix(str, pr.GitRootDir+"/") 98 temp = append(temp, modifiedStr) 99 } 100 101 response := commandline.AskMultipleChoice("Choose a pull request template to be applied", append(temp, "None")) 102 103 if response != "None" { 104 return response 105 } 106 } 107 108 return "" 109 } 110 111 func (pr *GitHubPullRequest) prTemplateOptions() []string { 112 identifiers := map[string]string{ 113 "templateDir": ".github", 114 "nestedDirName": "PULL_REQUEST_TEMPLATE", 115 "nonNestedFileName": "pull_request_template", 116 } 117 118 nestedTemplates, _ := filepath.Glob( 119 filepath.Join(pr.GitRootDir, identifiers["templateDir"], identifiers["nestedDirName"], "*.md"), 120 ) 121 nonNestedTemplates, _ := filepath.Glob( 122 filepath.Join(pr.GitRootDir, identifiers["templateDir"], identifiers["nonNestedFileName"]+".md"), 123 ) 124 rootTemplates, _ := filepath.Glob(filepath.Join(pr.GitRootDir, identifiers["nonNestedFileName"]+".md")) 125 126 allTemplates := append(append(nestedTemplates, nonNestedTemplates...), rootTemplates...) 127 uniqueTemplates := make(map[string]bool) 128 for _, template := range allTemplates { 129 uniqueTemplates[template] = true 130 } 131 132 templateList := []string{} 133 for template := range uniqueTemplates { 134 templateList = append(templateList, template) 135 } 136 137 return templateList 138 } 139 140 func (pr *GitHubPullRequest) github() *github.GitHub { 141 return github.NewGitHub(pr.Debug) 142 }