feature(cmd): Add --output option to `helm dep list`

Signed-off-by: Yonatan Kahana <yonatankahana.il@gmail.com>
pull/8074/head
Yonatan Kahana 5 years ago
parent e29ed7a108
commit d8b7a80bc0

@ -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"
)
const dependencyDesc = `
@ -99,8 +100,7 @@ func newDependencyCmd(out io.Writer) *cobra.Command {
}
func newDependencyListCmd(out io.Writer) *cobra.Command {
client := action.NewDependency()
var outfmt output.Format
cmd := &cobra.Command{
Use: "list CHART",
Aliases: []string{"ls"},
@ -112,8 +112,11 @@ func newDependencyListCmd(out io.Writer) *cobra.Command {
if len(args) > 0 {
chartpath = filepath.Clean(args[0])
}
return client.List(chartpath, out)
return outfmt.Write(out, &action.DependencyListWriter{Chartpath: chartpath})
},
}
bindOutputFlag(cmd, &outfmt)
return cmd
}

@ -27,6 +27,7 @@ import (
"helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/chart/loader"
"helm.sh/helm/v3/pkg/cli/output"
)
// Dependency is the action for building a given chart's dependency tree.
@ -43,25 +44,66 @@ func NewDependency() *Dependency {
return &Dependency{}
}
// List executes 'helm dependency list'.
func (d *Dependency) List(chartpath string, out io.Writer) error {
c, err := loader.Load(chartpath)
type dependencyListElement struct {
Name string `json:"name"`
Version string `json:"version"`
Repository string `json:"repository"`
Status string `json:"status"`
}
type DependencyListWriter struct {
Chartpath string
}
func (w *DependencyListWriter) WriteTable(out io.Writer) error {
c, err := loader.Load(w.Chartpath)
if err != nil {
return err
}
if c.Metadata.Dependencies == nil {
fmt.Fprintf(out, "WARNING: no dependencies at %s\n", filepath.Join(chartpath, "charts"))
fmt.Fprintf(out, "WARNING: no dependencies at %s\n", filepath.Join(w.Chartpath, "charts"))
return nil
}
d.printDependencies(chartpath, out, c)
w.printDependenciesTable(w.Chartpath, out, c)
fmt.Fprintln(out)
d.printMissing(chartpath, out, c.Metadata.Dependencies)
w.printMissing(w.Chartpath, out, c.Metadata.Dependencies)
return nil
}
func (w *DependencyListWriter) WriteJSON(out io.Writer) error {
return w.encodeByFormat(out, output.JSON)
}
func (w *DependencyListWriter) WriteYAML(out io.Writer) error {
return w.encodeByFormat(out, output.YAML)
}
func (w *DependencyListWriter) encodeByFormat(out io.Writer, format output.Format) error {
c, err := loader.Load(w.Chartpath)
if err != nil {
return err
}
// Initialize the array so no results returns an empty array instead of null
elements := make([]dependencyListElement, 0, len(c.Metadata.Dependencies))
for _, d := range c.Metadata.Dependencies {
elements = append(elements, dependencyListElement{Name: d.Name, Repository: d.Repository, Status: w.dependencyStatus(w.Chartpath, d, c), Version: d.Version})
}
switch format {
case output.JSON:
return output.EncodeJSON(out, elements)
case output.YAML:
return output.EncodeYAML(out, elements)
}
return nil
}
func (d *Dependency) dependencyStatus(chartpath string, dep *chart.Dependency, parent *chart.Chart) string {
func (w *DependencyListWriter) dependencyStatus(chartpath string, dep *chart.Dependency, parent *chart.Chart) string {
filename := fmt.Sprintf("%s-%s.tgz", dep.Name, "*")
// If a chart is unpacked, this will check the unpacked chart's `charts/` directory for tarballs.
@ -137,20 +179,20 @@ func (d *Dependency) dependencyStatus(chartpath string, dep *chart.Dependency, p
return "unpacked"
}
// printDependencies prints all of the dependencies in the yaml file.
func (d *Dependency) printDependencies(chartpath string, out io.Writer, c *chart.Chart) {
// printDependenciesTable prints all of the dependencies in the yaml file.
func (w *DependencyListWriter) printDependenciesTable(chartpath string, out io.Writer, c *chart.Chart) {
table := uitable.New()
table.MaxColWidth = 80
table.AddRow("NAME", "VERSION", "REPOSITORY", "STATUS")
for _, row := range c.Metadata.Dependencies {
table.AddRow(row.Name, row.Version, row.Repository, d.dependencyStatus(chartpath, row, c))
table.AddRow(row.Name, row.Version, row.Repository, w.dependencyStatus(chartpath, row, c))
}
fmt.Fprintln(out, table)
}
// printMissing prints warnings about charts that are present on disk, but are
// not in Charts.yaml.
func (d *Dependency) printMissing(chartpath string, out io.Writer, reqs []*chart.Dependency) {
func (w *DependencyListWriter) printMissing(chartpath string, out io.Writer, reqs []*chart.Dependency) {
folder := filepath.Join(chartpath, "charts/*")
files, err := filepath.Glob(folder)
if err != nil {
@ -161,7 +203,7 @@ func (d *Dependency) printMissing(chartpath string, out io.Writer, reqs []*chart
for _, f := range files {
fi, err := os.Stat(f)
if err != nil {
fmt.Fprintf(out, "Warning: %s\n", err)
fmt.Fprintf(out, "WARNING: %s\n", err)
}
// Skip anything that is not a directory and not a tgz file.
if !fi.IsDir() && filepath.Ext(f) != ".tgz" {

@ -21,36 +21,93 @@ import (
"testing"
"helm.sh/helm/v3/internal/test"
"helm.sh/helm/v3/pkg/cli/output"
)
func TestList(t *testing.T) {
for _, tcase := range []struct {
chart string
golden string
outfmt output.Format
}{
{
chart: "testdata/charts/chart-with-compressed-dependencies",
golden: "output/compressed-deps.txt",
outfmt: output.Table,
},
{
chart: "testdata/charts/chart-with-compressed-dependencies-2.1.8.tgz",
golden: "output/compressed-deps-tgz.txt",
outfmt: output.Table,
},
{
chart: "testdata/charts/chart-with-uncompressed-dependencies",
golden: "output/uncompressed-deps.txt",
outfmt: output.Table,
},
{
chart: "testdata/charts/chart-with-uncompressed-dependencies-2.1.8.tgz",
golden: "output/uncompressed-deps-tgz.txt",
outfmt: output.Table,
},
{
chart: "testdata/charts/chart-missing-deps",
golden: "output/missing-deps.txt",
outfmt: output.Table,
},
{
chart: "testdata/charts/chart-with-compressed-dependencies",
golden: "output/compressed-deps.json",
outfmt: output.JSON,
},
{
chart: "testdata/charts/chart-with-compressed-dependencies-2.1.8.tgz",
golden: "output/compressed-deps-tgz.json",
outfmt: output.JSON,
},
{
chart: "testdata/charts/chart-with-uncompressed-dependencies",
golden: "output/uncompressed-deps.json",
outfmt: output.JSON,
},
{
chart: "testdata/charts/chart-with-uncompressed-dependencies-2.1.8.tgz",
golden: "output/uncompressed-deps-tgz.json",
outfmt: output.JSON,
},
{
chart: "testdata/charts/chart-missing-deps",
golden: "output/missing-deps.json",
outfmt: output.JSON,
},
{
chart: "testdata/charts/chart-with-compressed-dependencies",
golden: "output/compressed-deps.yaml",
outfmt: output.YAML,
},
{
chart: "testdata/charts/chart-with-compressed-dependencies-2.1.8.tgz",
golden: "output/compressed-deps-tgz.yaml",
outfmt: output.YAML,
},
{
chart: "testdata/charts/chart-with-uncompressed-dependencies",
golden: "output/uncompressed-deps.yaml",
outfmt: output.YAML,
},
{
chart: "testdata/charts/chart-with-uncompressed-dependencies-2.1.8.tgz",
golden: "output/uncompressed-deps-tgz.yaml",
outfmt: output.YAML,
},
{
chart: "testdata/charts/chart-missing-deps",
golden: "output/missing-deps.yaml",
outfmt: output.YAML,
},
} {
buf := bytes.Buffer{}
if err := NewDependency().List(tcase.chart, &buf); err != nil {
if err := tcase.outfmt.Write(&buf, &DependencyListWriter{Chartpath: tcase.chart}); err != nil {
t.Fatal(err)
}
test.AssertGoldenBytes(t, buf.Bytes(), tcase.golden)

@ -0,0 +1 @@
[{"name":"mariadb","version":"4.x.x","repository":"https://kubernetes-charts.storage.googleapis.com/","status":"unpacked"}]

@ -0,0 +1,4 @@
- name: mariadb
repository: https://kubernetes-charts.storage.googleapis.com/
status: unpacked
version: 4.x.x

@ -0,0 +1 @@
[{"name":"mariadb","version":"4.x.x","repository":"https://kubernetes-charts.storage.googleapis.com/","status":"ok"}]

@ -0,0 +1,4 @@
- name: mariadb
repository: https://kubernetes-charts.storage.googleapis.com/
status: ok
version: 4.x.x

@ -0,0 +1 @@
[{"name":"mariadb","version":"4.x.x","repository":"https://kubernetes-charts.storage.googleapis.com/","status":"missing"}]

@ -0,0 +1,4 @@
- name: mariadb
repository: https://kubernetes-charts.storage.googleapis.com/
status: missing
version: 4.x.x

@ -0,0 +1 @@
[{"name":"mariadb","version":"4.x.x","repository":"https://kubernetes-charts.storage.googleapis.com/","status":"unpacked"}]

@ -0,0 +1,4 @@
- name: mariadb
repository: https://kubernetes-charts.storage.googleapis.com/
status: unpacked
version: 4.x.x

@ -0,0 +1 @@
[{"name":"mariadb","version":"4.x.x","repository":"https://kubernetes-charts.storage.googleapis.com/","status":"unpacked"}]

@ -0,0 +1,4 @@
- name: mariadb
repository: https://kubernetes-charts.storage.googleapis.com/
status: unpacked
version: 4.x.x
Loading…
Cancel
Save