Skip to content
18 changes: 18 additions & 0 deletions api/queries_pr.go
Original file line number Diff line number Diff line change
Expand Up @@ -944,6 +944,24 @@ func PullRequestClose(client *Client, repo ghrepo.Interface, pr *PullRequest) er
return err
}

func PullRequestComment(client *Client, repo ghrepo.Interface, pr *PullRequest) error {
var mutation struct {
AddComment struct {
ClientMutationID string
} `graphql:"addComment(input: $input)"`
}

input := githubv4.AddCommentInput{
SubjectID: pr.ID,
Body: githubv4.String(pr.Body),
}

v4 := githubv4.NewClient(client.http)
err := v4.Mutate(context.Background(), &mutation, input, nil)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great, I'm glad you used the githubv4 pattern instead of our old string-based graphql pattern!


return err
}

func PullRequestReopen(client *Client, repo ghrepo.Interface, pr *PullRequest) error {
var mutation struct {
ReopenPullRequest struct {
Expand Down
79 changes: 79 additions & 0 deletions command/pr.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package command

import (
"bufio"
"errors"
"fmt"
"io"
"os"
"regexp"
"sort"
"strconv"
Expand Down Expand Up @@ -322,6 +324,73 @@ func prView(cmd *cobra.Command, args []string) error {
}
}

// WaitForData Simulate key press on comment input
func WaitForData(in *os.File) string {
if in == nil {
in = os.Stdin
}

if EnabledTestingModeforComment {
in = TemporariFileforKeyPress
}
Body := ""
fmt.Println("Body comment (optional).")
fmt.Println("Let empty to skip or type EXIT at end.")

reader := bufio.NewReader(in)

var texto string
texto = ""
for {
fmt.Print("-> ")
text, _ := reader.ReadString('\n')
if strings.Compare("\n", text) == 0 && strings.Compare("", texto) == 0 {
break
}
if strings.Compare("EXIT\n", text) == 0 {
fmt.Println(texto)
for {
fmt.Println("Hit ENTER, to confirm or CANCEL, to cancel")
text, _ = reader.ReadString('\n')
if strings.Compare("\n", text) == 0 {
Body = texto
break
}
if strings.Compare("CANCEL\n", text) == 0 {
Body = ""
texto = ""
text = ""
fmt.Println("Comment cancelled.")
fmt.Println("Body comment (optional).")
fmt.Println("Let empty to skip or type EXIT at end.")
break
}
}
}
texto += text
if strings.Compare("", Body) != 0 {
break
}
}
return Body
}

func prComment(cmd *cobra.Command, args []string, apiClient *api.Client, pr *api.PullRequest, baseRepo ghrepo.Interface) error {

tmpbody := WaitForData(nil)

if tmpbody != "" {
pr.Body = tmpbody
err := api.PullRequestComment(apiClient, baseRepo, pr)
if err != nil {
return fmt.Errorf("API call failed: %w", err)
}
fmt.Fprintf(colorableErr(cmd), "%s Commented on pull request #%d\n", utils.Green("✔"), pr.Number)
}

return nil
}

func prClose(cmd *cobra.Command, args []string) error {
ctx := contextForCommand(cmd)
apiClient, err := apiClientForContext(ctx)
Expand All @@ -342,6 +411,11 @@ func prClose(cmd *cobra.Command, args []string) error {
return nil
}

err = prComment(cmd, args, apiClient, pr, baseRepo) // Ask user for comment (optional)
if err != nil {
return fmt.Errorf("Error on add comment: %w", err)
}

err = api.PullRequestClose(apiClient, baseRepo, pr)
if err != nil {
return fmt.Errorf("API call failed: %w", err)
Expand Down Expand Up @@ -374,6 +448,11 @@ func prReopen(cmd *cobra.Command, args []string) error {
return nil
}

err = prComment(cmd, args, apiClient, pr, baseRepo) // Ask user for comment (optional)
if err != nil {
return fmt.Errorf("Error on add comment: %w", err)
}

err = api.PullRequestReopen(apiClient, baseRepo, pr)
if err != nil {
return fmt.Errorf("API call failed: %w", err)
Expand Down
35 changes: 35 additions & 0 deletions command/pr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -860,9 +860,26 @@ func TestPrClose(t *testing.T) {

http.StubResponse(200, bytes.NewBufferString(`{"id": "THE-ID"}`))

//Sending empty line to skip comments, if you want to create a comment use "EXIT\n\n"
err := EnableTestingModeforComment()
if err != nil {
t.Fatalf("error on EnableTestingModeforComment :%v", err)
}

err = SimulateUserInput("\n")
if err != nil {
t.Fatalf("error on SimulateUserInput :%v", err)
}

output, err := RunCommand("pr close 96")
if err != nil {
t.Fatalf("error running command `pr close`: %v", err)

}
//Disabling Testing mode Comment
err = DisableTestingModeforComment()
if err != nil {
t.Fatalf("error on DisableTestingModeforComment :%v", err)
}

r := regexp.MustCompile(`Closed pull request #96`)
Expand Down Expand Up @@ -910,11 +927,29 @@ func TestPRReopen(t *testing.T) {

http.StubResponse(200, bytes.NewBufferString(`{"id": "THE-ID"}`))

//Sending empty line to skip comments, if you want to create a comment use "EXIT\n\n"
err := EnableTestingModeforComment()
if err != nil {
t.Fatalf("error on EnableTestingModeforComment :%v", err)
}

err = SimulateUserInput("\n")

if err != nil {
t.Fatalf("error on SimulateUserInput :%v", err)
}

output, err := RunCommand("pr reopen 666")
if err != nil {
t.Fatalf("error running command `pr reopen`: %v", err)
}

//Disabling Testing mode Comment
err = DisableTestingModeforComment()
if err != nil {
t.Fatalf("error on DisableTestingModeforComment :%v", err)
}

r := regexp.MustCompile(`Reopened pull request #666`)

if !r.MatchString(output.Stderr()) {
Expand Down
48 changes: 48 additions & 0 deletions command/simulate_user_comment.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package command

import (
"io"
"io/ioutil"
"os"
)

//EnabledTestingModeforComment is to simulate keypress on comments for Testing
var EnabledTestingModeforComment bool = false

//TemporariFileforKeyPress is a tmpfile to simulate input text for Testing
var TemporariFileforKeyPress *os.File

//DisableTestingModeforComment will disable simulate keypress
func DisableTestingModeforComment() error {
EnabledTestingModeforComment = false
defer TemporariFileforKeyPress.Close()
return nil
}

//EnableTestingModeforComment will enable simulate keypress
func EnableTestingModeforComment() error {
EnabledTestingModeforComment = true
in, err := ioutil.TempFile("", "")
if err != nil {
return err
}

TemporariFileforKeyPress = in

return nil
}

//SimulateUserInput is to simulate keypress on comments for Testing
func SimulateUserInput(text string) error {
_, err := io.WriteString(TemporariFileforKeyPress, text)
if err != nil {
return (err)
}

_, err = TemporariFileforKeyPress.Seek(0, io.SeekStart)
if err != nil {
return err
}

return nil
}