diff --git a/cmd/helm/repo_list.go b/cmd/helm/repo_list.go index 537f8bd2c..0499d6296 100644 --- a/cmd/helm/repo_list.go +++ b/cmd/helm/repo_list.go @@ -30,8 +30,15 @@ import ( "helm.sh/helm/v3/pkg/repo" ) +type repoListOptions struct { + allowEmpty bool + repoFile string + outputFormat output.Format +} + func newRepoListCmd(out io.Writer) *cobra.Command { - var outfmt output.Format + o := &repoListOptions{} + cmd := &cobra.Command{ Use: "list", Aliases: []string{"ls"}, @@ -39,20 +46,29 @@ func newRepoListCmd(out io.Writer) *cobra.Command { Args: require.NoArgs, ValidArgsFunction: noCompletions, RunE: func(cmd *cobra.Command, args []string) error { - f, err := repo.LoadFile(settings.RepositoryConfig) - if isNotExist(err) || (len(f.Repositories) == 0 && !(outfmt == output.JSON || outfmt == output.YAML)) { - return errors.New("no repositories to show") - } - - return outfmt.Write(out, &repoListWriter{f.Repositories}) + o.repoFile = settings.RepositoryConfig + return o.run(out) }, } - bindOutputFlag(cmd, &outfmt) + f := cmd.Flags() + f.BoolVar(&o.allowEmpty, "allow-empty", false, "exit with status 0 and no error message if no repositories to show") + bindOutputFlag(cmd, &o.outputFormat) return cmd } +func (o *repoListOptions) run(out io.Writer) error { + f, err := repo.LoadFile(o.repoFile) + if o.allowEmpty { + return o.outputFormat.Write(out, &repoListWriter{f.Repositories}) + } + if isNotExist(err) || (len(f.Repositories) == 0 && !(o.outputFormat == output.JSON || o.outputFormat == output.YAML)) { + return errors.New("no repositories to show") + } + return o.outputFormat.Write(out, &repoListWriter{f.Repositories}) +} + type repositoryElement struct { Name string `json:"name"` URL string `json:"url"` diff --git a/cmd/helm/repo_list_test.go b/cmd/helm/repo_list_test.go index 90149ebda..dca213c22 100644 --- a/cmd/helm/repo_list_test.go +++ b/cmd/helm/repo_list_test.go @@ -17,7 +17,12 @@ limitations under the License. package main import ( + "os" + "path/filepath" "testing" + + "helm.sh/helm/v3/pkg/cli/output" + "helm.sh/helm/v3/pkg/repo/repotest" ) func TestRepoListOutputCompletion(t *testing.T) { @@ -27,3 +32,35 @@ func TestRepoListOutputCompletion(t *testing.T) { func TestRepoListFileCompletion(t *testing.T) { checkFileCompletion(t, "repo list", false) } + +func TestRepoListAllowEmpty(t *testing.T) { + ts, err := repotest.NewTempServerWithCleanup(t, "testdata/testserver/*.*") + if err != nil { + t.Fatal(err) + } + defer ts.Stop() + + rootDir := ts.Root() + repoFile := filepath.Join(rootDir, "repositories.yaml") + + // Remove existing repo + const testRepoName = "test" + + rmOpts := repoRemoveOptions{ + names: []string{testRepoName}, + repoFile: repoFile, + repoCache: rootDir, + } + if err := rmOpts.run(os.Stderr); err != nil { + t.Error(err) + } + + listOpts := repoListOptions{ + allowEmpty: true, + repoFile: repoFile, + outputFormat: output.Table, + } + if err := listOpts.run(os.Stderr); err != nil { + t.Error("Error not expected when listing repositories with allow-empty flag") + } +}