-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
754c2a7
commit edd29c1
Showing
14 changed files
with
344 additions
and
77 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.