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

     1  package delete
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  	"strconv"
     7  
     8  	"github.com/AlecAivazis/survey/v2"
     9  	"github.com/ungtb10d/cli/v2/api"
    10  	"github.com/ungtb10d/cli/v2/internal/config"
    11  	"github.com/ungtb10d/cli/v2/internal/ghrepo"
    12  	"github.com/ungtb10d/cli/v2/pkg/cmd/issue/shared"
    13  	"github.com/ungtb10d/cli/v2/pkg/cmdutil"
    14  	"github.com/ungtb10d/cli/v2/pkg/iostreams"
    15  	"github.com/ungtb10d/cli/v2/pkg/prompt"
    16  	"github.com/shurcooL/githubv4"
    17  	"github.com/spf13/cobra"
    18  )
    19  
    20  type DeleteOptions struct {
    21  	HttpClient func() (*http.Client, error)
    22  	Config     func() (config.Config, error)
    23  	IO         *iostreams.IOStreams
    24  	BaseRepo   func() (ghrepo.Interface, error)
    25  
    26  	SelectorArg string
    27  	Confirmed   bool
    28  }
    29  
    30  func NewCmdDelete(f *cmdutil.Factory, runF func(*DeleteOptions) error) *cobra.Command {
    31  	opts := &DeleteOptions{
    32  		IO:         f.IOStreams,
    33  		HttpClient: f.HttpClient,
    34  		Config:     f.Config,
    35  	}
    36  
    37  	cmd := &cobra.Command{
    38  		Use:   "delete {<number> | <url>}",
    39  		Short: "Delete issue",
    40  		Args:  cobra.ExactArgs(1),
    41  		RunE: func(cmd *cobra.Command, args []string) error {
    42  			// support `-R, --repo` override
    43  			opts.BaseRepo = f.BaseRepo
    44  
    45  			if len(args) > 0 {
    46  				opts.SelectorArg = args[0]
    47  			}
    48  
    49  			if runF != nil {
    50  				return runF(opts)
    51  			}
    52  			return deleteRun(opts)
    53  		},
    54  	}
    55  
    56  	cmd.Flags().BoolVar(&opts.Confirmed, "confirm", false, "confirm deletion without prompting")
    57  	return cmd
    58  }
    59  
    60  func deleteRun(opts *DeleteOptions) error {
    61  	cs := opts.IO.ColorScheme()
    62  
    63  	httpClient, err := opts.HttpClient()
    64  	if err != nil {
    65  		return err
    66  	}
    67  
    68  	issue, baseRepo, err := shared.IssueFromArgWithFields(httpClient, opts.BaseRepo, opts.SelectorArg, []string{"id", "number", "title"})
    69  	if err != nil {
    70  		return err
    71  	}
    72  	if issue.IsPullRequest() {
    73  		return fmt.Errorf("issue #%d is a pull request and cannot be deleted", issue.Number)
    74  	}
    75  
    76  	// When executed in an interactive shell, require confirmation, unless
    77  	// already provided. Otherwise skip confirmation.
    78  	if opts.IO.CanPrompt() && !opts.Confirmed {
    79  		answer := ""
    80  		//nolint:staticcheck // SA1019: prompt.SurveyAskOne is deprecated: use Prompter
    81  		err = prompt.SurveyAskOne(
    82  			&survey.Input{
    83  				Message: fmt.Sprintf("You're going to delete issue #%d. This action cannot be reversed. To confirm, type the issue number:", issue.Number),
    84  			},
    85  			&answer,
    86  		)
    87  		if err != nil {
    88  			return err
    89  		}
    90  		answerInt, err := strconv.Atoi(answer)
    91  		if err != nil || answerInt != issue.Number {
    92  			fmt.Fprintf(opts.IO.Out, "Issue #%d was not deleted.\n", issue.Number)
    93  			return nil
    94  		}
    95  	}
    96  
    97  	if err := apiDelete(httpClient, baseRepo, issue.ID); err != nil {
    98  		return err
    99  	}
   100  
   101  	if opts.IO.IsStdoutTTY() {
   102  		fmt.Fprintf(opts.IO.ErrOut, "%s Deleted issue #%d (%s).\n", cs.Red("✔"), issue.Number, issue.Title)
   103  	}
   104  
   105  	return nil
   106  }
   107  
   108  func apiDelete(httpClient *http.Client, repo ghrepo.Interface, issueID string) error {
   109  	var mutation struct {
   110  		DeleteIssue struct {
   111  			Repository struct {
   112  				ID githubv4.ID
   113  			}
   114  		} `graphql:"deleteIssue(input: $input)"`
   115  	}
   116  
   117  	variables := map[string]interface{}{
   118  		"input": githubv4.DeleteIssueInput{
   119  			IssueID: issueID,
   120  		},
   121  	}
   122  
   123  	gql := api.NewClientFromHTTP(httpClient)
   124  	return gql.Mutate(repo.RepoHost(), "IssueDelete", &mutation, variables)
   125  }