Skip to content

Commit

Permalink
♻️ Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
jakubtobiasz committed May 1, 2023
1 parent 754c2a7 commit edd29c1
Show file tree
Hide file tree
Showing 14 changed files with 344 additions and 77 deletions.
33 changes: 13 additions & 20 deletions cmd/pr_merge.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,21 +79,6 @@ func (c *PrMergeCmd) RunE(cmd *cobra.Command, args []string) error {
return errors.New("⚠️ The Pull Request category must be provided")
}

mergeCategory, _ = cmd.Flags().GetString("category")

if "" == mergeCategory {
categoryPrompt := promptui.Select{
Label: "Select merge category",
Items: []string{"minor", "feature", "bugfix", "docs", "refactor", "test", "chore"},
}

_, mergeCategory, _ = categoryPrompt.Run()
}

if "" == mergeCategory {
return errors.New("⚠️ The Pull Request category must be provided")
}

mergeSubject := generator.GenerateCommitMessage(mergeCategory, pr.GetNumber(), pr.GetTitle(), pr.GetUser().GetLogin())

commits, commitsErr := c.ghClient.GetCommitsInPullRequest(pr.GetNumber())
Expand All @@ -104,10 +89,11 @@ func (c *PrMergeCmd) RunE(cmd *cobra.Command, args []string) error {
mergeBody := generator.GenerateCommitBody(pr, commits)

summaryMsg := `The pull request #%d on %s/%s will be merged with the following parameters:
- Subject: %s
- Strategy: %s
- Category: %s
- Body: %s`
Subject: %s
Strategy: %s
Category: %s
Body:
%s`
fmt.Printf(summaryMsg, pr.GetNumber(), c.ghClient.Repository.Owner(), c.ghClient.Repository.Name(), mergeSubject, mergeStrategy, mergeCategory, mergeBody)

confirmPrompt := promptui.Select{
Expand All @@ -121,7 +107,14 @@ func (c *PrMergeCmd) RunE(cmd *cobra.Command, args []string) error {
return errors.New("🛑 The pull request has not been merged")
}

mergeErr := c.ghCli.Merge(pr.GetNumber(), mergeSubject, mergeBody, mergeStrategy)
deleteBranchPrompt := promptui.Select{
Label: "Do you want to delete the branch?",
Items: []string{"yes", "no"},
}

_, deleteBranch, _ := deleteBranchPrompt.Run()

mergeErr := c.ghCli.Merge(pr.GetNumber(), mergeSubject, mergeBody, mergeStrategy, "yes" == deleteBranch)

if nil != mergeErr {
errMsg := fmt.Sprintf("🛑 The pull request #%d could not be merged. Error message: %s\r\n", pr.GetNumber(), mergeErr.Error())
Expand Down
25 changes: 25 additions & 0 deletions cmd/upmerge.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package cmd

import "github.com/spf13/cobra"

type UpmergeCmd struct {
cmd *cobra.Command
}

func (p UpmergeCmd) GetCommand() *cobra.Command {
return p.cmd
}

func NewUpmergeCmd(subcommands []Command) UpmergeCmd {
cmd := &cobra.Command{
Use: "upmerge",
Short: "Manage upmerges",
Long: `Manage upmerges`,
}

for _, subcommand := range subcommands {
cmd.AddCommand(GetCommand(subcommand))
}

return UpmergeCmd{cmd: cmd}
}
70 changes: 70 additions & 0 deletions cmd/upmerge_create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package cmd

import (
"errors"
"fmt"
"github.com/SyliusLabs/gh-kit/internal/github"
"github.com/spf13/cobra"
)

type UpmergeCreateCmd struct {
cmd *cobra.Command
ghClient *github.Client
ghCli *github.Cli
}

func (c UpmergeCreateCmd) GetCommand() *cobra.Command {
return c.cmd
}

func (c *UpmergeCreateCmd) RunE(cmd *cobra.Command, args []string) error {
base := args[0]
target := args[1]

compare, err := c.ghClient.Compare(base, target)
if nil != err {
return errors.New(fmt.Sprintf("🛑 An error occurred while comparing %s and %s: %s", base, target, err.Error()))
}

if 0 == compare.GetAheadBy() {
fmt.Printf("⚠️ The %s branch is already up to date with %s \r\n", target, base)
return nil
}

baseReference, err := c.ghClient.GetReference(fmt.Sprintf("heads/%s", base))
if nil != err {
return errors.New(fmt.Sprintf("🛑 The base reference %s does not exist", base))
}

branchName := fmt.Sprintf("upmerge/%s|%s/%s", base, target, baseReference.GetObject().GetSHA()[0:7])
err = c.ghClient.CreateReference(fmt.Sprintf("heads/%s", branchName), baseReference.GetObject().GetSHA())
if nil != err {
return errors.New(fmt.Sprintf("🛑 The upmerge branch could not be created: %s", err.Error()))
}

prTitle := fmt.Sprintf("Upmerge %s into %s", base, target)
err = c.ghCli.CreatePullRequest(prTitle, prTitle, branchName, target)
if nil != err {
return errors.New(fmt.Sprintf("🛑 The upmerge pull request could not be created: %s", err.Error()))
}

fmt.Println("✅ The upmerge pull request has been created")
return nil
}

func NewUpmergeCreateCmd(ghClient *github.Client, ghCli *github.Cli) UpmergeCreateCmd {
cmd := &cobra.Command{
Use: "create <base> <target>",
Short: "Create an upmerge pull request",
Long: `Create an upmerge pull request`,
Args: cobra.ExactArgs(2),
}

upmergeCreateCmd := new(UpmergeCreateCmd)
upmergeCreateCmd.cmd = cmd
upmergeCreateCmd.cmd.RunE = upmergeCreateCmd.RunE
upmergeCreateCmd.ghClient = ghClient
upmergeCreateCmd.ghCli = ghCli

return *upmergeCreateCmd
}
115 changes: 115 additions & 0 deletions cmd/upmerge_merge.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package cmd

import (
"errors"
"fmt"
"github.com/SyliusLabs/gh-kit/internal/extractor"
"github.com/SyliusLabs/gh-kit/internal/generator"
"github.com/SyliusLabs/gh-kit/internal/github"
"github.com/manifoldco/promptui"
"github.com/spf13/cobra"
"strconv"
)

type UpmergeMergeCmd struct {
cmd *cobra.Command
ghClient *github.Client
ghCli *github.Cli
}

func (c UpmergeMergeCmd) GetCommand() *cobra.Command {
return c.cmd
}

func (c *UpmergeMergeCmd) RunE(cmd *cobra.Command, args []string) error {
prNumber, err := strconv.Atoi(args[0])
if nil != err {
return errors.New("🛑 The pull request number is not a valid integer")
}

pr, prErr := c.ghClient.GetPullRequest(prNumber)
if nil != prErr {
errMsg := fmt.Sprintf(
"🛑 The pull request #%d on %s/%s seems to not exist",
prNumber,
c.ghClient.Repository.Owner(),
c.ghClient.Repository.Name(),
)
return errors.New(errMsg)
}

if pr.GetMerged() {
errMsg := fmt.Sprintf(
"ℹ️ The pull request #%d on %s/%s is already merged by %s\r\n",
pr.GetNumber(),
c.ghClient.Repository.Owner(),
c.ghClient.Repository.Name(),
pr.GetMergedBy().GetLogin(),
)
return errors.New(errMsg)
}

headBranch, err := extractor.ExtractBranchBaseRefFromBranchName(pr.GetHead().GetRef())
if nil != err {
return errors.New("🛑 The pull request head branch name is not valid")
}

mergeSubject := fmt.Sprintf("Merge branch %s into %s", headBranch, pr.GetBase().GetRef())

commits, commitsErr := c.ghClient.GetCommitsInPullRequest(pr.GetNumber())
if nil != commitsErr {
return errors.New("🛑 The pull request commits could not be fetched")
}

mergeBody := generator.GenerateCommitBodyForUpmerge(headBranch, commits)

summaryMsg := `The pull request #%d on %s/%s will be merged with the following parameters:
Subject: %s
Body:
%s`
fmt.Printf(summaryMsg, pr.GetNumber(), c.ghClient.Repository.Owner(), c.ghClient.Repository.Name(), mergeSubject, mergeBody)

confirmPrompt := promptui.Select{
Label: "Are you sure you want to merge it?",
Items: []string{"yes", "no"},
}

_, confirmed, _ := confirmPrompt.Run()

if "" == confirmed || "no" == confirmed {
return errors.New("🛑 The pull request has not been merged")
}

deleteBranchPrompt := promptui.Select{
Label: "Do you want to delete the intermediate branch?",
Items: []string{"yes", "no"},
}

_, deleteBranch, _ := deleteBranchPrompt.Run()

mergeErr := c.ghCli.Merge(pr.GetNumber(), mergeSubject, mergeBody, "merge", "yes" == deleteBranch)

if nil != mergeErr {
errMsg := fmt.Sprintf("🛑 The pull request #%d could not be merged. Error message: %s\r\n", pr.GetNumber(), mergeErr.Error())
return errors.New(errMsg)
}

fmt.Printf("✅ The pull request #%d on %s/%s has been merged\r\n", pr.GetNumber(), c.ghClient.Repository.Owner(), c.ghClient.Repository.Name())
return nil
}

func NewUpmergeMergeCmd(ghClient *github.Client, ghCli *github.Cli) UpmergeMergeCmd {
cmd := &cobra.Command{
Use: "merge <pull_request_number>",
Short: "Merge an upmerge",
Args: cobra.ExactArgs(1),
}

upmergeMergeCmd := new(UpmergeMergeCmd)
upmergeMergeCmd.cmd = cmd
upmergeMergeCmd.cmd.RunE = upmergeMergeCmd.RunE
upmergeMergeCmd.ghClient = ghClient
upmergeMergeCmd.ghCli = ghCli

return *upmergeMergeCmd
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ require (
github.com/cli/shurcooL-graphql v0.0.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 // indirect
github.com/henvic/httpretty v0.0.6 // indirect
github.com/inconshreveable/mousetrap v1.0.1 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ github.com/google/go-github/v49 v49.1.0 h1:LFkMgawGQ8dfzWLH/rNE0b3u1D3n6/dw7ZmrN
github.com/google/go-github/v49 v49.1.0/go.mod h1:MUUzHPrhGniB6vUKa27y37likpipzG+BXXJbG04J334=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
github.com/henvic/httpretty v0.0.6 h1:JdzGzKZBajBfnvlMALXXMVQWxWMF/ofTy8C3/OSUTxs=
Expand Down
27 changes: 27 additions & 0 deletions internal/extractor/branch_name_extractor.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package extractor

import (
"errors"
"fmt"
"regexp"
)

func ExtractBranchBaseRefFromBranchName(branchName string) (string, error) {
pattern := `upmerge/([^|]+)\|`

regex, err := regexp.Compile(pattern)
if err != nil {
fmt.Println("Error compiling regex:", err)
return "", err
}

matches := regex.FindStringSubmatch(branchName)
headBranchRef := ""
if len(matches) > 1 {
headBranchRef = matches[1]
} else {
return "", errors.New("no matches found")
}

return headBranchRef, nil
}
21 changes: 20 additions & 1 deletion internal/generator/commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package generator
import (
"fmt"
"github.com/google/go-github/v49/github"
"strings"
)

func GenerateCommitBody(pr github.PullRequest, commits []github.RepositoryCommit) string {
Expand All @@ -18,7 +19,25 @@ Commits
`, pr.GetBase().GetRef(), pr.GetBody())

for _, commit := range commits {
msg += fmt.Sprintf("\r\n%s %s", commit.GetSHA(), commit.GetCommit().GetMessage())
commitMsg := strings.Split(commit.GetCommit().GetMessage(), "\n")
firstLineOfCommitMsg := commitMsg[0]
msg += fmt.Sprintf(" %s\r\n", firstLineOfCommitMsg)
}

return msg
}

func GenerateCommitBodyForUpmerge(headBranchName string, commits []github.RepositoryCommit) string {
msg := fmt.Sprintf("* %s:\r\n", headBranchName)

for _, commit := range commits {
if len(commit.Parents) > 1 {
continue
}

commitMsg := strings.Split(commit.GetCommit().GetMessage(), "\n")
firstLineOfCommitMsg := commitMsg[0]
msg += fmt.Sprintf(" %s\r\n", firstLineOfCommitMsg)
}

return msg
Expand Down
6 changes: 5 additions & 1 deletion internal/github/cli_merge.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@ import (
"strconv"
)

func (c Cli) Merge(number int, subject string, body string, strategy string) error {
func (c Cli) Merge(number int, subject string, body string, strategy string, deleteBranch bool) error {
cmd := []string{"pr", "merge", strconv.Itoa(number), fmt.Sprintf("--%s", strategy)}

if "merge" == strategy {
cmd = append(cmd, "--subject", subject, "--body", body)
}

if deleteBranch {
cmd = append(cmd, "--delete-branch")
}

_, _, err := c.Exec(cmd...)

return err
Expand Down
Loading

0 comments on commit edd29c1

Please sign in to comment.