mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-03-27 22:01:46 +02:00
Implement pull request options menu
This commit is contained in:
parent
f2645da16a
commit
0e6598adbd
@ -37,24 +37,39 @@ func NewService(typeName string, repositoryDomain string, siteDomain string) *Se
|
|||||||
service = &Service{
|
service = &Service{
|
||||||
Name: repositoryDomain,
|
Name: repositoryDomain,
|
||||||
PullRequestURL: func(owner string, repository string, from string, to string) string {
|
PullRequestURL: func(owner string, repository string, from string, to string) string {
|
||||||
urlFormat := fmt.Sprintf("https://%s%s", siteDomain, "/%s/%s/compare/%s?expand=1")
|
if to == "" {
|
||||||
return fmt.Sprintf(urlFormat, owner, repository, from)
|
urlFormat := fmt.Sprintf("https://%s%s", siteDomain, "/%s/%s/compare/%s?expand=1")
|
||||||
|
return fmt.Sprintf(urlFormat, owner, repository, from)
|
||||||
|
} else {
|
||||||
|
urlFormat := fmt.Sprintf("https://%s%s", siteDomain, "/%s/%s/compare/%s...%s?expand=1")
|
||||||
|
return fmt.Sprintf(urlFormat, owner, repository, to, from)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
case "bitbucket":
|
case "bitbucket":
|
||||||
service = &Service{
|
service = &Service{
|
||||||
Name: repositoryDomain,
|
Name: repositoryDomain,
|
||||||
PullRequestURL: func(owner string, repository string, from string, to string) string {
|
PullRequestURL: func(owner string, repository string, from string, to string) string {
|
||||||
urlFormat := fmt.Sprintf("https://%s%s", siteDomain, "/%s/%s/pull-requests/new?source=%s&t=1")
|
if to == "" {
|
||||||
return fmt.Sprintf(urlFormat, owner, repository, from)
|
urlFormat := fmt.Sprintf("https://%s%s", siteDomain, "/%s/%s/pull-requests/new?source=%s&t=1")
|
||||||
|
return fmt.Sprintf(urlFormat, owner, repository, from)
|
||||||
|
} else {
|
||||||
|
urlFormat := fmt.Sprintf("https://%s%s", siteDomain, "/%s/%s/pull-requests/new?source=%s&dest=%s&t=1")
|
||||||
|
return fmt.Sprintf(urlFormat, owner, repository, from, to)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
case "gitlab":
|
case "gitlab":
|
||||||
service = &Service{
|
service = &Service{
|
||||||
Name: repositoryDomain,
|
Name: repositoryDomain,
|
||||||
PullRequestURL: func(owner string, repository string, from string, to string) string {
|
PullRequestURL: func(owner string, repository string, from string, to string) string {
|
||||||
urlFormat := fmt.Sprintf("https://%s%s", siteDomain, "/%s/%s/merge_requests/new?merge_request[source_branch]=%s")
|
if to == "" {
|
||||||
return fmt.Sprintf(urlFormat, owner, repository, from)
|
urlFormat := fmt.Sprintf("https://%s%s", siteDomain, "/%s/%s/merge_requests/new?merge_request[source_branch]=%s")
|
||||||
|
return fmt.Sprintf(urlFormat, owner, repository, from)
|
||||||
|
} else {
|
||||||
|
urlFormat := fmt.Sprintf("https://%s%s", siteDomain, "/%s/%s/merge_requests/new?merge_request[source_branch]=%s&merge_request[target_branch]=%s")
|
||||||
|
return fmt.Sprintf(urlFormat, owner, repository, from, to)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -99,8 +114,8 @@ func NewPullRequest(gitCommand *GitCommand) *PullRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create opens link to new pull request in browser
|
// Create opens link to new pull request in browser
|
||||||
func (pr *PullRequest) Create(branch *models.Branch) (string, error) {
|
func (pr *PullRequest) Create(from *models.Branch, to *models.Branch) (string, error) {
|
||||||
pullRequestURL, err := pr.getPullRequestURL(branch)
|
pullRequestURL, err := pr.getPullRequestURL(from, to)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@ -109,8 +124,8 @@ func (pr *PullRequest) Create(branch *models.Branch) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CopyURL copies the pull request URL to the clipboard
|
// CopyURL copies the pull request URL to the clipboard
|
||||||
func (pr *PullRequest) CopyURL(branch *models.Branch) (string, error) {
|
func (pr *PullRequest) CopyURL(from *models.Branch, to *models.Branch) (string, error) {
|
||||||
pullRequestURL, err := pr.getPullRequestURL(branch)
|
pullRequestURL, err := pr.getPullRequestURL(from, to)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@ -118,8 +133,8 @@ func (pr *PullRequest) CopyURL(branch *models.Branch) (string, error) {
|
|||||||
return pullRequestURL, pr.GitCommand.OSCommand.CopyToClipboard(pullRequestURL)
|
return pullRequestURL, pr.GitCommand.OSCommand.CopyToClipboard(pullRequestURL)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pr *PullRequest) getPullRequestURL(branch *models.Branch) (string, error) {
|
func (pr *PullRequest) getPullRequestURL(from *models.Branch, to *models.Branch) (string, error) {
|
||||||
branchExistsOnRemote := pr.GitCommand.CheckRemoteBranchExists(branch)
|
branchExistsOnRemote := pr.GitCommand.CheckRemoteBranchExists(from)
|
||||||
|
|
||||||
if !branchExistsOnRemote {
|
if !branchExistsOnRemote {
|
||||||
return "", errors.New(pr.GitCommand.Tr.NoBranchOnRemote)
|
return "", errors.New(pr.GitCommand.Tr.NoBranchOnRemote)
|
||||||
@ -140,7 +155,13 @@ func (pr *PullRequest) getPullRequestURL(branch *models.Branch) (string, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
repoInfo := getRepoInfoFromURL(repoURL)
|
repoInfo := getRepoInfoFromURL(repoURL)
|
||||||
pullRequestURL := gitService.PullRequestURL(repoInfo.Owner, repoInfo.Repository, branch.Name, "")
|
var toBranchName string
|
||||||
|
if to == nil {
|
||||||
|
toBranchName = ""
|
||||||
|
} else {
|
||||||
|
toBranchName = to.Name
|
||||||
|
}
|
||||||
|
pullRequestURL := gitService.PullRequestURL(repoInfo.Owner, repoInfo.Repository, from.Name, toBranchName)
|
||||||
|
|
||||||
return pullRequestURL, nil
|
return pullRequestURL, nil
|
||||||
}
|
}
|
||||||
|
@ -193,6 +193,7 @@ type KeybindingFilesConfig struct {
|
|||||||
|
|
||||||
type KeybindingBranchesConfig struct {
|
type KeybindingBranchesConfig struct {
|
||||||
CreatePullRequest string `yaml:"createPullRequest"`
|
CreatePullRequest string `yaml:"createPullRequest"`
|
||||||
|
ViewPullRequestOptions string `yaml:"viewPullRequestOptions"`
|
||||||
CopyPullRequestURL string `yaml:"copyPullRequestURL"`
|
CopyPullRequestURL string `yaml:"copyPullRequestURL"`
|
||||||
CheckoutBranchByName string `yaml:"checkoutBranchByName"`
|
CheckoutBranchByName string `yaml:"checkoutBranchByName"`
|
||||||
ForceCheckoutBranch string `yaml:"forceCheckoutBranch"`
|
ForceCheckoutBranch string `yaml:"forceCheckoutBranch"`
|
||||||
@ -437,6 +438,7 @@ func GetDefaultConfig() *UserConfig {
|
|||||||
Branches: KeybindingBranchesConfig{
|
Branches: KeybindingBranchesConfig{
|
||||||
CopyPullRequestURL: "<c-y>",
|
CopyPullRequestURL: "<c-y>",
|
||||||
CreatePullRequest: "o",
|
CreatePullRequest: "o",
|
||||||
|
ViewPullRequestOptions: "O",
|
||||||
CheckoutBranchByName: "c",
|
CheckoutBranchByName: "c",
|
||||||
ForceCheckoutBranch: "F",
|
ForceCheckoutBranch: "F",
|
||||||
RebaseBranch: "r",
|
RebaseBranch: "r",
|
||||||
|
@ -91,23 +91,25 @@ func (gui *Gui) handleBranchPress() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleCreatePullRequestPress() error {
|
func (gui *Gui) handleCreatePullRequestPress() error {
|
||||||
pullRequest := commands.NewPullRequest(gui.GitCommand)
|
|
||||||
|
|
||||||
branch := gui.getSelectedBranch()
|
branch := gui.getSelectedBranch()
|
||||||
url, err := pullRequest.Create(branch)
|
return createPullRequest(branch, nil, gui)
|
||||||
if err != nil {
|
}
|
||||||
return gui.surfaceError(err)
|
|
||||||
}
|
|
||||||
gui.OnRunCommand(oscommands.NewCmdLogEntry(fmt.Sprintf("Creating pull request at URL: %s", url), "Create pull request", false))
|
|
||||||
|
|
||||||
return nil
|
func (gui *Gui) handleCreatePullRequestMenu() error {
|
||||||
|
selectedBranch := gui.getSelectedBranch()
|
||||||
|
if selectedBranch == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
checkedOutBranch := gui.getCheckedOutBranch()
|
||||||
|
|
||||||
|
return gui.createPullRequestMenu(selectedBranch, checkedOutBranch)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleCopyPullRequestURLPress() error {
|
func (gui *Gui) handleCopyPullRequestURLPress() error {
|
||||||
pullRequest := commands.NewPullRequest(gui.GitCommand)
|
pullRequest := commands.NewPullRequest(gui.GitCommand)
|
||||||
|
|
||||||
branch := gui.getSelectedBranch()
|
branch := gui.getSelectedBranch()
|
||||||
url, err := pullRequest.CopyURL(branch)
|
url, err := pullRequest.CopyURL(branch, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return gui.surfaceError(err)
|
return gui.surfaceError(err)
|
||||||
}
|
}
|
||||||
|
@ -545,6 +545,13 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
|
|||||||
Handler: gui.handleCreatePullRequestPress,
|
Handler: gui.handleCreatePullRequestPress,
|
||||||
Description: gui.Tr.LcCreatePullRequest,
|
Description: gui.Tr.LcCreatePullRequest,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
ViewName: "branches",
|
||||||
|
Contexts: []string{string(LOCAL_BRANCHES_CONTEXT_KEY)},
|
||||||
|
Key: gui.getKey(config.Branches.ViewPullRequestOptions),
|
||||||
|
Handler: gui.handleCreatePullRequestMenu,
|
||||||
|
Description: gui.Tr.LcCreatePullRequest,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
ViewName: "branches",
|
ViewName: "branches",
|
||||||
Contexts: []string{string(LOCAL_BRANCHES_CONTEXT_KEY)},
|
Contexts: []string{string(LOCAL_BRANCHES_CONTEXT_KEY)},
|
||||||
|
52
pkg/gui/pull_request_menu_panel.go
Normal file
52
pkg/gui/pull_request_menu_panel.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package gui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/commands"
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (gui *Gui) createPullRequestMenu(selectedBranch *models.Branch, checkedOutBranch *models.Branch) error {
|
||||||
|
menuItems := make([]*menuItem, 0, 2)
|
||||||
|
|
||||||
|
if selectedBranch != checkedOutBranch {
|
||||||
|
menuItems = append(menuItems, &menuItem{
|
||||||
|
displayStrings: []string{
|
||||||
|
fmt.Sprintf("%s -> default branch", selectedBranch.Name),
|
||||||
|
},
|
||||||
|
onPress: func() error {
|
||||||
|
return createPullRequest(selectedBranch, nil, gui)
|
||||||
|
},
|
||||||
|
}, &menuItem{
|
||||||
|
displayStrings: []string{
|
||||||
|
fmt.Sprintf("%s -> %s", checkedOutBranch.Name, selectedBranch.Name),
|
||||||
|
},
|
||||||
|
onPress: func() error {
|
||||||
|
return createPullRequest(checkedOutBranch, selectedBranch, gui)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
menuItems = append(menuItems, &menuItem{
|
||||||
|
displayStrings: []string{
|
||||||
|
fmt.Sprintf("%s -> default branch", checkedOutBranch.Name),
|
||||||
|
},
|
||||||
|
onPress: func() error {
|
||||||
|
return createPullRequest(checkedOutBranch, nil, gui)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
return gui.createMenu(fmt.Sprintf(gui.Tr.CreatePullRequest), menuItems, createMenuOptions{showCancel: true})
|
||||||
|
}
|
||||||
|
|
||||||
|
func createPullRequest(checkedOutBranch *models.Branch, selectedBranch *models.Branch, gui *Gui) error {
|
||||||
|
pullRequest := commands.NewPullRequest(gui.GitCommand)
|
||||||
|
url, err := pullRequest.Create(checkedOutBranch, selectedBranch)
|
||||||
|
if err != nil {
|
||||||
|
return gui.surfaceError(err)
|
||||||
|
}
|
||||||
|
gui.OnRunCommand(oscommands.NewCmdLogEntry(fmt.Sprintf("Creating pull request at URL: %s", url), "Create pull request", false))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
@ -454,6 +454,7 @@ type TranslationSet struct {
|
|||||||
ToggleWhitespaceInDiffView string
|
ToggleWhitespaceInDiffView string
|
||||||
IgnoringWhitespaceInDiffView string
|
IgnoringWhitespaceInDiffView string
|
||||||
ShowingWhitespaceInDiffView string
|
ShowingWhitespaceInDiffView string
|
||||||
|
CreatePullRequest string
|
||||||
Spans Spans
|
Spans Spans
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1001,6 +1002,7 @@ func englishTranslationSet() TranslationSet {
|
|||||||
ToggleWhitespaceInDiffView: "Toggle whether or not whitespace changes are shown in the diff view",
|
ToggleWhitespaceInDiffView: "Toggle whether or not whitespace changes are shown in the diff view",
|
||||||
IgnoringWhitespaceInDiffView: "Whitespace will be ignored in the diff view",
|
IgnoringWhitespaceInDiffView: "Whitespace will be ignored in the diff view",
|
||||||
ShowingWhitespaceInDiffView: "Whitespace will be shown in the diff view",
|
ShowingWhitespaceInDiffView: "Whitespace will be shown in the diff view",
|
||||||
|
CreatePullRequest: "Create pull request",
|
||||||
Spans: Spans{
|
Spans: Spans{
|
||||||
// TODO: combine this with the original keybinding descriptions (those are all in lowercase atm)
|
// TODO: combine this with the original keybinding descriptions (those are all in lowercase atm)
|
||||||
CheckoutCommit: "Checkout commit",
|
CheckoutCommit: "Checkout commit",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user