github.com/ungtb10d/cli/v2@v2.0.0-20221110210412-98537dd9d6a1/pkg/cmd/pr/ready/ready.go (about)

     1  package ready
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  
     7  	"github.com/MakeNowJust/heredoc"
     8  	"github.com/ungtb10d/cli/v2/api"
     9  	"github.com/ungtb10d/cli/v2/pkg/cmd/pr/shared"
    10  	"github.com/ungtb10d/cli/v2/pkg/cmdutil"
    11  	"github.com/ungtb10d/cli/v2/pkg/iostreams"
    12  	"github.com/spf13/cobra"
    13  )
    14  
    15  type ReadyOptions struct {
    16  	HttpClient func() (*http.Client, error)
    17  	IO         *iostreams.IOStreams
    18  
    19  	Finder shared.PRFinder
    20  
    21  	SelectorArg string
    22  	Undo        bool
    23  }
    24  
    25  func NewCmdReady(f *cmdutil.Factory, runF func(*ReadyOptions) error) *cobra.Command {
    26  	opts := &ReadyOptions{
    27  		IO:         f.IOStreams,
    28  		HttpClient: f.HttpClient,
    29  	}
    30  
    31  	cmd := &cobra.Command{
    32  		Use:   "ready [<number> | <url> | <branch>]",
    33  		Short: "Mark a pull request as ready for review",
    34  		Long: heredoc.Doc(`
    35  			Mark a pull request as ready for review.
    36  
    37  			Without an argument, the pull request that belongs to the current branch
    38  			is marked as ready.
    39  
    40  			If supported by your plan, convert to draft with --undo
    41  		`),
    42  		Args: cobra.MaximumNArgs(1),
    43  		RunE: func(cmd *cobra.Command, args []string) error {
    44  			opts.Finder = shared.NewFinder(f)
    45  
    46  			if repoOverride, _ := cmd.Flags().GetString("repo"); repoOverride != "" && len(args) == 0 {
    47  				return cmdutil.FlagErrorf("argument required when using the --repo flag")
    48  			}
    49  
    50  			if len(args) > 0 {
    51  				opts.SelectorArg = args[0]
    52  			}
    53  
    54  			if runF != nil {
    55  				return runF(opts)
    56  			}
    57  			return readyRun(opts)
    58  		},
    59  	}
    60  
    61  	cmd.Flags().BoolVar(&opts.Undo, "undo", false, `Convert a pull request to "draft"`)
    62  	return cmd
    63  }
    64  
    65  func readyRun(opts *ReadyOptions) error {
    66  	cs := opts.IO.ColorScheme()
    67  
    68  	findOptions := shared.FindOptions{
    69  		Selector: opts.SelectorArg,
    70  		Fields:   []string{"id", "number", "state", "isDraft"},
    71  	}
    72  	pr, baseRepo, err := opts.Finder.Find(findOptions)
    73  	if err != nil {
    74  		return err
    75  	}
    76  
    77  	if !pr.IsOpen() {
    78  		fmt.Fprintf(opts.IO.ErrOut, "%s Pull request #%d is closed. Only draft pull requests can be marked as \"ready for review\"\n", cs.FailureIcon(), pr.Number)
    79  		return cmdutil.SilentError
    80  	}
    81  
    82  	httpClient, err := opts.HttpClient()
    83  	if err != nil {
    84  		return err
    85  	}
    86  	apiClient := api.NewClientFromHTTP(httpClient)
    87  
    88  	if opts.Undo { // convert to draft
    89  		if pr.IsDraft {
    90  			fmt.Fprintf(opts.IO.ErrOut, "%s Pull request #%d is already \"in draft\"\n", cs.WarningIcon(), pr.Number)
    91  			return nil
    92  		}
    93  		err = api.ConvertPullRequestToDraft(apiClient, baseRepo, pr)
    94  		if err != nil {
    95  			return fmt.Errorf("API call failed: %w", err)
    96  		}
    97  
    98  		fmt.Fprintf(opts.IO.ErrOut, "%s Pull request #%d is converted to \"draft\"\n", cs.SuccessIconWithColor(cs.Green), pr.Number)
    99  	} else { // mark as ready for review
   100  		if !pr.IsDraft {
   101  			fmt.Fprintf(opts.IO.ErrOut, "%s Pull request #%d is already \"ready for review\"\n", cs.WarningIcon(), pr.Number)
   102  			return nil
   103  		}
   104  
   105  		err = api.PullRequestReady(apiClient, baseRepo, pr)
   106  		if err != nil {
   107  			return fmt.Errorf("API call failed: %w", err)
   108  		}
   109  
   110  		fmt.Fprintf(opts.IO.ErrOut, "%s Pull request #%d is marked as \"ready for review\"\n", cs.SuccessIconWithColor(cs.Green), pr.Number)
   111  	}
   112  
   113  	return nil
   114  }