diff --git a/pkg/cmd/repo/delete/delete.go b/pkg/cmd/repo/delete/delete.go index 3036f7697..5fd5a5340 100644 --- a/pkg/cmd/repo/delete/delete.go +++ b/pkg/cmd/repo/delete/delete.go @@ -18,6 +18,7 @@ import ( type DeleteOptions struct { HttpClient func() (*http.Client, error) + BaseRepo func() (ghrepo.Interface, error) IO *iostreams.IOStreams RepoArg string Confirmed bool @@ -27,21 +28,27 @@ func NewCmdDelete(f *cmdutil.Factory, runF func(*DeleteOptions) error) *cobra.Co opts := &DeleteOptions{ IO: f.IOStreams, HttpClient: f.HttpClient, + BaseRepo: f.BaseRepo, } cmd := &cobra.Command{ - Use: "delete ", + Use: "delete []", Short: "Delete a repository", Long: `Delete a GitHub repository. +With no argument, deletes the current repository. Otherwise, deletes the specified repository. + Deletion requires authorization with the "delete_repo" scope. To authorize, run "gh auth refresh -s delete_repo"`, - Args: cmdutil.ExactArgs(1, "cannot delete: repository argument required"), + Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - opts.RepoArg = args[0] - if !opts.IO.CanPrompt() && !opts.Confirmed { - return cmdutil.FlagErrorf("could not prompt: confirmation with prompt or --confirm flag required") + if len(args) > 0 { + opts.RepoArg = args[0] } + if !opts.IO.CanPrompt() && !opts.Confirmed { + return cmdutil.FlagErrorf("--confirm required when not running interactively") + } + if runF != nil { return runF(opts) } @@ -60,21 +67,27 @@ func deleteRun(opts *DeleteOptions) error { } apiClient := api.NewClientFromHTTP(httpClient) - repoSelector := opts.RepoArg var toDelete ghrepo.Interface - if !strings.Contains(repoSelector, "/") { - currentUser, err := api.CurrentLoginName(apiClient, ghinstance.Default()) + if opts.RepoArg == "" { + toDelete, err = opts.BaseRepo() if err != nil { return err } - repoSelector = currentUser + "/" + repoSelector + } else { + repoSelector := opts.RepoArg + if !strings.Contains(repoSelector, "/") { + currentUser, err := api.CurrentLoginName(apiClient, ghinstance.Default()) + if err != nil { + return err + } + repoSelector = currentUser + "/" + repoSelector + } + toDelete, err = ghrepo.FromFullName(repoSelector) + if err != nil { + return fmt.Errorf("argument error: %w", err) + } } - toDelete, err = ghrepo.FromFullName(repoSelector) - if err != nil { - return fmt.Errorf("argument error: %w", err) - } - fullName := ghrepo.FullName(toDelete) if !opts.Confirmed { diff --git a/pkg/cmd/repo/delete/delete_test.go b/pkg/cmd/repo/delete/delete_test.go index d561a3269..da9c04223 100644 --- a/pkg/cmd/repo/delete/delete_test.go +++ b/pkg/cmd/repo/delete/delete_test.go @@ -5,6 +5,7 @@ import ( "net/http" "testing" + "github.com/cli/cli/v2/internal/ghrepo" "github.com/cli/cli/v2/pkg/cmdutil" "github.com/cli/cli/v2/pkg/httpmock" "github.com/cli/cli/v2/pkg/iostreams" @@ -24,21 +25,22 @@ func TestNewCmdDelete(t *testing.T) { }{ { name: "confirm flag", + tty: true, input: "OWNER/REPO --confirm", output: DeleteOptions{RepoArg: "OWNER/REPO", Confirmed: true}, }, { - name: "no confirmation no tty", + name: "no confirmation notty", input: "OWNER/REPO", output: DeleteOptions{RepoArg: "OWNER/REPO"}, wantErr: true, - errMsg: "could not prompt: confirmation with prompt or --confirm flag required"}, + errMsg: "--confirm required when not running interactively", + }, { - name: "no argument", - input: "", - wantErr: true, - errMsg: "cannot delete: repository argument required", - tty: true, + name: "base repo resolution", + input: "", + tty: true, + output: DeleteOptions{}, }, } for _, tt := range tests { @@ -101,7 +103,21 @@ func Test_deleteRun(t *testing.T) { }, }, { - name: "confimation no tty", + name: "infer base repo", + tty: true, + opts: &DeleteOptions{}, + wantStdout: "✓ Deleted repository OWNER/REPO\n", + askStubs: func(q *prompt.AskStubber) { + q.StubOne("OWNER/REPO") + }, + httpStubs: func(reg *httpmock.Registry) { + reg.Register( + httpmock.REST("DELETE", "repos/OWNER/REPO"), + httpmock.StatusStringResponse(204, "{}")) + }, + }, + { + name: "confirmation no tty", opts: &DeleteOptions{ RepoArg: "OWNER/REPO", Confirmed: true, @@ -137,6 +153,10 @@ func Test_deleteRun(t *testing.T) { tt.askStubs(q) } + tt.opts.BaseRepo = func() (ghrepo.Interface, error) { + return ghrepo.New("OWNER", "REPO"), nil + } + reg := &httpmock.Registry{} if tt.httpStubs != nil { tt.httpStubs(reg)