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  }