Skip to content

Commit 948088a

Browse files
authored
Merge pull request cli#2776 from cli/pr-comments
Comment on pull requests
2 parents 10b1314 + a70b69e commit 948088a

File tree

9 files changed

+607
-219
lines changed

9 files changed

+607
-219
lines changed

api/queries_issue.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,3 +481,11 @@ func milestoneNodeIdToDatabaseId(nodeId string) (string, error) {
481481
}
482482
return splitted[1], nil
483483
}
484+
485+
func (i Issue) Link() string {
486+
return i.URL
487+
}
488+
489+
func (i Issue) Identifier() string {
490+
return i.ID
491+
}

api/queries_pr.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,14 @@ func (pr PullRequest) HeadLabel() string {
136136
return pr.HeadRefName
137137
}
138138

139+
func (pr PullRequest) Link() string {
140+
return pr.URL
141+
}
142+
143+
func (pr PullRequest) Identifier() string {
144+
return pr.ID
145+
}
146+
139147
type PullRequestReviewStatus struct {
140148
ChangesRequested bool
141149
Approved bool

pkg/cmd/issue/comment/comment.go

Lines changed: 28 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -1,200 +1,69 @@
11
package comment
22

33
import (
4-
"errors"
5-
"fmt"
64
"net/http"
75

8-
"github.com/AlecAivazis/survey/v2"
96
"github.com/MakeNowJust/heredoc"
107
"github.com/cli/cli/api"
11-
"github.com/cli/cli/internal/config"
128
"github.com/cli/cli/internal/ghrepo"
13-
"github.com/cli/cli/pkg/cmd/issue/shared"
9+
issueShared "github.com/cli/cli/pkg/cmd/issue/shared"
10+
prShared "github.com/cli/cli/pkg/cmd/pr/shared"
1411
"github.com/cli/cli/pkg/cmdutil"
15-
"github.com/cli/cli/pkg/iostreams"
16-
"github.com/cli/cli/pkg/surveyext"
1712
"github.com/cli/cli/utils"
1813
"github.com/spf13/cobra"
1914
)
2015

21-
type CommentOptions struct {
22-
HttpClient func() (*http.Client, error)
23-
IO *iostreams.IOStreams
24-
BaseRepo func() (ghrepo.Interface, error)
25-
EditSurvey func() (string, error)
26-
InputTypeSurvey func() (inputType, error)
27-
ConfirmSubmitSurvey func() (bool, error)
28-
OpenInBrowser func(string) error
29-
30-
SelectorArg string
31-
Interactive bool
32-
InputType inputType
33-
Body string
34-
}
35-
36-
type inputType int
37-
38-
const (
39-
inputTypeEditor inputType = iota
40-
inputTypeInline
41-
inputTypeWeb
42-
)
43-
44-
func NewCmdComment(f *cmdutil.Factory, runF func(*CommentOptions) error) *cobra.Command {
45-
opts := &CommentOptions{
46-
IO: f.IOStreams,
47-
HttpClient: f.HttpClient,
48-
EditSurvey: editSurvey(f.Config, f.IOStreams),
49-
InputTypeSurvey: inputTypeSurvey,
50-
ConfirmSubmitSurvey: confirmSubmitSurvey,
51-
OpenInBrowser: utils.OpenInBrowser,
16+
func NewCmdComment(f *cmdutil.Factory, runF func(*prShared.CommentableOptions) error) *cobra.Command {
17+
opts := &prShared.CommentableOptions{
18+
IO: f.IOStreams,
19+
HttpClient: f.HttpClient,
20+
EditSurvey: prShared.CommentableEditSurvey(f.Config, f.IOStreams),
21+
InteractiveEditSurvey: prShared.CommentableInteractiveEditSurvey(f.Config, f.IOStreams),
22+
ConfirmSubmitSurvey: prShared.CommentableConfirmSubmitSurvey,
23+
OpenInBrowser: utils.OpenInBrowser,
5224
}
5325

54-
var webMode bool
55-
var editorMode bool
56-
5726
cmd := &cobra.Command{
5827
Use: "comment {<number> | <url>}",
5928
Short: "Create a new issue comment",
6029
Example: heredoc.Doc(`
6130
$ gh issue comment 22 --body "I was able to reproduce this issue, lets fix it."
6231
`),
6332
Args: cobra.ExactArgs(1),
64-
RunE: func(cmd *cobra.Command, args []string) error {
65-
// support `-R, --repo` override
66-
opts.BaseRepo = f.BaseRepo
67-
opts.SelectorArg = args[0]
68-
69-
inputFlags := 0
70-
if cmd.Flags().Changed("body") {
71-
opts.InputType = inputTypeInline
72-
inputFlags++
73-
}
74-
if webMode {
75-
opts.InputType = inputTypeWeb
76-
inputFlags++
77-
}
78-
if editorMode {
79-
opts.InputType = inputTypeEditor
80-
inputFlags++
81-
}
82-
83-
if inputFlags == 0 {
84-
if !opts.IO.CanPrompt() {
85-
return &cmdutil.FlagError{Err: errors.New("--body or --web required when not running interactively")}
86-
}
87-
opts.Interactive = true
88-
} else if inputFlags == 1 {
89-
if !opts.IO.CanPrompt() && opts.InputType == inputTypeEditor {
90-
return &cmdutil.FlagError{Err: errors.New("--body or --web required when not running interactively")}
91-
}
92-
} else if inputFlags > 1 {
93-
return &cmdutil.FlagError{Err: fmt.Errorf("specify only one of --body, --editor, or --web")}
94-
}
95-
33+
PreRunE: func(cmd *cobra.Command, args []string) error {
34+
opts.RetrieveCommentable = retrieveIssue(f.HttpClient, f.BaseRepo, args[0])
35+
return prShared.CommentablePreRun(cmd, opts)
36+
},
37+
RunE: func(_ *cobra.Command, args []string) error {
9638
if runF != nil {
9739
return runF(opts)
9840
}
99-
return commentRun(opts)
41+
return prShared.CommentableRun(opts)
10042
},
10143
}
10244

10345
cmd.Flags().StringVarP(&opts.Body, "body", "b", "", "Supply a body. Will prompt for one otherwise.")
104-
cmd.Flags().BoolVarP(&editorMode, "editor", "e", false, "Add body using editor")
105-
cmd.Flags().BoolVarP(&webMode, "web", "w", false, "Add body in browser")
46+
cmd.Flags().BoolP("editor", "e", false, "Add body using editor")
47+
cmd.Flags().BoolP("web", "w", false, "Add body in browser")
10648

10749
return cmd
10850
}
10951

110-
func commentRun(opts *CommentOptions) error {
111-
httpClient, err := opts.HttpClient()
112-
if err != nil {
113-
return err
114-
}
115-
apiClient := api.NewClientFromHTTP(httpClient)
116-
117-
issue, baseRepo, err := shared.IssueFromArg(apiClient, opts.BaseRepo, opts.SelectorArg)
118-
if err != nil {
119-
return err
120-
}
121-
122-
if opts.Interactive {
123-
inputType, err := opts.InputTypeSurvey()
52+
func retrieveIssue(httpClient func() (*http.Client, error),
53+
baseRepo func() (ghrepo.Interface, error),
54+
selector string) func() (prShared.Commentable, ghrepo.Interface, error) {
55+
return func() (prShared.Commentable, ghrepo.Interface, error) {
56+
httpClient, err := httpClient()
12457
if err != nil {
125-
return err
58+
return nil, nil, err
12659
}
127-
opts.InputType = inputType
128-
}
60+
apiClient := api.NewClientFromHTTP(httpClient)
12961

130-
switch opts.InputType {
131-
case inputTypeWeb:
132-
openURL := issue.URL + "#issuecomment-new"
133-
if opts.IO.IsStdoutTTY() {
134-
fmt.Fprintf(opts.IO.ErrOut, "Opening %s in your browser.\n", utils.DisplayURL(openURL))
135-
}
136-
return opts.OpenInBrowser(openURL)
137-
case inputTypeEditor:
138-
body, err := opts.EditSurvey()
62+
issue, repo, err := issueShared.IssueFromArg(apiClient, baseRepo, selector)
13963
if err != nil {
140-
return err
64+
return nil, nil, err
14165
}
142-
opts.Body = body
143-
}
144-
145-
if opts.Interactive {
146-
cont, err := opts.ConfirmSubmitSurvey()
147-
if err != nil {
148-
return err
149-
}
150-
if !cont {
151-
return fmt.Errorf("Discarding...")
152-
}
153-
}
154-
155-
params := api.CommentCreateInput{Body: opts.Body, SubjectId: issue.ID}
156-
url, err := api.CommentCreate(apiClient, baseRepo.RepoHost(), params)
157-
if err != nil {
158-
return err
159-
}
160-
fmt.Fprintln(opts.IO.Out, url)
161-
return nil
162-
}
163-
164-
var inputTypeSurvey = func() (inputType, error) {
165-
var result int
166-
inputTypeQuestion := &survey.Select{
167-
Message: "Where do you want to draft your comment?",
168-
Options: []string{"Editor", "Web"},
169-
}
170-
err := survey.AskOne(inputTypeQuestion, &result)
171-
if err != nil {
172-
return 0, err
173-
}
174-
175-
if result == 0 {
176-
return inputTypeEditor, nil
177-
} else {
178-
return inputTypeWeb, nil
179-
}
180-
}
18166

182-
var confirmSubmitSurvey = func() (bool, error) {
183-
var confirm bool
184-
submit := &survey.Confirm{
185-
Message: "Submit?",
186-
Default: true,
187-
}
188-
err := survey.AskOne(submit, &confirm)
189-
return confirm, err
190-
}
191-
192-
var editSurvey = func(cf func() (config.Config, error), io *iostreams.IOStreams) func() (string, error) {
193-
return func() (string, error) {
194-
editorCommand, err := cmdutil.DetermineEditor(cf)
195-
if err != nil {
196-
return "", err
197-
}
198-
return surveyext.Edit(editorCommand, "*.md", "", io.In, io.Out, io.ErrOut, nil)
67+
return issue, repo, nil
19968
}
20069
}

0 commit comments

Comments
 (0)