add delete HTTP request and confirmation prompting

This commit is contained in:
meiji163 2021-10-07 09:53:22 -07:00
parent 025f86b911
commit a8028be8f9
3 changed files with 101 additions and 3 deletions

View file

@ -1,10 +1,18 @@
package delete
import (
"errors"
"fmt"
"net/http"
"strings"
"github.com/cli/cli/v2/api"
"github.com/cli/cli/v2/internal/ghinstance"
"github.com/cli/cli/v2/internal/ghrepo"
"github.com/cli/cli/v2/pkg/cmdutil"
"github.com/cli/cli/v2/pkg/prompt"
"github.com/AlecAivazis/survey/v2"
"github.com/cli/cli/v2/pkg/iostreams"
"github.com/spf13/cobra"
)
@ -27,7 +35,8 @@ func NewCmdDelete(f *cmdutil.Factory, runF func(*DeleteOptions) error) *cobra.Co
Short: "Delete a repository",
Long: `Delete a GitHub repository.
Ensure that you have authorized the \"delete_repo\" scope: gh auth refresh -h github.com -s delete_repo"`,
Deletion requires authorization with the "delete_repo" scope.
To authorize, run "gh auth refresh -h github.com -s delete_repo"`,
Args: cmdutil.ExactArgs(1, "cannot delete: repository argument required"),
RunE: func(cmd *cobra.Command, args []string) error {
opts.RepoArg = args[0]
@ -38,11 +47,68 @@ func NewCmdDelete(f *cmdutil.Factory, runF func(*DeleteOptions) error) *cobra.Co
},
}
cmd.Flags().BoolVar(&opts.Confirmed, "yes", false, "Confirm deletion without prompting")
cmd.Flags().BoolVar(&opts.Confirmed, "yes", false, "confirm deletion without prompting")
return cmd
}
func deleteRun(opts *DeleteOptions) error {
httpClient, err := opts.HttpClient()
if err != nil {
return err
}
apiClient := api.NewClientFromHTTP(httpClient)
deleteURL := opts.RepoArg
var toDelete ghrepo.Interface
if !strings.Contains(deleteURL, "/") {
currentUser, err := api.CurrentLoginName(apiClient, ghinstance.Default())
if err != nil {
return err
}
deleteURL = currentUser + "/" + deleteURL
}
toDelete, err = ghrepo.FromFullName(deleteURL)
if err != nil {
return fmt.Errorf("argument error: %w", err)
}
fullName := ghrepo.FullName(toDelete)
doPrompt := opts.IO.CanPrompt()
if !opts.Confirmed && !doPrompt {
return errors.New("could not prompt: confirmation with prompt or --yes flag required")
}
if !opts.Confirmed && doPrompt {
var valid string
err := prompt.SurveyAskOne(
&survey.Input{Message: fmt.Sprintf("Type %s to confirm deletion:", fullName)},
&valid,
survey.WithValidator(
func(val interface{}) error {
if str := val.(string); str != fullName {
return fmt.Errorf("You entered %s", str)
}
return nil
}))
if err != nil {
return fmt.Errorf("could not prompt: %w", err)
}
}
err = deleteRepo(httpClient, toDelete)
if err != nil {
return fmt.Errorf("API call failed: %w", err)
}
if opts.IO.IsStdoutTTY() {
cs := opts.IO.ColorScheme()
fmt.Fprintf(opts.IO.Out,
"%s Deleted repository %s\n",
cs.SuccessIcon(),
fullName)
}
return nil
}

View file

@ -1,9 +1,39 @@
package delete
import (
"fmt"
"net/http"
"github.com/cli/cli/v2/api"
"github.com/cli/cli/v2/internal/ghinstance"
"github.com/cli/cli/v2/internal/ghrepo"
)
func deleteRepo(client *http.Client) error {
func deleteRepo(client *http.Client, repo ghrepo.Interface) error {
url := fmt.Sprintf("%srepos/%s",
ghinstance.RESTPrefix(repo.RepoHost()),
ghrepo.FullName(repo))
request, err := http.NewRequest("DELETE", url, nil)
request.Header.Set("Accept", "application/vnd.github.v3+json")
if err != nil {
return err
}
resp, err := client.Do(request)
if err != nil {
return err
}
defer resp.Body.Close()
err = api.HandleHTTPError(resp)
if resp.StatusCode == 403 {
return fmt.Errorf(`%w
Deletion requires authorization with the "delete_repo" scope. To authorize, run "gh auth refresh -s delete_repo"`, err)
} else if resp.StatusCode > 204 {
return err
}
return nil
}

View file

@ -5,6 +5,7 @@ import (
repoCloneCmd "github.com/cli/cli/v2/pkg/cmd/repo/clone"
repoCreateCmd "github.com/cli/cli/v2/pkg/cmd/repo/create"
creditsCmd "github.com/cli/cli/v2/pkg/cmd/repo/credits"
repoDeleteCmd "github.com/cli/cli/v2/pkg/cmd/repo/delete"
repoForkCmd "github.com/cli/cli/v2/pkg/cmd/repo/fork"
gardenCmd "github.com/cli/cli/v2/pkg/cmd/repo/garden"
repoListCmd "github.com/cli/cli/v2/pkg/cmd/repo/list"
@ -42,6 +43,7 @@ func NewCmdRepo(f *cmdutil.Factory) *cobra.Command {
cmd.AddCommand(repoSyncCmd.NewCmdSync(f, nil))
cmd.AddCommand(creditsCmd.NewCmdRepoCredits(f, nil))
cmd.AddCommand(gardenCmd.NewCmdGarden(f, nil))
cmd.AddCommand(repoDeleteCmd.NewCmdDelete(f, nil))
return cmd
}