forked from cli/cli
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathclose.go
More file actions
140 lines (116 loc) · 3.75 KB
/
close.go
File metadata and controls
140 lines (116 loc) · 3.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package close
import (
"fmt"
"net/http"
"github.com/cli/cli/v2/api"
"github.com/cli/cli/v2/git"
"github.com/cli/cli/v2/pkg/cmd/pr/shared"
"github.com/cli/cli/v2/pkg/cmdutil"
"github.com/cli/cli/v2/pkg/iostreams"
"github.com/spf13/cobra"
)
type CloseOptions struct {
HttpClient func() (*http.Client, error)
IO *iostreams.IOStreams
Branch func() (string, error)
Finder shared.PRFinder
SelectorArg string
DeleteBranch bool
DeleteLocalBranch bool
}
func NewCmdClose(f *cmdutil.Factory, runF func(*CloseOptions) error) *cobra.Command {
opts := &CloseOptions{
IO: f.IOStreams,
HttpClient: f.HttpClient,
Branch: f.Branch,
}
cmd := &cobra.Command{
Use: "close {<number> | <url> | <branch>}",
Short: "Close a pull request",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
opts.Finder = shared.NewFinder(f)
if len(args) > 0 {
opts.SelectorArg = args[0]
}
opts.DeleteLocalBranch = !cmd.Flags().Changed("repo")
if runF != nil {
return runF(opts)
}
return closeRun(opts)
},
}
cmd.Flags().BoolVarP(&opts.DeleteBranch, "delete-branch", "d", false, "Delete the local and remote branch after close")
return cmd
}
func closeRun(opts *CloseOptions) error {
cs := opts.IO.ColorScheme()
findOptions := shared.FindOptions{
Selector: opts.SelectorArg,
Fields: []string{"state", "number", "title", "isCrossRepository", "headRefName"},
}
pr, baseRepo, err := opts.Finder.Find(findOptions)
if err != nil {
return err
}
if pr.State == "MERGED" {
fmt.Fprintf(opts.IO.ErrOut, "%s Pull request #%d (%s) can't be closed because it was already merged\n", cs.FailureIcon(), pr.Number, pr.Title)
return cmdutil.SilentError
} else if !pr.IsOpen() {
fmt.Fprintf(opts.IO.ErrOut, "%s Pull request #%d (%s) is already closed\n", cs.WarningIcon(), pr.Number, pr.Title)
return nil
}
httpClient, err := opts.HttpClient()
if err != nil {
return err
}
err = api.PullRequestClose(httpClient, baseRepo, pr.ID)
if err != nil {
return fmt.Errorf("API call failed: %w", err)
}
fmt.Fprintf(opts.IO.ErrOut, "%s Closed pull request #%d (%s)\n", cs.SuccessIconWithColor(cs.Red), pr.Number, pr.Title)
if opts.DeleteBranch {
branchSwitchString := ""
apiClient := api.NewClientFromHTTP(httpClient)
localBranchExists := git.HasLocalBranch(pr.HeadRefName)
if opts.DeleteLocalBranch {
if localBranchExists {
currentBranch, err := opts.Branch()
if err != nil {
return err
}
var branchToSwitchTo string
if currentBranch == pr.HeadRefName {
branchToSwitchTo, err = api.RepoDefaultBranch(apiClient, baseRepo)
if err != nil {
return err
}
err = git.CheckoutBranch(branchToSwitchTo)
if err != nil {
return err
}
}
if err := git.DeleteLocalBranch(pr.HeadRefName); err != nil {
return fmt.Errorf("failed to delete local branch %s: %w", cs.Cyan(pr.HeadRefName), err)
}
if branchToSwitchTo != "" {
branchSwitchString = fmt.Sprintf(" and switched to branch %s", cs.Cyan(branchToSwitchTo))
}
} else {
fmt.Fprintf(opts.IO.ErrOut, "%s Skipped deleting the local branch since current directory is not a git repository \n", cs.WarningIcon())
}
}
if pr.IsCrossRepository {
fmt.Fprintf(opts.IO.ErrOut, "%s Skipped deleting the remote branch of a pull request from fork\n", cs.WarningIcon())
if !opts.DeleteLocalBranch {
return nil
}
} else {
if err := api.BranchDeleteRemote(apiClient, baseRepo, pr.HeadRefName); err != nil {
return fmt.Errorf("failed to delete remote branch %s: %w", cs.Cyan(pr.HeadRefName), err)
}
}
fmt.Fprintf(opts.IO.ErrOut, "%s Deleted branch %s%s\n", cs.SuccessIconWithColor(cs.Red), cs.Cyan(pr.HeadRefName), branchSwitchString)
}
return nil
}