Fix various golangci-lint errors (#2059)

This commit is contained in:
Anton Bretting 2022-02-12 12:28:08 +01:00 committed by GitHub
parent 9a2df3c0a2
commit 2f04831817
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 362 additions and 263 deletions

View File

@ -737,7 +737,10 @@ type configImpl struct {
func NewUrfaveCliConfigImpl(c *cli.Context) (configImpl, error) { func NewUrfaveCliConfigImpl(c *cli.Context) (configImpl, error) {
if c.NArg() > 0 { if c.NArg() > 0 {
cli.ShowAppHelp(c) err := cli.ShowAppHelp(c)
if err != nil {
return configImpl{}, err
}
return configImpl{}, fmt.Errorf("err: extraneous arguments: %s", strings.Join(c.Args(), ", ")) return configImpl{}, fmt.Errorf("err: extraneous arguments: %s", strings.Join(c.Args(), ", "))
} }

View File

@ -567,7 +567,7 @@ func (a *App) ListReleases(c ListConfigProvider) error {
} }
var keys []string var keys []string
for k, _ := range r.Labels { for k := range r.Labels {
keys = append(keys, k) keys = append(keys, k)
} }
sort.Strings(keys) sort.Strings(keys)
@ -949,7 +949,8 @@ func withBatches(templated *state.HelmState, batches [][]state.Release, helm hel
var releaseIds []string var releaseIds []string
for _, r := range targets { for _, r := range targets {
releaseIds = append(releaseIds, state.ReleaseToID(&r)) release := r
releaseIds = append(releaseIds, state.ReleaseToID(&release))
} }
logger.Debugf("processing releases in group %d/%d: %s", i+1, numBatches, strings.Join(releaseIds, ", ")) logger.Debugf("processing releases in group %d/%d: %s", i+1, numBatches, strings.Join(releaseIds, ", "))
@ -959,7 +960,7 @@ func withBatches(templated *state.HelmState, batches [][]state.Release, helm hel
processed, errs := converge(&batchSt, helm) processed, errs := converge(&batchSt, helm)
if errs != nil && len(errs) > 0 { if len(errs) > 0 {
return false, errs return false, errs
} }
@ -1181,7 +1182,8 @@ func (a *App) getSelectedReleases(r *Run, includeTransitiveNeeds bool) ([]state.
// We iterate over allReleases rather than groupsByID // We iterate over allReleases rather than groupsByID
// to preserve the order of releases // to preserve the order of releases
for _, seq := range allReleases { for _, seq := range allReleases {
id := state.ReleaseToID(&seq) release := seq
id := state.ReleaseToID(&release)
rs := groupsByID[id] rs := groupsByID[id]
@ -1199,7 +1201,7 @@ func (a *App) getSelectedReleases(r *Run, includeTransitiveNeeds bool) ([]state.
// Otherwise we can't compute the DAG of releases correctly. // Otherwise we can't compute the DAG of releases correctly.
r, deduped := selectedIds[id] r, deduped := selectedIds[id]
if !deduped { if !deduped {
panic(fmt.Errorf("assertion error: release %q has never been selected. This shouldn't happen!", id)) panic(fmt.Errorf("assertion error: release %q has never been selected. This shouldn't happen", id))
} }
deduplicated = append(deduplicated, r) deduplicated = append(deduplicated, r)
@ -1286,11 +1288,12 @@ func (a *App) apply(r *Run, c ApplyConfigProvider) (bool, bool, []error) {
releasesWithNoChange := map[string]state.ReleaseSpec{} releasesWithNoChange := map[string]state.ReleaseSpec{}
for _, r := range toApplyWithNeeds { for _, r := range toApplyWithNeeds {
id := state.ReleaseToID(&r) release := r
id := state.ReleaseToID(&release)
_, uninstalled := releasesToBeDeleted[id] _, uninstalled := releasesToBeDeleted[id]
_, updated := releasesToBeUpdated[id] _, updated := releasesToBeUpdated[id]
if !uninstalled && !updated { if !uninstalled && !updated {
releasesWithNoChange[id] = r releasesWithNoChange[id] = release
} }
} }
@ -1336,7 +1339,8 @@ Do you really want to apply?
var rs []state.ReleaseSpec var rs []state.ReleaseSpec
for _, r := range subst.Releases { for _, r := range subst.Releases {
if r2, ok := releasesToBeDeleted[state.ReleaseToID(&r)]; ok { release := r
if r2, ok := releasesToBeDeleted[state.ReleaseToID(&release)]; ok {
rs = append(rs, r2) rs = append(rs, r2)
} }
} }
@ -1346,7 +1350,7 @@ Do you really want to apply?
return subst.DeleteReleasesForSync(&affectedReleases, helm, c.Concurrency()) return subst.DeleteReleasesForSync(&affectedReleases, helm, c.Concurrency())
})) }))
if deletionErrs != nil && len(deletionErrs) > 0 { if len(deletionErrs) > 0 {
syncErrs = append(syncErrs, deletionErrs...) syncErrs = append(syncErrs, deletionErrs...)
} }
} }
@ -1357,7 +1361,8 @@ Do you really want to apply?
var rs []state.ReleaseSpec var rs []state.ReleaseSpec
for _, r := range subst.Releases { for _, r := range subst.Releases {
if r2, ok := releasesToBeUpdated[state.ReleaseToID(&r)]; ok { release := r
if r2, ok := releasesToBeUpdated[state.ReleaseToID(&release)]; ok {
rs = append(rs, r2) rs = append(rs, r2)
} }
} }
@ -1374,7 +1379,7 @@ Do you really want to apply?
return subst.SyncReleases(&affectedReleases, helm, c.Values(), c.Concurrency(), &syncOpts) return subst.SyncReleases(&affectedReleases, helm, c.Values(), c.Concurrency(), &syncOpts)
})) }))
if updateErrs != nil && len(updateErrs) > 0 { if len(updateErrs) > 0 {
syncErrs = append(syncErrs, updateErrs...) syncErrs = append(syncErrs, updateErrs...)
} }
} }
@ -1405,16 +1410,18 @@ func (a *App) delete(r *Run, purge bool, c DestroyConfigProvider) (bool, []error
releasesToDelete := map[string]state.ReleaseSpec{} releasesToDelete := map[string]state.ReleaseSpec{}
for _, r := range toDelete { for _, r := range toDelete {
id := state.ReleaseToID(&r) release := r
releasesToDelete[id] = r id := state.ReleaseToID(&release)
releasesToDelete[id] = release
} }
releasesWithNoChange := map[string]state.ReleaseSpec{} releasesWithNoChange := map[string]state.ReleaseSpec{}
for _, r := range toSync { for _, r := range toSync {
id := state.ReleaseToID(&r) release := r
id := state.ReleaseToID(&release)
_, uninstalled := releasesToDelete[id] _, uninstalled := releasesToDelete[id]
if !uninstalled { if !uninstalled {
releasesWithNoChange[id] = r releasesWithNoChange[id] = release
} }
} }
@ -1450,7 +1457,7 @@ Do you really want to delete?
return subst.DeleteReleases(&affectedReleases, helm, c.Concurrency(), purge) return subst.DeleteReleases(&affectedReleases, helm, c.Concurrency(), purge)
})) }))
if deletionErrs != nil && len(deletionErrs) > 0 { if len(deletionErrs) > 0 {
errs = append(errs, deletionErrs...) errs = append(errs, deletionErrs...)
} }
} }
@ -1574,7 +1581,7 @@ func (a *App) lint(r *Run, c LintConfigProvider) (bool, []error, []error) {
return lintErrs return lintErrs
})) }))
if templateErrs != nil && len(templateErrs) > 0 { if len(templateErrs) > 0 {
errs = append(errs, templateErrs...) errs = append(errs, templateErrs...)
} }
} }
@ -1626,7 +1633,7 @@ func (a *App) status(r *Run, c StatusesConfigProvider) (bool, []error) {
return subst.ReleaseStatuses(helm, c.Concurrency()) return subst.ReleaseStatuses(helm, c.Concurrency())
})) }))
if templateErrs != nil && len(templateErrs) > 0 { if len(templateErrs) > 0 {
errs = append(errs, templateErrs...) errs = append(errs, templateErrs...)
} }
} }
@ -1675,36 +1682,39 @@ func (a *App) sync(r *Run, c SyncConfigProvider) (bool, []error) {
releasesToDelete := map[string]state.ReleaseSpec{} releasesToDelete := map[string]state.ReleaseSpec{}
for _, r := range toDelete { for _, r := range toDelete {
id := state.ReleaseToID(&r) release := r
releasesToDelete[id] = r id := state.ReleaseToID(&release)
releasesToDelete[id] = release
} }
var toUpdate []state.ReleaseSpec var toUpdate []state.ReleaseSpec
for _, r := range toSyncWithNeeds { for _, r := range toSyncWithNeeds {
if _, deleted := releasesToDelete[state.ReleaseToID(&r)]; !deleted { release := r
if r.Installed == nil || *r.Installed { if _, deleted := releasesToDelete[state.ReleaseToID(&release)]; !deleted {
toUpdate = append(toUpdate, r) if release.Installed == nil || *release.Installed {
} else { toUpdate = append(toUpdate, release)
// TODO Emit error when the user opted to fail when the needed release is disabled,
// instead of silently ignoring it.
// See https://github.com/roboll/helmfile/issues/1018
} }
// TODO Emit error when the user opted to fail when the needed release is disabled,
// instead of silently ignoring it.
// See https://github.com/roboll/helmfile/issues/1018
} }
} }
releasesToUpdate := map[string]state.ReleaseSpec{} releasesToUpdate := map[string]state.ReleaseSpec{}
for _, r := range toUpdate { for _, r := range toUpdate {
id := state.ReleaseToID(&r) release := r
releasesToUpdate[id] = r id := state.ReleaseToID(&release)
releasesToUpdate[id] = release
} }
releasesWithNoChange := map[string]state.ReleaseSpec{} releasesWithNoChange := map[string]state.ReleaseSpec{}
for _, r := range toSyncWithNeeds { for _, r := range toSyncWithNeeds {
id := state.ReleaseToID(&r) release := r
id := state.ReleaseToID(&release)
_, uninstalled := releasesToDelete[id] _, uninstalled := releasesToDelete[id]
_, updated := releasesToUpdate[id] _, updated := releasesToUpdate[id]
if !uninstalled && !updated { if !uninstalled && !updated {
releasesWithNoChange[id] = r releasesWithNoChange[id] = release
} }
} }
@ -1745,7 +1755,8 @@ func (a *App) sync(r *Run, c SyncConfigProvider) (bool, []error) {
var rs []state.ReleaseSpec var rs []state.ReleaseSpec
for _, r := range subst.Releases { for _, r := range subst.Releases {
if r2, ok := releasesToDelete[state.ReleaseToID(&r)]; ok { release := r
if r2, ok := releasesToDelete[state.ReleaseToID(&release)]; ok {
rs = append(rs, r2) rs = append(rs, r2)
} }
} }
@ -1755,7 +1766,7 @@ func (a *App) sync(r *Run, c SyncConfigProvider) (bool, []error) {
return subst.DeleteReleasesForSync(&affectedReleases, helm, c.Concurrency()) return subst.DeleteReleasesForSync(&affectedReleases, helm, c.Concurrency())
})) }))
if deletionErrs != nil && len(deletionErrs) > 0 { if len(deletionErrs) > 0 {
errs = append(errs, deletionErrs...) errs = append(errs, deletionErrs...)
} }
} }
@ -1765,8 +1776,9 @@ func (a *App) sync(r *Run, c SyncConfigProvider) (bool, []error) {
var rs []state.ReleaseSpec var rs []state.ReleaseSpec
for _, r := range subst.Releases { for _, r := range subst.Releases {
if _, ok := releasesToDelete[state.ReleaseToID(&r)]; !ok { release := r
rs = append(rs, r) if _, ok := releasesToDelete[state.ReleaseToID(&release)]; !ok {
rs = append(rs, release)
} }
} }
@ -1781,7 +1793,7 @@ func (a *App) sync(r *Run, c SyncConfigProvider) (bool, []error) {
return subst.SyncReleases(&affectedReleases, helm, c.Values(), c.Concurrency(), opts) return subst.SyncReleases(&affectedReleases, helm, c.Values(), c.Concurrency(), opts)
})) }))
if syncErrs != nil && len(syncErrs) > 0 { if len(syncErrs) > 0 {
errs = append(errs, syncErrs...) errs = append(errs, syncErrs...)
} }
} }
@ -1824,11 +1836,12 @@ func (a *App) template(r *Run, c TemplateConfigProvider) (bool, []error) {
releasesDisabled := map[string]state.ReleaseSpec{} releasesDisabled := map[string]state.ReleaseSpec{}
for _, r := range selectedReleasesWithNeeds { for _, r := range selectedReleasesWithNeeds {
id := state.ReleaseToID(&r) release := r
if r.Installed != nil && !*r.Installed { id := state.ReleaseToID(&release)
releasesDisabled[id] = r if release.Installed != nil && !*release.Installed {
releasesDisabled[id] = release
} else { } else {
toRender = append(toRender, r) toRender = append(toRender, release)
} }
} }
@ -1908,11 +1921,12 @@ func (a *App) writeValues(r *Run, c WriteValuesConfigProvider) (bool, []error) {
releasesToWrite := map[string]state.ReleaseSpec{} releasesToWrite := map[string]state.ReleaseSpec{}
for _, r := range toRender { for _, r := range toRender {
id := state.ReleaseToID(&r) release := r
if r.Installed != nil && !*r.Installed { id := state.ReleaseToID(&release)
if release.Installed != nil && !*release.Installed {
continue continue
} }
releasesToWrite[id] = r releasesToWrite[id] = release
} }
var errs []error var errs []error
@ -2060,7 +2074,7 @@ type context struct {
} }
func (c context) wrapErrs(errs ...error) error { func (c context) wrapErrs(errs ...error) error {
if errs != nil && len(errs) > 0 { if len(errs) > 0 {
for _, err := range errs { for _, err := range errs {
switch e := err.(type) { switch e := err.(type) {
case *state.ReleaseError: case *state.ReleaseError:

View File

@ -505,9 +505,9 @@ releases:
errMsg string errMsg string
}{ }{
{label: "name=prometheus", expectedCount: 1, expectErr: false}, {label: "name=prometheus", expectedCount: 1, expectErr: false},
{label: "name=", expectedCount: 0, expectErr: true, errMsg: "in ./helmfile.yaml: in .helmfiles[0]: in /path/to/helmfile.d/a1.yaml: Malformed label: name=. Expected label in form k=v or k!=v"}, {label: "name=", expectedCount: 0, expectErr: true, errMsg: "in ./helmfile.yaml: in .helmfiles[0]: in /path/to/helmfile.d/a1.yaml: malformed label: name=. Expected label in form k=v or k!=v"},
{label: "name!=", expectedCount: 0, expectErr: true, errMsg: "in ./helmfile.yaml: in .helmfiles[0]: in /path/to/helmfile.d/a1.yaml: Malformed label: name!=. Expected label in form k=v or k!=v"}, {label: "name!=", expectedCount: 0, expectErr: true, errMsg: "in ./helmfile.yaml: in .helmfiles[0]: in /path/to/helmfile.d/a1.yaml: malformed label: name!=. Expected label in form k=v or k!=v"},
{label: "name", expectedCount: 0, expectErr: true, errMsg: "in ./helmfile.yaml: in .helmfiles[0]: in /path/to/helmfile.d/a1.yaml: Malformed label: name. Expected label in form k=v or k!=v"}, {label: "name", expectedCount: 0, expectErr: true, errMsg: "in ./helmfile.yaml: in .helmfiles[0]: in /path/to/helmfile.d/a1.yaml: malformed label: name. Expected label in form k=v or k!=v"},
// See https://github.com/roboll/helmfile/issues/193 // See https://github.com/roboll/helmfile/issues/193
{label: "duplicatedNs=yes", expectedCount: 0, expectErr: true, errMsg: "in ./helmfile.yaml: in .helmfiles[2]: in /path/to/helmfile.d/b.yaml: duplicate release \"foo\" found in namespace \"zoo\" in kubecontext \"default\": there were 2 releases named \"foo\" matching specified selector"}, {label: "duplicatedNs=yes", expectedCount: 0, expectErr: true, errMsg: "in ./helmfile.yaml: in .helmfiles[2]: in /path/to/helmfile.d/b.yaml: duplicate release \"foo\" found in namespace \"zoo\" in kubecontext \"default\": there were 2 releases named \"foo\" matching specified selector"},
{label: "duplicatedCtx=yes", expectedCount: 0, expectErr: true, errMsg: "in ./helmfile.yaml: in .helmfiles[2]: in /path/to/helmfile.d/b.yaml: duplicate release \"foo\" found in namespace \"zoo\" in kubecontext \"default\": there were 2 releases named \"foo\" matching specified selector"}, {label: "duplicatedCtx=yes", expectedCount: 0, expectErr: true, errMsg: "in ./helmfile.yaml: in .helmfiles[2]: in /path/to/helmfile.d/b.yaml: duplicate release \"foo\" found in namespace \"zoo\" in kubecontext \"default\": there were 2 releases named \"foo\" matching specified selector"},
@ -873,9 +873,7 @@ tillerNs: INLINE_TILLER_NS_2
processed := []state.ReleaseSpec{} processed := []state.ReleaseSpec{}
collectReleases := func(run *Run) (bool, []error) { collectReleases := func(run *Run) (bool, []error) {
for _, r := range run.state.Releases { processed = append(processed, run.state.Releases...)
processed = append(processed, r)
}
return false, []error{} return false, []error{}
} }
@ -1151,9 +1149,7 @@ x:
actual := []state.ReleaseSpec{} actual := []state.ReleaseSpec{}
collectReleases := func(run *Run) (bool, []error) { collectReleases := func(run *Run) (bool, []error) {
for _, r := range run.state.Releases { actual = append(actual, run.state.Releases...)
actual = append(actual, r)
}
return false, []error{} return false, []error{}
} }
app := appWithFs(&App{ app := appWithFs(&App{
@ -1206,9 +1202,7 @@ releases:
actual := []state.ReleaseSpec{} actual := []state.ReleaseSpec{}
collectReleases := func(run *Run) (bool, []error) { collectReleases := func(run *Run) (bool, []error) {
for _, r := range run.state.Releases { actual = append(actual, run.state.Releases...)
actual = append(actual, r)
}
return false, []error{} return false, []error{}
} }
app := appWithFs(&App{ app := appWithFs(&App{
@ -1264,9 +1258,7 @@ releases:
actual := []state.ReleaseSpec{} actual := []state.ReleaseSpec{}
collectReleases := func(run *Run) (bool, []error) { collectReleases := func(run *Run) (bool, []error) {
for _, r := range run.state.Releases { actual = append(actual, run.state.Releases...)
actual = append(actual, r)
}
return false, []error{} return false, []error{}
} }
app := appWithFs(&App{ app := appWithFs(&App{
@ -1316,9 +1308,7 @@ releases:
actual := []state.ReleaseSpec{} actual := []state.ReleaseSpec{}
collectReleases := func(run *Run) (bool, []error) { collectReleases := func(run *Run) (bool, []error) {
for _, r := range run.state.Releases { actual = append(actual, run.state.Releases...)
actual = append(actual, r)
}
return false, []error{} return false, []error{}
} }
app := appWithFs(&App{ app := appWithFs(&App{
@ -1365,9 +1355,7 @@ releases:
actual := []state.ReleaseSpec{} actual := []state.ReleaseSpec{}
collectReleases := func(run *Run) (bool, []error) { collectReleases := func(run *Run) (bool, []error) {
for _, r := range run.state.Releases { actual = append(actual, run.state.Releases...)
actual = append(actual, r)
}
return false, []error{} return false, []error{}
} }
app := appWithFs(&App{ app := appWithFs(&App{
@ -1409,9 +1397,7 @@ releases:
actual := []state.ReleaseSpec{} actual := []state.ReleaseSpec{}
collectReleases := func(run *Run) (bool, []error) { collectReleases := func(run *Run) (bool, []error) {
for _, r := range run.state.Releases { actual = append(actual, run.state.Releases...)
actual = append(actual, r)
}
return false, []error{} return false, []error{}
} }
app := appWithFs(&App{ app := appWithFs(&App{
@ -1453,9 +1439,7 @@ releases:
actual := []state.ReleaseSpec{} actual := []state.ReleaseSpec{}
collectReleases := func(run *Run) (bool, []error) { collectReleases := func(run *Run) (bool, []error) {
for _, r := range run.state.Releases { actual = append(actual, run.state.Releases...)
actual = append(actual, r)
}
return false, []error{} return false, []error{}
} }
app := appWithFs(&App{ app := appWithFs(&App{
@ -1501,9 +1485,7 @@ releases:
actual := []state.ReleaseSpec{} actual := []state.ReleaseSpec{}
collectReleases := func(run *Run) (bool, []error) { collectReleases := func(run *Run) (bool, []error) {
for _, r := range run.state.Releases { actual = append(actual, run.state.Releases...)
actual = append(actual, r)
}
return false, []error{} return false, []error{}
} }
app := appWithFs(&App{ app := appWithFs(&App{
@ -2500,8 +2482,6 @@ func (d depsConfig) Args() string {
// Mocking the command-line runner // Mocking the command-line runner
type mockRunner struct { type mockRunner struct {
output []byte
err error
} }
func (mock *mockRunner) ExecuteStdIn(cmd string, args []string, env map[string]string, stdin io.Reader) ([]byte, error) { func (mock *mockRunner) ExecuteStdIn(cmd string, args []string, env map[string]string, stdin io.Reader) ([]byte, error) {
@ -2519,16 +2499,9 @@ func MockExecer(logger *zap.SugaredLogger, kubeContext string) helmexec.Interfac
// mocking helmexec.Interface // mocking helmexec.Interface
type listKey struct {
filter string
flags string
}
type mockHelmExec struct { type mockHelmExec struct {
templated []mockTemplates templated []mockTemplates
repos []mockRepo repos []mockRepo
updateDepsCallbacks map[string]func(string) error
} }
type mockTemplates struct { type mockTemplates struct {
@ -2562,10 +2535,8 @@ func (helm *mockHelmExec) BuildDeps(name, chart string) error {
} }
func (helm *mockHelmExec) SetExtraArgs(args ...string) { func (helm *mockHelmExec) SetExtraArgs(args ...string) {
return
} }
func (helm *mockHelmExec) SetHelmBinary(bin string) { func (helm *mockHelmExec) SetHelmBinary(bin string) {
return
} }
func (helm *mockHelmExec) AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials string, skipTLSVerify string) error { func (helm *mockHelmExec) AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials string, skipTLSVerify string) error {
helm.repos = append(helm.repos, mockRepo{Name: name}) helm.repos = append(helm.repos, mockRepo{Name: name})
@ -4715,7 +4686,10 @@ func captureStdout(f func()) string {
go func() { go func() {
var buf bytes.Buffer var buf bytes.Buffer
wg.Done() wg.Done()
io.Copy(&buf, reader) _, err = io.Copy(&buf, reader)
if err != nil {
panic(err)
}
out <- buf.String() out <- buf.String()
}() }()
wg.Wait() wg.Wait()

View File

@ -42,11 +42,9 @@ func (helm *noCallHelmExec) BuildDeps(name, chart string) error {
func (helm *noCallHelmExec) SetExtraArgs(args ...string) { func (helm *noCallHelmExec) SetExtraArgs(args ...string) {
helm.doPanic() helm.doPanic()
return
} }
func (helm *noCallHelmExec) SetHelmBinary(bin string) { func (helm *noCallHelmExec) SetHelmBinary(bin string) {
helm.doPanic() helm.doPanic()
return
} }
func (helm *noCallHelmExec) AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials string, skipTLSVerify string) error { func (helm *noCallHelmExec) AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials string, skipTLSVerify string) error {
helm.doPanic() helm.doPanic()

View File

@ -155,17 +155,19 @@ func (r *Run) diff(triggerCleanupEvent bool, detailedExitCode bool, c DiffConfig
releasesToBeDeleted := map[string]state.ReleaseSpec{} releasesToBeDeleted := map[string]state.ReleaseSpec{}
for _, r := range deletingReleases { for _, r := range deletingReleases {
id := state.ReleaseToID(&r) release := r
releasesToBeDeleted[id] = r id := state.ReleaseToID(&release)
releasesToBeDeleted[id] = release
} }
releasesToBeUpdated := map[string]state.ReleaseSpec{} releasesToBeUpdated := map[string]state.ReleaseSpec{}
for _, r := range changedReleases { for _, r := range changedReleases {
id := state.ReleaseToID(&r) release := r
id := state.ReleaseToID(&release)
// If `helm-diff` detected changes but it is not being `helm delete`ed, we should run `helm upgrade` // If `helm-diff` detected changes but it is not being `helm delete`ed, we should run `helm upgrade`
if _, ok := releasesToBeDeleted[id]; !ok { if _, ok := releasesToBeDeleted[id]; !ok {
releasesToBeUpdated[id] = r releasesToBeUpdated[id] = release
} }
} }

View File

@ -1,11 +1,12 @@
package app package app
import ( import (
"github.com/roboll/helmfile/pkg/remote"
"os" "os"
"strings" "strings"
"testing" "testing"
"github.com/roboll/helmfile/pkg/remote"
"github.com/roboll/helmfile/pkg/helmexec" "github.com/roboll/helmfile/pkg/helmexec"
"github.com/roboll/helmfile/pkg/state" "github.com/roboll/helmfile/pkg/state"
"github.com/roboll/helmfile/pkg/testhelper" "github.com/roboll/helmfile/pkg/testhelper"
@ -56,6 +57,9 @@ releases:
var state state.HelmState var state state.HelmState
err = yaml.Unmarshal(yamlBuf.Bytes(), &state) err = yaml.Unmarshal(yamlBuf.Bytes(), &state)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if testfs.FileReaderCalls() > 2 { if testfs.FileReaderCalls() > 2 {
t.Error("reader should be called only twice") t.Error("reader should be called only twice")
@ -183,7 +187,10 @@ releases:
rendered, _ := r.renderTemplatesToYaml("", "", yamlContent) rendered, _ := r.renderTemplatesToYaml("", "", yamlContent)
var state state.HelmState var state state.HelmState
yaml.Unmarshal(rendered.Bytes(), &state) err := yaml.Unmarshal(rendered.Bytes(), &state)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if len(state.Releases) != 1 { if len(state.Releases) != 1 {
t.Fatal("there should be 1 release") t.Fatal("there should be 1 release")
@ -210,6 +217,9 @@ func TestReadFromYaml_RenderTemplateWithNamespace(t *testing.T) {
var state state.HelmState var state state.HelmState
err = yaml.Unmarshal(yamlBuf.Bytes(), &state) err = yaml.Unmarshal(yamlBuf.Bytes(), &state)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if state.Releases[0].Name != "namespace-myrelease" { if state.Releases[0].Name != "namespace-myrelease" {
t.Errorf("release name should be namespace-myrelease") t.Errorf("release name should be namespace-myrelease")

View File

@ -2,8 +2,9 @@ package argparser
import ( import (
"fmt" "fmt"
"github.com/roboll/helmfile/pkg/state"
"strings" "strings"
"github.com/roboll/helmfile/pkg/state"
) )
type keyVal struct { type keyVal struct {
@ -95,10 +96,9 @@ func GetArgs(args string, state *state.HelmState) []string {
argArr = append(argArr, fmt.Sprintf("%s=%s", obj.key, obj.val)) argArr = append(argArr, fmt.Sprintf("%s=%s", obj.key, obj.val))
} }
} else { } else {
argArr = append(argArr, fmt.Sprintf("%s", obj.key)) argArr = append(argArr, obj.key)
} }
} }
} }
state.HelmDefaults.Args = argArr state.HelmDefaults.Args = argArr

View File

@ -1,9 +1,10 @@
package argparser package argparser
import ( import (
"github.com/roboll/helmfile/pkg/state"
"strings" "strings"
"testing" "testing"
"github.com/roboll/helmfile/pkg/state"
) )
func TestGetArgs(t *testing.T) { func TestGetArgs(t *testing.T) {
@ -44,10 +45,5 @@ func Test2(t *testing.T) {
} }
func compareArgs(expectedArgs string, args []string) bool { func compareArgs(expectedArgs string, args []string) bool {
return strings.Compare(strings.Join(args, " "), expectedArgs) == 0
if strings.Compare(strings.Join(args, " "), expectedArgs) != 0 {
return false
}
return true
} }

View File

@ -3,17 +3,13 @@ package event
import ( import (
"fmt" "fmt"
"io" "io"
"os"
"testing" "testing"
"github.com/roboll/helmfile/pkg/environment" "github.com/roboll/helmfile/pkg/environment"
"github.com/roboll/helmfile/pkg/helmexec"
"go.uber.org/zap" "go.uber.org/zap"
"go.uber.org/zap/zaptest/observer" "go.uber.org/zap/zaptest/observer"
) )
var logger = helmexec.NewLogger(os.Stdout, "warn")
type runner struct { type runner struct {
} }

View File

@ -79,10 +79,8 @@ func (helm *Helm) BuildDeps(name, chart string) error {
} }
func (helm *Helm) SetExtraArgs(args ...string) { func (helm *Helm) SetExtraArgs(args ...string) {
return
} }
func (helm *Helm) SetHelmBinary(bin string) { func (helm *Helm) SetHelmBinary(bin string) {
return
} }
func (helm *Helm) AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials string, skipTLSVerify string) error { func (helm *Helm) AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials string, skipTLSVerify string) error {
helm.Repo = []string{name, repository, cafile, certfile, keyfile, username, password, managed, passCredentials, skipTLSVerify} helm.Repo = []string{name, repository, cafile, certfile, keyfile, username, password, managed, passCredentials, skipTLSVerify}

View File

@ -89,10 +89,14 @@ func Test_AddRepo_Helm_3_3_2(t *testing.T) {
kubeContext: "dev", kubeContext: "dev",
runner: &mockRunner{}, runner: &mockRunner{},
} }
helm.AddRepo("myRepo", "https://repo.example.com/", "", "cert.pem", "key.pem", "", "", "", "", "") err := helm.AddRepo("myRepo", "https://repo.example.com/", "", "cert.pem", "key.pem", "", "", "", "", "")
expected := `Adding repo myRepo https://repo.example.com/ expected := `Adding repo myRepo https://repo.example.com/
exec: helm --kube-context dev repo add myRepo https://repo.example.com/ --force-update --cert-file cert.pem --key-file key.pem exec: helm --kube-context dev repo add myRepo https://repo.example.com/ --force-update --cert-file cert.pem --key-file key.pem
` `
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected { if buffer.String() != expected {
t.Errorf("helmexec.AddRepo()\nactual = %v\nexpect = %v", buffer.String(), expected) t.Errorf("helmexec.AddRepo()\nactual = %v\nexpect = %v", buffer.String(), expected)
} }
@ -102,93 +106,129 @@ func Test_AddRepo(t *testing.T) {
var buffer bytes.Buffer var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug") logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "dev") helm := MockExecer(logger, "dev")
helm.AddRepo("myRepo", "https://repo.example.com/", "", "cert.pem", "key.pem", "", "", "", "", "") err := helm.AddRepo("myRepo", "https://repo.example.com/", "", "cert.pem", "key.pem", "", "", "", "", "")
expected := `Adding repo myRepo https://repo.example.com/ expected := `Adding repo myRepo https://repo.example.com/
exec: helm --kube-context dev repo add myRepo https://repo.example.com/ --cert-file cert.pem --key-file key.pem exec: helm --kube-context dev repo add myRepo https://repo.example.com/ --cert-file cert.pem --key-file key.pem
` `
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected { if buffer.String() != expected {
t.Errorf("helmexec.AddRepo()\nactual = %v\nexpect = %v", buffer.String(), expected) t.Errorf("helmexec.AddRepo()\nactual = %v\nexpect = %v", buffer.String(), expected)
} }
buffer.Reset() buffer.Reset()
helm.AddRepo("myRepo", "https://repo.example.com/", "ca.crt", "", "", "", "", "", "", "") err = helm.AddRepo("myRepo", "https://repo.example.com/", "ca.crt", "", "", "", "", "", "", "")
expected = `Adding repo myRepo https://repo.example.com/ expected = `Adding repo myRepo https://repo.example.com/
exec: helm --kube-context dev repo add myRepo https://repo.example.com/ --ca-file ca.crt exec: helm --kube-context dev repo add myRepo https://repo.example.com/ --ca-file ca.crt
` `
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected { if buffer.String() != expected {
t.Errorf("helmexec.AddRepo()\nactual = %v\nexpect = %v", buffer.String(), expected) t.Errorf("helmexec.AddRepo()\nactual = %v\nexpect = %v", buffer.String(), expected)
} }
buffer.Reset() buffer.Reset()
helm.AddRepo("myRepo", "https://repo.example.com/", "", "", "", "", "", "", "", "") err = helm.AddRepo("myRepo", "https://repo.example.com/", "", "", "", "", "", "", "", "")
expected = `Adding repo myRepo https://repo.example.com/ expected = `Adding repo myRepo https://repo.example.com/
exec: helm --kube-context dev repo add myRepo https://repo.example.com/ exec: helm --kube-context dev repo add myRepo https://repo.example.com/
` `
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected { if buffer.String() != expected {
t.Errorf("helmexec.AddRepo()\nactual = %v\nexpect = %v", buffer.String(), expected) t.Errorf("helmexec.AddRepo()\nactual = %v\nexpect = %v", buffer.String(), expected)
} }
buffer.Reset() buffer.Reset()
helm.AddRepo("acrRepo", "", "", "", "", "", "", "acr", "", "") err = helm.AddRepo("acrRepo", "", "", "", "", "", "", "acr", "", "")
expected = `Adding repo acrRepo (acr) expected = `Adding repo acrRepo (acr)
exec: az acr helm repo add --name acrRepo exec: az acr helm repo add --name acrRepo
exec: az acr helm repo add --name acrRepo: exec: az acr helm repo add --name acrRepo:
` `
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected { if buffer.String() != expected {
t.Errorf("helmexec.AddRepo()\nactual = %v\nexpect = %v", buffer.String(), expected) t.Errorf("helmexec.AddRepo()\nactual = %v\nexpect = %v", buffer.String(), expected)
} }
buffer.Reset() buffer.Reset()
helm.AddRepo("otherRepo", "", "", "", "", "", "", "unknown", "", "") err = helm.AddRepo("otherRepo", "", "", "", "", "", "", "unknown", "", "")
expected = `ERROR: unknown type 'unknown' for repository otherRepo expected = `ERROR: unknown type 'unknown' for repository otherRepo
` `
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected { if buffer.String() != expected {
t.Errorf("helmexec.AddRepo()\nactual = %v\nexpect = %v", buffer.String(), expected) t.Errorf("helmexec.AddRepo()\nactual = %v\nexpect = %v", buffer.String(), expected)
} }
buffer.Reset() buffer.Reset()
helm.AddRepo("myRepo", "https://repo.example.com/", "", "", "", "example_user", "example_password", "", "", "") err = helm.AddRepo("myRepo", "https://repo.example.com/", "", "", "", "example_user", "example_password", "", "", "")
expected = `Adding repo myRepo https://repo.example.com/ expected = `Adding repo myRepo https://repo.example.com/
exec: helm --kube-context dev repo add myRepo https://repo.example.com/ --username example_user --password example_password exec: helm --kube-context dev repo add myRepo https://repo.example.com/ --username example_user --password example_password
` `
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected { if buffer.String() != expected {
t.Errorf("helmexec.AddRepo()\nactual = %v\nexpect = %v", buffer.String(), expected) t.Errorf("helmexec.AddRepo()\nactual = %v\nexpect = %v", buffer.String(), expected)
} }
buffer.Reset() buffer.Reset()
helm.AddRepo("", "https://repo.example.com/", "", "", "", "", "", "", "", "") err = helm.AddRepo("", "https://repo.example.com/", "", "", "", "", "", "", "", "")
expected = `empty field name expected = `empty field name
` `
if err != nil && err.Error() != "empty field name" {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected { if buffer.String() != expected {
t.Errorf("helmexec.AddRepo()\nactual = %v\nexpect = %v", buffer.String(), expected) t.Errorf("helmexec.AddRepo()\nactual = %v\nexpect = %v", buffer.String(), expected)
} }
buffer.Reset() buffer.Reset()
helm.AddRepo("myRepo", "https://repo.example.com/", "", "", "", "example_user", "example_password", "", "true", "") err = helm.AddRepo("myRepo", "https://repo.example.com/", "", "", "", "example_user", "example_password", "", "true", "")
expected = `Adding repo myRepo https://repo.example.com/ expected = `Adding repo myRepo https://repo.example.com/
exec: helm --kube-context dev repo add myRepo https://repo.example.com/ --username example_user --password example_password --pass-credentials exec: helm --kube-context dev repo add myRepo https://repo.example.com/ --username example_user --password example_password --pass-credentials
` `
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected { if buffer.String() != expected {
t.Errorf("helmexec.AddRepo()\nactual = %v\nexpect = %v", buffer.String(), expected) t.Errorf("helmexec.AddRepo()\nactual = %v\nexpect = %v", buffer.String(), expected)
} }
buffer.Reset() buffer.Reset()
helm.AddRepo("myRepo", "https://repo.example.com/", "", "", "", "", "", "", "", "true") err = helm.AddRepo("myRepo", "https://repo.example.com/", "", "", "", "", "", "", "", "true")
expected = `Adding repo myRepo https://repo.example.com/ expected = `Adding repo myRepo https://repo.example.com/
exec: helm --kube-context dev repo add myRepo https://repo.example.com/ --insecure-skip-tls-verify exec: helm --kube-context dev repo add myRepo https://repo.example.com/ --insecure-skip-tls-verify
` `
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected {
t.Errorf("helmexec.AddRepo()\nactual = %v\nexpect = %v", buffer.String(), expected)
}
} }
func Test_UpdateRepo(t *testing.T) { func Test_UpdateRepo(t *testing.T) {
var buffer bytes.Buffer var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug") logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "dev") helm := MockExecer(logger, "dev")
helm.UpdateRepo() err := helm.UpdateRepo()
expected := `Updating repo expected := `Updating repo
exec: helm --kube-context dev repo update exec: helm --kube-context dev repo update
` `
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected { if buffer.String() != expected {
t.Errorf("helmexec.UpdateRepo()\nactual = %v\nexpect = %v", buffer.String(), expected) t.Errorf("helmexec.UpdateRepo()\nactual = %v\nexpect = %v", buffer.String(), expected)
} }
@ -198,19 +238,25 @@ func Test_SyncRelease(t *testing.T) {
var buffer bytes.Buffer var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug") logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "dev") helm := MockExecer(logger, "dev")
helm.SyncRelease(HelmContext{}, "release", "chart", "--timeout 10", "--wait", "--wait-for-jobs") err := helm.SyncRelease(HelmContext{}, "release", "chart", "--timeout 10", "--wait", "--wait-for-jobs")
expected := `Upgrading release=release, chart=chart expected := `Upgrading release=release, chart=chart
exec: helm --kube-context dev upgrade --install --reset-values release chart --timeout 10 --wait --wait-for-jobs exec: helm --kube-context dev upgrade --install --reset-values release chart --timeout 10 --wait --wait-for-jobs
` `
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected { if buffer.String() != expected {
t.Errorf("helmexec.SyncRelease()\nactual = %v\nexpect = %v", buffer.String(), expected) t.Errorf("helmexec.SyncRelease()\nactual = %v\nexpect = %v", buffer.String(), expected)
} }
buffer.Reset() buffer.Reset()
helm.SyncRelease(HelmContext{}, "release", "chart") err = helm.SyncRelease(HelmContext{}, "release", "chart")
expected = `Upgrading release=release, chart=chart expected = `Upgrading release=release, chart=chart
exec: helm --kube-context dev upgrade --install --reset-values release chart exec: helm --kube-context dev upgrade --install --reset-values release chart
` `
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected { if buffer.String() != expected {
t.Errorf("helmexec.SyncRelease()\nactual = %v\nexpect = %v", buffer.String(), expected) t.Errorf("helmexec.SyncRelease()\nactual = %v\nexpect = %v", buffer.String(), expected)
} }
@ -220,11 +266,14 @@ func Test_SyncReleaseTillerless(t *testing.T) {
var buffer bytes.Buffer var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug") logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "dev") helm := MockExecer(logger, "dev")
helm.SyncRelease(HelmContext{Tillerless: true, TillerNamespace: "foo"}, "release", "chart", err := helm.SyncRelease(HelmContext{Tillerless: true, TillerNamespace: "foo"}, "release", "chart",
"--timeout 10", "--wait", "--wait-for-jobs") "--timeout 10", "--wait", "--wait-for-jobs")
expected := `Upgrading release=release, chart=chart expected := `Upgrading release=release, chart=chart
exec: helm --kube-context dev tiller run foo -- helm upgrade --install --reset-values release chart --timeout 10 --wait --wait-for-jobs exec: helm --kube-context dev tiller run foo -- helm upgrade --install --reset-values release chart --timeout 10 --wait --wait-for-jobs
` `
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected { if buffer.String() != expected {
t.Errorf("helmexec.SyncRelease()\nactual = %v\nexpect = %v", buffer.String(), expected) t.Errorf("helmexec.SyncRelease()\nactual = %v\nexpect = %v", buffer.String(), expected)
} }
@ -234,20 +283,26 @@ func Test_UpdateDeps(t *testing.T) {
var buffer bytes.Buffer var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug") logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "dev") helm := MockExecer(logger, "dev")
helm.UpdateDeps("./chart/foo") err := helm.UpdateDeps("./chart/foo")
expected := `Updating dependency ./chart/foo expected := `Updating dependency ./chart/foo
exec: helm --kube-context dev dependency update ./chart/foo exec: helm --kube-context dev dependency update ./chart/foo
` `
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected { if buffer.String() != expected {
t.Errorf("helmexec.UpdateDeps()\nactual = %v\nexpect = %v", buffer.String(), expected) t.Errorf("helmexec.UpdateDeps()\nactual = %v\nexpect = %v", buffer.String(), expected)
} }
buffer.Reset() buffer.Reset()
helm.SetExtraArgs("--verify") helm.SetExtraArgs("--verify")
helm.UpdateDeps("./chart/foo") err = helm.UpdateDeps("./chart/foo")
expected = `Updating dependency ./chart/foo expected = `Updating dependency ./chart/foo
exec: helm --kube-context dev dependency update ./chart/foo --verify exec: helm --kube-context dev dependency update ./chart/foo --verify
` `
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected { if buffer.String() != expected {
t.Errorf("helmexec.AddRepo()\nactual = %v\nexpect = %v", buffer.String(), expected) t.Errorf("helmexec.AddRepo()\nactual = %v\nexpect = %v", buffer.String(), expected)
} }
@ -257,20 +312,26 @@ func Test_BuildDeps(t *testing.T) {
var buffer bytes.Buffer var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug") logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "dev") helm := MockExecer(logger, "dev")
helm.BuildDeps("foo", "./chart/foo") err := helm.BuildDeps("foo", "./chart/foo")
expected := `Building dependency release=foo, chart=./chart/foo expected := `Building dependency release=foo, chart=./chart/foo
exec: helm --kube-context dev dependency build ./chart/foo exec: helm --kube-context dev dependency build ./chart/foo
` `
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected { if buffer.String() != expected {
t.Errorf("helmexec.BuildDeps()\nactual = %v\nexpect = %v", buffer.String(), expected) t.Errorf("helmexec.BuildDeps()\nactual = %v\nexpect = %v", buffer.String(), expected)
} }
buffer.Reset() buffer.Reset()
helm.SetExtraArgs("--verify") helm.SetExtraArgs("--verify")
helm.BuildDeps("foo", "./chart/foo") err = helm.BuildDeps("foo", "./chart/foo")
expected = `Building dependency release=foo, chart=./chart/foo expected = `Building dependency release=foo, chart=./chart/foo
exec: helm --kube-context dev dependency build ./chart/foo --verify exec: helm --kube-context dev dependency build ./chart/foo --verify
` `
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected { if buffer.String() != expected {
t.Errorf("helmexec.BuildDeps()\nactual = %v\nexpect = %v", buffer.String(), expected) t.Errorf("helmexec.BuildDeps()\nactual = %v\nexpect = %v", buffer.String(), expected)
} }
@ -286,13 +347,19 @@ func Test_DecryptSecret(t *testing.T) {
return tmpFilePath, nil return tmpFilePath, nil
} }
helm.DecryptSecret(HelmContext{}, "secretName") _, err := helm.DecryptSecret(HelmContext{}, "secretName")
if err != nil {
if _, ok := err.(*os.PathError); ok {
} else {
t.Errorf("Error: %v", err)
}
}
cwd, err := filepath.Abs(".") cwd, err := filepath.Abs(".")
if err != nil { if err != nil {
t.Errorf("Error: %v", err) t.Errorf("Error: %v", err)
} }
// Run again for caching // Run again for caching
helm.DecryptSecret(HelmContext{}, "secretName") _, err = helm.DecryptSecret(HelmContext{}, "secretName")
expected := fmt.Sprintf(`Preparing to decrypt secret %v/secretName expected := fmt.Sprintf(`Preparing to decrypt secret %v/secretName
Decrypting secret %s/secretName Decrypting secret %s/secretName
@ -300,6 +367,12 @@ exec: helm --kube-context dev secrets dec %s/secretName
Preparing to decrypt secret %s/secretName Preparing to decrypt secret %s/secretName
Found secret in cache %s/secretName Found secret in cache %s/secretName
`, cwd, cwd, cwd, cwd, cwd) `, cwd, cwd, cwd, cwd, cwd)
if err != nil {
if _, ok := err.(*os.PathError); ok {
} else {
t.Errorf("Error: %v", err)
}
}
if d := cmp.Diff(expected, buffer.String()); d != "" { if d := cmp.Diff(expected, buffer.String()); d != "" {
t.Errorf("helmexec.DecryptSecret(): want (-), got (+):\n%s", d) t.Errorf("helmexec.DecryptSecret(): want (-), got (+):\n%s", d)
} }
@ -332,19 +405,25 @@ func Test_DiffRelease(t *testing.T) {
var buffer bytes.Buffer var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug") logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "dev") helm := MockExecer(logger, "dev")
helm.DiffRelease(HelmContext{}, "release", "chart", false, "--timeout 10", "--wait", "--wait-for-jobs") err := helm.DiffRelease(HelmContext{}, "release", "chart", false, "--timeout 10", "--wait", "--wait-for-jobs")
expected := `Comparing release=release, chart=chart expected := `Comparing release=release, chart=chart
exec: helm --kube-context dev diff upgrade --reset-values --allow-unreleased release chart --timeout 10 --wait --wait-for-jobs exec: helm --kube-context dev diff upgrade --reset-values --allow-unreleased release chart --timeout 10 --wait --wait-for-jobs
` `
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected { if buffer.String() != expected {
t.Errorf("helmexec.DiffRelease()\nactual = %v\nexpect = %v", buffer.String(), expected) t.Errorf("helmexec.DiffRelease()\nactual = %v\nexpect = %v", buffer.String(), expected)
} }
buffer.Reset() buffer.Reset()
helm.DiffRelease(HelmContext{}, "release", "chart", false) err = helm.DiffRelease(HelmContext{}, "release", "chart", false)
expected = `Comparing release=release, chart=chart expected = `Comparing release=release, chart=chart
exec: helm --kube-context dev diff upgrade --reset-values --allow-unreleased release chart exec: helm --kube-context dev diff upgrade --reset-values --allow-unreleased release chart
` `
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected { if buffer.String() != expected {
t.Errorf("helmexec.DiffRelease()\nactual = %v\nexpect = %v", buffer.String(), expected) t.Errorf("helmexec.DiffRelease()\nactual = %v\nexpect = %v", buffer.String(), expected)
} }
@ -354,10 +433,13 @@ func Test_DiffReleaseTillerless(t *testing.T) {
var buffer bytes.Buffer var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug") logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "dev") helm := MockExecer(logger, "dev")
helm.DiffRelease(HelmContext{Tillerless: true}, "release", "chart", false, "--timeout 10", "--wait", "--wait-for-jobs") err := helm.DiffRelease(HelmContext{Tillerless: true}, "release", "chart", false, "--timeout 10", "--wait", "--wait-for-jobs")
expected := `Comparing release=release, chart=chart expected := `Comparing release=release, chart=chart
exec: helm --kube-context dev tiller run -- helm diff upgrade --reset-values --allow-unreleased release chart --timeout 10 --wait --wait-for-jobs exec: helm --kube-context dev tiller run -- helm diff upgrade --reset-values --allow-unreleased release chart --timeout 10 --wait --wait-for-jobs
` `
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected { if buffer.String() != expected {
t.Errorf("helmexec.DiffRelease()\nactual = %v\nexpect = %v", buffer.String(), expected) t.Errorf("helmexec.DiffRelease()\nactual = %v\nexpect = %v", buffer.String(), expected)
} }
@ -367,10 +449,13 @@ func Test_DeleteRelease(t *testing.T) {
var buffer bytes.Buffer var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug") logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "dev") helm := MockExecer(logger, "dev")
helm.DeleteRelease(HelmContext{}, "release") err := helm.DeleteRelease(HelmContext{}, "release")
expected := `Deleting release expected := `Deleting release
exec: helm --kube-context dev delete release exec: helm --kube-context dev delete release
` `
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected { if buffer.String() != expected {
t.Errorf("helmexec.DeleteRelease()\nactual = %v\nexpect = %v", buffer.String(), expected) t.Errorf("helmexec.DeleteRelease()\nactual = %v\nexpect = %v", buffer.String(), expected)
} }
@ -379,10 +464,13 @@ func Test_DeleteRelease_Flags(t *testing.T) {
var buffer bytes.Buffer var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug") logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "dev") helm := MockExecer(logger, "dev")
helm.DeleteRelease(HelmContext{}, "release", "--purge") err := helm.DeleteRelease(HelmContext{}, "release", "--purge")
expected := `Deleting release expected := `Deleting release
exec: helm --kube-context dev delete release --purge exec: helm --kube-context dev delete release --purge
` `
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected { if buffer.String() != expected {
t.Errorf("helmexec.DeleteRelease()\nactual = %v\nexpect = %v", buffer.String(), expected) t.Errorf("helmexec.DeleteRelease()\nactual = %v\nexpect = %v", buffer.String(), expected)
} }
@ -392,10 +480,13 @@ func Test_TestRelease(t *testing.T) {
var buffer bytes.Buffer var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug") logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "dev") helm := MockExecer(logger, "dev")
helm.TestRelease(HelmContext{}, "release") err := helm.TestRelease(HelmContext{}, "release")
expected := `Testing release expected := `Testing release
exec: helm --kube-context dev test release exec: helm --kube-context dev test release
` `
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected { if buffer.String() != expected {
t.Errorf("helmexec.TestRelease()\nactual = %v\nexpect = %v", buffer.String(), expected) t.Errorf("helmexec.TestRelease()\nactual = %v\nexpect = %v", buffer.String(), expected)
} }
@ -404,10 +495,13 @@ func Test_TestRelease_Flags(t *testing.T) {
var buffer bytes.Buffer var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug") logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "dev") helm := MockExecer(logger, "dev")
helm.TestRelease(HelmContext{}, "release", "--cleanup", "--timeout", "60") err := helm.TestRelease(HelmContext{}, "release", "--cleanup", "--timeout", "60")
expected := `Testing release expected := `Testing release
exec: helm --kube-context dev test release --cleanup --timeout 60 exec: helm --kube-context dev test release --cleanup --timeout 60
` `
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected { if buffer.String() != expected {
t.Errorf("helmexec.TestRelease()\nactual = %v\nexpect = %v", buffer.String(), expected) t.Errorf("helmexec.TestRelease()\nactual = %v\nexpect = %v", buffer.String(), expected)
} }
@ -417,10 +511,13 @@ func Test_ReleaseStatus(t *testing.T) {
var buffer bytes.Buffer var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug") logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "dev") helm := MockExecer(logger, "dev")
helm.ReleaseStatus(HelmContext{}, "myRelease") err := helm.ReleaseStatus(HelmContext{}, "myRelease")
expected := `Getting status myRelease expected := `Getting status myRelease
exec: helm --kube-context dev status myRelease exec: helm --kube-context dev status myRelease
` `
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected { if buffer.String() != expected {
t.Errorf("helmexec.ReleaseStatus()\nactual = %v\nexpect = %v", buffer.String(), expected) t.Errorf("helmexec.ReleaseStatus()\nactual = %v\nexpect = %v", buffer.String(), expected)
} }
@ -431,9 +528,12 @@ func Test_exec(t *testing.T) {
logger := NewLogger(&buffer, "debug") logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "") helm := MockExecer(logger, "")
env := map[string]string{} env := map[string]string{}
helm.exec([]string{"version"}, env) _, err := helm.exec([]string{"version"}, env)
expected := `exec: helm version expected := `exec: helm version
` `
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected { if buffer.String() != expected {
t.Errorf("helmexec.exec()\nactual = %v\nexpect = %v", buffer.String(), expected) t.Errorf("helmexec.exec()\nactual = %v\nexpect = %v", buffer.String(), expected)
} }
@ -446,26 +546,35 @@ func Test_exec(t *testing.T) {
buffer.Reset() buffer.Reset()
helm = MockExecer(logger, "dev") helm = MockExecer(logger, "dev")
helm.exec([]string{"diff", "release", "chart", "--timeout 10", "--wait", "--wait-for-jobs"}, env) _, err = helm.exec([]string{"diff", "release", "chart", "--timeout 10", "--wait", "--wait-for-jobs"}, env)
expected = `exec: helm --kube-context dev diff release chart --timeout 10 --wait --wait-for-jobs expected = `exec: helm --kube-context dev diff release chart --timeout 10 --wait --wait-for-jobs
` `
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected { if buffer.String() != expected {
t.Errorf("helmexec.exec()\nactual = %v\nexpect = %v", buffer.String(), expected) t.Errorf("helmexec.exec()\nactual = %v\nexpect = %v", buffer.String(), expected)
} }
buffer.Reset() buffer.Reset()
helm.exec([]string{"version"}, env) _, err = helm.exec([]string{"version"}, env)
expected = `exec: helm --kube-context dev version expected = `exec: helm --kube-context dev version
` `
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected { if buffer.String() != expected {
t.Errorf("helmexec.exec()\nactual = %v\nexpect = %v", buffer.String(), expected) t.Errorf("helmexec.exec()\nactual = %v\nexpect = %v", buffer.String(), expected)
} }
buffer.Reset() buffer.Reset()
helm.SetExtraArgs("foo") helm.SetExtraArgs("foo")
helm.exec([]string{"version"}, env) _, err = helm.exec([]string{"version"}, env)
expected = `exec: helm --kube-context dev version foo expected = `exec: helm --kube-context dev version foo
` `
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected { if buffer.String() != expected {
t.Errorf("helmexec.exec()\nactual = %v\nexpect = %v", buffer.String(), expected) t.Errorf("helmexec.exec()\nactual = %v\nexpect = %v", buffer.String(), expected)
} }
@ -473,9 +582,12 @@ func Test_exec(t *testing.T) {
buffer.Reset() buffer.Reset()
helm = MockExecer(logger, "") helm = MockExecer(logger, "")
helm.SetHelmBinary("overwritten") helm.SetHelmBinary("overwritten")
helm.exec([]string{"version"}, env) _, err = helm.exec([]string{"version"}, env)
expected = `exec: overwritten version expected = `exec: overwritten version
` `
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected { if buffer.String() != expected {
t.Errorf("helmexec.exec()\nactual = %v\nexpect = %v", buffer.String(), expected) t.Errorf("helmexec.exec()\nactual = %v\nexpect = %v", buffer.String(), expected)
} }
@ -485,10 +597,13 @@ func Test_Lint(t *testing.T) {
var buffer bytes.Buffer var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug") logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "dev") helm := MockExecer(logger, "dev")
helm.Lint("release", "path/to/chart", "--values", "file.yml") err := helm.Lint("release", "path/to/chart", "--values", "file.yml")
expected := `Linting release=release, chart=path/to/chart expected := `Linting release=release, chart=path/to/chart
exec: helm --kube-context dev lint path/to/chart --values file.yml exec: helm --kube-context dev lint path/to/chart --values file.yml
` `
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected { if buffer.String() != expected {
t.Errorf("helmexec.Lint()\nactual = %v\nexpect = %v", buffer.String(), expected) t.Errorf("helmexec.Lint()\nactual = %v\nexpect = %v", buffer.String(), expected)
} }
@ -498,10 +613,13 @@ func Test_Fetch(t *testing.T) {
var buffer bytes.Buffer var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug") logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "dev") helm := MockExecer(logger, "dev")
helm.Fetch("chart", "--version", "1.2.3", "--untar", "--untardir", "/tmp/dir") err := helm.Fetch("chart", "--version", "1.2.3", "--untar", "--untardir", "/tmp/dir")
expected := `Fetching chart expected := `Fetching chart
exec: helm --kube-context dev fetch chart --version 1.2.3 --untar --untardir /tmp/dir exec: helm --kube-context dev fetch chart --version 1.2.3 --untar --untardir /tmp/dir
` `
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected { if buffer.String() != expected {
t.Errorf("helmexec.Lint()\nactual = %v\nexpect = %v", buffer.String(), expected) t.Errorf("helmexec.Lint()\nactual = %v\nexpect = %v", buffer.String(), expected)
} }
@ -522,7 +640,10 @@ func Test_LogLevels(t *testing.T) {
buffer.Reset() buffer.Reset()
logger := NewLogger(&buffer, logLevel) logger := NewLogger(&buffer, logLevel)
helm := MockExecer(logger, "") helm := MockExecer(logger, "")
helm.AddRepo("myRepo", "https://repo.example.com/", "", "", "", "example_user", "example_password", "", "", "") err := helm.AddRepo("myRepo", "https://repo.example.com/", "", "", "", "example_user", "example_password", "", "", "")
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected { if buffer.String() != expected {
t.Errorf("helmexec.AddRepo()\nactual = %v\nexpect = %v", buffer.String(), expected) t.Errorf("helmexec.AddRepo()\nactual = %v\nexpect = %v", buffer.String(), expected)
} }
@ -567,10 +688,13 @@ func Test_Template(t *testing.T) {
var buffer bytes.Buffer var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug") logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "dev") helm := MockExecer(logger, "dev")
helm.TemplateRelease("release", "path/to/chart", "--values", "file.yml") err := helm.TemplateRelease("release", "path/to/chart", "--values", "file.yml")
expected := `Templating release=release, chart=path/to/chart expected := `Templating release=release, chart=path/to/chart
exec: helm --kube-context dev template path/to/chart --name release --values file.yml exec: helm --kube-context dev template path/to/chart --name release --values file.yml
` `
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected { if buffer.String() != expected {
t.Errorf("helmexec.Template()\nactual = %v\nexpect = %v", buffer.String(), expected) t.Errorf("helmexec.Template()\nactual = %v\nexpect = %v", buffer.String(), expected)
} }

View File

@ -14,11 +14,6 @@ import (
"go.uber.org/zap" "go.uber.org/zap"
) )
const (
tmpPrefix = "helmfile-"
tmpSuffix = "-exec"
)
// Runner interface for shell commands // Runner interface for shell commands
type Runner interface { type Runner interface {
Execute(cmd string, args []string, env map[string]string) ([]byte, error) Execute(cmd string, args []string, env map[string]string) ([]byte, error)

View File

@ -158,11 +158,11 @@ func ParseKey(key string) []string {
for _, rune := range key { for _, rune := range key {
split := false split := false
switch { switch {
case escaped == false && rune == '\\': case !escaped && rune == '\\':
escaped = true escaped = true
continue continue
case rune == '.': case rune == '.':
split = escaped == false split = !escaped
} }
escaped = false escaped = false
if split { if split {

View File

@ -358,13 +358,13 @@ func (c *StateCreator) scatterGatherEnvSecretFiles(st *HelmState, envSecretFiles
for _, err := range errs { for _, err := range errs {
st.logger.Error(err) st.logger.Error(err)
} }
return fmt.Errorf("Failed loading environment secrets with %d errors", len(errs)) return fmt.Errorf("failed loading environment secrets with %d errors", len(errs))
} }
return nil return nil
} }
func (st *HelmState) loadValuesEntries(missingFileHandler *string, entries []interface{}, remote *remote.Remote, ctxEnv *environment.Environment) (map[string]interface{}, error) { func (st *HelmState) loadValuesEntries(missingFileHandler *string, entries []interface{}, remote *remote.Remote, ctxEnv *environment.Environment) (map[string]interface{}, error) {
envVals := map[string]interface{}{} var envVals map[string]interface{}
valuesEntries := append([]interface{}{}, entries...) valuesEntries := append([]interface{}{}, entries...)
ld := NewEnvironmentValuesLoader(st.storage(), st.readFile, st.logger, remote) ld := NewEnvironmentValuesLoader(st.storage(), st.readFile, st.logger, remote)

View File

@ -140,9 +140,7 @@ func (st *HelmState) PrepareChartify(helm helmexec.Interface, release *ReleaseSp
filesNeedCleaning = append(filesNeedCleaning, generatedFiles...) filesNeedCleaning = append(filesNeedCleaning, generatedFiles...)
for _, f := range generatedFiles { c.Opts.JsonPatches = append(c.Opts.JsonPatches, generatedFiles...)
c.Opts.JsonPatches = append(c.Opts.JsonPatches, f)
}
shouldRun = true shouldRun = true
} }
@ -154,9 +152,7 @@ func (st *HelmState) PrepareChartify(helm helmexec.Interface, release *ReleaseSp
return nil, clean, err return nil, clean, err
} }
for _, f := range generatedFiles { c.Opts.StrategicMergePatches = append(c.Opts.StrategicMergePatches, generatedFiles...)
c.Opts.StrategicMergePatches = append(c.Opts.StrategicMergePatches, f)
}
filesNeedCleaning = append(filesNeedCleaning, generatedFiles...) filesNeedCleaning = append(filesNeedCleaning, generatedFiles...)
@ -170,9 +166,7 @@ func (st *HelmState) PrepareChartify(helm helmexec.Interface, release *ReleaseSp
return nil, clean, err return nil, clean, err
} }
for _, f := range generatedFiles { c.Opts.Transformers = append(c.Opts.Transformers, generatedFiles...)
c.Opts.Transformers = append(c.Opts.Transformers, f)
}
filesNeedCleaning = append(filesNeedCleaning, generatedFiles...) filesNeedCleaning = append(filesNeedCleaning, generatedFiles...)

View File

@ -54,15 +54,17 @@ func ParseLabels(l string) (LabelFilter, error) {
lf.negativeLabels = [][]string{} lf.negativeLabels = [][]string{}
var err error var err error
labels := strings.Split(l, ",") labels := strings.Split(l, ",")
reMissmatch := regexp.MustCompile("^[a-zA-Z0-9_-]+!=[a-zA-Z0-9_-]+$")
reMatch := regexp.MustCompile("^[a-zA-Z0-9_-]+=[a-zA-Z0-9_-]+$")
for _, label := range labels { for _, label := range labels {
if match, _ := regexp.MatchString("^[a-zA-Z0-9_-]+!=[a-zA-Z0-9_-]+$", label); match == true { // k!=v case if match := reMissmatch.MatchString(label); match { // k!=v case
kv := strings.Split(label, "!=") kv := strings.Split(label, "!=")
lf.negativeLabels = append(lf.negativeLabels, kv) lf.negativeLabels = append(lf.negativeLabels, kv)
} else if match, _ := regexp.MatchString("^[a-zA-Z0-9_-]+=[a-zA-Z0-9_-]+$", label); match == true { // k=v case } else if match := reMatch.MatchString(label); match { // k=v case
kv := strings.Split(label, "=") kv := strings.Split(label, "=")
lf.positiveLabels = append(lf.positiveLabels, kv) lf.positiveLabels = append(lf.positiveLabels, kv)
} else { // malformed case } else { // malformed case
return lf, fmt.Errorf("Malformed label: %s. Expected label in form k=v or k!=v", label) return lf, fmt.Errorf("malformed label: %s. Expected label in form k=v or k!=v", label)
} }
} }
return lf, err return lf, err

View File

@ -97,7 +97,6 @@ type HelmState struct {
tempDir func(string, string) (string, error) tempDir func(string, string) (string, error)
directoryExistsAt func(string) bool directoryExistsAt func(string) bool
runner helmexec.Runner
valsRuntime vals.Evaluator valsRuntime vals.Evaluator
// RenderedValues is the helmfile-wide values that is `.Values` // RenderedValues is the helmfile-wide values that is `.Values`
@ -555,14 +554,12 @@ func (st *HelmState) prepareSyncReleases(helm helmexec.Interface, additionalValu
}, },
func() { func() {
for i := 0; i < numReleases; { for i := 0; i < numReleases; {
select { r := <-results
case r := <-results: for _, e := range r.errors {
for _, e := range r.errors { errs = append(errs, e)
errs = append(errs, e)
}
res = append(res, r)
i++
} }
res = append(res, r)
i++
} }
}, },
) )
@ -739,12 +736,10 @@ func (st *HelmState) DeleteReleasesForSync(affectedReleases *AffectedReleases, h
}, },
func() { func() {
for i := 0; i < len(releases); { for i := 0; i < len(releases); {
select { res := <-results
case res := <-results: if len(res.errors) > 0 {
if len(res.errors) > 0 { for _, e := range res.errors {
for _, e := range res.errors { errs = append(errs, e)
errs = append(errs, e)
}
} }
} }
i++ i++
@ -875,12 +870,10 @@ func (st *HelmState) SyncReleases(affectedReleases *AffectedReleases, helm helme
}, },
func() { func() {
for i := 0; i < len(preps); { for i := 0; i < len(preps); {
select { res := <-results
case res := <-results: if len(res.errors) > 0 {
if len(res.errors) > 0 { for _, e := range res.errors {
for _, e := range res.errors { errs = append(errs, e)
errs = append(errs, e)
}
} }
} }
i++ i++
@ -1722,7 +1715,7 @@ func (st *HelmState) prepareDiffReleases(helm helmexec.Interface, additionalValu
} }
if opts.Output != "" { if opts.Output != "" {
flags = append(flags, "--output", fmt.Sprintf("%s", opts.Output)) flags = append(flags, "--output", opts.Output)
} }
if opts.Set != nil { if opts.Set != nil {
@ -2028,8 +2021,7 @@ func (st *HelmState) Clean() []error {
func (st *HelmState) GetReleasesWithOverrides() []ReleaseSpec { func (st *HelmState) GetReleasesWithOverrides() []ReleaseSpec {
var rs []ReleaseSpec var rs []ReleaseSpec
for _, r := range st.Releases { for _, r := range st.Releases {
var spec ReleaseSpec spec := r
spec = r
st.ApplyOverrides(&spec) st.ApplyOverrides(&spec)
rs = append(rs, spec) rs = append(rs, spec)
} }
@ -2296,15 +2288,10 @@ func (st *HelmState) UpdateDeps(helm helmexec.Interface, includeTransitiveNeeds
return nil return nil
} }
func chartNameWithoutRepository(chart string) string {
chartSplit := strings.Split(chart, "/")
return chartSplit[len(chartSplit)-1]
}
// find "Chart.yaml" // find "Chart.yaml"
func findChartDirectory(topLevelDir string) (string, error) { func findChartDirectory(topLevelDir string) (string, error) {
var files []string var files []string
filepath.Walk(topLevelDir, func(path string, f os.FileInfo, err error) error { err := filepath.Walk(topLevelDir, func(path string, f os.FileInfo, err error) error {
if err != nil { if err != nil {
return fmt.Errorf("error walking through %s: %v", path, err) return fmt.Errorf("error walking through %s: %v", path, err)
} }
@ -2316,6 +2303,9 @@ func findChartDirectory(topLevelDir string) (string, error) {
} }
return nil return nil
}) })
if err != nil {
return topLevelDir, err
}
// Sort to get the shortest path // Sort to get the shortest path
sort.Strings(files) sort.Strings(files)
if len(files) > 0 { if len(files) > 0 {
@ -2323,15 +2313,13 @@ func findChartDirectory(topLevelDir string) (string, error) {
return first, nil return first, nil
} }
return topLevelDir, errors.New("No Chart.yaml found") return topLevelDir, errors.New("no Chart.yaml found")
} }
// appendConnectionFlags append all the helm command-line flags related to K8s API and Tiller connection including the kubecontext // appendConnectionFlags append all the helm command-line flags related to K8s API and Tiller connection including the kubecontext
func (st *HelmState) appendConnectionFlags(flags []string, helm helmexec.Interface, release *ReleaseSpec) []string { func (st *HelmState) appendConnectionFlags(flags []string, helm helmexec.Interface, release *ReleaseSpec) []string {
adds := st.connectionFlags(helm, release) adds := st.connectionFlags(helm, release)
for _, a := range adds { flags = append(flags, adds...)
flags = append(flags, a)
}
return flags return flags
} }
@ -2963,7 +2951,10 @@ func (ar *AffectedReleases) DisplayAffectedReleases(logger *zap.SugaredLogger) {
) )
tbl.Separator = " " tbl.Separator = " "
for _, release := range ar.Upgraded { for _, release := range ar.Upgraded {
tbl.AddRow(release.Name, release.Chart, release.installedVersion) err := tbl.AddRow(release.Name, release.Chart, release.installedVersion)
if err != nil {
logger.Warn("Could not add row, %v", err)
}
} }
logger.Info(tbl.String()) logger.Info(tbl.String())
} }
@ -3041,7 +3032,7 @@ func (hf *SubHelmfileSpec) UnmarshalYAML(unmarshal func(interface{}) error) erro
} }
//also exclude SelectorsInherited to true and explicit selectors //also exclude SelectorsInherited to true and explicit selectors
if hf.SelectorsInherited && len(hf.Selectors) > 0 { if hf.SelectorsInherited && len(hf.Selectors) > 0 {
return fmt.Errorf("You cannot use 'SelectorsInherited: true' along with and explicit selector for path: %v", hf.Path) return fmt.Errorf("you cannot use 'SelectorsInherited: true' along with and explicit selector for path: %v", hf.Path)
} }
return nil return nil
} }
@ -3056,7 +3047,10 @@ func (st *HelmState) GenerateOutputDir(outputDir string, release *ReleaseSpec, o
} }
hasher := sha1.New() hasher := sha1.New()
io.WriteString(hasher, stateAbsPath) _, err = io.WriteString(hasher, stateAbsPath)
if err != nil {
return "", err
}
var stateFileExtension = filepath.Ext(st.FilePath) var stateFileExtension = filepath.Ext(st.FilePath)
var stateFileName = st.FilePath[0 : len(st.FilePath)-len(stateFileExtension)] var stateFileName = st.FilePath[0 : len(st.FilePath)-len(stateFileExtension)]
@ -3120,7 +3114,10 @@ func (st *HelmState) GenerateOutputFilePath(release *ReleaseSpec, outputFileTemp
} }
hasher := sha1.New() hasher := sha1.New()
io.WriteString(hasher, stateAbsPath) _, err = io.WriteString(hasher, stateAbsPath)
if err != nil {
return "", err
}
var stateFileExtension = filepath.Ext(st.FilePath) var stateFileExtension = filepath.Ext(st.FilePath)
var stateFileName = st.FilePath[0 : len(st.FilePath)-len(stateFileExtension)] var stateFileName = st.FilePath[0 : len(st.FilePath)-len(stateFileExtension)]

View File

@ -90,27 +90,28 @@ func (st *HelmState) ExecuteTemplates() (*HelmState, error) {
vals := st.Values() vals := st.Values()
for i, rt := range st.Releases { for i, rt := range st.Releases {
if rt.KubeContext == "" { release := rt
rt.KubeContext = r.HelmDefaults.KubeContext if release.KubeContext == "" {
release.KubeContext = r.HelmDefaults.KubeContext
} }
if rt.Labels == nil { if release.Labels == nil {
rt.Labels = map[string]string{} release.Labels = map[string]string{}
} }
for k, v := range st.CommonLabels { for k, v := range st.CommonLabels {
rt.Labels[k] = v release.Labels[k] = v
} }
successFlag := false successFlag := false
for it, prev := 0, &rt; it < 6; it++ { for it, prev := 0, &release; it < 6; it++ {
tmplData := st.createReleaseTemplateData(prev, vals) tmplData := st.createReleaseTemplateData(prev, vals)
renderer := tmpl.NewFileRenderer(st.readFile, st.basePath, tmplData) renderer := tmpl.NewFileRenderer(st.readFile, st.basePath, tmplData)
r, err := rt.ExecuteTemplateExpressions(renderer) r, err := release.ExecuteTemplateExpressions(renderer)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed executing templates in release \"%s\".\"%s\": %v", st.FilePath, rt.Name, err) return nil, fmt.Errorf("failed executing templates in release \"%s\".\"%s\": %v", st.FilePath, release.Name, err)
} }
if reflect.DeepEqual(prev, r) { if reflect.DeepEqual(prev, r) {
successFlag = true successFlag = true
if err := updateBoolTemplatedValues(r); err != nil { if err := updateBoolTemplatedValues(r); err != nil {
return nil, fmt.Errorf("failed executing templates in release \"%s\".\"%s\": %v", st.FilePath, rt.Name, err) return nil, fmt.Errorf("failed executing templates in release \"%s\".\"%s\": %v", st.FilePath, release.Name, err)
} }
st.Releases[i] = *r st.Releases[i] = *r
break break
@ -118,7 +119,7 @@ func (st *HelmState) ExecuteTemplates() (*HelmState, error) {
prev = r prev = r
} }
if !successFlag { if !successFlag {
return nil, fmt.Errorf("failed executing templates in release \"%s\".\"%s\": %s", st.FilePath, rt.Name, return nil, fmt.Errorf("failed executing templates in release \"%s\".\"%s\": %s", st.FilePath, release.Name,
"recursive references can't be resolved") "recursive references can't be resolved")
} }
} }

View File

@ -17,11 +17,6 @@ func boolPtrToString(ptr *bool) string {
return fmt.Sprintf("&%t", *ptr) return fmt.Sprintf("&%t", *ptr)
} }
func ptr(v interface{}) interface{} {
r := v
return reflect.ValueOf(r).Addr().Interface()
}
func TestHelmState_executeTemplates(t *testing.T) { func TestHelmState_executeTemplates(t *testing.T) {
tests := []struct { tests := []struct {
name string name string

View File

@ -2,11 +2,12 @@ package state
import ( import (
"fmt" "fmt"
"github.com/google/go-cmp/cmp"
"github.com/roboll/helmfile/pkg/helmexec"
"io/ioutil" "io/ioutil"
"os" "os"
"testing" "testing"
"github.com/google/go-cmp/cmp"
"github.com/roboll/helmfile/pkg/helmexec"
) )
func TestGoGetter(t *testing.T) { func TestGoGetter(t *testing.T) {
@ -28,6 +29,7 @@ func TestGoGetter(t *testing.T) {
} }
for i, tc := range testcases { for i, tc := range testcases {
test := tc
t.Run(fmt.Sprintf("case %d", i), func(t *testing.T) { t.Run(fmt.Sprintf("case %d", i), func(t *testing.T) {
d, err := ioutil.TempDir("", "testgogetter") d, err := ioutil.TempDir("", "testgogetter")
if err != nil { if err != nil {
@ -41,9 +43,9 @@ func TestGoGetter(t *testing.T) {
basePath: d, basePath: d,
} }
out, err := st.goGetterChart(tc.chart, tc.dir, "", false) out, err := st.goGetterChart(test.chart, test.dir, "", false)
if diff := cmp.Diff(tc.out, out); diff != "" { if diff := cmp.Diff(test.out, out); diff != "" {
t.Fatalf("Unexpected out:\n%s", diff) t.Fatalf("Unexpected out:\n%s", diff)
} }
@ -53,7 +55,7 @@ func TestGoGetter(t *testing.T) {
errMsg = err.Error() errMsg = err.Error()
} }
if diff := cmp.Diff(tc.err, errMsg); diff != "" { if diff := cmp.Diff(test.err, errMsg); diff != "" {
t.Fatalf("Unexpected err:\n%s", diff) t.Fatalf("Unexpected err:\n%s", diff)
} }
}) })

View File

@ -166,7 +166,8 @@ func GroupReleasesByDependency(releases []Release, opts PlanOptions) ([][]Releas
var selectedReleaseIDs []string var selectedReleaseIDs []string
for _, r := range opts.SelectedReleases { for _, r := range opts.SelectedReleases {
id := ReleaseToID(&r) release := r
id := ReleaseToID(&release)
selectedReleaseIDs = append(selectedReleaseIDs, id) selectedReleaseIDs = append(selectedReleaseIDs, id)
} }

View File

@ -149,14 +149,6 @@ func boolValue(v bool) *bool {
return &v return &v
} }
// Mocking the command-line runner
type mockRunner struct{}
func (mock *mockRunner) Execute(cmd string, args []string, env map[string]string) ([]byte, error) {
return []byte{}, nil
}
func TestHelmState_flagsForUpgrade(t *testing.T) { func TestHelmState_flagsForUpgrade(t *testing.T) {
enable := true enable := true
disable := false disable := false
@ -1122,7 +1114,7 @@ func TestHelmState_SyncReleases(t *testing.T) {
valsRuntime: valsRuntime, valsRuntime: valsRuntime,
RenderedValues: map[string]interface{}{}, RenderedValues: map[string]interface{}{},
} }
if errs := state.SyncReleases(&AffectedReleases{}, tt.helm, []string{}, 1); errs != nil && len(errs) > 0 { if errs := state.SyncReleases(&AffectedReleases{}, tt.helm, []string{}, 1); len(errs) > 0 {
if len(errs) != len(tt.wantErrorMsgs) { if len(errs) != len(tt.wantErrorMsgs) {
t.Fatalf("Unexpected errors: %v\nExpected: %v", errs, tt.wantErrorMsgs) t.Fatalf("Unexpected errors: %v\nExpected: %v", errs, tt.wantErrorMsgs)
} }
@ -1613,7 +1605,7 @@ func TestHelmState_DiffReleases(t *testing.T) {
RenderedValues: map[string]interface{}{}, RenderedValues: map[string]interface{}{},
} }
_, errs := state.DiffReleases(tt.helm, []string{}, 1, false, false, []string{}, false, false, false, false) _, errs := state.DiffReleases(tt.helm, []string{}, 1, false, false, []string{}, false, false, false, false)
if errs != nil && len(errs) > 0 { if len(errs) > 0 {
t.Errorf("unexpected error: %v", errs) t.Errorf("unexpected error: %v", errs)
} }
if !reflect.DeepEqual(tt.helm.Diffed, tt.wantReleases) { if !reflect.DeepEqual(tt.helm.Diffed, tt.wantReleases) {
@ -1695,11 +1687,11 @@ func TestHelmState_SyncReleasesCleanup(t *testing.T) {
"/path/to/someFile": `foo: FOO`, "/path/to/someFile": `foo: FOO`,
}) })
state = injectFs(state, testfs) state = injectFs(state, testfs)
if errs := state.SyncReleases(&AffectedReleases{}, tt.helm, []string{}, 1); errs != nil && len(errs) > 0 { if errs := state.SyncReleases(&AffectedReleases{}, tt.helm, []string{}, 1); len(errs) > 0 {
t.Errorf("unexpected errors: %v", errs) t.Errorf("unexpected errors: %v", errs)
} }
if errs := state.Clean(); errs != nil && len(errs) > 0 { if errs := state.Clean(); len(errs) > 0 {
t.Errorf("unexpected errors: %v", errs) t.Errorf("unexpected errors: %v", errs)
} }
@ -1783,11 +1775,11 @@ func TestHelmState_DiffReleasesCleanup(t *testing.T) {
`, `,
}) })
state = injectFs(state, testfs) state = injectFs(state, testfs)
if _, errs := state.DiffReleases(tt.helm, []string{}, 1, false, false, []string{}, false, false, false, false); errs != nil && len(errs) > 0 { if _, errs := state.DiffReleases(tt.helm, []string{}, 1, false, false, []string{}, false, false, false, false); len(errs) > 0 {
t.Errorf("unexpected errors: %v", errs) t.Errorf("unexpected errors: %v", errs)
} }
if errs := state.Clean(); errs != nil && len(errs) > 0 { if errs := state.Clean(); len(errs) > 0 {
t.Errorf("unexpected errors: %v", errs) t.Errorf("unexpected errors: %v", errs)
} }

View File

@ -42,11 +42,9 @@ func tempValuesFilePath(release *ReleaseSpec, data interface{}) (*string, error)
d := filepath.Join(workDir, id) d := filepath.Join(workDir, id)
info, err := os.Stat(d) _, err = os.Stat(d)
if err != nil && !errors.Is(err, os.ErrNotExist) { if err != nil && !errors.Is(err, os.ErrNotExist) {
panic(err) panic(err)
} else if info == nil {
} }
return &d, nil return &d, nil

View File

@ -13,14 +13,14 @@ func isLocalChart(chart string) bool {
return true return true
} }
uriLike := strings.Index(chart, "://") > -1 uriLike := strings.Contains(chart, "://")
if uriLike { if uriLike {
return false return false
} }
return chart == "" || return chart == "" ||
chart[0] == '/' || chart[0] == '/' ||
strings.Index(chart, "/") == -1 || !strings.Contains(chart, "/") ||
(len(strings.Split(chart, "/")) != 2 && (len(strings.Split(chart, "/")) != 2 &&
len(strings.Split(chart, "/")) != 3) len(strings.Split(chart, "/")) != 3)
} }
@ -30,7 +30,7 @@ func resolveRemoteChart(repoAndChart string) (string, string, bool) {
return "", "", false return "", "", false
} }
uriLike := strings.Index(repoAndChart, "://") > -1 uriLike := strings.Contains(repoAndChart, "://")
if uriLike { if uriLike {
return "", "", false return "", "", false
} }

View File

@ -20,7 +20,7 @@ type TestFs struct {
func NewTestFs(files map[string]string) *TestFs { func NewTestFs(files map[string]string) *TestFs {
dirs := map[string]bool{} dirs := map[string]bool{}
for abs, _ := range files { for abs := range files {
for d := filepath.ToSlash(filepath.Dir(abs)); !dirs[d]; d = filepath.ToSlash(filepath.Dir(d)) { for d := filepath.ToSlash(filepath.Dir(abs)); !dirs[d]; d = filepath.ToSlash(filepath.Dir(d)) {
dirs[d] = true dirs[d] = true
fmt.Fprintf(os.Stderr, "testfs: recognized dir: %s\n", d) fmt.Fprintf(os.Stderr, "testfs: recognized dir: %s\n", d)
@ -102,7 +102,7 @@ func (f *TestFs) Glob(relPattern string) ([]string, error) {
} }
matches := []string{} matches := []string{}
for name, _ := range f.files { for name := range f.files {
matched, err := filepath.Match(pattern, name) matched, err := filepath.Match(pattern, name)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -56,7 +56,7 @@ func (c *Context) Exec(command string, args []interface{}, inputs ...string) (st
for i, a := range args { for i, a := range args {
switch a.(type) { switch a.(type) {
case string: case string:
strArgs[i] = a.(string) strArgs[i] = fmt.Sprintf("%v", a)
default: default:
return "", fmt.Errorf("unexpected type of arg \"%s\" in args %v at index %d", reflect.TypeOf(a), args, i) return "", fmt.Errorf("unexpected type of arg \"%s\" in args %v at index %d", reflect.TypeOf(a), args, i)
} }

View File

@ -3,10 +3,11 @@ package tmpl
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/google/go-cmp/cmp"
"path/filepath" "path/filepath"
"reflect" "reflect"
"testing" "testing"
"github.com/google/go-cmp/cmp"
) )
func TestReadFile(t *testing.T) { func TestReadFile(t *testing.T) {
@ -207,14 +208,15 @@ func TestRequired(t *testing.T) {
}, },
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { testCase := tt
got, err := Required(tt.args.warn, tt.args.val) t.Run(testCase.name, func(t *testing.T) {
if (err != nil) != tt.wantErr { got, err := Required(testCase.args.warn, testCase.args.val)
t.Errorf("Required() error = %v, wantErr %v", err, tt.wantErr) if (err != nil) != testCase.wantErr {
t.Errorf("Required() error = %v, wantErr %v", err, testCase.wantErr)
return return
} }
if !reflect.DeepEqual(got, tt.want) { if !reflect.DeepEqual(got, testCase.want) {
t.Errorf("Required() got = %v, want %v", got, tt.want) t.Errorf("Required() got = %v, want %v", got, testCase.want)
} }
}) })
} }

View File

@ -1,11 +1,11 @@
package tmpl package tmpl
import ( import (
"errors"
"fmt" "fmt"
"sync"
"github.com/roboll/helmfile/pkg/plugins" "github.com/roboll/helmfile/pkg/plugins"
"github.com/variantdev/vals" "github.com/variantdev/vals"
"sync"
) )
//to generate mock run mockgen -source=expand_secret_ref.go -destination=expand_secrets_mock.go -package=tmpl //to generate mock run mockgen -source=expand_secret_ref.go -destination=expand_secrets_mock.go -package=tmpl
@ -26,12 +26,12 @@ func fetchSecretValue(path string) (string, error) {
rendered, ok := resultMap["key"] rendered, ok := resultMap["key"]
if !ok { if !ok {
return "", errors.New(fmt.Sprintf("unexpected error occurred, %v doesn't have 'key' key", resultMap)) return "", fmt.Errorf("unexpected error occurred, %v doesn't have 'key' key", resultMap)
} }
result, ok := rendered.(string) result, ok := rendered.(string)
if !ok { if !ok {
return "", errors.New(fmt.Sprintf("expected %v to be string", rendered)) return "", fmt.Errorf("expected %v to be string", rendered)
} }
return result, nil return result, nil

View File

@ -271,5 +271,10 @@ func (p *pair) add(node resource, source diffSource) error {
} }
func main() { func main() {
rootCmd.Execute() err := rootCmd.Execute()
if err != nil {
fmt.Println(fmt.Errorf("unexpected error: %v", err))
os.Exit(1)
}
} }