Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 76 additions & 12 deletions pkg/cmd/gist/delete/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import (
"net/http"
"strings"

"github.com/MakeNowJust/heredoc"
"github.com/cli/cli/v2/api"
"github.com/cli/cli/v2/internal/gh"
"github.com/cli/cli/v2/internal/prompter"
"github.com/cli/cli/v2/pkg/cmd/gist/shared"
"github.com/cli/cli/v2/pkg/cmdutil"
"github.com/cli/cli/v2/pkg/iostreams"
Expand All @@ -18,62 +20,124 @@ type DeleteOptions struct {
IO *iostreams.IOStreams
Config func() (gh.Config, error)
HttpClient func() (*http.Client, error)
Prompter prompter.Prompter

Selector string
Selector string
Confirmed bool
}

func NewCmdDelete(f *cmdutil.Factory, runF func(*DeleteOptions) error) *cobra.Command {
opts := DeleteOptions{
IO: f.IOStreams,
Config: f.Config,
HttpClient: f.HttpClient,
Prompter: f.Prompter,
}

cmd := &cobra.Command{
Use: "delete {<id> | <url>}",
Short: "Delete a gist",
Args: cmdutil.ExactArgs(1, "cannot delete: gist argument required"),
Long: heredoc.Docf(`
Delete a GitHub gist.
To delete a gist interactively, use %[1]sgh gist delete%[1]s with no arguments.
To delete a gist non-interactively, supply the gist id or url.
`, "`"),
Example: heredoc.Doc(`
# delete a gist interactively
gh gist delete
# delete a gist non-interactively
gh gist delete 1234
`),
Args: cobra.MaximumNArgs(1),
RunE: func(c *cobra.Command, args []string) error {
opts.Selector = args[0]
if !opts.IO.CanPrompt() && !opts.Confirmed {
return cmdutil.FlagErrorf("--yes required when not running interactively")
}

if !opts.IO.CanPrompt() && len(args) == 0 {
return cmdutil.FlagErrorf("id or url argument required in non-interactive mode")
}

if len(args) == 1 {
opts.Selector = args[0]
}

if runF != nil {
return runF(&opts)
}
return deleteRun(&opts)
},
}
cmd.Flags().BoolVar(&opts.Confirmed, "yes", false, "confirm deletion without prompting")
return cmd
}

func deleteRun(opts *DeleteOptions) error {
gistID := opts.Selector
client, err := opts.HttpClient()
if err != nil {
return err
}

cfg, err := opts.Config()
if err != nil {
return err
}

host, _ := cfg.Authentication().DefaultHost()

gistID := opts.Selector
if strings.Contains(gistID, "/") {
id, err := shared.GistIDFromURL(gistID)
if err != nil {
return err
}
gistID = id
}
client, err := opts.HttpClient()
if err != nil {
return err
}

cfg, err := opts.Config()
cs := opts.IO.ColorScheme()
var gist *shared.Gist
if gistID == "" {
gist, err = shared.PromptGists(opts.Prompter, client, host, cs)
} else {
gist, err = shared.GetGist(client, host, gistID)
}
if err != nil {
return err
}
if gist.ID == "" {
fmt.Fprintln(opts.IO.Out, "No gists found.")
return nil
}

host, _ := cfg.Authentication().DefaultHost()
if !opts.Confirmed {
confirmed, err := opts.Prompter.Confirm(fmt.Sprintf("Delete %q gist?", gist.Filename()), false)
if err != nil {
return err
}
if !confirmed {
return cmdutil.CancelError
}
}

apiClient := api.NewClientFromHTTP(client)
if err := deleteGist(apiClient, host, gistID); err != nil {
if err := deleteGist(apiClient, host, gist.ID); err != nil {
if errors.Is(err, shared.NotFoundErr) {
return fmt.Errorf("unable to delete gist %s: either the gist is not found or it is not owned by you", gistID)
return fmt.Errorf("unable to delete gist %q: either the gist is not found or it is not owned by you", gist.Filename())
}
return err
}

if opts.IO.IsStdoutTTY() {
cs := opts.IO.ColorScheme()
fmt.Fprintf(opts.IO.Out,
"%s Gist %q deleted\n",
cs.SuccessIcon(),
gist.Filename())
}

return nil
}

Expand Down
Loading