diff --git a/cmd/helm/flags.go b/cmd/helm/flags.go index 32eb5bf57..09676e658 100644 --- a/cmd/helm/flags.go +++ b/cmd/helm/flags.go @@ -23,6 +23,7 @@ import ( "github.com/spf13/pflag" "helm.sh/helm/v3/pkg/action" + "helm.sh/helm/v3/pkg/cli/output" "helm.sh/helm/v3/pkg/cli/values" ) @@ -48,10 +49,34 @@ func addChartPathOptionsFlags(f *pflag.FlagSet, c *action.ChartPathOptions) { } // bindOutputFlag will add the output flag to the given command and bind the -// value to the given string pointer -func bindOutputFlag(cmd *cobra.Command, varRef *string) { - // NOTE(taylor): A possible refactor here is that we can implement all the - // validation for the OutputFormat type here so we don't have to do the - // parsing and checking in the command - cmd.Flags().StringVarP(varRef, outputFlag, "o", string(action.Table), fmt.Sprintf("prints the output in the specified format. Allowed values: %s, %s, %s", action.Table, action.JSON, action.YAML)) +// value to the given format pointer +func bindOutputFlag(cmd *cobra.Command, varRef *output.Format) { + cmd.Flags().VarP(newOutputValue(output.Table, varRef), outputFlag, "o", fmt.Sprintf("prints the output in the specified format. Allowed values: %s, %s, %s", output.Table, output.JSON, output.YAML)) +} + +type outputValue output.Format + +func newOutputValue(defaultValue output.Format, p *output.Format) *outputValue { + *p = defaultValue + return (*outputValue)(p) +} + +func (o *outputValue) String() string { + // It is much cleaner looking (and technically less allocations) to just + // convert to a string rather than type asserting to the underlying + // output.Format + return string(*o) +} + +func (o *outputValue) Type() string { + return "format" +} + +func (o *outputValue) Set(s string) error { + outfmt, err := output.ParseFormat(s) + if err != nil { + return err + } + *o = outputValue(outfmt) + return nil } diff --git a/cmd/helm/get.go b/cmd/helm/get.go index fb7fef233..d9c8a2d8c 100644 --- a/cmd/helm/get.go +++ b/cmd/helm/get.go @@ -23,6 +23,7 @@ import ( "helm.sh/helm/v3/cmd/helm/require" "helm.sh/helm/v3/pkg/action" + "helm.sh/helm/v3/pkg/cli/output" ) var getHelp = ` @@ -58,7 +59,8 @@ func newGetCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { } return tpl(template, data, out) } - return printRelease(out, res) + + return output.Table.Write(out, &statusPrinter{res, true}) }, } diff --git a/cmd/helm/history.go b/cmd/helm/history.go index 59b7c9379..c4a74bb2c 100644 --- a/cmd/helm/history.go +++ b/cmd/helm/history.go @@ -19,6 +19,7 @@ package main import ( "fmt" "io" + "time" "github.com/gosuri/uitable" "github.com/spf13/cobra" @@ -26,6 +27,7 @@ import ( "helm.sh/helm/v3/cmd/helm/require" "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/chart" + "helm.sh/helm/v3/pkg/cli/output" "helm.sh/helm/v3/pkg/release" "helm.sh/helm/v3/pkg/releaseutil" ) @@ -48,6 +50,7 @@ The historical release set is printed as a formatted table, e.g: func newHistoryCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { client := action.NewHistory(cfg) + var outfmt output.Format cmd := &cobra.Command{ Use: "history RELEASE_NAME", @@ -56,55 +59,48 @@ func newHistoryCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { Aliases: []string{"hist"}, Args: require.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - // validate the output format first so we don't waste time running a - // request that we'll throw away - output, err := action.ParseOutputFormat(client.OutputFormat) - if err != nil { - return err - } - history, err := getHistory(client, args[0]) if err != nil { return err } - return output.Write(out, history) + return outfmt.Write(out, history) }, } f := cmd.Flags() f.IntVar(&client.Max, "max", 256, "maximum number of revision to include in history") - bindOutputFlag(cmd, &client.OutputFormat) + bindOutputFlag(cmd, &outfmt) return cmd } type releaseInfo struct { - Revision int `json:"revision"` - Updated string `json:"updated"` - Status string `json:"status"` - Chart string `json:"chart"` - AppVersion string `json:"app_version"` - Description string `json:"description"` + Revision int `json:"revision"` + Updated time.Time `json:"updated"` + Status string `json:"status"` + Chart string `json:"chart"` + AppVersion string `json:"app_version"` + Description string `json:"description"` } type releaseHistory []releaseInfo func (r releaseHistory) WriteJSON(out io.Writer) error { - return action.EncodeJSON(out, r) + return output.EncodeJSON(out, r) } func (r releaseHistory) WriteYAML(out io.Writer) error { - return action.EncodeYAML(out, r) + return output.EncodeYAML(out, r) } func (r releaseHistory) WriteTable(out io.Writer) error { tbl := uitable.New() tbl.AddRow("REVISION", "UPDATED", "STATUS", "CHART", "APP VERSION", "DESCRIPTION") for _, item := range r { - tbl.AddRow(item.Revision, item.Updated, item.Status, item.Chart, item.AppVersion, item.Description) + tbl.AddRow(item.Revision, item.Updated.Format(time.ANSIC), item.Status, item.Chart, item.AppVersion, item.Description) } - return action.EncodeTable(out, tbl) + return output.EncodeTable(out, tbl) } func getHistory(client *action.History, name string) (releaseHistory, error) { @@ -146,7 +142,7 @@ func getReleaseHistory(rls []*release.Release) (history releaseHistory) { Description: d, } if !r.Info.LastDeployed.IsZero() { - rInfo.Updated = r.Info.LastDeployed.String() + rInfo.Updated = r.Info.LastDeployed } history = append(history, rInfo) diff --git a/cmd/helm/install.go b/cmd/helm/install.go index a5a77cbc2..d43a12f80 100644 --- a/cmd/helm/install.go +++ b/cmd/helm/install.go @@ -28,6 +28,7 @@ import ( "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/chart" "helm.sh/helm/v3/pkg/chart/loader" + "helm.sh/helm/v3/pkg/cli/output" "helm.sh/helm/v3/pkg/cli/values" "helm.sh/helm/v3/pkg/downloader" "helm.sh/helm/v3/pkg/getter" @@ -104,6 +105,7 @@ charts in a repository, use 'helm search'. func newInstallCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { client := action.NewInstall(cfg) valueOpts := &values.Options{} + var outfmt output.Format cmd := &cobra.Command{ Use: "install [NAME] [CHART]", @@ -111,24 +113,17 @@ func newInstallCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { Long: installDesc, Args: require.MinimumNArgs(1), RunE: func(_ *cobra.Command, args []string) error { - // validate the output format first so we don't waste time running a - // request that we'll throw away - output, err := action.ParseOutputFormat(client.OutputFormat) - if err != nil { - return err - } - rel, err := runInstall(args, client, valueOpts, out) if err != nil { return err } - return output.Write(out, &statusPrinter{rel}) + return outfmt.Write(out, &statusPrinter{rel, settings.Debug}) }, } addInstallFlags(cmd.Flags(), client, valueOpts) - bindOutputFlag(cmd, &client.OutputFormat) + bindOutputFlag(cmd, &outfmt) return cmd } diff --git a/cmd/helm/list.go b/cmd/helm/list.go index 57af01e51..8c89425f5 100644 --- a/cmd/helm/list.go +++ b/cmd/helm/list.go @@ -26,6 +26,7 @@ import ( "helm.sh/helm/v3/cmd/helm/require" "helm.sh/helm/v3/pkg/action" + "helm.sh/helm/v3/pkg/cli/output" "helm.sh/helm/v3/pkg/release" ) @@ -58,6 +59,7 @@ flag with the '--offset' flag allows you to page through results. func newListCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { client := action.NewList(cfg) + var outfmt output.Format cmd := &cobra.Command{ Use: "list", @@ -66,13 +68,6 @@ func newListCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { Aliases: []string{"ls"}, Args: require.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { - // validate the output format first so we don't waste time running a - // request that we'll throw away - output, err := action.ParseOutputFormat(client.OutputFormat) - if err != nil { - return err - } - if client.AllNamespaces { initActionConfig(cfg, true) } @@ -87,7 +82,7 @@ func newListCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { return err } - return output.Write(out, newReleaseListWriter(results)) + return outfmt.Write(out, newReleaseListWriter(results)) }, } @@ -106,7 +101,7 @@ func newListCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { f.IntVarP(&client.Limit, "max", "m", 256, "maximum number of releases to fetch") f.IntVar(&client.Offset, "offset", 0, "next release name in the list, used to offset from start value") f.StringVarP(&client.Filter, "filter", "f", "", "a regular expression (Perl compatible). Any releases that match the expression will be included in the results") - bindOutputFlag(cmd, &client.OutputFormat) + bindOutputFlag(cmd, &outfmt) return cmd } @@ -153,13 +148,13 @@ func (r *releaseListWriter) WriteTable(out io.Writer) error { for _, r := range r.releases { table.AddRow(r.Name, r.Namespace, r.Revision, r.Updated, r.Status, r.Chart, r.AppVersion) } - return action.EncodeTable(out, table) + return output.EncodeTable(out, table) } func (r *releaseListWriter) WriteJSON(out io.Writer) error { - return action.EncodeJSON(out, r.releases) + return output.EncodeJSON(out, r.releases) } func (r *releaseListWriter) WriteYAML(out io.Writer) error { - return action.EncodeYAML(out, r.releases) + return output.EncodeYAML(out, r.releases) } diff --git a/cmd/helm/printer.go b/cmd/helm/printer.go index f8d1bd2d5..7cf7bf994 100644 --- a/cmd/helm/printer.go +++ b/cmd/helm/printer.go @@ -19,59 +19,8 @@ package main import ( "io" "text/template" - "time" - - "sigs.k8s.io/yaml" - - "helm.sh/helm/v3/pkg/chartutil" - "helm.sh/helm/v3/pkg/release" ) -var printReleaseTemplate = `REVISION: {{.Release.Version}} -RELEASED: {{.ReleaseDate}} -CHART: {{.Release.Chart.Metadata.Name}}-{{.Release.Chart.Metadata.Version}} -USER-SUPPLIED VALUES: -{{.Config}} -COMPUTED VALUES: -{{.ComputedValues}} -HOOKS: -{{- range .Release.Hooks }} ---- -# {{.Name}} -{{.Manifest}} -{{- end }} -MANIFEST: -{{.Release.Manifest}} -` - -func printRelease(out io.Writer, rel *release.Release) error { - if rel == nil { - return nil - } - - cfg, err := chartutil.CoalesceValues(rel.Chart, rel.Config) - if err != nil { - return err - } - computed, err := cfg.YAML() - if err != nil { - return err - } - - config, err := yaml.Marshal(rel.Config) - if err != nil { - return err - } - - data := map[string]interface{}{ - "Release": rel, - "Config": string(config), - "ComputedValues": computed, - "ReleaseDate": rel.Info.LastDeployed.Format(time.ANSIC), - } - return tpl(printReleaseTemplate, data, out) -} - func tpl(t string, vals map[string]interface{}, out io.Writer) error { tt, err := template.New("_").Parse(t) if err != nil { diff --git a/cmd/helm/repo_list.go b/cmd/helm/repo_list.go index b0050682a..10d8976fe 100644 --- a/cmd/helm/repo_list.go +++ b/cmd/helm/repo_list.go @@ -24,24 +24,18 @@ import ( "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/require" - "helm.sh/helm/v3/pkg/action" + "helm.sh/helm/v3/pkg/cli/output" "helm.sh/helm/v3/pkg/repo" ) func newRepoListCmd(out io.Writer) *cobra.Command { - var output string + var outfmt output.Format cmd := &cobra.Command{ Use: "list", Aliases: []string{"ls"}, Short: "list chart repositories", Args: require.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { - // validate the output format first so we don't waste time running a - // request that we'll throw away - outfmt, err := action.ParseOutputFormat(output) - if err != nil { - return err - } f, err := repo.LoadFile(settings.RepositoryConfig) if isNotExist(err) || len(f.Repositories) == 0 { return errors.New("no repositories to show") @@ -51,7 +45,7 @@ func newRepoListCmd(out io.Writer) *cobra.Command { }, } - bindOutputFlag(cmd, &output) + bindOutputFlag(cmd, &outfmt) return cmd } @@ -71,18 +65,18 @@ func (r *repoListWriter) WriteTable(out io.Writer) error { for _, re := range r.repos { table.AddRow(re.Name, re.URL) } - return action.EncodeTable(out, table) + return output.EncodeTable(out, table) } func (r *repoListWriter) WriteJSON(out io.Writer) error { - return r.encodeByFormat(out, action.JSON) + return r.encodeByFormat(out, output.JSON) } func (r *repoListWriter) WriteYAML(out io.Writer) error { - return r.encodeByFormat(out, action.YAML) + return r.encodeByFormat(out, output.YAML) } -func (r *repoListWriter) encodeByFormat(out io.Writer, format action.OutputFormat) error { +func (r *repoListWriter) encodeByFormat(out io.Writer, format output.Format) error { // Initialize the array so no results returns an empty array instead of null repolist := make([]repositoryElement, 0, len(r.repos)) @@ -91,10 +85,10 @@ func (r *repoListWriter) encodeByFormat(out io.Writer, format action.OutputForma } switch format { - case action.JSON: - return action.EncodeJSON(out, repolist) - case action.YAML: - return action.EncodeYAML(out, repolist) + case output.JSON: + return output.EncodeJSON(out, repolist) + case output.YAML: + return output.EncodeYAML(out, repolist) } // Because this is a non-exported function and only called internally by diff --git a/cmd/helm/search_hub.go b/cmd/helm/search_hub.go index bf2a3aeab..e4c149f4a 100644 --- a/cmd/helm/search_hub.go +++ b/cmd/helm/search_hub.go @@ -26,7 +26,7 @@ import ( "github.com/spf13/cobra" "helm.sh/helm/v3/internal/monocular" - "helm.sh/helm/v3/pkg/action" + "helm.sh/helm/v3/pkg/cli/output" ) const searchHubDesc = ` @@ -44,7 +44,7 @@ Helm Hub. You can find it at https://github.com/helm/monocular type searchHubOptions struct { searchEndpoint string maxColWidth uint - outputFormat string + outputFormat output.Format } func newSearchHubCmd(out io.Writer) *cobra.Command { @@ -68,13 +68,6 @@ func newSearchHubCmd(out io.Writer) *cobra.Command { } func (o *searchHubOptions) run(out io.Writer, args []string) error { - // validate the output format first so we don't waste time running a - // request that we'll throw away - outfmt, err := action.ParseOutputFormat(o.outputFormat) - if err != nil { - return err - } - c, err := monocular.New(o.searchEndpoint) if err != nil { return errors.Wrap(err, fmt.Sprintf("unable to create connection to %q", o.searchEndpoint)) @@ -87,7 +80,7 @@ func (o *searchHubOptions) run(out io.Writer, args []string) error { return fmt.Errorf("unable to perform search against %q", o.searchEndpoint) } - return outfmt.Write(out, newHubSearchWriter(results, o.searchEndpoint, o.maxColWidth)) + return o.outputFormat.Write(out, newHubSearchWriter(results, o.searchEndpoint, o.maxColWidth)) } type hubChartElement struct { @@ -125,18 +118,18 @@ func (h *hubSearchWriter) WriteTable(out io.Writer) error { for _, r := range h.elements { table.AddRow(r.URL, r.Version, r.AppVersion, r.Description) } - return action.EncodeTable(out, table) + return output.EncodeTable(out, table) } func (h *hubSearchWriter) WriteJSON(out io.Writer) error { - return h.encodeByFormat(out, action.JSON) + return h.encodeByFormat(out, output.JSON) } func (h *hubSearchWriter) WriteYAML(out io.Writer) error { - return h.encodeByFormat(out, action.YAML) + return h.encodeByFormat(out, output.YAML) } -func (h *hubSearchWriter) encodeByFormat(out io.Writer, format action.OutputFormat) error { +func (h *hubSearchWriter) encodeByFormat(out io.Writer, format output.Format) error { // Initialize the array so no results returns an empty array instead of null chartList := make([]hubChartElement, 0, len(h.elements)) @@ -145,10 +138,10 @@ func (h *hubSearchWriter) encodeByFormat(out io.Writer, format action.OutputForm } switch format { - case action.JSON: - return action.EncodeJSON(out, chartList) - case action.YAML: - return action.EncodeYAML(out, chartList) + case output.JSON: + return output.EncodeJSON(out, chartList) + case output.YAML: + return output.EncodeYAML(out, chartList) } // Because this is a non-exported function and only called internally by diff --git a/cmd/helm/search_repo.go b/cmd/helm/search_repo.go index a30629420..9a448f75f 100644 --- a/cmd/helm/search_repo.go +++ b/cmd/helm/search_repo.go @@ -28,7 +28,7 @@ import ( "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/search" - "helm.sh/helm/v3/pkg/action" + "helm.sh/helm/v3/pkg/cli/output" "helm.sh/helm/v3/pkg/helmpath" "helm.sh/helm/v3/pkg/repo" ) @@ -51,7 +51,7 @@ type searchRepoOptions struct { maxColWidth uint repoFile string repoCacheDir string - outputFormat string + outputFormat output.Format } func newSearchRepoCmd(out io.Writer) *cobra.Command { @@ -79,13 +79,6 @@ func newSearchRepoCmd(out io.Writer) *cobra.Command { } func (o *searchRepoOptions) run(out io.Writer, args []string) error { - // validate the output format first so we don't waste time running a - // request that we'll throw away - outfmt, err := action.ParseOutputFormat(o.outputFormat) - if err != nil { - return err - } - index, err := o.buildIndex(out) if err != nil { return err @@ -108,7 +101,7 @@ func (o *searchRepoOptions) run(out io.Writer, args []string) error { return err } - return outfmt.Write(out, &repoSearchWriter{data, o.maxColWidth}) + return o.outputFormat.Write(out, &repoSearchWriter{data, o.maxColWidth}) } func (o *searchRepoOptions) applyConstraint(res []*search.Result) ([]*search.Result, error) { @@ -188,18 +181,18 @@ func (r *repoSearchWriter) WriteTable(out io.Writer) error { for _, r := range r.results { table.AddRow(r.Name, r.Chart.Version, r.Chart.AppVersion, r.Chart.Description) } - return action.EncodeTable(out, table) + return output.EncodeTable(out, table) } func (r *repoSearchWriter) WriteJSON(out io.Writer) error { - return r.encodeByFormat(out, action.JSON) + return r.encodeByFormat(out, output.JSON) } func (r *repoSearchWriter) WriteYAML(out io.Writer) error { - return r.encodeByFormat(out, action.YAML) + return r.encodeByFormat(out, output.YAML) } -func (r *repoSearchWriter) encodeByFormat(out io.Writer, format action.OutputFormat) error { +func (r *repoSearchWriter) encodeByFormat(out io.Writer, format output.Format) error { // Initialize the array so no results returns an empty array instead of null chartList := make([]repoChartElement, 0, len(r.results)) @@ -208,10 +201,10 @@ func (r *repoSearchWriter) encodeByFormat(out io.Writer, format action.OutputFor } switch format { - case action.JSON: - return action.EncodeJSON(out, chartList) - case action.YAML: - return action.EncodeYAML(out, chartList) + case output.JSON: + return output.EncodeJSON(out, chartList) + case output.YAML: + return output.EncodeYAML(out, chartList) } // Because this is a non-exported function and only called internally by diff --git a/cmd/helm/status.go b/cmd/helm/status.go index af08d92ab..b1475be38 100644 --- a/cmd/helm/status.go +++ b/cmd/helm/status.go @@ -17,12 +17,17 @@ limitations under the License. package main import ( + "fmt" "io" + "strings" + "time" "github.com/spf13/cobra" "helm.sh/helm/v3/cmd/helm/require" "helm.sh/helm/v3/pkg/action" + "helm.sh/helm/v3/pkg/chartutil" + "helm.sh/helm/v3/pkg/cli/output" "helm.sh/helm/v3/pkg/release" ) @@ -39,6 +44,7 @@ The status consists of: func newStatusCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { client := action.NewStatus(cfg) + var outfmt output.Format cmd := &cobra.Command{ Use: "status RELEASE_NAME", @@ -46,13 +52,6 @@ func newStatusCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { Long: statusHelp, Args: require.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - // validate the output format first so we don't waste time running a - // request that we'll throw away - outfmt, err := action.ParseOutputFormat(client.OutputFormat) - if err != nil { - return err - } - rel, err := client.Run(args[0]) if err != nil { return err @@ -61,30 +60,105 @@ func newStatusCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { // strip chart metadata from the output rel.Chart = nil - return outfmt.Write(out, &statusPrinter{rel}) + return outfmt.Write(out, &statusPrinter{rel, false}) }, } f := cmd.PersistentFlags() f.IntVar(&client.Version, "revision", 0, "if set, display the status of the named release with revision") - bindOutputFlag(cmd, &client.OutputFormat) + bindOutputFlag(cmd, &outfmt) return cmd } type statusPrinter struct { release *release.Release + debug bool } func (s statusPrinter) WriteJSON(out io.Writer) error { - return action.EncodeJSON(out, s.release) + return output.EncodeJSON(out, s.release) } func (s statusPrinter) WriteYAML(out io.Writer) error { - return action.EncodeYAML(out, s.release) + return output.EncodeYAML(out, s.release) } func (s statusPrinter) WriteTable(out io.Writer) error { - action.PrintRelease(out, s.release) + if s.release == nil { + return nil + } + fmt.Fprintf(out, "NAME: %s\n", s.release.Name) + if !s.release.Info.LastDeployed.IsZero() { + fmt.Fprintf(out, "LAST DEPLOYED: %s\n", s.release.Info.LastDeployed.Format(time.ANSIC)) + } + fmt.Fprintf(out, "NAMESPACE: %s\n", s.release.Namespace) + fmt.Fprintf(out, "STATUS: %s\n", s.release.Info.Status.String()) + fmt.Fprintf(out, "REVISION: %d\n", s.release.Version) + + executions := executionsByHookEvent(s.release) + if tests, ok := executions[release.HookTest]; ok { + for _, h := range tests { + // Don't print anything if hook has not been initiated + if h.LastRun.StartedAt.IsZero() { + continue + } + fmt.Fprintf(out, "TEST SUITE: %s\n%s\n%s\n%s\n\n", + h.Name, + fmt.Sprintf("Last Started: %s", h.LastRun.StartedAt.Format(time.ANSIC)), + fmt.Sprintf("Last Completed: %s", h.LastRun.CompletedAt.Format(time.ANSIC)), + fmt.Sprintf("Phase: %s", h.LastRun.Phase), + ) + } + } + + if s.debug { + fmt.Fprintln(out, "USER-SUPPLIED VALUES:") + err := output.EncodeYAML(out, s.release.Config) + if err != nil { + return err + } + // Print an extra newline + fmt.Fprintln(out) + + cfg, err := chartutil.CoalesceValues(s.release.Chart, s.release.Config) + if err != nil { + return err + } + + fmt.Fprintln(out, "COMPUTED VALUES:") + err = output.EncodeYAML(out, cfg.AsMap()) + if err != nil { + return err + } + // Print an extra newline + fmt.Fprintln(out) + } + + if strings.EqualFold(s.release.Info.Description, "Dry run complete") || s.debug { + fmt.Fprintln(out, "HOOKS:") + for _, h := range s.release.Hooks { + fmt.Fprintf(out, "---\n# Source: %s\n%s\n", h.Path, h.Manifest) + } + fmt.Fprintf(out, "MANIFEST:\n%s\n", s.release.Manifest) + } + + if len(s.release.Info.Notes) > 0 { + fmt.Fprintf(out, "NOTES:\n%s\n", strings.TrimSpace(s.release.Info.Notes)) + } return nil } + +func executionsByHookEvent(rel *release.Release) map[release.HookEvent][]*release.Hook { + result := make(map[release.HookEvent][]*release.Hook) + for _, h := range rel.Hooks { + for _, e := range h.Events { + executions, ok := result[e] + if !ok { + executions = []*release.Hook{} + } + result[e] = append(executions, h) + } + } + return result +} diff --git a/cmd/helm/testdata/output/get-release.txt b/cmd/helm/testdata/output/get-release.txt index 2c6127f33..e12ed19cd 100644 --- a/cmd/helm/testdata/output/get-release.txt +++ b/cmd/helm/testdata/output/get-release.txt @@ -1,6 +1,8 @@ +NAME: thomas-guide +LAST DEPLOYED: Fri Sep 2 22:04:05 1977 +NAMESPACE: default +STATUS: deployed REVISION: 1 -RELEASED: Fri Sep 2 22:04:05 1977 -CHART: foo-0.1.0-beta.1 USER-SUPPLIED VALUES: name: value @@ -9,7 +11,7 @@ name: value HOOKS: --- -# pre-install-hook +# Source: pre-install-hook.yaml apiVersion: v1 kind: Job metadata: diff --git a/cmd/helm/testdata/output/history-limit.txt b/cmd/helm/testdata/output/history-limit.txt index 92ce86edf..aee0fadb2 100644 --- a/cmd/helm/testdata/output/history-limit.txt +++ b/cmd/helm/testdata/output/history-limit.txt @@ -1,3 +1,3 @@ -REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION -3 1977-09-02 22:04:05 +0000 UTC superseded foo-0.1.0-beta.1 1.0 Release mock -4 1977-09-02 22:04:05 +0000 UTC deployed foo-0.1.0-beta.1 1.0 Release mock +REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION +3 Fri Sep 2 22:04:05 1977 superseded foo-0.1.0-beta.1 1.0 Release mock +4 Fri Sep 2 22:04:05 1977 deployed foo-0.1.0-beta.1 1.0 Release mock diff --git a/cmd/helm/testdata/output/history.json b/cmd/helm/testdata/output/history.json index 364007f3c..35311d3ce 100644 --- a/cmd/helm/testdata/output/history.json +++ b/cmd/helm/testdata/output/history.json @@ -1 +1 @@ -[{"revision":3,"updated":"1977-09-02 22:04:05 +0000 UTC","status":"superseded","chart":"foo-0.1.0-beta.1","app_version":"1.0","description":"Release mock"},{"revision":4,"updated":"1977-09-02 22:04:05 +0000 UTC","status":"deployed","chart":"foo-0.1.0-beta.1","app_version":"1.0","description":"Release mock"}] +[{"revision":3,"updated":"1977-09-02T22:04:05Z","status":"superseded","chart":"foo-0.1.0-beta.1","app_version":"1.0","description":"Release mock"},{"revision":4,"updated":"1977-09-02T22:04:05Z","status":"deployed","chart":"foo-0.1.0-beta.1","app_version":"1.0","description":"Release mock"}] diff --git a/cmd/helm/testdata/output/history.txt b/cmd/helm/testdata/output/history.txt index a6161b524..2a5d69c11 100644 --- a/cmd/helm/testdata/output/history.txt +++ b/cmd/helm/testdata/output/history.txt @@ -1,5 +1,5 @@ -REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION -1 1977-09-02 22:04:05 +0000 UTC superseded foo-0.1.0-beta.1 1.0 Release mock -2 1977-09-02 22:04:05 +0000 UTC superseded foo-0.1.0-beta.1 1.0 Release mock -3 1977-09-02 22:04:05 +0000 UTC superseded foo-0.1.0-beta.1 1.0 Release mock -4 1977-09-02 22:04:05 +0000 UTC deployed foo-0.1.0-beta.1 1.0 Release mock +REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION +1 Fri Sep 2 22:04:05 1977 superseded foo-0.1.0-beta.1 1.0 Release mock +2 Fri Sep 2 22:04:05 1977 superseded foo-0.1.0-beta.1 1.0 Release mock +3 Fri Sep 2 22:04:05 1977 superseded foo-0.1.0-beta.1 1.0 Release mock +4 Fri Sep 2 22:04:05 1977 deployed foo-0.1.0-beta.1 1.0 Release mock diff --git a/cmd/helm/testdata/output/history.yaml b/cmd/helm/testdata/output/history.yaml index d315b6fc9..b7ae03be7 100644 --- a/cmd/helm/testdata/output/history.yaml +++ b/cmd/helm/testdata/output/history.yaml @@ -3,10 +3,10 @@ description: Release mock revision: 3 status: superseded - updated: 1977-09-02 22:04:05 +0000 UTC + updated: "1977-09-02T22:04:05Z" - app_version: "1.0" chart: foo-0.1.0-beta.1 description: Release mock revision: 4 status: deployed - updated: 1977-09-02 22:04:05 +0000 UTC + updated: "1977-09-02T22:04:05Z" diff --git a/cmd/helm/testdata/output/install-and-replace.txt b/cmd/helm/testdata/output/install-and-replace.txt index 2dd9e3335..0a9aa1803 100644 --- a/cmd/helm/testdata/output/install-and-replace.txt +++ b/cmd/helm/testdata/output/install-and-replace.txt @@ -1,4 +1,5 @@ NAME: aeneas -LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC +LAST DEPLOYED: Fri Sep 2 22:04:05 1977 NAMESPACE: default STATUS: deployed +REVISION: 1 diff --git a/cmd/helm/testdata/output/install-name-template.txt b/cmd/helm/testdata/output/install-name-template.txt index f82687f9b..70d9b71b9 100644 --- a/cmd/helm/testdata/output/install-name-template.txt +++ b/cmd/helm/testdata/output/install-name-template.txt @@ -1,4 +1,5 @@ NAME: FOOBAR -LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC +LAST DEPLOYED: Fri Sep 2 22:04:05 1977 NAMESPACE: default STATUS: deployed +REVISION: 1 diff --git a/cmd/helm/testdata/output/install-no-hooks.txt b/cmd/helm/testdata/output/install-no-hooks.txt index 2dd9e3335..0a9aa1803 100644 --- a/cmd/helm/testdata/output/install-no-hooks.txt +++ b/cmd/helm/testdata/output/install-no-hooks.txt @@ -1,4 +1,5 @@ NAME: aeneas -LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC +LAST DEPLOYED: Fri Sep 2 22:04:05 1977 NAMESPACE: default STATUS: deployed +REVISION: 1 diff --git a/cmd/helm/testdata/output/install-with-multiple-values-files.txt b/cmd/helm/testdata/output/install-with-multiple-values-files.txt index f64fd64a8..201e74927 100644 --- a/cmd/helm/testdata/output/install-with-multiple-values-files.txt +++ b/cmd/helm/testdata/output/install-with-multiple-values-files.txt @@ -1,4 +1,5 @@ NAME: virgil -LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC +LAST DEPLOYED: Fri Sep 2 22:04:05 1977 NAMESPACE: default STATUS: deployed +REVISION: 1 diff --git a/cmd/helm/testdata/output/install-with-multiple-values.txt b/cmd/helm/testdata/output/install-with-multiple-values.txt index f64fd64a8..201e74927 100644 --- a/cmd/helm/testdata/output/install-with-multiple-values.txt +++ b/cmd/helm/testdata/output/install-with-multiple-values.txt @@ -1,4 +1,5 @@ NAME: virgil -LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC +LAST DEPLOYED: Fri Sep 2 22:04:05 1977 NAMESPACE: default STATUS: deployed +REVISION: 1 diff --git a/cmd/helm/testdata/output/install-with-timeout.txt b/cmd/helm/testdata/output/install-with-timeout.txt index 97e3a1a95..9115085db 100644 --- a/cmd/helm/testdata/output/install-with-timeout.txt +++ b/cmd/helm/testdata/output/install-with-timeout.txt @@ -1,4 +1,5 @@ NAME: foobar -LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC +LAST DEPLOYED: Fri Sep 2 22:04:05 1977 NAMESPACE: default STATUS: deployed +REVISION: 1 diff --git a/cmd/helm/testdata/output/install-with-values-file.txt b/cmd/helm/testdata/output/install-with-values-file.txt index f64fd64a8..201e74927 100644 --- a/cmd/helm/testdata/output/install-with-values-file.txt +++ b/cmd/helm/testdata/output/install-with-values-file.txt @@ -1,4 +1,5 @@ NAME: virgil -LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC +LAST DEPLOYED: Fri Sep 2 22:04:05 1977 NAMESPACE: default STATUS: deployed +REVISION: 1 diff --git a/cmd/helm/testdata/output/install-with-values.txt b/cmd/helm/testdata/output/install-with-values.txt index f64fd64a8..201e74927 100644 --- a/cmd/helm/testdata/output/install-with-values.txt +++ b/cmd/helm/testdata/output/install-with-values.txt @@ -1,4 +1,5 @@ NAME: virgil -LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC +LAST DEPLOYED: Fri Sep 2 22:04:05 1977 NAMESPACE: default STATUS: deployed +REVISION: 1 diff --git a/cmd/helm/testdata/output/install-with-wait.txt b/cmd/helm/testdata/output/install-with-wait.txt index a1cb43db0..a5609edb7 100644 --- a/cmd/helm/testdata/output/install-with-wait.txt +++ b/cmd/helm/testdata/output/install-with-wait.txt @@ -1,4 +1,5 @@ NAME: apollo -LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC +LAST DEPLOYED: Fri Sep 2 22:04:05 1977 NAMESPACE: default STATUS: deployed +REVISION: 1 diff --git a/cmd/helm/testdata/output/install.txt b/cmd/helm/testdata/output/install.txt index 2dd9e3335..0a9aa1803 100644 --- a/cmd/helm/testdata/output/install.txt +++ b/cmd/helm/testdata/output/install.txt @@ -1,4 +1,5 @@ NAME: aeneas -LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC +LAST DEPLOYED: Fri Sep 2 22:04:05 1977 NAMESPACE: default STATUS: deployed +REVISION: 1 diff --git a/cmd/helm/testdata/output/schema.txt b/cmd/helm/testdata/output/schema.txt index 945f17d42..7424e723e 100644 --- a/cmd/helm/testdata/output/schema.txt +++ b/cmd/helm/testdata/output/schema.txt @@ -1,4 +1,5 @@ NAME: schema -LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC +LAST DEPLOYED: Fri Sep 2 22:04:05 1977 NAMESPACE: default STATUS: deployed +REVISION: 1 diff --git a/cmd/helm/testdata/output/status-with-notes.txt b/cmd/helm/testdata/output/status-with-notes.txt index 96b06e363..f460b343d 100644 --- a/cmd/helm/testdata/output/status-with-notes.txt +++ b/cmd/helm/testdata/output/status-with-notes.txt @@ -1,6 +1,7 @@ NAME: flummoxed-chickadee -LAST DEPLOYED: 2016-01-16 00:00:00 +0000 UTC +LAST DEPLOYED: Sat Jan 16 00:00:00 2016 NAMESPACE: default STATUS: deployed +REVISION: 0 NOTES: release notes diff --git a/cmd/helm/testdata/output/status-with-test-suite.txt b/cmd/helm/testdata/output/status-with-test-suite.txt index 7ff195d82..79ea4e442 100644 --- a/cmd/helm/testdata/output/status-with-test-suite.txt +++ b/cmd/helm/testdata/output/status-with-test-suite.txt @@ -1,14 +1,15 @@ NAME: flummoxed-chickadee -LAST DEPLOYED: 2016-01-16 00:00:00 +0000 UTC +LAST DEPLOYED: Sat Jan 16 00:00:00 2016 NAMESPACE: default STATUS: deployed +REVISION: 0 TEST SUITE: passing-test -Last Started: 2006-01-02 15:04:05 +0000 UTC -Last Completed: 2006-01-02 15:04:07 +0000 UTC +Last Started: Mon Jan 2 15:04:05 2006 +Last Completed: Mon Jan 2 15:04:07 2006 Phase: Succeeded TEST SUITE: failing-test -Last Started: 2006-01-02 15:10:05 +0000 UTC -Last Completed: 2006-01-02 15:10:07 +0000 UTC +Last Started: Mon Jan 2 15:10:05 2006 +Last Completed: Mon Jan 2 15:10:07 2006 Phase: Failed diff --git a/cmd/helm/testdata/output/status.txt b/cmd/helm/testdata/output/status.txt index 94c0cf899..9d89842db 100644 --- a/cmd/helm/testdata/output/status.txt +++ b/cmd/helm/testdata/output/status.txt @@ -1,4 +1,5 @@ NAME: flummoxed-chickadee -LAST DEPLOYED: 2016-01-16 00:00:00 +0000 UTC +LAST DEPLOYED: Sat Jan 16 00:00:00 2016 NAMESPACE: default STATUS: deployed +REVISION: 0 diff --git a/cmd/helm/testdata/output/subchart-schema-cli.txt b/cmd/helm/testdata/output/subchart-schema-cli.txt index 945f17d42..7424e723e 100644 --- a/cmd/helm/testdata/output/subchart-schema-cli.txt +++ b/cmd/helm/testdata/output/subchart-schema-cli.txt @@ -1,4 +1,5 @@ NAME: schema -LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC +LAST DEPLOYED: Fri Sep 2 22:04:05 1977 NAMESPACE: default STATUS: deployed +REVISION: 1 diff --git a/cmd/helm/testdata/output/upgrade-with-install-timeout.txt b/cmd/helm/testdata/output/upgrade-with-install-timeout.txt index 7d433a51b..e49fb7dc4 100644 --- a/cmd/helm/testdata/output/upgrade-with-install-timeout.txt +++ b/cmd/helm/testdata/output/upgrade-with-install-timeout.txt @@ -1,5 +1,6 @@ Release "crazy-bunny" has been upgraded. Happy Helming! NAME: crazy-bunny -LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC +LAST DEPLOYED: Fri Sep 2 22:04:05 1977 NAMESPACE: default STATUS: deployed +REVISION: 2 diff --git a/cmd/helm/testdata/output/upgrade-with-install.txt b/cmd/helm/testdata/output/upgrade-with-install.txt index 98df9d332..bf8b8c403 100644 --- a/cmd/helm/testdata/output/upgrade-with-install.txt +++ b/cmd/helm/testdata/output/upgrade-with-install.txt @@ -1,5 +1,6 @@ Release "zany-bunny" has been upgraded. Happy Helming! NAME: zany-bunny -LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC +LAST DEPLOYED: Fri Sep 2 22:04:05 1977 NAMESPACE: default STATUS: deployed +REVISION: 2 diff --git a/cmd/helm/testdata/output/upgrade-with-reset-values.txt b/cmd/helm/testdata/output/upgrade-with-reset-values.txt index be776ed4f..dfb8fec5c 100644 --- a/cmd/helm/testdata/output/upgrade-with-reset-values.txt +++ b/cmd/helm/testdata/output/upgrade-with-reset-values.txt @@ -1,5 +1,6 @@ Release "funny-bunny" has been upgraded. Happy Helming! NAME: funny-bunny -LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC +LAST DEPLOYED: Fri Sep 2 22:04:05 1977 NAMESPACE: default STATUS: deployed +REVISION: 5 diff --git a/cmd/helm/testdata/output/upgrade-with-reset-values2.txt b/cmd/helm/testdata/output/upgrade-with-reset-values2.txt index be776ed4f..34fbe3d07 100644 --- a/cmd/helm/testdata/output/upgrade-with-reset-values2.txt +++ b/cmd/helm/testdata/output/upgrade-with-reset-values2.txt @@ -1,5 +1,6 @@ Release "funny-bunny" has been upgraded. Happy Helming! NAME: funny-bunny -LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC +LAST DEPLOYED: Fri Sep 2 22:04:05 1977 NAMESPACE: default STATUS: deployed +REVISION: 6 diff --git a/cmd/helm/testdata/output/upgrade-with-timeout.txt b/cmd/helm/testdata/output/upgrade-with-timeout.txt index be776ed4f..7b4181f09 100644 --- a/cmd/helm/testdata/output/upgrade-with-timeout.txt +++ b/cmd/helm/testdata/output/upgrade-with-timeout.txt @@ -1,5 +1,6 @@ Release "funny-bunny" has been upgraded. Happy Helming! NAME: funny-bunny -LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC +LAST DEPLOYED: Fri Sep 2 22:04:05 1977 NAMESPACE: default STATUS: deployed +REVISION: 4 diff --git a/cmd/helm/testdata/output/upgrade-with-wait.txt b/cmd/helm/testdata/output/upgrade-with-wait.txt index 7d433a51b..f47ac718d 100644 --- a/cmd/helm/testdata/output/upgrade-with-wait.txt +++ b/cmd/helm/testdata/output/upgrade-with-wait.txt @@ -1,5 +1,6 @@ Release "crazy-bunny" has been upgraded. Happy Helming! NAME: crazy-bunny -LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC +LAST DEPLOYED: Fri Sep 2 22:04:05 1977 NAMESPACE: default STATUS: deployed +REVISION: 3 diff --git a/cmd/helm/testdata/output/upgrade.txt b/cmd/helm/testdata/output/upgrade.txt index be776ed4f..0f070cce5 100644 --- a/cmd/helm/testdata/output/upgrade.txt +++ b/cmd/helm/testdata/output/upgrade.txt @@ -1,5 +1,6 @@ Release "funny-bunny" has been upgraded. Happy Helming! NAME: funny-bunny -LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC +LAST DEPLOYED: Fri Sep 2 22:04:05 1977 NAMESPACE: default STATUS: deployed +REVISION: 3 diff --git a/cmd/helm/upgrade.go b/cmd/helm/upgrade.go index 5c107d2df..33631504f 100644 --- a/cmd/helm/upgrade.go +++ b/cmd/helm/upgrade.go @@ -27,6 +27,7 @@ import ( "helm.sh/helm/v3/cmd/helm/require" "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/chart/loader" + "helm.sh/helm/v3/pkg/cli/output" "helm.sh/helm/v3/pkg/cli/values" "helm.sh/helm/v3/pkg/getter" "helm.sh/helm/v3/pkg/storage/driver" @@ -62,6 +63,7 @@ set for a key called 'foo', the 'newbar' value would take precedence: func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { client := action.NewUpgrade(cfg) valueOpts := &values.Options{} + var outfmt output.Format cmd := &cobra.Command{ Use: "upgrade [RELEASE] [CHART]", @@ -69,13 +71,6 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { Long: upgradeDesc, Args: require.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - // validate the output format first so we don't waste time running a - // request that we'll throw away - output, err := action.ParseOutputFormat(client.OutputFormat) - if err != nil { - return err - } - client.Namespace = getNamespace() if client.Version == "" && client.Devel { @@ -99,7 +94,10 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { histClient := action.NewHistory(cfg) histClient.Max = 1 if _, err := histClient.Run(args[0]); err == driver.ErrReleaseNotFound { - fmt.Fprintf(out, "Release %q does not exist. Installing it now.\n", args[0]) + // Only print this to stdout for table output + if outfmt == output.Table { + fmt.Fprintf(out, "Release %q does not exist. Installing it now.\n", args[0]) + } instClient := action.NewInstall(cfg) instClient.ChartPathOptions = client.ChartPathOptions instClient.DryRun = client.DryRun @@ -114,7 +112,7 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { if err != nil { return err } - return output.Write(out, &statusPrinter{rel}) + return outfmt.Write(out, &statusPrinter{rel, settings.Debug}) } } @@ -129,27 +127,16 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { } } - resp, err := client.Run(args[0], ch, vals) + rel, err := client.Run(args[0], ch, vals) if err != nil { return errors.Wrap(err, "UPGRADE FAILED") } - if settings.Debug { - action.PrintRelease(out, resp) - } - - if output == action.Table { + if outfmt == output.Table { fmt.Fprintf(out, "Release %q has been upgraded. Happy Helming!\n", args[0]) } - // Print the status like status command does - statusClient := action.NewStatus(cfg) - rel, err := statusClient.Run(args[0]) - if err != nil { - return err - } - - return output.Write(out, &statusPrinter{rel}) + return outfmt.Write(out, &statusPrinter{rel, settings.Debug}) }, } @@ -171,7 +158,7 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { f.BoolVar(&client.SubNotes, "render-subchart-notes", false, "if set, render subchart notes along with the parent") addChartPathOptionsFlags(f, &client.ChartPathOptions) addValueOptionsFlags(f, valueOpts) - bindOutputFlag(cmd, &client.OutputFormat) + bindOutputFlag(cmd, &outfmt) return cmd } diff --git a/pkg/action/history.go b/pkg/action/history.go index 350876a9d..a592745e9 100644 --- a/pkg/action/history.go +++ b/pkg/action/history.go @@ -28,8 +28,8 @@ import ( type History struct { cfg *Configuration - Max int - OutputFormat string + Max int + Version int } // NewHistory creates a new History object with the given configuration. diff --git a/pkg/action/install.go b/pkg/action/install.go index 0badcdb58..b8f9eb585 100644 --- a/pkg/action/install.go +++ b/pkg/action/install.go @@ -82,7 +82,6 @@ type Install struct { OutputDir string Atomic bool SkipCRDs bool - OutputFormat string SubNotes bool } diff --git a/pkg/action/list.go b/pkg/action/list.go index 6fb36ef40..f72edc83b 100644 --- a/pkg/action/list.go +++ b/pkg/action/list.go @@ -125,7 +125,6 @@ type List struct { Deployed bool Failed bool Pending bool - OutputFormat string } // NewList constructs a new *List diff --git a/pkg/action/printer.go b/pkg/action/printer.go deleted file mode 100644 index 7133e4d1b..000000000 --- a/pkg/action/printer.go +++ /dev/null @@ -1,76 +0,0 @@ -/* -Copyright The Helm Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package action - -import ( - "fmt" - "io" - "strings" - - "helm.sh/helm/v3/pkg/release" -) - -// PrintRelease prints info about a release -func PrintRelease(out io.Writer, rel *release.Release) { - if rel == nil { - return - } - fmt.Fprintf(out, "NAME: %s\n", rel.Name) - if !rel.Info.LastDeployed.IsZero() { - fmt.Fprintf(out, "LAST DEPLOYED: %s\n", rel.Info.LastDeployed) - } - fmt.Fprintf(out, "NAMESPACE: %s\n", rel.Namespace) - fmt.Fprintf(out, "STATUS: %s\n", rel.Info.Status.String()) - - executions := executionsByHookEvent(rel) - if tests, ok := executions[release.HookTest]; ok { - for _, h := range tests { - // Don't print anything if hook has not been initiated - if h.LastRun.StartedAt.IsZero() { - continue - } - fmt.Fprintf(out, "TEST SUITE: %s\n%s\n%s\n%s\n\n", - h.Name, - fmt.Sprintf("Last Started: %s", h.LastRun.StartedAt), - fmt.Sprintf("Last Completed: %s", h.LastRun.CompletedAt), - fmt.Sprintf("Phase: %s", h.LastRun.Phase), - ) - } - } - - if strings.EqualFold(rel.Info.Description, "Dry run complete") { - fmt.Fprintf(out, "MANIFEST:\n%s\n", rel.Manifest) - } - - if len(rel.Info.Notes) > 0 { - fmt.Fprintf(out, "NOTES:\n%s\n", strings.TrimSpace(rel.Info.Notes)) - } -} - -func executionsByHookEvent(rel *release.Release) map[release.HookEvent][]*release.Hook { - result := make(map[release.HookEvent][]*release.Hook) - for _, h := range rel.Hooks { - for _, e := range h.Events { - executions, ok := result[e] - if !ok { - executions = []*release.Hook{} - } - result[e] = append(executions, h) - } - } - return result -} diff --git a/pkg/action/status.go b/pkg/action/status.go index 5e873ddd8..a0c7f6e21 100644 --- a/pkg/action/status.go +++ b/pkg/action/status.go @@ -26,8 +26,7 @@ import ( type Status struct { cfg *Configuration - Version int - OutputFormat string + Version int } // NewStatus creates a new Status object with the given configuration. diff --git a/pkg/action/upgrade.go b/pkg/action/upgrade.go index f8fbbb442..1b7b19557 100644 --- a/pkg/action/upgrade.go +++ b/pkg/action/upgrade.go @@ -57,7 +57,6 @@ type Upgrade struct { MaxHistory int Atomic bool CleanupOnFail bool - OutputFormat string SubNotes bool } diff --git a/pkg/action/output.go b/pkg/cli/output/output.go similarity index 86% rename from pkg/action/output.go rename to pkg/cli/output/output.go index 0b3ee029a..da9ee63a8 100644 --- a/pkg/action/output.go +++ b/pkg/cli/output/output.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package action +package output import ( "encoding/json" @@ -26,26 +26,26 @@ import ( "sigs.k8s.io/yaml" ) -// OutputFormat is a type for capturing supported output formats -type OutputFormat string +// Format is a type for capturing supported output formats +type Format string const ( - Table OutputFormat = "table" - JSON OutputFormat = "json" - YAML OutputFormat = "yaml" + Table Format = "table" + JSON Format = "json" + YAML Format = "yaml" ) // ErrInvalidFormatType is returned when an unsupported format type is used var ErrInvalidFormatType = fmt.Errorf("invalid format type") -// String returns the string reprsentation of the OutputFormat -func (o OutputFormat) String() string { +// String returns the string reprsentation of the Format +func (o Format) String() string { return string(o) } // Write the output in the given format to the io.Writer. Unsupported formats // will return an error -func (o OutputFormat) Write(out io.Writer, w Writer) error { +func (o Format) Write(out io.Writer, w Writer) error { switch o { case Table: return w.WriteTable(out) @@ -57,9 +57,9 @@ func (o OutputFormat) Write(out io.Writer, w Writer) error { return ErrInvalidFormatType } -// ParseOutputFormat takes a raw string and returns the matching OutputFormat. +// ParseFormat takes a raw string and returns the matching Format. // If the format does not exists, ErrInvalidFormatType is returned -func ParseOutputFormat(s string) (out OutputFormat, err error) { +func ParseFormat(s string) (out Format, err error) { switch s { case Table.String(): out, err = Table, nil