Skip to content

Commit

Permalink
Export empty results for cache list
Browse files Browse the repository at this point in the history
  • Loading branch information
williammartin committed Nov 6, 2024
1 parent fe5afb1 commit a569d10
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 2 deletions.
36 changes: 36 additions & 0 deletions acceptance/testdata/workflow/cache-list-empty.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# It's unclear what we want to do with these acceptance tests beyond our GHEC discovery, so skip new ones by default
skip

# Set up env vars
env REPO=${ORG}/${SCRIPT_NAME}-${RANDOM_STRING}

# Create a repository with a file so it has a default branch
exec gh repo create ${REPO} --add-readme --private

# Defer repo cleanup
defer gh repo delete --yes ${REPO}

# Set the repo to be targeted by all following commands
env GH_REPO=${REPO}

# Listing the cache non-interactively shows nothing
exec gh cache list
! stdout '.'

# Listing the cache non-interactively with --json shows an empty array
exec gh cache list --json id
stdout '\[\]'

# Now set an env var so the commands run interactively and without colour for stdout matching
# Unfortunately testscript provides no way to turn them off again, and since this
# script is for discovery, we're not adding a new command.
env GH_FORCE_TTY=true
env CLICOLOR=0

# Listing the cache interactively shows an informative message on stderr
exec gh cache list
stderr 'No caches found in'

# Listing the cache interactively with --json shows an empty array
exec gh cache list --json id
stdout '\[\]'
2 changes: 1 addition & 1 deletion pkg/cmd/cache/list/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ func listRun(opts *ListOptions) error {
return fmt.Errorf("%s Failed to get caches: %w", opts.IO.ColorScheme().FailureIcon(), err)
}

if len(result.ActionsCaches) == 0 {
if len(result.ActionsCaches) == 0 && opts.Exporter == nil {
return cmdutil.NewNoResultsError(fmt.Sprintf("No caches found in %s", ghrepo.FullName(repo)))
}

Expand Down
62 changes: 61 additions & 1 deletion pkg/cmd/cache/list/list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package list

import (
"bytes"
"fmt"
"net/http"
"testing"
"time"
Expand Down Expand Up @@ -243,7 +244,8 @@ ID KEY SIZE CREATED ACCESSED
wantErrMsg: "No caches found in OWNER/REPO",
},
{
name: "displays no results",
name: "displays no results when there is a tty",
tty: true,
stubs: func(reg *httpmock.Registry) {
reg.Register(
httpmock.REST("GET", "repos/OWNER/REPO/actions/caches"),
Expand All @@ -267,6 +269,48 @@ ID KEY SIZE CREATED ACCESSED
wantErr: true,
wantErrMsg: "X Failed to get caches: HTTP 404 (https://api.github.com/repos/OWNER/REPO/actions/caches?per_page=100)",
},
{
name: "calls the exporter when requested",
opts: ListOptions{
Exporter: &verboseExporter{},
},
stubs: func(reg *httpmock.Registry) {
reg.Register(
httpmock.REST("GET", "repos/OWNER/REPO/actions/caches"),
httpmock.JSONResponse(shared.CachePayload{
ActionsCaches: []shared.Cache{
{
Id: 1,
Key: "foo",
CreatedAt: time.Date(2021, 1, 1, 1, 1, 1, 1, time.UTC),
LastAccessedAt: time.Date(2022, 1, 1, 1, 1, 1, 1, time.UTC),
SizeInBytes: 100,
},
},
TotalCount: 1,
}),
)
},
wantErr: false,
wantStdout: "[{CreatedAt:2021-01-01 01:01:01.000000001 +0000 UTC Id:1 Key:foo LastAccessedAt:2022-01-01 01:01:01.000000001 +0000 UTC Ref: SizeInBytes:100 Version:}]",
},
{
name: "calls the exporter even when there are no results",
opts: ListOptions{
Exporter: &verboseExporter{},
},
stubs: func(reg *httpmock.Registry) {
reg.Register(
httpmock.REST("GET", "repos/OWNER/REPO/actions/caches"),
httpmock.JSONResponse(shared.CachePayload{
ActionsCaches: []shared.Cache{},
TotalCount: 0,
}),
)
},
wantErr: false,
wantStdout: "[]",
},
}

for _, tt := range tests {
Expand Down Expand Up @@ -305,6 +349,22 @@ ID KEY SIZE CREATED ACCESSED
}
}

// The verboseExporter just writes data formatted as %+v to stdout.
// This allows for easy assertion on the data provided to the exporter.
type verboseExporter struct{}

func (e *verboseExporter) Fields() []string {
return nil
}

func (e *verboseExporter) Write(io *iostreams.IOStreams, data interface{}) error {
_, err := io.Out.Write([]byte(fmt.Sprintf("%+v", data)))
if err != nil {
return err
}
return nil
}

func Test_humanFileSize(t *testing.T) {
tests := []struct {
name string
Expand Down

0 comments on commit a569d10

Please sign in to comment.