github.com/gfleury/gobbs@v0.0.0-20200831213239-44ca2b94c1a1/pullrequests/create.go (about)

     1  package pullrequests
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"net"
     8  	"net/http"
     9  	"time"
    10  
    11  	"github.com/gfleury/gobbs/common"
    12  	"github.com/gfleury/gobbs/common/log"
    13  
    14  	bitbucketv1 "github.com/gfleury/go-bitbucket-v1"
    15  	"github.com/spf13/cobra"
    16  )
    17  
    18  var (
    19  	description, title *string
    20  )
    21  
    22  func init() {
    23  	description = Create.Flags().StringP("description", "d", "", "PR description")
    24  	title = Create.Flags().StringP("title", "T", "", "PR title")
    25  }
    26  
    27  // Create is the cmd implementation for Creating Pull Requests
    28  var Create = &cobra.Command{
    29  	Use:     "create fromBranch toBranch",
    30  	Aliases: []string{"cr"},
    31  	Short:   "Create pull requests for repository",
    32  	Args:    cobra.MinimumNArgs(2),
    33  	RunE: func(cmd *cobra.Command, args []string) error {
    34  		apiClient, cancel, err := common.APIClient(cmd)
    35  		defer cancel()
    36  
    37  		if err != nil {
    38  			cmd.SilenceUsage = true
    39  			return err
    40  		}
    41  
    42  		stashInfo := cmd.Context().Value(common.StashInfoKey).(*common.StashInfo)
    43  		err = mustHaveProjectRepo(stashInfo)
    44  		if err != nil {
    45  			return err
    46  		}
    47  
    48  		if *title == "" {
    49  			*title = titleFromBranch(args[0], args[1])
    50  		}
    51  
    52  		if *description == "" {
    53  			*description = titleFromBranch(args[0], args[1])
    54  		}
    55  
    56  		pr := bitbucketv1.PullRequest{
    57  			Title:       *title,
    58  			Description: *description,
    59  			Version:     0,
    60  			State:       "OPEN",
    61  			Open:        true,
    62  			Closed:      false,
    63  			FromRef: bitbucketv1.PullRequestRef{
    64  				ID: fmt.Sprintf("refs/heads/%s", args[0]),
    65  				Repository: bitbucketv1.Repository{
    66  					Slug: *stashInfo.Repo(),
    67  					Project: &bitbucketv1.Project{
    68  						Key: *stashInfo.Project(),
    69  					},
    70  				},
    71  			},
    72  			ToRef: bitbucketv1.PullRequestRef{
    73  				ID: fmt.Sprintf("refs/heads/%s", args[1]),
    74  				Repository: bitbucketv1.Repository{
    75  					Slug: *stashInfo.Repo(),
    76  					Project: &bitbucketv1.Project{
    77  						Key: *stashInfo.Project(),
    78  					},
    79  				},
    80  			},
    81  			Locked: false,
    82  			//"reviewers": reviewers,
    83  		}
    84  
    85  		response, err := apiClient.DefaultApi.CreatePullRequest(*stashInfo.Project(), *stashInfo.Repo(), pr)
    86  
    87  		if netError, ok := err.(net.Error); (!ok || (ok && !netError.Timeout())) &&
    88  			!errors.Is(err, context.Canceled) &&
    89  			!errors.Is(err, context.DeadlineExceeded) &&
    90  			response != nil && response.Response != nil &&
    91  			response.Response.StatusCode >= http.StatusMultipleChoices {
    92  			common.PrintApiError(response.Values)
    93  			cmd.SilenceUsage = true
    94  			log.Debugf(err.Error())
    95  			return fmt.Errorf("Unable to process request, API Error")
    96  		} else if err != nil {
    97  			cmd.SilenceUsage = true
    98  			return err
    99  		}
   100  
   101  		pr, err = bitbucketv1.GetPullRequestResponse(response)
   102  		if err != nil {
   103  			cmd.SilenceUsage = true
   104  			return err
   105  		}
   106  
   107  		header := []string{"ID", "State", "Created", "Short Desc.", "Reviewers"}
   108  		table := common.Table(header)
   109  
   110  		table.Append([]string{
   111  			fmt.Sprintf("%d", pr.ID),
   112  			pr.State,
   113  			fmt.Sprint(time.Unix(pr.CreatedDate/1000, 0).Format("2006-01-02T15:04:05-0700")),
   114  			//pr.Author.User.Name,
   115  			fmt.Sprintf("[%s -> %s] %s", pr.FromRef.DisplayID, pr.ToRef.DisplayID, pr.Title),
   116  			func() (r string) {
   117  				for _, reviewer := range pr.Reviewers {
   118  					r = fmt.Sprintf("%s%s %s\n", r, reviewer.User.Name,
   119  						func() string {
   120  							if reviewer.Approved {
   121  								return "(A)"
   122  							}
   123  							return "( )"
   124  						}())
   125  				}
   126  				return
   127  			}(),
   128  		})
   129  		table.Render()
   130  
   131  		return nil
   132  	},
   133  }
   134  
   135  func titleFromBranch(from, to string) string {
   136  	return fmt.Sprintf("Merge '%s' into '%s'", from, to)
   137  }