1/*
2Copyright The Helm Authors.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8    http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17package main
18
19import (
20	"fmt"
21	"io"
22	"log"
23
24	"github.com/spf13/cobra"
25
26	"helm.sh/helm/v3/cmd/helm/require"
27	"helm.sh/helm/v3/pkg/action"
28)
29
30const showDesc = `
31This command consists of multiple subcommands to display information about a chart
32`
33
34const showAllDesc = `
35This command inspects a chart (directory, file, or URL) and displays all its content
36(values.yaml, Charts.yaml, README)
37`
38
39const showValuesDesc = `
40This command inspects a chart (directory, file, or URL) and displays the contents
41of the values.yaml file
42`
43
44const showChartDesc = `
45This command inspects a chart (directory, file, or URL) and displays the contents
46of the Charts.yaml file
47`
48
49const readmeChartDesc = `
50This command inspects a chart (directory, file, or URL) and displays the contents
51of the README file
52`
53
54func newShowCmd(out io.Writer) *cobra.Command {
55	client := action.NewShow(action.ShowAll)
56
57	showCommand := &cobra.Command{
58		Use:               "show",
59		Short:             "show information of a chart",
60		Aliases:           []string{"inspect"},
61		Long:              showDesc,
62		Args:              require.NoArgs,
63		ValidArgsFunction: noCompletions, // Disable file completion
64	}
65
66	// Function providing dynamic auto-completion
67	validArgsFunc := func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
68		if len(args) != 0 {
69			return nil, cobra.ShellCompDirectiveNoFileComp
70		}
71		return compListCharts(toComplete, true)
72	}
73
74	all := &cobra.Command{
75		Use:               "all [CHART]",
76		Short:             "show all information of the chart",
77		Long:              showAllDesc,
78		Args:              require.ExactArgs(1),
79		ValidArgsFunction: validArgsFunc,
80		RunE: func(cmd *cobra.Command, args []string) error {
81			client.OutputFormat = action.ShowAll
82			output, err := runShow(args, client)
83			if err != nil {
84				return err
85			}
86			fmt.Fprint(out, output)
87			return nil
88		},
89	}
90
91	valuesSubCmd := &cobra.Command{
92		Use:               "values [CHART]",
93		Short:             "show the chart's values",
94		Long:              showValuesDesc,
95		Args:              require.ExactArgs(1),
96		ValidArgsFunction: validArgsFunc,
97		RunE: func(cmd *cobra.Command, args []string) error {
98			client.OutputFormat = action.ShowValues
99			output, err := runShow(args, client)
100			if err != nil {
101				return err
102			}
103			fmt.Fprint(out, output)
104			return nil
105		},
106	}
107
108	chartSubCmd := &cobra.Command{
109		Use:               "chart [CHART]",
110		Short:             "show the chart's definition",
111		Long:              showChartDesc,
112		Args:              require.ExactArgs(1),
113		ValidArgsFunction: validArgsFunc,
114		RunE: func(cmd *cobra.Command, args []string) error {
115			client.OutputFormat = action.ShowChart
116			output, err := runShow(args, client)
117			if err != nil {
118				return err
119			}
120			fmt.Fprint(out, output)
121			return nil
122		},
123	}
124
125	readmeSubCmd := &cobra.Command{
126		Use:               "readme [CHART]",
127		Short:             "show the chart's README",
128		Long:              readmeChartDesc,
129		Args:              require.ExactArgs(1),
130		ValidArgsFunction: validArgsFunc,
131		RunE: func(cmd *cobra.Command, args []string) error {
132			client.OutputFormat = action.ShowReadme
133			output, err := runShow(args, client)
134			if err != nil {
135				return err
136			}
137			fmt.Fprint(out, output)
138			return nil
139		},
140	}
141
142	cmds := []*cobra.Command{all, readmeSubCmd, valuesSubCmd, chartSubCmd}
143	for _, subCmd := range cmds {
144		addShowFlags(subCmd, client)
145		showCommand.AddCommand(subCmd)
146	}
147
148	return showCommand
149}
150
151func addShowFlags(subCmd *cobra.Command, client *action.Show) {
152	f := subCmd.Flags()
153
154	f.BoolVar(&client.Devel, "devel", false, "use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored")
155	if subCmd.Name() == "values" {
156		f.StringVar(&client.JSONPathTemplate, "jsonpath", "", "supply a JSONPath expression to filter the output")
157	}
158	addChartPathOptionsFlags(f, &client.ChartPathOptions)
159
160	err := subCmd.RegisterFlagCompletionFunc("version", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
161		if len(args) != 1 {
162			return nil, cobra.ShellCompDirectiveNoFileComp
163		}
164		return compVersionFlag(args[0], toComplete)
165	})
166
167	if err != nil {
168		log.Fatal(err)
169	}
170}
171
172func runShow(args []string, client *action.Show) (string, error) {
173	debug("Original chart version: %q", client.Version)
174	if client.Version == "" && client.Devel {
175		debug("setting version to >0.0.0-0")
176		client.Version = ">0.0.0-0"
177	}
178
179	cp, err := client.ChartPathOptions.LocateChart(args[0], settings)
180	if err != nil {
181		return "", err
182	}
183	return client.Run(cp)
184}
185