Merge pull request #10327 from iamazeem/9897-gh-cache-delete-exit-code
[gh cache delete --all] Add `--succeed-on-no-caches` flag to return exit code 0
This commit is contained in:
commit
5aa36de302
2 changed files with 100 additions and 5 deletions
28
pkg/cmd/cache/delete/delete.go
vendored
28
pkg/cmd/cache/delete/delete.go
vendored
|
|
@ -22,8 +22,9 @@ type DeleteOptions struct {
|
|||
HttpClient func() (*http.Client, error)
|
||||
IO *iostreams.IOStreams
|
||||
|
||||
DeleteAll bool
|
||||
Identifier string
|
||||
DeleteAll bool
|
||||
SucceedOnNoCaches bool
|
||||
Identifier string
|
||||
}
|
||||
|
||||
func NewCmdDelete(f *cmdutil.Factory, runF func(*DeleteOptions) error) *cobra.Command {
|
||||
|
|
@ -33,7 +34,7 @@ func NewCmdDelete(f *cmdutil.Factory, runF func(*DeleteOptions) error) *cobra.Co
|
|||
}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "delete [<cache-id>| <cache-key> | --all]",
|
||||
Use: "delete [<cache-id> | <cache-key> | --all]",
|
||||
Short: "Delete GitHub Actions caches",
|
||||
Long: heredoc.Docf(`
|
||||
Delete GitHub Actions caches.
|
||||
|
|
@ -50,8 +51,11 @@ func NewCmdDelete(f *cmdutil.Factory, runF func(*DeleteOptions) error) *cobra.Co
|
|||
# Delete a cache by id in a specific repo
|
||||
$ gh cache delete 1234 --repo cli/cli
|
||||
|
||||
# Delete all caches
|
||||
# Delete all caches (exit code 1 on no caches)
|
||||
$ gh cache delete --all
|
||||
|
||||
# Delete all caches (exit code 0 on no caches)
|
||||
$ gh cache delete --all --succeed-on-no-caches
|
||||
`),
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
|
@ -65,6 +69,10 @@ func NewCmdDelete(f *cmdutil.Factory, runF func(*DeleteOptions) error) *cobra.Co
|
|||
return err
|
||||
}
|
||||
|
||||
if !opts.DeleteAll && opts.SucceedOnNoCaches {
|
||||
return cmdutil.FlagErrorf("--succeed-on-no-caches must be used in conjunction with --all")
|
||||
}
|
||||
|
||||
if !opts.DeleteAll && len(args) == 0 {
|
||||
return cmdutil.FlagErrorf("must provide either cache id, cache key, or use --all")
|
||||
}
|
||||
|
|
@ -82,6 +90,7 @@ func NewCmdDelete(f *cmdutil.Factory, runF func(*DeleteOptions) error) *cobra.Co
|
|||
}
|
||||
|
||||
cmd.Flags().BoolVarP(&opts.DeleteAll, "all", "a", false, "Delete all caches")
|
||||
cmd.Flags().BoolVar(&opts.SucceedOnNoCaches, "succeed-on-no-caches", false, "Return exit code 0 if no caches found. Must be used in conjunction with `--all`")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
|
@ -100,12 +109,21 @@ func deleteRun(opts *DeleteOptions) error {
|
|||
|
||||
var toDelete []string
|
||||
if opts.DeleteAll {
|
||||
opts.IO.StartProgressIndicator()
|
||||
caches, err := shared.GetCaches(client, repo, shared.GetCachesOptions{Limit: -1})
|
||||
opts.IO.StopProgressIndicator()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(caches.ActionsCaches) == 0 {
|
||||
return fmt.Errorf("%s No caches to delete", opts.IO.ColorScheme().FailureIcon())
|
||||
if opts.SucceedOnNoCaches {
|
||||
if opts.IO.IsStdoutTTY() {
|
||||
fmt.Fprintf(opts.IO.Out, "%s No caches to delete\n", opts.IO.ColorScheme().SuccessIcon())
|
||||
}
|
||||
return nil
|
||||
} else {
|
||||
return fmt.Errorf("%s No caches to delete", opts.IO.ColorScheme().FailureIcon())
|
||||
}
|
||||
}
|
||||
for _, cache := range caches.ActionsCaches {
|
||||
toDelete = append(toDelete, strconv.Itoa(cache.Id))
|
||||
|
|
|
|||
77
pkg/cmd/cache/delete/delete_test.go
vendored
77
pkg/cmd/cache/delete/delete_test.go
vendored
|
|
@ -43,6 +43,21 @@ func TestNewCmdDelete(t *testing.T) {
|
|||
cli: "--all",
|
||||
wants: DeleteOptions{DeleteAll: true},
|
||||
},
|
||||
{
|
||||
name: "delete all and succeed-on-no-caches flags",
|
||||
cli: "--all --succeed-on-no-caches",
|
||||
wants: DeleteOptions{DeleteAll: true, SucceedOnNoCaches: true},
|
||||
},
|
||||
{
|
||||
name: "succeed-on-no-caches flag",
|
||||
cli: "--succeed-on-no-caches",
|
||||
wantsErr: "--succeed-on-no-caches must be used in conjunction with --all",
|
||||
},
|
||||
{
|
||||
name: "succeed-on-no-caches flag and id argument",
|
||||
cli: "--succeed-on-no-caches 123",
|
||||
wantsErr: "--succeed-on-no-caches must be used in conjunction with --all",
|
||||
},
|
||||
{
|
||||
name: "id argument and delete all flag",
|
||||
cli: "1 --all",
|
||||
|
|
@ -72,6 +87,7 @@ func TestNewCmdDelete(t *testing.T) {
|
|||
}
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tt.wants.DeleteAll, gotOpts.DeleteAll)
|
||||
assert.Equal(t, tt.wants.SucceedOnNoCaches, gotOpts.SucceedOnNoCaches)
|
||||
assert.Equal(t, tt.wants.Identifier, gotOpts.Identifier)
|
||||
})
|
||||
}
|
||||
|
|
@ -160,6 +176,19 @@ func TestDeleteRun(t *testing.T) {
|
|||
tty: true,
|
||||
wantStdout: "✓ Deleted 2 caches from OWNER/REPO\n",
|
||||
},
|
||||
{
|
||||
name: "attempts to delete all caches but api errors",
|
||||
opts: DeleteOptions{DeleteAll: true},
|
||||
stubs: func(reg *httpmock.Registry) {
|
||||
reg.Register(
|
||||
httpmock.REST("GET", "repos/OWNER/REPO/actions/caches"),
|
||||
httpmock.StatusStringResponse(500, ""),
|
||||
)
|
||||
},
|
||||
tty: true,
|
||||
wantErr: true,
|
||||
wantErrMsg: "HTTP 500 (https://api.github.com/repos/OWNER/REPO/actions/caches?per_page=100)",
|
||||
},
|
||||
{
|
||||
name: "displays delete error",
|
||||
opts: DeleteOptions{Identifier: "123"},
|
||||
|
|
@ -186,6 +215,54 @@ func TestDeleteRun(t *testing.T) {
|
|||
tty: true,
|
||||
wantStdout: "✓ Deleted 1 cache from OWNER/REPO\n",
|
||||
},
|
||||
{
|
||||
name: "no caches to delete when deleting all",
|
||||
opts: DeleteOptions{DeleteAll: true},
|
||||
stubs: func(reg *httpmock.Registry) {
|
||||
reg.Register(
|
||||
httpmock.REST("GET", "repos/OWNER/REPO/actions/caches"),
|
||||
httpmock.JSONResponse(shared.CachePayload{
|
||||
ActionsCaches: []shared.Cache{},
|
||||
TotalCount: 0,
|
||||
}),
|
||||
)
|
||||
},
|
||||
tty: false,
|
||||
wantErr: true,
|
||||
wantErrMsg: "X No caches to delete",
|
||||
},
|
||||
{
|
||||
name: "no caches to delete when deleting all but succeed on no cache tty",
|
||||
opts: DeleteOptions{DeleteAll: true, SucceedOnNoCaches: true},
|
||||
stubs: func(reg *httpmock.Registry) {
|
||||
reg.Register(
|
||||
httpmock.REST("GET", "repos/OWNER/REPO/actions/caches"),
|
||||
httpmock.JSONResponse(shared.CachePayload{
|
||||
ActionsCaches: []shared.Cache{},
|
||||
TotalCount: 0,
|
||||
}),
|
||||
)
|
||||
},
|
||||
tty: true,
|
||||
wantErr: false,
|
||||
wantStdout: "✓ No caches to delete\n",
|
||||
},
|
||||
{
|
||||
name: "no caches to delete when deleting all but succeed on no cache non-tty",
|
||||
opts: DeleteOptions{DeleteAll: true, SucceedOnNoCaches: true},
|
||||
stubs: func(reg *httpmock.Registry) {
|
||||
reg.Register(
|
||||
httpmock.REST("GET", "repos/OWNER/REPO/actions/caches"),
|
||||
httpmock.JSONResponse(shared.CachePayload{
|
||||
ActionsCaches: []shared.Cache{},
|
||||
TotalCount: 0,
|
||||
}),
|
||||
)
|
||||
},
|
||||
tty: false,
|
||||
wantErr: false,
|
||||
wantStdout: "",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue