Merge pull request #346 from stek29/list-noprepare

feat: dont prepare on list
This commit is contained in:
yxxhero 2022-09-06 17:22:41 +08:00 committed by GitHub
commit 700d708b29
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 159 additions and 106 deletions

View File

@ -32,6 +32,7 @@ func NewListCmd(globalCfg *config.GlobalImpl) *cobra.Command {
f := cmd.Flags()
f.BoolVar(&listOptions.KeepTempDir, "keep-temp-dir", false, "Keep temporary directory")
f.BoolVar(&listOptions.SkipCharts, "skip-charts", false, "don't prepare charts when listing releases")
f.StringVar(&listOptions.Output, "output", "", "output releases list as a json string")
return cmd

View File

@ -547,12 +547,50 @@ func (a *App) ListReleases(c ListConfigProvider) error {
var releases []*HelmRelease
err := a.ForEachState(func(run *Run) (_ bool, errs []error) {
err := run.withPreparedCharts("list", state.ChartPrepareOptions{
var stateReleases []*HelmRelease
var err error
if !c.SkipCharts() {
err = run.withPreparedCharts("list", state.ChartPrepareOptions{
SkipRepos: true,
SkipDeps: true,
Concurrency: 2,
}, func() {
// var releases m
rel, err := a.list(run)
if err != nil {
panic(err)
}
stateReleases = rel
})
} else {
stateReleases, err = a.list(run)
}
if err != nil {
errs = append(errs, err)
}
releases = append(releases, stateReleases...)
return
}, false, SetFilter(true))
if err != nil {
return err
}
if c.Output() == "json" {
err = FormatAsJson(releases)
} else {
err = FormatAsTable(releases)
}
return err
}
func (a *App) list(run *Run) ([]*HelmRelease, error) {
var releases []*HelmRelease
for _, r := range run.state.Releases {
labels := ""
if r.Labels == nil {
@ -576,7 +614,7 @@ func (a *App) ListReleases(c ListConfigProvider) error {
enabled, err := state.ConditionEnabled(r, run.state.Values())
if err != nil {
panic(err)
return nil, err
}
installed := r.Installed == nil || *r.Installed
@ -590,26 +628,8 @@ func (a *App) ListReleases(c ListConfigProvider) error {
Version: r.Version,
})
}
})
if err != nil {
errs = append(errs, err)
}
return
}, false, SetFilter(true))
if err != nil {
return err
}
if c.Output() == "json" {
err = FormatAsJson(releases)
} else {
err = FormatAsTable(releases)
}
return err
return releases, nil
}
func (a *App) within(dir string, do func() error) error {

View File

@ -4,6 +4,7 @@ import (
"bufio"
"bytes"
"io"
"os"
"sync"
"testing"
@ -17,7 +18,7 @@ import (
"github.com/helmfile/helmfile/pkg/testutil"
)
func TestListWithEnvironment(t *testing.T) {
func testListWithEnvironment(t *testing.T, cfg configImpl) {
type testcase struct {
environment string
ns string
@ -26,7 +27,7 @@ func TestListWithEnvironment(t *testing.T) {
expected string
}
check := func(t *testing.T, tc testcase) {
check := func(t *testing.T, tc testcase, cfg configImpl) {
t.Helper()
bs := &bytes.Buffer{}
@ -164,7 +165,7 @@ releases:
var listErr error
out := testutil.CaptureStdout(func() {
listErr = app.ListReleases(configImpl{})
listErr = app.ListReleases(cfg)
})
var gotErr string
@ -197,14 +198,14 @@ cache my-app true true app:test bitnami/redis
database my-app true true bitnami/postgres 11.6.22
global kube-system true true incubator/raw
`,
})
}, cfg)
})
t.Run("fail on unknown environment", func(t *testing.T) {
check(t, testcase{
environment: "staging",
error: `err: no releases found that matches specified selector() and environment(staging), in any helmfile`,
})
}, cfg)
})
t.Run("list releases matching selector and environment", func(t *testing.T) {
@ -215,7 +216,7 @@ global kube-system true true incubator/raw
external-secrets default true true app:test,chart:raw,name:external-secrets,namespace:default incubator/raw
my-release default true true app:test,chart:raw,name:my-release,namespace:default incubator/raw
`,
})
}, cfg)
})
t.Run("filters releases for environment used in one file only", func(t *testing.T) {
@ -225,7 +226,7 @@ my-release default true true app:test,chart:raw,name:my-release,
cache my-app true true app:test bitnami/redis 17.0.7
database my-app true true bitnami/postgres 11.6.22
`,
})
}, cfg)
})
t.Run("filters releases for environment used in multiple files", func(t *testing.T) {
@ -243,6 +244,82 @@ test3 true true incubator/raw
cache my-app true true app:test bitnami/redis 17.0.7
database my-app true true bitnami/postgres 11.6.22
`,
})
}, cfg)
})
}
func TestListWithEnvironment(t *testing.T) {
t.Run("with skipCharts=false", func(t *testing.T) {
testListWithEnvironment(t, configImpl{skipCharts: false})
})
t.Run("with skipCharts=true", func(t *testing.T) {
testListWithEnvironment(t, configImpl{skipCharts: true})
})
}
func testListWithJSONOutput(t *testing.T, cfg configImpl) {
cfg.output = "json"
files := map[string]string{
"/path/to/helmfile.d/first.yaml": `
environments:
default:
values:
- myrelease2:
enabled: false
releases:
- name: myrelease1
chart: mychart1
installed: no
labels:
id: myrelease1
- name: myrelease2
chart: mychart1
condition: myrelease2.enabled
`,
"/path/to/helmfile.d/second.yaml": `
releases:
- name: myrelease3
chart: mychart1
installed: yes
- name: myrelease4
chart: mychart1
labels:
id: myrelease1
`,
}
stdout := os.Stdout
defer func() { os.Stdout = stdout }()
var buffer bytes.Buffer
logger := helmexec.NewLogger(&buffer, "debug")
app := appWithFs(&App{
OverrideHelmBinary: DefaultHelmBinary,
fs: ffs.DefaultFileSystem(),
OverrideKubeContext: "default",
Env: "default",
Logger: logger,
Namespace: "testNamespace",
}, files)
expectNoCallsToHelm(app)
out := testutil.CaptureStdout(func() {
err := app.ListReleases(cfg)
assert.Nil(t, err)
})
expected := `[{"name":"myrelease1","namespace":"","enabled":true,"installed":false,"labels":"id:myrelease1","chart":"mychart1","version":""},{"name":"myrelease2","namespace":"","enabled":false,"installed":true,"labels":"","chart":"mychart1","version":""},{"name":"myrelease3","namespace":"","enabled":true,"installed":true,"labels":"","chart":"mychart1","version":""},{"name":"myrelease4","namespace":"","enabled":true,"installed":true,"labels":"id:myrelease1","chart":"mychart1","version":""}]
`
assert.Equal(t, expected, out)
}
func TestListWithJSONOutput(t *testing.T) {
t.Run("with skipCharts=false", func(t *testing.T) {
testListWithJSONOutput(t, configImpl{skipCharts: false})
})
t.Run("with skipCharts=true", func(t *testing.T) {
testListWithJSONOutput(t, configImpl{skipCharts: true})
})
}

View File

@ -2220,6 +2220,7 @@ type configImpl struct {
skipNeeds bool
includeNeeds bool
includeTransitiveNeeds bool
skipCharts bool
}
func (c configImpl) Selectors() []string {
@ -2294,6 +2295,10 @@ func (c configImpl) Output() string {
return c.output
}
func (c configImpl) SkipCharts() bool {
return c.skipCharts
}
type applyConfig struct {
args string
values []string
@ -4622,64 +4627,6 @@ myrelease4 true true id:myrelease1 mychart1
assert.Equal(t, expected, out)
}
func TestListWithJsonOutput(t *testing.T) {
files := map[string]string{
"/path/to/helmfile.d/first.yaml": `
environments:
default:
values:
- myrelease2:
enabled: false
releases:
- name: myrelease1
chart: mychart1
installed: no
labels:
id: myrelease1
- name: myrelease2
chart: mychart1
condition: myrelease2.enabled
`,
"/path/to/helmfile.d/second.yaml": `
releases:
- name: myrelease3
chart: mychart1
installed: yes
- name: myrelease4
chart: mychart1
labels:
id: myrelease1
`,
}
stdout := os.Stdout
defer func() { os.Stdout = stdout }()
var buffer bytes.Buffer
logger := helmexec.NewLogger(&buffer, "debug")
app := appWithFs(&App{
OverrideHelmBinary: DefaultHelmBinary,
fs: ffs.DefaultFileSystem(),
OverrideKubeContext: "default",
Env: "default",
Logger: logger,
Namespace: "testNamespace",
}, files)
expectNoCallsToHelm(app)
out := testutil.CaptureStdout(func() {
err := app.ListReleases(configImpl{
output: "json",
})
assert.Nil(t, err)
})
expected := `[{"name":"myrelease1","namespace":"","enabled":true,"installed":false,"labels":"id:myrelease1","chart":"mychart1","version":""},{"name":"myrelease2","namespace":"","enabled":false,"installed":true,"labels":"","chart":"mychart1","version":""},{"name":"myrelease3","namespace":"","enabled":true,"installed":true,"labels":"","chart":"mychart1","version":""},{"name":"myrelease4","namespace":"","enabled":true,"installed":true,"labels":"id:myrelease1","chart":"mychart1","version":""}]
`
assert.Equal(t, expected, out)
}
func TestSetValuesTemplate(t *testing.T) {
files := map[string]string{
"/path/to/helmfile.yaml": `

View File

@ -236,6 +236,7 @@ type interactive interface {
type ListConfigProvider interface {
Output() string
SkipCharts() bool
}
type CacheConfigProvider interface{}

View File

@ -6,6 +6,8 @@ type ListOptions struct {
Output string
// KeepTempDir is the keep temp dir flag
KeepTempDir bool
// SkipCharts makes List skip `withPreparedCharts`
SkipCharts bool
}
// NewListOptions creates a new Apply
@ -36,3 +38,8 @@ func (c *ListImpl) Args() string {
func (c *ListImpl) Output() string {
return c.ListOptions.Output
}
// SkipCharts returns skipCharts flag
func (c *ListImpl) SkipCharts() bool {
return c.ListOptions.SkipCharts
}