github.com/emmahsax/go-git-helper@v0.0.8-0.20240519163017-907b9de0fa52/internal/gitlabMergeRequest/gitlabMergeRequest.go (about)

     1  package gitlabMergeRequest
     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/gitlab"
    13  	"github.com/emmahsax/go-git-helper/internal/utils"
    14  	go_github "github.com/xanzy/go-gitlab"
    15  )
    16  
    17  type GitLabMergeRequest struct {
    18  	BaseBranch   string
    19  	Debug        bool
    20  	GitRootDir   string
    21  	LocalBranch  string
    22  	Draft        string
    23  	LocalProject string
    24  	NewMrTitle   string
    25  }
    26  
    27  func NewGitLabMergeRequest(options map[string]string, debug bool) *GitLabMergeRequest {
    28  	return &GitLabMergeRequest{
    29  		BaseBranch:   options["baseBranch"],
    30  		Debug:        debug,
    31  		Draft:        options["draft"],
    32  		GitRootDir:   options["gitRootDir"],
    33  		LocalBranch:  options["localBranch"],
    34  		LocalProject: options["localProject"],
    35  		NewMrTitle:   options["newMrTitle"],
    36  	}
    37  }
    38  
    39  func (mr *GitLabMergeRequest) Create() {
    40  	t := mr.determineTitle()
    41  
    42  	options := go_github.CreateMergeRequestOptions{
    43  		Description:        go_github.Ptr(mr.newMrBody()),
    44  		RemoveSourceBranch: go_github.Ptr(true),
    45  		SourceBranch:       go_github.Ptr(mr.LocalBranch),
    46  		Squash:             go_github.Ptr(true),
    47  		TargetBranch:       go_github.Ptr(mr.BaseBranch),
    48  		Title:              go_github.Ptr(t),
    49  	}
    50  
    51  	fmt.Println("Creating merge request:", t)
    52  	resp, err := mr.gitlab().CreateMergeRequest(mr.LocalProject, &options)
    53  	if err != nil {
    54  		customErr := errors.New("could not create merge request: " + err.Error())
    55  		utils.HandleError(customErr, mr.Debug, nil)
    56  		return
    57  	}
    58  
    59  	fmt.Println("Merge request successfully created:", resp.WebURL)
    60  }
    61  
    62  func (mr *GitLabMergeRequest) determineTitle() string {
    63  	var t string
    64  	if d, _ := strconv.ParseBool(mr.Draft); d {
    65  		t = "Draft: " + mr.NewMrTitle
    66  	} else {
    67  		t = mr.NewMrTitle
    68  	}
    69  
    70  	return t
    71  }
    72  
    73  func (mr *GitLabMergeRequest) newMrBody() string {
    74  	templateName := mr.templateNameToApply()
    75  	if templateName != "" {
    76  		content, err := os.ReadFile(templateName)
    77  		if err != nil {
    78  			utils.HandleError(err, mr.Debug, nil)
    79  			return ""
    80  		}
    81  
    82  		return string(content)
    83  	}
    84  	return ""
    85  }
    86  
    87  func (mr *GitLabMergeRequest) templateNameToApply() string {
    88  	templateName := ""
    89  	if len(mr.mrTemplateOptions()) > 0 {
    90  		templateName = mr.determineTemplate()
    91  	}
    92  
    93  	return templateName
    94  }
    95  
    96  func (mr *GitLabMergeRequest) determineTemplate() string {
    97  	if len(mr.mrTemplateOptions()) == 1 {
    98  		applySingleTemplate := commandline.AskYesNoQuestion(
    99  			fmt.Sprintf("Apply the merge request template from %s?", strings.TrimPrefix(mr.mrTemplateOptions()[0], mr.GitRootDir+"/")),
   100  		)
   101  		if applySingleTemplate {
   102  			return mr.mrTemplateOptions()[0]
   103  		}
   104  	} else {
   105  		temp := []string{}
   106  		for _, str := range mr.mrTemplateOptions() {
   107  			modifiedStr := strings.TrimPrefix(str, mr.GitRootDir+"/")
   108  			temp = append(temp, modifiedStr)
   109  		}
   110  
   111  		response := commandline.AskMultipleChoice("Choose a merge request template to be applied", append(temp, "None"))
   112  
   113  		if response != "None" {
   114  			return response
   115  		}
   116  	}
   117  
   118  	return ""
   119  }
   120  
   121  func (mr *GitLabMergeRequest) mrTemplateOptions() []string {
   122  	identifiers := map[string]string{
   123  		"templateDir":       ".gitlab",
   124  		"nestedDirName":     "merge_request_templates",
   125  		"nonNestedFileName": "merge_request_template",
   126  	}
   127  
   128  	nestedTemplates, _ := filepath.Glob(
   129  		filepath.Join(mr.GitRootDir, identifiers["templateDir"], identifiers["nestedDirName"], "*.md"),
   130  	)
   131  	nonNestedTemplates, _ := filepath.Glob(
   132  		filepath.Join(mr.GitRootDir, identifiers["templateDir"], identifiers["nonNestedFileName"]+".md"),
   133  	)
   134  	rootTemplates, _ := filepath.Glob(filepath.Join(mr.GitRootDir, identifiers["nonNestedFileName"]+".md"))
   135  
   136  	allTemplates := append(append(nestedTemplates, nonNestedTemplates...), rootTemplates...)
   137  	uniqueTemplates := make(map[string]bool)
   138  	for _, template := range allTemplates {
   139  		uniqueTemplates[template] = true
   140  	}
   141  
   142  	templateList := []string{}
   143  	for template := range uniqueTemplates {
   144  		templateList = append(templateList, template)
   145  	}
   146  
   147  	return templateList
   148  }
   149  
   150  func (mr *GitLabMergeRequest) gitlab() *gitlab.GitLab {
   151  	return gitlab.NewGitLab(mr.Debug)
   152  }