@@ -10,7 +10,9 @@ import (
1010 "github.com/MakeNowJust/heredoc"
1111 "github.com/cli/cli/v2/api"
1212 "github.com/cli/cli/v2/internal/gh"
13+ "github.com/cli/cli/v2/internal/ghrepo"
1314 "github.com/cli/cli/v2/pkg/cmd/pr/reviewapi"
15+ "github.com/cli/cli/v2/pkg/cmd/pr/shared"
1416 "github.com/cli/cli/v2/pkg/cmdutil"
1517 "github.com/cli/cli/v2/pkg/iostreams"
1618 "github.com/spf13/cobra"
@@ -23,8 +25,10 @@ type ReplyCommentOptions struct {
2325 HttpClient func () (* http.Client , error )
2426 Config func () (gh.Config , error )
2527
26- Org string
27- Repo string
28+ BaseRepo func () (ghrepo.Interface , error )
29+
30+ Repo ghrepo.Interface
31+ Selector string
2832 Pull int
2933 CommentID int64
3034 Body string
@@ -37,17 +41,26 @@ func NewCmdReplyComment(f *cmdutil.Factory) *cobra.Command {
3741 IO : f .IOStreams ,
3842 HttpClient : f .HttpClient ,
3943 Config : f .Config ,
44+ BaseRepo : func () (ghrepo.Interface , error ) {
45+ return f .BaseRepo ()
46+ },
4047 }
4148
4249 cmd := & cobra.Command {
43- Use : "reply-comment" ,
50+ Use : "reply-comment [<number> | <url> | <owner>/<repo>#<number>] " ,
4451 Short : "Reply to a pull request review comment" ,
4552 Long : heredoc .Doc (`
4653 Reply to an existing pull request review comment by comment identifier.
4754 ` ),
55+ Args : cobra .MaximumNArgs (1 ),
4856 RunE : func (cmd * cobra.Command , args []string ) error {
57+ if len (args ) > 0 {
58+ opts .Selector = args [0 ]
59+ }
4960 if opts .Pull <= 0 {
50- return cmdutil .FlagErrorf ("invalid value for --pr: %d" , opts .Pull )
61+ if opts .Selector == "" {
62+ return cmdutil .FlagErrorf ("must specify a pull request via --pr or as an argument" )
63+ }
5164 }
5265 if opts .CommentID <= 0 {
5366 return cmdutil .FlagErrorf ("invalid value for --comment-id: %d" , opts .CommentID )
@@ -60,30 +73,34 @@ func NewCmdReplyComment(f *cmdutil.Factory) *cobra.Command {
6073 },
6174 }
6275
63- cmd .Flags ().StringVar (& opts .Org , "org" , "" , "Organization that owns the repository" )
64- cmd .Flags ().StringVar (& opts .Repo , "repo" , "" , "Repository name" )
6576 cmd .Flags ().IntVar (& opts .Pull , "pr" , 0 , "Pull request number" )
6677 cmd .Flags ().Int64Var (& opts .CommentID , "comment-id" , 0 , "Review comment identifier to reply to" )
6778 cmd .Flags ().StringVar (& opts .Body , "body" , "" , "Reply text" )
6879 cmd .Flags ().BoolVar (& opts .AutoSubmitPending , "auto-submit-pending" , false , "Submit pending reviews before replying" )
6980 cmd .Flags ().StringVar (& opts .Hostname , "hostname" , "" , "GitHub hostname (default to authenticated host)" )
70-
71- _ = cmd .MarkFlagRequired ("org" )
72- _ = cmd .MarkFlagRequired ("repo" )
73- _ = cmd .MarkFlagRequired ("pr" )
7481 _ = cmd .MarkFlagRequired ("comment-id" )
7582 _ = cmd .MarkFlagRequired ("body" )
7683
7784 return cmd
7885}
7986
8087func runReplyComment (ctx context.Context , opts * ReplyCommentOptions ) error {
88+ repo , number , err := shared .ResolvePullRequest (opts .BaseRepo , opts .Selector , opts .Pull )
89+ if err != nil {
90+ return err
91+ }
92+ opts .Repo = repo
93+ opts .Pull = number
94+
8195 cfg , err := opts .Config ()
8296 if err != nil {
8397 return err
8498 }
8599
86- host , _ := cfg .Authentication ().DefaultHost ()
100+ host := repo .RepoHost ()
101+ if host == "" {
102+ host , _ = cfg .Authentication ().DefaultHost ()
103+ }
87104 if opts .Hostname != "" {
88105 host = opts .Hostname
89106 }
@@ -94,34 +111,36 @@ func runReplyComment(ctx context.Context, opts *ReplyCommentOptions) error {
94111 }
95112
96113 service := reviewapi .NewService (httpClient , host )
114+ owner := repo .RepoOwner ()
115+ name := repo .RepoName ()
97116
98- reply , err := service .ReplyToComment (ctx , opts . Org , opts . Repo , opts .Pull , opts .CommentID , opts .Body )
117+ reply , err := service .ReplyToComment (ctx , owner , name , opts .Pull , opts .CommentID , opts .Body )
99118 if err != nil {
100119 var pendingErr * reviewapi.PendingReviewError
101120 if errors .As (err , & pendingErr ) {
102121 if ! opts .AutoSubmitPending {
103- return fmt .Errorf ("pending review detected for %s/%s#%d. Submit the review or re-run with --auto-submit-pending, or use the GraphQL review thread mutation." , opts . Org , opts . Repo , opts .Pull )
122+ return fmt .Errorf ("pending review detected for %s/%s#%d. Submit the review or re-run with --auto-submit-pending, or use the GraphQL review thread mutation." , owner , name , opts .Pull )
104123 }
105124
106125 reviewer , loginErr := service .CurrentLogin (ctx )
107126 if loginErr != nil {
108- return formatReplyError (loginErr , opts , "failed to resolve authenticated user" )
127+ return formatReplyError (loginErr , "failed to resolve authenticated user" )
109128 }
110129
111- submitted , submitErr := service .SubmitPendingReviews (ctx , opts . Org , opts . Repo , opts .Pull , reviewer , autoSubmitSummary )
130+ submitted , submitErr := service .SubmitPendingReviews (ctx , owner , name , opts .Pull , reviewer , autoSubmitSummary )
112131 if submitErr != nil {
113- return formatReplyError (submitErr , opts , "failed to submit pending review" )
132+ return formatReplyError (submitErr , "failed to submit pending review" )
114133 }
115134 if submitted == 0 {
116135 return fmt .Errorf ("no pending reviews owned by %s found on pull request #%d" , reviewer , opts .Pull )
117136 }
118137
119- reply , err = service .ReplyToComment (ctx , opts . Org , opts . Repo , opts .Pull , opts .CommentID , opts .Body )
138+ reply , err = service .ReplyToComment (ctx , owner , name , opts .Pull , opts .CommentID , opts .Body )
120139 if err != nil {
121- return formatReplyError (err , opts , "failed to post reply after submitting pending review" )
140+ return formatReplyError (err , "failed to post reply after submitting pending review" )
122141 }
123142 } else {
124- return formatReplyError (err , opts , "failed to post reply" )
143+ return formatReplyError (err , "failed to post reply" )
125144 }
126145 }
127146
@@ -134,7 +153,7 @@ func runReplyComment(ctx context.Context, opts *ReplyCommentOptions) error {
134153 return nil
135154}
136155
137- func formatReplyError (err error , opts * ReplyCommentOptions , prefix string ) error {
156+ func formatReplyError (err error , prefix string ) error {
138157 switch e := err .(type ) {
139158 case * reviewapi.PullRequestNotFoundError :
140159 return fmt .Errorf ("%s: %w" , prefix , e )
0 commit comments