diff --git a/cmd/helm/inspect.go b/cmd/helm/inspect.go index 6369b5ddc..736f14fce 100644 --- a/cmd/helm/inspect.go +++ b/cmd/helm/inspect.go @@ -19,11 +19,14 @@ package main import ( "fmt" "io" + "strings" "github.com/ghodss/yaml" + "github.com/golang/protobuf/ptypes/any" "github.com/spf13/cobra" "k8s.io/helm/pkg/chartutil" + "k8s.io/kubernetes/pkg/util/slice" ) const inspectDesc = ` @@ -43,6 +46,11 @@ This command inspects a chart (directory, file, or URL) and displays the content of the Charts.yaml file ` +const readmeChartDesc = ` +This command inspects a chart (directory, file, or URL) and displays the contents +of the README file +` + type inspectCmd struct { chartpath string output string @@ -60,13 +68,16 @@ type inspectCmd struct { const ( chartOnly = "chart" valuesOnly = "values" - both = "both" + readmeOnly = "readme" + all = "all" ) +var readmeFileNames = []string{"readme.md", "readme.txt", "readme"} + func newInspectCmd(out io.Writer) *cobra.Command { insp := &inspectCmd{ out: out, - output: both, + output: all, } inspectCommand := &cobra.Command{ @@ -125,51 +136,72 @@ func newInspectCmd(out io.Writer) *cobra.Command { }, } + readmeSubCmd := &cobra.Command{ + Use: "readme [CHART]", + Short: "shows inspect readme", + Long: readmeChartDesc, + RunE: func(cmd *cobra.Command, args []string) error { + insp.output = readmeOnly + if err := checkArgsLength(len(args), "chart name"); err != nil { + return err + } + cp, err := locateChartPath(insp.repoURL, args[0], insp.version, insp.verify, insp.keyring, + insp.certFile, insp.keyFile, insp.caFile) + if err != nil { + return err + } + insp.chartpath = cp + return insp.run() + }, + } + + cmds := []*cobra.Command{inspectCommand, readmeSubCmd, valuesSubCmd, chartSubCmd} vflag := "verify" vdesc := "verify the provenance data for this chart" - inspectCommand.Flags().BoolVar(&insp.verify, vflag, false, vdesc) - valuesSubCmd.Flags().BoolVar(&insp.verify, vflag, false, vdesc) - chartSubCmd.Flags().BoolVar(&insp.verify, vflag, false, vdesc) + for _, subCmd := range cmds { + subCmd.Flags().BoolVar(&insp.verify, vflag, false, vdesc) + } kflag := "keyring" kdesc := "path to the keyring containing public verification keys" kdefault := defaultKeyring() - inspectCommand.Flags().StringVar(&insp.keyring, kflag, kdefault, kdesc) - valuesSubCmd.Flags().StringVar(&insp.keyring, kflag, kdefault, kdesc) - chartSubCmd.Flags().StringVar(&insp.keyring, kflag, kdefault, kdesc) + for _, subCmd := range cmds { + subCmd.Flags().StringVar(&insp.keyring, kflag, kdefault, kdesc) + } verflag := "version" verdesc := "version of the chart. By default, the newest chart is shown" - inspectCommand.Flags().StringVar(&insp.version, verflag, "", verdesc) - valuesSubCmd.Flags().StringVar(&insp.version, verflag, "", verdesc) - chartSubCmd.Flags().StringVar(&insp.version, verflag, "", verdesc) + for _, subCmd := range cmds { + subCmd.Flags().StringVar(&insp.version, verflag, "", verdesc) + } repoURL := "repo" repoURLdesc := "chart repository url where to locate the requested chart" - inspectCommand.Flags().StringVar(&insp.repoURL, repoURL, "", repoURLdesc) - valuesSubCmd.Flags().StringVar(&insp.repoURL, repoURL, "", repoURLdesc) - chartSubCmd.Flags().StringVar(&insp.repoURL, repoURL, "", repoURLdesc) + for _, subCmd := range cmds { + subCmd.Flags().StringVar(&insp.repoURL, repoURL, "", repoURLdesc) + } certFile := "cert-file" certFiledesc := "verify certificates of HTTPS-enabled servers using this CA bundle" - inspectCommand.Flags().StringVar(&insp.certFile, certFile, "", certFiledesc) - valuesSubCmd.Flags().StringVar(&insp.certFile, certFile, "", certFiledesc) - chartSubCmd.Flags().StringVar(&insp.certFile, certFile, "", certFiledesc) + for _, subCmd := range cmds { + subCmd.Flags().StringVar(&insp.certFile, certFile, "", certFiledesc) + } keyFile := "key-file" keyFiledesc := "identify HTTPS client using this SSL key file" - inspectCommand.Flags().StringVar(&insp.keyFile, keyFile, "", keyFiledesc) - valuesSubCmd.Flags().StringVar(&insp.keyFile, keyFile, "", keyFiledesc) - chartSubCmd.Flags().StringVar(&insp.keyFile, keyFile, "", keyFiledesc) + for _, subCmd := range cmds { + subCmd.Flags().StringVar(&insp.keyFile, keyFile, "", keyFiledesc) + } caFile := "ca-file" caFiledesc := "chart repository url where to locate the requested chart" - inspectCommand.Flags().StringVar(&insp.caFile, caFile, "", caFiledesc) - valuesSubCmd.Flags().StringVar(&insp.caFile, caFile, "", caFiledesc) - chartSubCmd.Flags().StringVar(&insp.caFile, caFile, "", caFiledesc) + for _, subCmd := range cmds { + subCmd.Flags().StringVar(&insp.caFile, caFile, "", caFiledesc) + } - inspectCommand.AddCommand(valuesSubCmd) - inspectCommand.AddCommand(chartSubCmd) + for _, subCmd := range cmds[1:] { + inspectCommand.AddCommand(subCmd) + } return inspectCommand } @@ -184,16 +216,35 @@ func (i *inspectCmd) run() error { return err } - if i.output == chartOnly || i.output == both { + if i.output == chartOnly || i.output == all { fmt.Fprintln(i.out, string(cf)) } - if (i.output == valuesOnly || i.output == both) && chrt.Values != nil { - if i.output == both { + if (i.output == valuesOnly || i.output == all) && chrt.Values != nil { + if i.output == all { fmt.Fprintln(i.out, "---") } fmt.Fprintln(i.out, chrt.Values.Raw) } + if i.output == readmeOnly || i.output == all { + if i.output == all { + fmt.Fprintln(i.out, "---") + } + readme := findReadme(chrt.Files) + if readme == nil { + return nil + } + fmt.Fprintln(i.out, string(readme.Value)) + } + return nil +} + +func findReadme(files []*any.Any) (file *any.Any) { + for _, file := range files { + if slice.ContainsString(readmeFileNames, strings.ToLower(file.TypeUrl), nil) { + return file + } + } return nil } diff --git a/cmd/helm/inspect_test.go b/cmd/helm/inspect_test.go index b34b793f6..44d71fbbd 100644 --- a/cmd/helm/inspect_test.go +++ b/cmd/helm/inspect_test.go @@ -28,7 +28,7 @@ func TestInspect(t *testing.T) { insp := &inspectCmd{ chartpath: "testdata/testcharts/alpine", - output: "both", + output: all, out: b, } insp.run() @@ -42,15 +42,19 @@ func TestInspect(t *testing.T) { if err != nil { t.Fatal(err) } - - parts := strings.SplitN(b.String(), "---", 2) - if len(parts) != 2 { + readmeData, err := ioutil.ReadFile("testdata/testcharts/alpine/README.md") + if err != nil { + t.Fatal(err) + } + parts := strings.SplitN(b.String(), "---", 3) + if len(parts) != 3 { t.Fatalf("Expected 2 parts, got %d", len(parts)) } expect := []string{ strings.Replace(strings.TrimSpace(string(cdata)), "\r", "", -1), strings.Replace(strings.TrimSpace(string(data)), "\r", "", -1), + strings.Replace(strings.TrimSpace(string(readmeData)), "\r", "", -1), } // Problem: ghodss/yaml doesn't marshal into struct order. To solve, we @@ -73,5 +77,4 @@ func TestInspect(t *testing.T) { if b.Len() != 0 { t.Errorf("expected empty values buffer, got %q", b.String()) } - } diff --git a/docs/helm/helm.md b/docs/helm/helm.md index f470e84b2..8592cad7c 100644 --- a/docs/helm/helm.md +++ b/docs/helm/helm.md @@ -68,4 +68,4 @@ Environment: * [helm verify](helm_verify.md) - verify that a chart at the given path has been signed and is valid * [helm version](helm_version.md) - print the client/server version information -###### Auto generated by spf13/cobra on 8-Mar-2018 +###### Auto generated by spf13/cobra on 14-Mar-2018 diff --git a/docs/helm/helm_inspect.md b/docs/helm/helm_inspect.md index df122f763..9928ed847 100644 --- a/docs/helm/helm_inspect.md +++ b/docs/helm/helm_inspect.md @@ -42,6 +42,7 @@ helm inspect [CHART] ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. * [helm inspect chart](helm_inspect_chart.md) - shows inspect chart +* [helm inspect readme](helm_inspect_readme.md) - shows inspect readme * [helm inspect values](helm_inspect_values.md) - shows inspect values -###### Auto generated by spf13/cobra on 8-Mar-2018 +###### Auto generated by spf13/cobra on 14-Mar-2018 diff --git a/docs/helm/helm_inspect_readme.md b/docs/helm/helm_inspect_readme.md new file mode 100644 index 000000000..9dd9ebd43 --- /dev/null +++ b/docs/helm/helm_inspect_readme.md @@ -0,0 +1,43 @@ +## helm inspect readme + +shows inspect readme + +### Synopsis + + + +This command inspects a chart (directory, file, or URL) and displays the contents +of the README file + + +``` +helm inspect readme [CHART] +``` + +### Options + +``` + --ca-file string chart repository url where to locate the requested chart + --cert-file string verify certificates of HTTPS-enabled servers using this CA bundle + --key-file string identify HTTPS client using this SSL key file + --keyring string path to the keyring containing public verification keys (default "~/.gnupg/pubring.gpg") + --repo string chart repository url where to locate the requested chart + --verify verify the provenance data for this chart + --version string version of the chart. By default, the newest chart is shown +``` + +### Options inherited from parent commands + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") +``` + +### SEE ALSO +* [helm inspect](helm_inspect.md) - inspect a chart + +###### Auto generated by spf13/cobra on 14-Mar-2018