mirror of
https://github.com/helmfile/helmfile.git
synced 2026-10-18 10:10:39 +02:00
Introduce Helmfile's own filesystem abstraction to correctly unit test some components (#307)
Use abstracted FS Signed-off-by: Arkaitz Jimenez <arkaitzj@gmail.com> Signed-off-by: Arkaitz Jimenez <arkaitzj@gmail.com>
This commit is contained in:
@@ -146,8 +146,8 @@ func (st *HelmState) mergeLockedDependencies() (*HelmState, error) {
|
||||
|
||||
depMan := NewChartDependencyManager(filename, st.logger)
|
||||
|
||||
if st.readFile != nil {
|
||||
depMan.readFile = st.readFile
|
||||
if st.fs.ReadFile != nil {
|
||||
depMan.readFile = st.fs.ReadFile
|
||||
}
|
||||
|
||||
return resolveDependencies(st, depMan, unresolved)
|
||||
|
||||
+12
-27
@@ -5,7 +5,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/imdario/mergo"
|
||||
"github.com/variantdev/vals"
|
||||
@@ -13,6 +12,7 @@ import (
|
||||
"gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/helmfile/helmfile/pkg/environment"
|
||||
"github.com/helmfile/helmfile/pkg/filesystem"
|
||||
"github.com/helmfile/helmfile/pkg/helmexec"
|
||||
"github.com/helmfile/helmfile/pkg/maputil"
|
||||
"github.com/helmfile/helmfile/pkg/remote"
|
||||
@@ -43,12 +43,7 @@ func (e *UndefinedEnvError) Error() string {
|
||||
type StateCreator struct {
|
||||
logger *zap.SugaredLogger
|
||||
|
||||
readFile func(string) ([]byte, error)
|
||||
fileExists func(string) (bool, error)
|
||||
abs func(string) (string, error)
|
||||
glob func(string) ([]string, error)
|
||||
DeleteFile func(string) error
|
||||
directoryExistsAt func(string) bool
|
||||
fs *filesystem.FileSystem
|
||||
|
||||
valsRuntime vals.Evaluator
|
||||
|
||||
@@ -63,17 +58,12 @@ type StateCreator struct {
|
||||
remote *remote.Remote
|
||||
}
|
||||
|
||||
func NewCreator(logger *zap.SugaredLogger, readFile func(string) ([]byte, error), fileExists func(string) (bool, error), abs func(string) (string, error), glob func(string) ([]string, error), directoryExistsAt func(string) bool, valsRuntime vals.Evaluator, getHelm func(*HelmState) helmexec.Interface, overrideHelmBinary string, remote *remote.Remote) *StateCreator {
|
||||
func NewCreator(logger *zap.SugaredLogger, fs *filesystem.FileSystem, valsRuntime vals.Evaluator, getHelm func(*HelmState) helmexec.Interface, overrideHelmBinary string, remote *remote.Remote) *StateCreator {
|
||||
return &StateCreator{
|
||||
logger: logger,
|
||||
|
||||
readFile: readFile,
|
||||
fileExists: fileExists,
|
||||
abs: abs,
|
||||
glob: glob,
|
||||
directoryExistsAt: directoryExistsAt,
|
||||
|
||||
Strict: true,
|
||||
fs: fs,
|
||||
valsRuntime: valsRuntime,
|
||||
getHelm: getHelm,
|
||||
|
||||
@@ -87,6 +77,7 @@ func NewCreator(logger *zap.SugaredLogger, readFile func(string) ([]byte, error)
|
||||
func (c *StateCreator) Parse(content []byte, baseDir, file string) (*HelmState, error) {
|
||||
var state HelmState
|
||||
|
||||
state.fs = c.fs
|
||||
state.FilePath = file
|
||||
state.basePath = baseDir
|
||||
|
||||
@@ -132,12 +123,6 @@ func (c *StateCreator) Parse(content []byte, baseDir, file string) (*HelmState,
|
||||
}
|
||||
|
||||
state.logger = c.logger
|
||||
|
||||
state.readFile = c.readFile
|
||||
state.removeFile = os.Remove
|
||||
state.fileExists = c.fileExists
|
||||
state.glob = c.glob
|
||||
state.directoryExistsAt = c.directoryExistsAt
|
||||
state.valsRuntime = c.valsRuntime
|
||||
|
||||
return &state, nil
|
||||
@@ -147,7 +132,7 @@ func (c *StateCreator) Parse(content []byte, baseDir, file string) (*HelmState,
|
||||
func (c *StateCreator) LoadEnvValues(target *HelmState, env string, ctxEnv *environment.Environment, failOnMissingEnv bool) (*HelmState, error) {
|
||||
state := *target
|
||||
|
||||
e, err := c.loadEnvValues(&state, env, failOnMissingEnv, ctxEnv, c.readFile, c.glob)
|
||||
e, err := c.loadEnvValues(&state, env, failOnMissingEnv, ctxEnv)
|
||||
if err != nil {
|
||||
return nil, &StateLoadError{fmt.Sprintf("failed to read %s", state.FilePath), err}
|
||||
}
|
||||
@@ -222,7 +207,7 @@ func (c *StateCreator) loadBases(envValues *environment.Environment, st *HelmSta
|
||||
}
|
||||
|
||||
// nolint: unparam
|
||||
func (c *StateCreator) loadEnvValues(st *HelmState, name string, failOnMissingEnv bool, ctxEnv *environment.Environment, readFile func(string) ([]byte, error), glob func(string) ([]string, error)) (*environment.Environment, error) {
|
||||
func (c *StateCreator) loadEnvValues(st *HelmState, name string, failOnMissingEnv bool, ctxEnv *environment.Environment) (*environment.Environment, error) {
|
||||
envVals := map[string]interface{}{}
|
||||
envSpec, ok := st.Environments[name]
|
||||
if ok {
|
||||
@@ -245,7 +230,7 @@ func (c *StateCreator) loadEnvValues(st *HelmState, name string, failOnMissingEn
|
||||
|
||||
envSecretFiles = append(envSecretFiles, resolved...)
|
||||
}
|
||||
if err = c.scatterGatherEnvSecretFiles(st, envSecretFiles, envVals, readFile); err != nil {
|
||||
if err = c.scatterGatherEnvSecretFiles(st, envSecretFiles, envVals); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
@@ -268,7 +253,7 @@ func (c *StateCreator) loadEnvValues(st *HelmState, name string, failOnMissingEn
|
||||
return newEnv, nil
|
||||
}
|
||||
|
||||
func (c *StateCreator) scatterGatherEnvSecretFiles(st *HelmState, envSecretFiles []string, envVals map[string]interface{}, readFile func(string) ([]byte, error)) error {
|
||||
func (c *StateCreator) scatterGatherEnvSecretFiles(st *HelmState, envSecretFiles []string, envVals map[string]interface{}) error {
|
||||
var errs []error
|
||||
|
||||
helm := c.getHelm(st)
|
||||
@@ -308,11 +293,11 @@ func (c *StateCreator) scatterGatherEnvSecretFiles(st *HelmState, envSecretFiles
|
||||
}
|
||||
// nolint: staticcheck
|
||||
defer func() {
|
||||
if err := c.DeleteFile(decFile); err != nil {
|
||||
if err := c.fs.DeleteFile(decFile); err != nil {
|
||||
c.logger.Warnf("removing decrypted file %s: %w", decFile, err)
|
||||
}
|
||||
}()
|
||||
bytes, err := readFile(decFile)
|
||||
bytes, err := c.fs.ReadFile(decFile)
|
||||
if err != nil {
|
||||
results <- secretResult{secret.id, nil, fmt.Errorf("failed to load environment secrets file \"%s\": %v", secret.path, err), secret.path}
|
||||
continue
|
||||
@@ -367,7 +352,7 @@ func (st *HelmState) loadValuesEntries(missingFileHandler *string, entries []int
|
||||
var envVals map[string]interface{}
|
||||
|
||||
valuesEntries := append([]interface{}{}, entries...)
|
||||
ld := NewEnvironmentValuesLoader(st.storage(), st.readFile, st.logger, remote)
|
||||
ld := NewEnvironmentValuesLoader(st.storage(), st.fs, st.logger, remote)
|
||||
var err error
|
||||
envVals, err = ld.LoadEnvironmentValues(missingFileHandler, valuesEntries, ctxEnv)
|
||||
if err != nil {
|
||||
|
||||
+10
-13
@@ -1,7 +1,6 @@
|
||||
package state
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"testing"
|
||||
@@ -10,18 +9,16 @@ import (
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/helmfile/helmfile/pkg/environment"
|
||||
"github.com/helmfile/helmfile/pkg/filesystem"
|
||||
"github.com/helmfile/helmfile/pkg/remote"
|
||||
"github.com/helmfile/helmfile/pkg/testhelper"
|
||||
)
|
||||
|
||||
func createFromYaml(content []byte, file string, env string, logger *zap.SugaredLogger) (*HelmState, error) {
|
||||
c := &StateCreator{
|
||||
logger: logger,
|
||||
readFile: os.ReadFile,
|
||||
abs: filepath.Abs,
|
||||
|
||||
DeleteFile: os.Remove,
|
||||
Strict: true,
|
||||
logger: logger,
|
||||
fs: filesystem.DefaultFileSystem(),
|
||||
Strict: true,
|
||||
}
|
||||
return c.ParseAndLoad(content, filepath.Dir(file), file, env, true, nil)
|
||||
}
|
||||
@@ -81,8 +78,8 @@ func (testEnv stateTestEnv) MustLoadState(t *testing.T, file, envName string) *H
|
||||
t.Fatalf("no file named %q registered", file)
|
||||
}
|
||||
|
||||
r := remote.NewRemote(logger, testFs.Cwd, testFs.ReadFile, testFs.DirectoryExistsAt, testFs.FileExistsAt)
|
||||
state, err := NewCreator(logger, testFs.ReadFile, testFs.FileExists, testFs.Abs, testFs.Glob, testFs.DirectoryExistsAt, nil, nil, "", r).
|
||||
r := remote.NewRemote(logger, testFs.Cwd, testFs.ToFileSystem())
|
||||
state, err := NewCreator(logger, testFs.ToFileSystem(), nil, nil, "", r).
|
||||
ParseAndLoad([]byte(yamlContent), filepath.Dir(file), file, envName, true, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
@@ -148,11 +145,11 @@ releaseNamespace: mynamespace
|
||||
})
|
||||
testFs.Cwd = "/example/path/to"
|
||||
|
||||
r := remote.NewRemote(logger, testFs.Cwd, testFs.ReadFile, testFs.DirectoryExistsAt, testFs.FileExistsAt)
|
||||
r := remote.NewRemote(logger, testFs.Cwd, testFs.ToFileSystem())
|
||||
env := environment.Environment{
|
||||
Name: "production",
|
||||
}
|
||||
state, err := NewCreator(logger, testFs.ReadFile, testFs.FileExists, testFs.Abs, testFs.Glob, testFs.DirectoryExistsAt, nil, nil, "", r).
|
||||
state, err := NewCreator(logger, testFs.ToFileSystem(), nil, nil, "", r).
|
||||
ParseAndLoad(yamlContent, filepath.Dir(yamlFile), yamlFile, "production", true, &env)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
@@ -238,8 +235,8 @@ overrideNamespace: myns
|
||||
})
|
||||
testFs.Cwd = "/example/path/to"
|
||||
|
||||
r := remote.NewRemote(logger, testFs.Cwd, testFs.ReadFile, testFs.DirectoryExistsAt, testFs.FileExistsAt)
|
||||
state, err := NewCreator(logger, testFs.ReadFile, testFs.FileExists, testFs.Abs, testFs.Glob, testFs.DirectoryExistsAt, nil, nil, "", r).
|
||||
r := remote.NewRemote(logger, testFs.Cwd, testFs.ToFileSystem())
|
||||
state, err := NewCreator(logger, testFs.ToFileSystem(), nil, nil, "", r).
|
||||
ParseAndLoad(yamlContent, filepath.Dir(yamlFile), yamlFile, "production", true, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/helmfile/helmfile/pkg/environment"
|
||||
"github.com/helmfile/helmfile/pkg/filesystem"
|
||||
"github.com/helmfile/helmfile/pkg/maputil"
|
||||
"github.com/helmfile/helmfile/pkg/remote"
|
||||
"github.com/helmfile/helmfile/pkg/tmpl"
|
||||
@@ -17,19 +18,19 @@ import (
|
||||
type EnvironmentValuesLoader struct {
|
||||
storage *Storage
|
||||
|
||||
readFile func(string) ([]byte, error)
|
||||
fs *filesystem.FileSystem
|
||||
|
||||
logger *zap.SugaredLogger
|
||||
|
||||
remote *remote.Remote
|
||||
}
|
||||
|
||||
func NewEnvironmentValuesLoader(storage *Storage, readFile func(string) ([]byte, error), logger *zap.SugaredLogger, remote *remote.Remote) *EnvironmentValuesLoader {
|
||||
func NewEnvironmentValuesLoader(storage *Storage, fs *filesystem.FileSystem, logger *zap.SugaredLogger, remote *remote.Remote) *EnvironmentValuesLoader {
|
||||
return &EnvironmentValuesLoader{
|
||||
storage: storage,
|
||||
readFile: readFile,
|
||||
logger: logger,
|
||||
remote: remote,
|
||||
storage: storage,
|
||||
fs: fs,
|
||||
logger: logger,
|
||||
remote: remote,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +65,7 @@ func (ld *EnvironmentValuesLoader) LoadEnvironmentValues(missingFileHandler *str
|
||||
}
|
||||
|
||||
tmplData := NewEnvironmentTemplateData(env, "", map[string]interface{}{})
|
||||
r := tmpl.NewFileRenderer(ld.readFile, filepath.Dir(f), tmplData)
|
||||
r := tmpl.NewFileRenderer(ld.fs, filepath.Dir(f), tmplData)
|
||||
bytes, err := r.RenderToBytes(f)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load environment values file \"%s\": %v", f, err)
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
package state
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"go.uber.org/zap"
|
||||
|
||||
ffs "github.com/helmfile/helmfile/pkg/filesystem"
|
||||
"github.com/helmfile/helmfile/pkg/remote"
|
||||
)
|
||||
|
||||
@@ -22,14 +21,11 @@ func newLoader() *EnvironmentValuesLoader {
|
||||
storage := &Storage{
|
||||
FilePath: "./helmfile.yaml",
|
||||
basePath: ".",
|
||||
glob: filepath.Glob,
|
||||
fs: ffs.DefaultFileSystem(),
|
||||
logger: sugar,
|
||||
}
|
||||
|
||||
readFile := func(s string) ([]byte, error) { return []byte{}, nil }
|
||||
dirExists := func(d string) bool { return false }
|
||||
fileExists := func(f string) bool { return false }
|
||||
return NewEnvironmentValuesLoader(storage, os.ReadFile, sugar, remote.NewRemote(sugar, "/tmp", readFile, dirExists, fileExists))
|
||||
return NewEnvironmentValuesLoader(storage, storage.fs, sugar, remote.NewRemote(sugar, "/tmp", storage.fs))
|
||||
}
|
||||
|
||||
// See https://github.com/roboll/helmfile/pull/1169
|
||||
|
||||
+3
-13
@@ -26,16 +26,6 @@ func (st *HelmState) appendHelmXFlags(flags []string, release *ReleaseSpec) ([]s
|
||||
return flags, nil
|
||||
}
|
||||
|
||||
func fileExistsAt(path string) bool {
|
||||
fileInfo, err := os.Stat(path)
|
||||
return err == nil && fileInfo.Mode().IsRegular()
|
||||
}
|
||||
|
||||
func directoryExistsAt(path string) bool {
|
||||
fileInfo, err := os.Stat(path)
|
||||
return err == nil && fileInfo.Mode().IsDir()
|
||||
}
|
||||
|
||||
type Chartify struct {
|
||||
Opts *chartify.ChartifyOpts
|
||||
Clean func()
|
||||
@@ -70,7 +60,7 @@ func (st *HelmState) goGetterChart(chart, dir, cacheDir string, force bool) (str
|
||||
return "", fmt.Errorf("Parsing url from dir failed due to error %q.\nContinuing the process assuming this is a regular Helm chart or a local dir.", err.Error())
|
||||
}
|
||||
} else {
|
||||
r := remote.NewRemote(st.logger, "", st.readFile, directoryExistsAt, fileExistsAt)
|
||||
r := remote.NewRemote(st.logger, "", st.fs)
|
||||
|
||||
fetchedDir, err := r.Fetch(chart, cacheDir)
|
||||
if err != nil {
|
||||
@@ -107,14 +97,14 @@ func (st *HelmState) PrepareChartify(helm helmexec.Interface, release *ReleaseSp
|
||||
dir = filepath.Join(st.basePath, chart)
|
||||
}
|
||||
if stat, _ := os.Stat(dir); stat != nil && stat.IsDir() {
|
||||
if exists, err := st.fileExists(filepath.Join(dir, "Chart.yaml")); err == nil && !exists {
|
||||
if exists, err := st.fs.FileExists(filepath.Join(dir, "Chart.yaml")); err == nil && !exists {
|
||||
shouldRun = true
|
||||
}
|
||||
}
|
||||
|
||||
for _, d := range release.Dependencies {
|
||||
chart := d.Chart
|
||||
if st.directoryExistsAt(chart) {
|
||||
if st.fs.DirectoryExistsAt(chart) {
|
||||
var err error
|
||||
|
||||
// Otherwise helm-dependency-up on the temporary chart generated by chartify ends up errors like:
|
||||
|
||||
+15
-19
@@ -26,6 +26,7 @@ import (
|
||||
|
||||
"github.com/helmfile/helmfile/pkg/environment"
|
||||
"github.com/helmfile/helmfile/pkg/event"
|
||||
"github.com/helmfile/helmfile/pkg/filesystem"
|
||||
"github.com/helmfile/helmfile/pkg/helmexec"
|
||||
"github.com/helmfile/helmfile/pkg/remote"
|
||||
"github.com/helmfile/helmfile/pkg/tmpl"
|
||||
@@ -92,14 +93,9 @@ type HelmState struct {
|
||||
|
||||
ReleaseSetSpec `yaml:",inline"`
|
||||
|
||||
logger *zap.SugaredLogger
|
||||
|
||||
readFile func(string) ([]byte, error)
|
||||
removeFile func(string) error
|
||||
fileExists func(string) (bool, error)
|
||||
glob func(string) ([]string, error)
|
||||
tempDir func(string, string) (string, error)
|
||||
directoryExistsAt func(string) bool
|
||||
logger *zap.SugaredLogger
|
||||
fs *filesystem.FileSystem
|
||||
tempDir func(string, string) (string, error)
|
||||
|
||||
valsRuntime vals.Evaluator
|
||||
|
||||
@@ -553,7 +549,7 @@ func (st *HelmState) prepareSyncReleases(helm helmexec.Interface, additionalValu
|
||||
errs = append(errs, newReleaseFailedError(release, err))
|
||||
}
|
||||
|
||||
ok, err := st.fileExists(valfile)
|
||||
ok, err := st.fs.FileExists(valfile)
|
||||
if err != nil {
|
||||
errs = append(errs, newReleaseFailedError(release, err))
|
||||
} else if !ok {
|
||||
@@ -1118,7 +1114,7 @@ func (st *HelmState) PrepareCharts(helm helmexec.Interface, dir string, concurre
|
||||
}
|
||||
}
|
||||
|
||||
isLocal := st.directoryExistsAt(normalizeChart(st.basePath, chartName))
|
||||
isLocal := st.fs.DirectoryExistsAt(normalizeChart(st.basePath, chartName))
|
||||
|
||||
chartification, clean, err := st.PrepareChartify(helm, release, chartPath, workerIndex)
|
||||
if !opts.SkipCleanup {
|
||||
@@ -1172,7 +1168,7 @@ func (st *HelmState) PrepareCharts(helm helmexec.Interface, dir string, concurre
|
||||
// Skip `helm dep build` and `helm dep up` altogether when the chart is from remote or the dep is
|
||||
// explicitly skipped.
|
||||
buildDeps = !skipDeps
|
||||
} else if normalizedChart := normalizeChart(st.basePath, chartPath); st.directoryExistsAt(normalizedChart) {
|
||||
} else if normalizedChart := normalizeChart(st.basePath, chartPath); st.fs.DirectoryExistsAt(normalizedChart) {
|
||||
// At this point, we are sure that chartPath is a local directory containing either:
|
||||
// - A remote chart fetched by go-getter or
|
||||
// - A local chart
|
||||
@@ -1505,7 +1501,7 @@ func (st *HelmState) WriteReleasesValues(helm helmexec.Interface, additionalValu
|
||||
for _, f := range append(generatedFiles, additionalValues...) {
|
||||
src := map[string]interface{}{}
|
||||
|
||||
srcBytes, err := st.readFile(f)
|
||||
srcBytes, err := st.fs.ReadFile(f)
|
||||
if err != nil {
|
||||
return []error{fmt.Errorf("reading %s: %w", f, err)}
|
||||
}
|
||||
@@ -2236,7 +2232,7 @@ func (st *HelmState) triggerGlobalReleaseEvent(evt string, evtErr error, helmfil
|
||||
Chart: st.OverrideChart,
|
||||
Env: st.Env,
|
||||
Logger: st.logger,
|
||||
ReadFile: st.readFile,
|
||||
Fs: st.fs,
|
||||
}
|
||||
data := map[string]interface{}{
|
||||
"HelmfileCommand": helmfileCmd,
|
||||
@@ -2269,7 +2265,7 @@ func (st *HelmState) triggerReleaseEvent(evt string, evtErr error, r *ReleaseSpe
|
||||
Chart: st.OverrideChart,
|
||||
Env: st.Env,
|
||||
Logger: st.logger,
|
||||
ReadFile: st.readFile,
|
||||
Fs: st.fs,
|
||||
}
|
||||
vals := st.Values()
|
||||
data := map[string]interface{}{
|
||||
@@ -2307,7 +2303,7 @@ func (st *HelmState) UpdateDeps(helm helmexec.Interface, includeTransitiveNeeds
|
||||
var errs []error
|
||||
|
||||
for _, release := range releases {
|
||||
if st.directoryExistsAt(release.ChartPathOrName()) {
|
||||
if st.fs.DirectoryExistsAt(release.ChartPathOrName()) {
|
||||
if err := helm.UpdateDeps(release.ChartPathOrName()); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
@@ -2631,7 +2627,7 @@ func (st *HelmState) newReleaseTemplateData(release *ReleaseSpec) releaseTemplat
|
||||
}
|
||||
|
||||
func (st *HelmState) newReleaseTemplateFuncMap(dir string) template.FuncMap {
|
||||
r := tmpl.NewFileRenderer(st.readFile, dir, nil)
|
||||
r := tmpl.NewFileRenderer(st.fs, dir, nil)
|
||||
|
||||
return r.Context.CreateFuncMap()
|
||||
}
|
||||
@@ -2639,7 +2635,7 @@ func (st *HelmState) newReleaseTemplateFuncMap(dir string) template.FuncMap {
|
||||
func (st *HelmState) RenderReleaseValuesFileToBytes(release *ReleaseSpec, path string) ([]byte, error) {
|
||||
templateData := st.newReleaseTemplateData(release)
|
||||
|
||||
r := tmpl.NewFileRenderer(st.readFile, filepath.Dir(path), templateData)
|
||||
r := tmpl.NewFileRenderer(st.fs, filepath.Dir(path), templateData)
|
||||
rawBytes, err := r.RenderToBytes(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -2673,8 +2669,8 @@ func (st *HelmState) storage() *Storage {
|
||||
return &Storage{
|
||||
FilePath: st.FilePath,
|
||||
basePath: st.basePath,
|
||||
glob: st.glob,
|
||||
logger: st.logger,
|
||||
fs: st.fs,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2710,7 +2706,7 @@ func (st *HelmState) ExpandedHelmfiles() ([]SubHelmfileSpec, error) {
|
||||
|
||||
func (st *HelmState) removeFiles(files []string) {
|
||||
for _, f := range files {
|
||||
if err := st.removeFile(f); err != nil {
|
||||
if err := st.fs.DeleteFile(f); err != nil {
|
||||
st.logger.Warnf("Removing %s: %v", err)
|
||||
} else {
|
||||
st.logger.Debugf("Removed %s", f)
|
||||
|
||||
@@ -110,7 +110,7 @@ func (st *HelmState) ExecuteTemplates() (*HelmState, error) {
|
||||
successFlag := false
|
||||
for it, prev := 0, &release; it < 6; it++ {
|
||||
tmplData := st.createReleaseTemplateData(prev, vals)
|
||||
renderer := tmpl.NewFileRenderer(st.readFile, st.basePath, tmplData)
|
||||
renderer := tmpl.NewFileRenderer(st.fs, st.basePath, tmplData)
|
||||
r, err := release.ExecuteTemplateExpressions(renderer)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed executing templates in release \"%s\".\"%s\": %v", st.FilePath, release.Name, err)
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
|
||||
"github.com/helmfile/helmfile/pkg/filesystem"
|
||||
"github.com/helmfile/helmfile/pkg/helmexec"
|
||||
)
|
||||
|
||||
@@ -39,7 +40,7 @@ func TestGoGetter(t *testing.T) {
|
||||
|
||||
st := &HelmState{
|
||||
logger: logger,
|
||||
readFile: os.ReadFile,
|
||||
fs: filesystem.DefaultFileSystem(),
|
||||
basePath: d,
|
||||
}
|
||||
|
||||
|
||||
+34
-32
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/variantdev/vals"
|
||||
|
||||
"github.com/helmfile/helmfile/pkg/exectest"
|
||||
"github.com/helmfile/helmfile/pkg/filesystem"
|
||||
"github.com/helmfile/helmfile/pkg/helmexec"
|
||||
"github.com/helmfile/helmfile/pkg/testhelper"
|
||||
)
|
||||
@@ -19,10 +20,7 @@ var logger = helmexec.NewLogger(os.Stdout, "warn")
|
||||
var valsRuntime, _ = vals.New(vals.Options{CacheSize: 32})
|
||||
|
||||
func injectFs(st *HelmState, fs *testhelper.TestFs) *HelmState {
|
||||
st.glob = fs.Glob
|
||||
st.readFile = fs.ReadFile
|
||||
st.fileExists = fs.FileExists
|
||||
st.directoryExistsAt = fs.DirectoryExistsAt
|
||||
st.fs = fs.ToFileSystem()
|
||||
return st
|
||||
}
|
||||
|
||||
@@ -1715,17 +1713,17 @@ func TestHelmState_SyncReleasesCleanup(t *testing.T) {
|
||||
ReleaseSetSpec: ReleaseSetSpec{
|
||||
Releases: tt.releases,
|
||||
},
|
||||
logger: logger,
|
||||
valsRuntime: valsRuntime,
|
||||
removeFile: func(f string) error {
|
||||
numRemovedFiles += 1
|
||||
return nil
|
||||
},
|
||||
logger: logger,
|
||||
valsRuntime: valsRuntime,
|
||||
RenderedValues: map[string]interface{}{},
|
||||
}
|
||||
testfs := testhelper.NewTestFs(map[string]string{
|
||||
"/path/to/someFile": `foo: FOO`,
|
||||
})
|
||||
testfs.DeleteFile = func(f string) error {
|
||||
numRemovedFiles += 1
|
||||
return nil
|
||||
}
|
||||
state = injectFs(state, testfs)
|
||||
if errs := state.SyncReleases(&AffectedReleases{}, tt.helm, []string{}, 1); len(errs) > 0 {
|
||||
t.Errorf("unexpected errors: %v", errs)
|
||||
@@ -1802,18 +1800,18 @@ func TestHelmState_DiffReleasesCleanup(t *testing.T) {
|
||||
ReleaseSetSpec: ReleaseSetSpec{
|
||||
Releases: tt.releases,
|
||||
},
|
||||
logger: logger,
|
||||
valsRuntime: valsRuntime,
|
||||
removeFile: func(f string) error {
|
||||
numRemovedFiles += 1
|
||||
return nil
|
||||
},
|
||||
logger: logger,
|
||||
valsRuntime: valsRuntime,
|
||||
RenderedValues: map[string]interface{}{},
|
||||
}
|
||||
testfs := testhelper.NewTestFs(map[string]string{
|
||||
"/path/to/someFile": `foo: bar
|
||||
`,
|
||||
})
|
||||
testfs.DeleteFile = func(f string) error {
|
||||
numRemovedFiles += 1
|
||||
return nil
|
||||
}
|
||||
state = injectFs(state, testfs)
|
||||
if _, errs := state.DiffReleases(tt.helm, []string{}, 1, false, false, []string{}, false, false, false, false); len(errs) > 0 {
|
||||
t.Errorf("unexpected errors: %v", errs)
|
||||
@@ -1960,11 +1958,13 @@ func TestHelmState_ResolveDeps_NoLockFile(t *testing.T) {
|
||||
},
|
||||
},
|
||||
logger: logger,
|
||||
readFile: func(f string) ([]byte, error) {
|
||||
if f != "helmfile.lock" {
|
||||
return nil, fmt.Errorf("stub: unexpected file: %s", f)
|
||||
}
|
||||
return nil, os.ErrNotExist
|
||||
fs: &filesystem.FileSystem{
|
||||
ReadFile: func(f string) ([]byte, error) {
|
||||
if f != "helmfile.lock" {
|
||||
return nil, fmt.Errorf("stub: unexpected file: %s", f)
|
||||
}
|
||||
return nil, os.ErrNotExist
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -2053,17 +2053,19 @@ func TestHelmState_ReleaseStatuses(t *testing.T) {
|
||||
Releases: tt.releases,
|
||||
},
|
||||
logger: logger,
|
||||
fileExists: func(f string) (bool, error) {
|
||||
if f != "foo.yaml" {
|
||||
return false, fmt.Errorf("unexpected file: %s", f)
|
||||
}
|
||||
return true, nil
|
||||
},
|
||||
readFile: func(f string) ([]byte, error) {
|
||||
if f != "foo.yaml" {
|
||||
return nil, fmt.Errorf("unexpected file: %s", f)
|
||||
}
|
||||
return []byte{}, nil
|
||||
fs: &filesystem.FileSystem{
|
||||
FileExists: func(f string) (bool, error) {
|
||||
if f != "foo.yaml" {
|
||||
return false, fmt.Errorf("unexpected file: %s", f)
|
||||
}
|
||||
return true, nil
|
||||
},
|
||||
ReadFile: func(f string) ([]byte, error) {
|
||||
if f != "foo.yaml" {
|
||||
return nil, fmt.Errorf("unexpected file: %s", f)
|
||||
}
|
||||
return []byte{}, nil
|
||||
},
|
||||
},
|
||||
}
|
||||
errs := state.ReleaseStatuses(tt.helm, 1)
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/helmfile/helmfile/pkg/filesystem"
|
||||
"github.com/helmfile/helmfile/pkg/remote"
|
||||
)
|
||||
|
||||
@@ -16,17 +17,16 @@ type Storage struct {
|
||||
|
||||
FilePath string
|
||||
|
||||
readFile func(string) ([]byte, error)
|
||||
basePath string
|
||||
glob func(string) ([]string, error)
|
||||
fs *filesystem.FileSystem
|
||||
}
|
||||
|
||||
func NewStorage(forFile string, logger *zap.SugaredLogger, glob func(string) ([]string, error)) *Storage {
|
||||
func NewStorage(forFile string, logger *zap.SugaredLogger, fs *filesystem.FileSystem) *Storage {
|
||||
return &Storage{
|
||||
FilePath: forFile,
|
||||
basePath: filepath.Dir(forFile),
|
||||
logger: logger,
|
||||
glob: glob,
|
||||
fs: fs,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,14 +36,14 @@ func (st *Storage) resolveFile(missingFileHandler *string, tpe, path string) ([]
|
||||
var files []string
|
||||
var err error
|
||||
if remote.IsRemote(path) {
|
||||
r := remote.NewRemote(st.logger, "", st.readFile, directoryExistsAt, fileExistsAt)
|
||||
r := remote.NewRemote(st.logger, "", st.fs)
|
||||
|
||||
fetchedFilePath, err := r.Fetch(path, "values")
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
if fileExistsAt(fetchedFilePath) {
|
||||
if st.fs.FileExistsAt(fetchedFilePath) {
|
||||
files = []string{fetchedFilePath}
|
||||
}
|
||||
} else {
|
||||
@@ -92,7 +92,7 @@ func (st *Storage) resolveFile(missingFileHandler *string, tpe, path string) ([]
|
||||
func (st *Storage) ExpandPaths(globPattern string) ([]string, error) {
|
||||
result := []string{}
|
||||
absPathPattern := st.normalizePath(globPattern)
|
||||
matches, err := st.glob(absPathPattern)
|
||||
matches, err := st.fs.Glob(absPathPattern)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed processing %s: %v", globPattern, err)
|
||||
}
|
||||
|
||||
@@ -3,10 +3,10 @@ package state
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/helmfile/helmfile/pkg/filesystem"
|
||||
"github.com/helmfile/helmfile/pkg/helmexec"
|
||||
"github.com/helmfile/helmfile/pkg/remote"
|
||||
)
|
||||
@@ -73,7 +73,7 @@ func TestStorage_resolveFile(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
st := NewStorage(cacheDir, helmexec.NewLogger(os.Stderr, "debug"), filepath.Glob)
|
||||
st := NewStorage(cacheDir, helmexec.NewLogger(os.Stderr, "debug"), filesystem.DefaultFileSystem())
|
||||
|
||||
files, skipped, err := st.resolveFile(tt.args.missingFileHandler, tt.args.title, tt.args.path)
|
||||
if (err != nil) != tt.wantErr {
|
||||
|
||||
Reference in New Issue
Block a user