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:
parent
a626664f46
commit
cc33e7b7d8
|
|
@ -17,6 +17,7 @@ import (
|
|||
"go.uber.org/zap"
|
||||
|
||||
"github.com/helmfile/helmfile/pkg/argparser"
|
||||
"github.com/helmfile/helmfile/pkg/filesystem"
|
||||
"github.com/helmfile/helmfile/pkg/helmexec"
|
||||
"github.com/helmfile/helmfile/pkg/plugins"
|
||||
"github.com/helmfile/helmfile/pkg/remote"
|
||||
|
|
@ -39,16 +40,7 @@ type App struct {
|
|||
|
||||
FileOrDir string
|
||||
|
||||
readFile func(string) ([]byte, error)
|
||||
deleteFile func(string) error
|
||||
fileExists func(string) (bool, error)
|
||||
glob func(string) ([]string, error)
|
||||
abs func(string) (string, error)
|
||||
fileExistsAt func(string) bool
|
||||
directoryExistsAt func(string) bool
|
||||
|
||||
getwd func() (string, error)
|
||||
chdir func(string) error
|
||||
fs *filesystem.FileSystem
|
||||
|
||||
remote *remote.Remote
|
||||
|
||||
|
|
@ -81,20 +73,11 @@ func New(conf ConfigProvider) *App {
|
|||
FileOrDir: conf.FileOrDir(),
|
||||
ValuesFiles: conf.StateValuesFiles(),
|
||||
Set: conf.StateValuesSet(),
|
||||
fs: filesystem.DefaultFileSystem(),
|
||||
})
|
||||
}
|
||||
|
||||
func Init(app *App) *App {
|
||||
app.readFile = os.ReadFile
|
||||
app.deleteFile = os.Remove
|
||||
app.glob = filepath.Glob
|
||||
app.abs = filepath.Abs
|
||||
app.getwd = os.Getwd
|
||||
app.chdir = os.Chdir
|
||||
app.fileExistsAt = fileExistsAt
|
||||
app.fileExists = fileExists
|
||||
app.directoryExistsAt = directoryExistsAt
|
||||
|
||||
var err error
|
||||
app.valsRuntime, err = plugins.ValsInstance()
|
||||
if err != nil {
|
||||
|
|
@ -619,19 +602,19 @@ func (a *App) within(dir string, do func() error) error {
|
|||
return do()
|
||||
}
|
||||
|
||||
prev, err := a.getwd()
|
||||
prev, err := a.fs.Getwd()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed getting current working direcotyr: %v", err)
|
||||
}
|
||||
|
||||
absDir, err := a.abs(dir)
|
||||
absDir, err := a.fs.Abs(dir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
a.Logger.Debugf("changing working directory to \"%s\"", absDir)
|
||||
|
||||
if err := a.chdir(absDir); err != nil {
|
||||
if err := a.fs.Chdir(absDir); err != nil {
|
||||
return fmt.Errorf("failed changing working directory to \"%s\": %v", absDir, err)
|
||||
}
|
||||
|
||||
|
|
@ -639,7 +622,7 @@ func (a *App) within(dir string, do func() error) error {
|
|||
|
||||
a.Logger.Debugf("changing working directory back to \"%s\"", prev)
|
||||
|
||||
if chdirBackErr := a.chdir(prev); chdirBackErr != nil {
|
||||
if chdirBackErr := a.fs.Chdir(prev); chdirBackErr != nil {
|
||||
if appErr != nil {
|
||||
a.Logger.Warnf("%v", appErr)
|
||||
}
|
||||
|
|
@ -658,7 +641,7 @@ func (a *App) visitStateFiles(fileOrDir string, opts LoadOpts, do func(string, s
|
|||
for _, relPath := range desiredStateFiles {
|
||||
var file string
|
||||
var dir string
|
||||
if a.directoryExistsAt(relPath) {
|
||||
if a.fs.DirectoryExistsAt(relPath) {
|
||||
file = relPath
|
||||
dir = relPath
|
||||
} else {
|
||||
|
|
@ -668,7 +651,7 @@ func (a *App) visitStateFiles(fileOrDir string, opts LoadOpts, do func(string, s
|
|||
|
||||
a.Logger.Debugf("processing file \"%s\" in directory \"%s\"", file, dir)
|
||||
|
||||
absd, errAbsDir := a.abs(dir)
|
||||
absd, errAbsDir := a.fs.Abs(dir)
|
||||
if errAbsDir != nil {
|
||||
return errAbsDir
|
||||
}
|
||||
|
|
@ -690,20 +673,15 @@ func (a *App) loadDesiredStateFromYaml(file string, opts ...LoadOpts) (*state.He
|
|||
}
|
||||
|
||||
ld := &desiredStateLoader{
|
||||
readFile: a.readFile,
|
||||
deleteFile: a.deleteFile,
|
||||
fileExists: a.fileExists,
|
||||
directoryExistsAt: a.directoryExistsAt,
|
||||
env: a.Env,
|
||||
namespace: a.Namespace,
|
||||
chart: a.Chart,
|
||||
logger: a.Logger,
|
||||
abs: a.abs,
|
||||
remote: a.remote,
|
||||
fs: a.fs,
|
||||
env: a.Env,
|
||||
namespace: a.Namespace,
|
||||
chart: a.Chart,
|
||||
logger: a.Logger,
|
||||
remote: a.remote,
|
||||
|
||||
overrideKubeContext: a.OverrideKubeContext,
|
||||
overrideHelmBinary: a.OverrideHelmBinary,
|
||||
glob: a.glob,
|
||||
getHelm: a.getHelm,
|
||||
valsRuntime: a.valsRuntime,
|
||||
}
|
||||
|
|
@ -995,7 +973,7 @@ func (a *App) visitStatesWithSelectorsAndRemoteSupport(fileOrDir string, converg
|
|||
opts.Environment.OverrideValues = envvals
|
||||
}
|
||||
|
||||
a.remote = remote.NewRemote(a.Logger, "", a.readFile, a.directoryExistsAt, a.fileExistsAt)
|
||||
a.remote = remote.NewRemote(a.Logger, "", a.fs)
|
||||
|
||||
f := converge
|
||||
if opts.Filter {
|
||||
|
|
@ -1095,18 +1073,18 @@ func (a *App) findDesiredStateFiles(specifiedPath string, opts LoadOpts) ([]stri
|
|||
var helmfileDir string
|
||||
if specifiedPath != "" {
|
||||
switch {
|
||||
case a.fileExistsAt(specifiedPath):
|
||||
case a.fs.FileExistsAt(specifiedPath):
|
||||
return []string{specifiedPath}, nil
|
||||
case a.directoryExistsAt(specifiedPath):
|
||||
case a.fs.DirectoryExistsAt(specifiedPath):
|
||||
helmfileDir = specifiedPath
|
||||
default:
|
||||
return []string{}, fmt.Errorf("specified state file %s is not found", specifiedPath)
|
||||
}
|
||||
} else {
|
||||
var defaultFile string
|
||||
if a.fileExistsAt(DefaultHelmfile) {
|
||||
if a.fs.FileExistsAt(DefaultHelmfile) {
|
||||
defaultFile = DefaultHelmfile
|
||||
} else if a.fileExistsAt(DeprecatedHelmfile) {
|
||||
} else if a.fs.FileExistsAt(DeprecatedHelmfile) {
|
||||
log.Printf(
|
||||
"warn: %s is being loaded: %s is deprecated in favor of %s. See https://github.com/roboll/helmfile/issues/25 for more information",
|
||||
DeprecatedHelmfile,
|
||||
|
|
@ -1117,7 +1095,7 @@ func (a *App) findDesiredStateFiles(specifiedPath string, opts LoadOpts) ([]stri
|
|||
}
|
||||
|
||||
switch {
|
||||
case a.directoryExistsAt(DefaultHelmfileDirectory):
|
||||
case a.fs.DirectoryExistsAt(DefaultHelmfileDirectory):
|
||||
if defaultFile != "" {
|
||||
return []string{}, fmt.Errorf("configuration conlict error: you can have either %s or %s, but not both", defaultFile, DefaultHelmfileDirectory)
|
||||
}
|
||||
|
|
@ -1130,7 +1108,7 @@ func (a *App) findDesiredStateFiles(specifiedPath string, opts LoadOpts) ([]stri
|
|||
}
|
||||
}
|
||||
|
||||
files, err := a.glob(filepath.Join(helmfileDir, "*.y*ml"))
|
||||
files, err := a.fs.Glob(filepath.Join(helmfileDir, "*.y*ml"))
|
||||
if err != nil {
|
||||
return []string{}, err
|
||||
}
|
||||
|
|
@ -1926,28 +1904,6 @@ func (a *App) writeValues(r *Run, c WriteValuesConfigProvider) (bool, []error) {
|
|||
return true, errs
|
||||
}
|
||||
|
||||
func fileExistsAt(path string) bool {
|
||||
fileInfo, err := os.Stat(path)
|
||||
return err == nil && fileInfo.Mode().IsRegular()
|
||||
}
|
||||
|
||||
func fileExists(path string) (bool, error) {
|
||||
_, err := os.Stat(path)
|
||||
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func directoryExistsAt(path string) bool {
|
||||
fileInfo, err := os.Stat(path)
|
||||
return err == nil && fileInfo.Mode().IsDir()
|
||||
}
|
||||
|
||||
// Error is a wrapper around an error that adds context to the error.
|
||||
type Error struct {
|
||||
msg string
|
||||
|
|
@ -2064,10 +2020,10 @@ func (c context) wrapErrs(errs ...error) error {
|
|||
func (a *App) ShowCacheDir(c CacheConfigProvider) error {
|
||||
fmt.Printf("Cache directory: %s\n", remote.CacheDir())
|
||||
|
||||
if !directoryExistsAt(remote.CacheDir()) {
|
||||
if !a.fs.DirectoryExistsAt(remote.CacheDir()) {
|
||||
return nil
|
||||
}
|
||||
dirs, err := os.ReadDir(remote.CacheDir())
|
||||
dirs, err := a.fs.ReadDir(remote.CacheDir())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -2079,7 +2035,7 @@ func (a *App) ShowCacheDir(c CacheConfigProvider) error {
|
|||
}
|
||||
|
||||
func (a *App) CleanCacheDir(c CacheConfigProvider) error {
|
||||
if !directoryExistsAt(remote.CacheDir()) {
|
||||
if !a.fs.DirectoryExistsAt(remote.CacheDir()) {
|
||||
return nil
|
||||
}
|
||||
fmt.Printf("Cleaning up cache directory: %s\n", remote.CacheDir())
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import (
|
|||
"bufio"
|
||||
"bytes"
|
||||
"io"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
|
|
@ -12,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"
|
||||
)
|
||||
|
|
@ -90,8 +90,7 @@ func TestApply_3(t *testing.T) {
|
|||
|
||||
app := appWithFs(&App{
|
||||
OverrideHelmBinary: DefaultHelmBinary,
|
||||
glob: filepath.Glob,
|
||||
abs: filepath.Abs,
|
||||
fs: filesystem.DefaultFileSystem(),
|
||||
OverrideKubeContext: "",
|
||||
Env: "default",
|
||||
Logger: logger,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import (
|
|||
"bufio"
|
||||
"bytes"
|
||||
"io"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
|
|
@ -12,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"
|
||||
)
|
||||
|
|
@ -90,8 +90,7 @@ func TestApply_2(t *testing.T) {
|
|||
|
||||
app := appWithFs(&App{
|
||||
OverrideHelmBinary: DefaultHelmBinary,
|
||||
glob: filepath.Glob,
|
||||
abs: filepath.Abs,
|
||||
fs: filesystem.DefaultFileSystem(),
|
||||
OverrideKubeContext: "default",
|
||||
Env: "default",
|
||||
Logger: logger,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import (
|
|||
"bufio"
|
||||
"bytes"
|
||||
"io"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
|
|
@ -13,6 +12,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"
|
||||
)
|
||||
|
|
@ -129,8 +129,7 @@ releases:
|
|||
|
||||
app := appWithFs(&App{
|
||||
OverrideHelmBinary: DefaultHelmBinary,
|
||||
glob: filepath.Glob,
|
||||
abs: filepath.Abs,
|
||||
fs: filesystem.DefaultFileSystem(),
|
||||
OverrideKubeContext: "default",
|
||||
Env: "default",
|
||||
Logger: logger,
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import (
|
|||
"github.com/variantdev/vals"
|
||||
|
||||
"github.com/helmfile/helmfile/pkg/exectest"
|
||||
ffs "github.com/helmfile/helmfile/pkg/filesystem"
|
||||
"github.com/helmfile/helmfile/pkg/helmexec"
|
||||
"github.com/helmfile/helmfile/pkg/testhelper"
|
||||
)
|
||||
|
|
@ -131,8 +132,7 @@ releases:
|
|||
|
||||
app := appWithFs(&App{
|
||||
OverrideHelmBinary: DefaultHelmBinary,
|
||||
glob: filepath.Glob,
|
||||
abs: filepath.Abs,
|
||||
fs: ffs.DefaultFileSystem(),
|
||||
OverrideKubeContext: "default",
|
||||
Env: "default",
|
||||
Logger: logger,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import (
|
|||
"bufio"
|
||||
"bytes"
|
||||
"io"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
|
|
@ -12,6 +11,7 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
"github.com/variantdev/vals"
|
||||
|
||||
ffs "github.com/helmfile/helmfile/pkg/filesystem"
|
||||
"github.com/helmfile/helmfile/pkg/helmexec"
|
||||
"github.com/helmfile/helmfile/pkg/testhelper"
|
||||
"github.com/helmfile/helmfile/pkg/testutil"
|
||||
|
|
@ -145,8 +145,7 @@ releases:
|
|||
|
||||
app := appWithFs(&App{
|
||||
OverrideHelmBinary: DefaultHelmBinary,
|
||||
glob: filepath.Glob,
|
||||
abs: filepath.Abs,
|
||||
fs: ffs.DefaultFileSystem(),
|
||||
OverrideKubeContext: "default",
|
||||
Env: tc.environment,
|
||||
Logger: logger,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import (
|
|||
"bufio"
|
||||
"bytes"
|
||||
"io"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
|
|
@ -12,6 +11,7 @@ import (
|
|||
"github.com/variantdev/vals"
|
||||
|
||||
"github.com/helmfile/helmfile/pkg/exectest"
|
||||
ffs "github.com/helmfile/helmfile/pkg/filesystem"
|
||||
"github.com/helmfile/helmfile/pkg/helmexec"
|
||||
"github.com/helmfile/helmfile/pkg/testhelper"
|
||||
)
|
||||
|
|
@ -88,8 +88,7 @@ func TestSync(t *testing.T) {
|
|||
|
||||
app := appWithFs(&App{
|
||||
OverrideHelmBinary: DefaultHelmBinary,
|
||||
glob: filepath.Glob,
|
||||
abs: filepath.Abs,
|
||||
fs: ffs.DefaultFileSystem(),
|
||||
OverrideKubeContext: "default",
|
||||
Env: "default",
|
||||
Logger: logger,
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import (
|
|||
"github.com/variantdev/vals"
|
||||
|
||||
"github.com/helmfile/helmfile/pkg/exectest"
|
||||
ffs "github.com/helmfile/helmfile/pkg/filesystem"
|
||||
"github.com/helmfile/helmfile/pkg/helmexec"
|
||||
"github.com/helmfile/helmfile/pkg/testhelper"
|
||||
)
|
||||
|
|
@ -131,8 +132,7 @@ releases:
|
|||
|
||||
app := appWithFs(&App{
|
||||
OverrideHelmBinary: DefaultHelmBinary,
|
||||
glob: filepath.Glob,
|
||||
abs: filepath.Abs,
|
||||
fs: &ffs.FileSystem{Glob: filepath.Glob},
|
||||
OverrideKubeContext: "default",
|
||||
Env: "default",
|
||||
Logger: logger,
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import (
|
|||
|
||||
"github.com/helmfile/helmfile/pkg/envvar"
|
||||
"github.com/helmfile/helmfile/pkg/exectest"
|
||||
ffs "github.com/helmfile/helmfile/pkg/filesystem"
|
||||
"github.com/helmfile/helmfile/pkg/helmexec"
|
||||
"github.com/helmfile/helmfile/pkg/remote"
|
||||
"github.com/helmfile/helmfile/pkg/state"
|
||||
|
|
@ -40,14 +41,7 @@ func injectFs(app *App, fs *testhelper.TestFs) *App {
|
|||
app.Set = make(map[string]interface{})
|
||||
}
|
||||
|
||||
app.readFile = fs.ReadFile
|
||||
app.glob = fs.Glob
|
||||
app.abs = fs.Abs
|
||||
app.getwd = fs.Getwd
|
||||
app.chdir = fs.Chdir
|
||||
app.fileExistsAt = fs.FileExistsAt
|
||||
app.fileExists = fs.FileExists
|
||||
app.directoryExistsAt = fs.DirectoryExistsAt
|
||||
app.fs = fs.ToFileSystem()
|
||||
return app
|
||||
}
|
||||
|
||||
|
|
@ -1529,12 +1523,11 @@ func TestLoadDesiredStateFromYaml_DuplicateReleaseName(t *testing.T) {
|
|||
}
|
||||
return yamlContent, nil
|
||||
}
|
||||
fs := ffs.FromFileSystem(ffs.FileSystem{ReadFile: readFile})
|
||||
app := &App{
|
||||
OverrideHelmBinary: DefaultHelmBinary,
|
||||
OverrideKubeContext: "default",
|
||||
readFile: readFile,
|
||||
glob: filepath.Glob,
|
||||
abs: filepath.Abs,
|
||||
fs: fs,
|
||||
Env: "default",
|
||||
Logger: helmexec.NewLogger(os.Stderr, "debug"),
|
||||
}
|
||||
|
|
@ -1593,16 +1586,11 @@ helmDefaults:
|
|||
app := &App{
|
||||
OverrideHelmBinary: DefaultHelmBinary,
|
||||
OverrideKubeContext: "default",
|
||||
readFile: testFs.ReadFile,
|
||||
glob: testFs.Glob,
|
||||
abs: testFs.Abs,
|
||||
directoryExistsAt: testFs.DirectoryExistsAt,
|
||||
fileExistsAt: testFs.FileExistsAt,
|
||||
fileExists: testFs.FileExists,
|
||||
fs: testFs.ToFileSystem(),
|
||||
Env: "default",
|
||||
Logger: helmexec.NewLogger(os.Stderr, "debug"),
|
||||
}
|
||||
app.remote = remote.NewRemote(app.Logger, "", app.readFile, app.directoryExistsAt, app.fileExistsAt)
|
||||
app.remote = remote.NewRemote(app.Logger, "", app.fs)
|
||||
|
||||
expectNoCallsToHelm(app)
|
||||
|
||||
|
|
@ -1683,14 +1671,11 @@ helmDefaults:
|
|||
})
|
||||
app := &App{
|
||||
OverrideHelmBinary: DefaultHelmBinary,
|
||||
readFile: testFs.ReadFile,
|
||||
fileExists: testFs.FileExists,
|
||||
glob: testFs.Glob,
|
||||
abs: testFs.Abs,
|
||||
fs: testFs.ToFileSystem(),
|
||||
Env: "default",
|
||||
Logger: helmexec.NewLogger(os.Stderr, "debug"),
|
||||
}
|
||||
app.remote = remote.NewRemote(app.Logger, testFs.Cwd, testFs.ReadFile, testFs.DirectoryExistsAt, testFs.FileExistsAt)
|
||||
app.remote = remote.NewRemote(app.Logger, testFs.Cwd, app.fs)
|
||||
|
||||
expectNoCallsToHelm(app)
|
||||
|
||||
|
|
@ -1762,14 +1747,11 @@ foo: FOO
|
|||
})
|
||||
app := &App{
|
||||
OverrideHelmBinary: DefaultHelmBinary,
|
||||
readFile: testFs.ReadFile,
|
||||
fileExists: testFs.FileExists,
|
||||
glob: testFs.Glob,
|
||||
abs: testFs.Abs,
|
||||
fs: testFs.ToFileSystem(),
|
||||
Env: "default",
|
||||
Logger: helmexec.NewLogger(os.Stderr, "debug"),
|
||||
}
|
||||
app.remote = remote.NewRemote(app.Logger, testFs.Cwd, testFs.ReadFile, testFs.DirectoryExistsAt, testFs.FileExistsAt)
|
||||
app.remote = remote.NewRemote(app.Logger, testFs.Cwd, app.fs)
|
||||
|
||||
expectNoCallsToHelm(app)
|
||||
|
||||
|
|
@ -1828,14 +1810,11 @@ foo: FOO
|
|||
})
|
||||
app := &App{
|
||||
OverrideHelmBinary: DefaultHelmBinary,
|
||||
readFile: testFs.ReadFile,
|
||||
fileExists: testFs.FileExists,
|
||||
glob: testFs.Glob,
|
||||
abs: testFs.Abs,
|
||||
fs: testFs.ToFileSystem(),
|
||||
Env: "default",
|
||||
Logger: helmexec.NewLogger(os.Stderr, "debug"),
|
||||
}
|
||||
app.remote = remote.NewRemote(app.Logger, testFs.Cwd, testFs.ReadFile, testFs.DirectoryExistsAt, testFs.FileExistsAt)
|
||||
app.remote = remote.NewRemote(app.Logger, testFs.Cwd, app.fs)
|
||||
|
||||
expectNoCallsToHelm(app)
|
||||
|
||||
|
|
@ -1912,14 +1891,11 @@ helmDefaults:
|
|||
})
|
||||
app := &App{
|
||||
OverrideHelmBinary: DefaultHelmBinary,
|
||||
readFile: testFs.ReadFile,
|
||||
fileExists: testFs.FileExists,
|
||||
glob: testFs.Glob,
|
||||
abs: testFs.Abs,
|
||||
fs: testFs.ToFileSystem(),
|
||||
Env: "test",
|
||||
Logger: helmexec.NewLogger(os.Stderr, "debug"),
|
||||
}
|
||||
app.remote = remote.NewRemote(app.Logger, testFs.Cwd, testFs.ReadFile, testFs.DirectoryExistsAt, testFs.FileExistsAt)
|
||||
app.remote = remote.NewRemote(app.Logger, testFs.Cwd, app.fs)
|
||||
|
||||
expectNoCallsToHelm(app)
|
||||
|
||||
|
|
@ -1988,13 +1964,11 @@ releases:
|
|||
})
|
||||
app := &App{
|
||||
OverrideHelmBinary: DefaultHelmBinary,
|
||||
readFile: testFs.ReadFile,
|
||||
glob: testFs.Glob,
|
||||
abs: testFs.Abs,
|
||||
fs: testFs.ToFileSystem(),
|
||||
Env: "default",
|
||||
Logger: helmexec.NewLogger(os.Stderr, "debug"),
|
||||
}
|
||||
app.remote = remote.NewRemote(app.Logger, testFs.Cwd, testFs.ReadFile, testFs.DirectoryExistsAt, testFs.FileExistsAt)
|
||||
app.remote = remote.NewRemote(app.Logger, testFs.Cwd, app.fs)
|
||||
|
||||
expectNoCallsToHelm(app)
|
||||
|
||||
|
|
@ -2046,14 +2020,12 @@ releases:
|
|||
})
|
||||
app := &App{
|
||||
OverrideHelmBinary: DefaultHelmBinary,
|
||||
readFile: testFs.ReadFile,
|
||||
glob: testFs.Glob,
|
||||
abs: testFs.Abs,
|
||||
fs: testFs.ToFileSystem(),
|
||||
Env: "default",
|
||||
Logger: helmexec.NewLogger(os.Stderr, "debug"),
|
||||
}
|
||||
|
||||
app.remote = remote.NewRemote(app.Logger, testFs.Cwd, testFs.ReadFile, testFs.DirectoryExistsAt, testFs.FileExistsAt)
|
||||
app.remote = remote.NewRemote(app.Logger, testFs.Cwd, app.fs)
|
||||
expectNoCallsToHelm(app)
|
||||
|
||||
st, err := app.loadDesiredStateFromYaml(statePath, LoadOpts{Reverse: true})
|
||||
|
|
@ -2103,13 +2075,11 @@ releases:
|
|||
})
|
||||
app := &App{
|
||||
OverrideHelmBinary: DefaultHelmBinary,
|
||||
readFile: testFs.ReadFile,
|
||||
glob: testFs.Glob,
|
||||
abs: testFs.Abs,
|
||||
fs: testFs.ToFileSystem(),
|
||||
Env: "default",
|
||||
Logger: helmexec.NewLogger(os.Stderr, "debug"),
|
||||
}
|
||||
app.remote = remote.NewRemote(app.Logger, testFs.Cwd, testFs.ReadFile, testFs.DirectoryExistsAt, testFs.FileExistsAt)
|
||||
app.remote = remote.NewRemote(app.Logger, testFs.Cwd, app.fs)
|
||||
|
||||
opts := LoadOpts{
|
||||
CalleePath: statePath,
|
||||
|
|
@ -2217,13 +2187,11 @@ services:
|
|||
})
|
||||
app := &App{
|
||||
OverrideHelmBinary: DefaultHelmBinary,
|
||||
readFile: testFs.ReadFile,
|
||||
glob: testFs.Glob,
|
||||
abs: testFs.Abs,
|
||||
fs: testFs.ToFileSystem(),
|
||||
Env: "default",
|
||||
Logger: helmexec.NewLogger(os.Stderr, "debug"),
|
||||
}
|
||||
app.remote = remote.NewRemote(app.Logger, testFs.Cwd, testFs.ReadFile, testFs.DirectoryExistsAt, testFs.FileExistsAt)
|
||||
app.remote = remote.NewRemote(app.Logger, testFs.Cwd, app.fs)
|
||||
|
||||
expectNoCallsToHelm(app)
|
||||
|
||||
|
|
@ -2656,8 +2624,7 @@ releases:
|
|||
|
||||
app := appWithFs(&App{
|
||||
OverrideHelmBinary: DefaultHelmBinary,
|
||||
glob: filepath.Glob,
|
||||
abs: filepath.Abs,
|
||||
fs: ffs.DefaultFileSystem(),
|
||||
OverrideKubeContext: "default",
|
||||
Env: "default",
|
||||
Logger: logger,
|
||||
|
|
@ -2729,8 +2696,6 @@ releases:
|
|||
|
||||
app := appWithFs(&App{
|
||||
OverrideHelmBinary: DefaultHelmBinary,
|
||||
glob: filepath.Glob,
|
||||
abs: filepath.Abs,
|
||||
OverrideKubeContext: "default",
|
||||
Env: "default",
|
||||
Logger: logger,
|
||||
|
|
@ -2741,6 +2706,8 @@ releases:
|
|||
valsRuntime: valsRuntime,
|
||||
}, files)
|
||||
|
||||
fmt.Printf("CRAFTED APP WITH %p\n", app.fs.DirectoryExistsAt)
|
||||
|
||||
if err := app.Template(configImpl{}); err != nil {
|
||||
t.Fatalf("%v", err)
|
||||
}
|
||||
|
|
@ -4282,8 +4249,7 @@ changing working directory back to "/path/to"
|
|||
|
||||
app := appWithFs(&App{
|
||||
OverrideHelmBinary: DefaultHelmBinary,
|
||||
glob: filepath.Glob,
|
||||
abs: filepath.Abs,
|
||||
fs: ffs.DefaultFileSystem(),
|
||||
OverrideKubeContext: "default",
|
||||
Env: "default",
|
||||
Logger: logger,
|
||||
|
|
@ -4465,8 +4431,7 @@ changing working directory back to "/path/to"
|
|||
|
||||
app := appWithFs(&App{
|
||||
OverrideHelmBinary: DefaultHelmBinary,
|
||||
glob: filepath.Glob,
|
||||
abs: filepath.Abs,
|
||||
fs: ffs.DefaultFileSystem(),
|
||||
OverrideKubeContext: "default",
|
||||
Env: "default",
|
||||
Logger: logger,
|
||||
|
|
@ -4523,8 +4488,7 @@ releases:
|
|||
|
||||
app := appWithFs(&App{
|
||||
OverrideHelmBinary: DefaultHelmBinary,
|
||||
glob: filepath.Glob,
|
||||
abs: filepath.Abs,
|
||||
fs: ffs.DefaultFileSystem(),
|
||||
OverrideKubeContext: "default",
|
||||
Env: "default",
|
||||
Logger: logger,
|
||||
|
|
@ -4570,8 +4534,7 @@ releases:
|
|||
|
||||
app := appWithFs(&App{
|
||||
OverrideHelmBinary: DefaultHelmBinary,
|
||||
glob: filepath.Glob,
|
||||
abs: filepath.Abs,
|
||||
fs: ffs.DefaultFileSystem(),
|
||||
OverrideKubeContext: "default",
|
||||
Env: "default",
|
||||
Logger: logger,
|
||||
|
|
@ -4631,8 +4594,7 @@ releases:
|
|||
|
||||
app := appWithFs(&App{
|
||||
OverrideHelmBinary: DefaultHelmBinary,
|
||||
glob: filepath.Glob,
|
||||
abs: filepath.Abs,
|
||||
fs: ffs.DefaultFileSystem(),
|
||||
OverrideKubeContext: "default",
|
||||
Env: "default",
|
||||
Logger: logger,
|
||||
|
|
@ -4693,8 +4655,7 @@ releases:
|
|||
|
||||
app := appWithFs(&App{
|
||||
OverrideHelmBinary: DefaultHelmBinary,
|
||||
glob: filepath.Glob,
|
||||
abs: filepath.Abs,
|
||||
fs: ffs.DefaultFileSystem(),
|
||||
OverrideKubeContext: "default",
|
||||
Env: "default",
|
||||
Logger: logger,
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import (
|
|||
"go.uber.org/zap"
|
||||
|
||||
"github.com/helmfile/helmfile/pkg/environment"
|
||||
"github.com/helmfile/helmfile/pkg/filesystem"
|
||||
"github.com/helmfile/helmfile/pkg/helmexec"
|
||||
"github.com/helmfile/helmfile/pkg/remote"
|
||||
"github.com/helmfile/helmfile/pkg/state"
|
||||
|
|
@ -27,14 +28,9 @@ type desiredStateLoader struct {
|
|||
env string
|
||||
namespace string
|
||||
chart string
|
||||
fs *filesystem.FileSystem
|
||||
|
||||
readFile func(string) ([]byte, error)
|
||||
deleteFile func(string) error
|
||||
fileExists func(string) (bool, error)
|
||||
abs func(string) (string, error)
|
||||
glob func(string) ([]string, error)
|
||||
directoryExistsAt func(string) bool
|
||||
getHelm func(*state.HelmState) helmexec.Interface
|
||||
getHelm func(*state.HelmState) helmexec.Interface
|
||||
|
||||
remote *remote.Remote
|
||||
logger *zap.SugaredLogger
|
||||
|
|
@ -50,8 +46,8 @@ func (ld *desiredStateLoader) Load(f string, opts LoadOpts) (*state.HelmState, e
|
|||
if opts.CalleePath == "" {
|
||||
return nil, fmt.Errorf("bug: opts.CalleePath was nil: f=%s, opts=%v", f, opts)
|
||||
}
|
||||
storage := state.NewStorage(opts.CalleePath, ld.logger, ld.glob)
|
||||
envld := state.NewEnvironmentValuesLoader(storage, ld.readFile, ld.logger, ld.remote)
|
||||
storage := state.NewStorage(opts.CalleePath, ld.logger, ld.fs)
|
||||
envld := state.NewEnvironmentValuesLoader(storage, ld.fs, ld.logger, ld.remote)
|
||||
handler := state.MissingFileHandlerError
|
||||
vals, err := envld.LoadEnvironmentValues(&handler, args, &environment.EmptyEnvironment)
|
||||
if err != nil {
|
||||
|
|
@ -120,7 +116,7 @@ func (ld *desiredStateLoader) loadFileWithOverrides(inheritedEnv, overrodeEnv *e
|
|||
f = filepath.Join(baseDir, file)
|
||||
}
|
||||
|
||||
fileBytes, err := ld.readFile(f)
|
||||
fileBytes, err := ld.fs.ReadFile(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -166,8 +162,7 @@ func (ld *desiredStateLoader) loadFileWithOverrides(inheritedEnv, overrodeEnv *e
|
|||
}
|
||||
|
||||
func (a *desiredStateLoader) underlying() *state.StateCreator {
|
||||
c := state.NewCreator(a.logger, a.readFile, a.fileExists, a.abs, a.glob, a.directoryExistsAt, a.valsRuntime, a.getHelm, a.overrideHelmBinary, a.remote)
|
||||
c.DeleteFile = a.deleteFile
|
||||
c := state.NewCreator(a.logger, a.fs, a.valsRuntime, a.getHelm, a.overrideHelmBinary, a.remote)
|
||||
c.LoadFile = a.loadFile
|
||||
return c
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,13 +4,13 @@ import (
|
|||
"bufio"
|
||||
"bytes"
|
||||
"io"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/variantdev/vals"
|
||||
|
||||
"github.com/helmfile/helmfile/pkg/exectest"
|
||||
ffs "github.com/helmfile/helmfile/pkg/filesystem"
|
||||
"github.com/helmfile/helmfile/pkg/helmexec"
|
||||
"github.com/helmfile/helmfile/pkg/testhelper"
|
||||
)
|
||||
|
|
@ -83,8 +83,7 @@ func TestDestroy_2(t *testing.T) {
|
|||
|
||||
app := appWithFs(&App{
|
||||
OverrideHelmBinary: DefaultHelmBinary,
|
||||
glob: filepath.Glob,
|
||||
abs: filepath.Abs,
|
||||
fs: ffs.DefaultFileSystem(),
|
||||
OverrideKubeContext: "",
|
||||
Env: "default",
|
||||
Logger: logger,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import (
|
|||
"bufio"
|
||||
"bytes"
|
||||
"io"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
|
|
@ -12,6 +11,7 @@ import (
|
|||
"go.uber.org/zap"
|
||||
|
||||
"github.com/helmfile/helmfile/pkg/exectest"
|
||||
ffs "github.com/helmfile/helmfile/pkg/filesystem"
|
||||
"github.com/helmfile/helmfile/pkg/helmexec"
|
||||
"github.com/helmfile/helmfile/pkg/testhelper"
|
||||
)
|
||||
|
|
@ -124,8 +124,7 @@ func TestDestroy(t *testing.T) {
|
|||
|
||||
app := appWithFs(&App{
|
||||
OverrideHelmBinary: DefaultHelmBinary,
|
||||
glob: filepath.Glob,
|
||||
abs: filepath.Abs,
|
||||
fs: ffs.DefaultFileSystem(),
|
||||
OverrideKubeContext: "default",
|
||||
Env: "default",
|
||||
Logger: logger,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import (
|
|||
"bufio"
|
||||
"bytes"
|
||||
"io"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
|
|
@ -12,6 +11,7 @@ import (
|
|||
"github.com/variantdev/vals"
|
||||
|
||||
"github.com/helmfile/helmfile/pkg/exectest"
|
||||
ffs "github.com/helmfile/helmfile/pkg/filesystem"
|
||||
"github.com/helmfile/helmfile/pkg/helmexec"
|
||||
"github.com/helmfile/helmfile/pkg/testhelper"
|
||||
)
|
||||
|
|
@ -1060,8 +1060,7 @@ changing working directory back to "/path/to"
|
|||
|
||||
app := appWithFs(&App{
|
||||
OverrideHelmBinary: DefaultHelmBinary,
|
||||
glob: filepath.Glob,
|
||||
abs: filepath.Abs,
|
||||
fs: ffs.DefaultFileSystem(),
|
||||
OverrideKubeContext: "",
|
||||
Env: "default",
|
||||
Logger: logger,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import (
|
|||
"bufio"
|
||||
"bytes"
|
||||
"io"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
|
|
@ -13,6 +12,7 @@ import (
|
|||
"go.uber.org/zap"
|
||||
|
||||
"github.com/helmfile/helmfile/pkg/exectest"
|
||||
ffs "github.com/helmfile/helmfile/pkg/filesystem"
|
||||
"github.com/helmfile/helmfile/pkg/helmexec"
|
||||
"github.com/helmfile/helmfile/pkg/testhelper"
|
||||
)
|
||||
|
|
@ -1352,8 +1352,7 @@ changing working directory back to "/path/to"
|
|||
|
||||
app := appWithFs(&App{
|
||||
OverrideHelmBinary: DefaultHelmBinary,
|
||||
glob: filepath.Glob,
|
||||
abs: filepath.Abs,
|
||||
fs: ffs.DefaultFileSystem(),
|
||||
OverrideKubeContext: overrideKubeContext,
|
||||
Env: "default",
|
||||
Logger: logger,
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ func (r *desiredStateLoader) twoPassRenderTemplateToYaml(inherited, overrode *en
|
|||
}
|
||||
|
||||
tmplData := state.NewEnvironmentTemplateData(*finalEnv, r.namespace, vals)
|
||||
secondPassRenderer := tmpl.NewFileRenderer(r.readFile, baseDir, tmplData)
|
||||
secondPassRenderer := tmpl.NewFileRenderer(r.fs, baseDir, tmplData)
|
||||
yamlBuf, err := secondPassRenderer.RenderTemplateContentToBuffer(content)
|
||||
if err != nil {
|
||||
if r.logger != nil {
|
||||
|
|
|
|||
|
|
@ -17,16 +17,13 @@ import (
|
|||
func makeLoader(files map[string]string, env string) (*desiredStateLoader, *testhelper.TestFs) {
|
||||
testfs := testhelper.NewTestFs(files)
|
||||
logger := helmexec.NewLogger(os.Stdout, "debug")
|
||||
r := remote.NewRemote(logger, testfs.Cwd, testfs.ReadFile, testfs.DirectoryExistsAt, testfs.FileExistsAt)
|
||||
r := remote.NewRemote(logger, testfs.Cwd, testfs.ToFileSystem())
|
||||
return &desiredStateLoader{
|
||||
env: env,
|
||||
namespace: "namespace",
|
||||
logger: helmexec.NewLogger(os.Stdout, "debug"),
|
||||
readFile: testfs.ReadFile,
|
||||
fileExists: testfs.FileExists,
|
||||
abs: testfs.Abs,
|
||||
glob: testfs.Glob,
|
||||
remote: r,
|
||||
env: env,
|
||||
namespace: "namespace",
|
||||
logger: helmexec.NewLogger(os.Stdout, "debug"),
|
||||
fs: testfs.ToFileSystem(),
|
||||
remote: r,
|
||||
}, testfs
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import (
|
|||
"go.uber.org/zap"
|
||||
|
||||
"github.com/helmfile/helmfile/pkg/environment"
|
||||
"github.com/helmfile/helmfile/pkg/filesystem"
|
||||
"github.com/helmfile/helmfile/pkg/helmexec"
|
||||
"github.com/helmfile/helmfile/pkg/tmpl"
|
||||
)
|
||||
|
|
@ -35,9 +36,9 @@ type Bus struct {
|
|||
Chart string
|
||||
|
||||
Env environment.Environment
|
||||
Fs *filesystem.FileSystem
|
||||
|
||||
ReadFile func(string) ([]byte, error)
|
||||
Logger *zap.SugaredLogger
|
||||
Logger *zap.SugaredLogger
|
||||
}
|
||||
|
||||
func (bus *Bus) Trigger(evt string, evtErr error, context map[string]interface{}) (bool, error) {
|
||||
|
|
@ -100,7 +101,7 @@ func (bus *Bus) Trigger(evt string, evtErr error, context map[string]interface{}
|
|||
for k, v := range context {
|
||||
data[k] = v
|
||||
}
|
||||
render := tmpl.NewTextRenderer(bus.ReadFile, bus.BasePath, data)
|
||||
render := tmpl.NewTextRenderer(bus.Fs, bus.BasePath, data)
|
||||
|
||||
bus.Logger.Debugf("hook[%s]: triggered by event \"%s\"\n", name, evt)
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import (
|
|||
"go.uber.org/zap/zaptest/observer"
|
||||
|
||||
"github.com/helmfile/helmfile/pkg/environment"
|
||||
ffs "github.com/helmfile/helmfile/pkg/filesystem"
|
||||
)
|
||||
|
||||
type runner struct {
|
||||
|
|
@ -154,7 +155,7 @@ func TestTrigger(t *testing.T) {
|
|||
Namespace: "myns",
|
||||
Env: environment.Environment{Name: "prod"},
|
||||
Logger: zeLogger,
|
||||
ReadFile: readFile,
|
||||
Fs: &ffs.FileSystem{ReadFile: readFile},
|
||||
}
|
||||
|
||||
bus.Runner = &runner{}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,101 @@
|
|||
package filesystem
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
type FileSystem struct {
|
||||
ReadFile func(string) ([]byte, error)
|
||||
ReadDir func(string) ([]fs.DirEntry, error)
|
||||
DeleteFile func(string) error
|
||||
FileExists func(string) (bool, error)
|
||||
Glob func(string) ([]string, error)
|
||||
FileExistsAt func(string) bool
|
||||
DirectoryExistsAt func(string) bool
|
||||
Stat func(string) (os.FileInfo, error)
|
||||
Getwd func() (string, error)
|
||||
Chdir func(string) error
|
||||
Abs func(string) (string, error)
|
||||
}
|
||||
|
||||
func DefaultFileSystem() *FileSystem {
|
||||
dfs := FileSystem{
|
||||
ReadFile: os.ReadFile,
|
||||
ReadDir: os.ReadDir,
|
||||
DeleteFile: os.Remove,
|
||||
Stat: os.Stat,
|
||||
Glob: filepath.Glob,
|
||||
Getwd: os.Getwd,
|
||||
Chdir: os.Chdir,
|
||||
Abs: filepath.Abs,
|
||||
}
|
||||
|
||||
dfs.FileExistsAt = dfs.fileExistsAtDefault
|
||||
dfs.DirectoryExistsAt = dfs.directoryExistsDefault
|
||||
dfs.FileExists = dfs.fileExistsDefault
|
||||
return &dfs
|
||||
}
|
||||
|
||||
func FromFileSystem(params FileSystem) *FileSystem {
|
||||
dfs := DefaultFileSystem()
|
||||
|
||||
if params.ReadFile != nil {
|
||||
dfs.ReadFile = params.ReadFile
|
||||
}
|
||||
if params.ReadDir != nil {
|
||||
dfs.ReadDir = params.ReadDir
|
||||
}
|
||||
if params.DeleteFile != nil {
|
||||
dfs.DeleteFile = params.DeleteFile
|
||||
}
|
||||
if params.FileExists != nil {
|
||||
dfs.FileExists = params.FileExists
|
||||
}
|
||||
if params.Glob != nil {
|
||||
dfs.Glob = params.Glob
|
||||
}
|
||||
if params.FileExistsAt != nil {
|
||||
dfs.FileExistsAt = params.FileExistsAt
|
||||
}
|
||||
if params.DirectoryExistsAt != nil {
|
||||
dfs.DirectoryExistsAt = params.DirectoryExistsAt
|
||||
}
|
||||
if params.Stat != nil {
|
||||
dfs.Stat = params.Stat
|
||||
}
|
||||
if params.Getwd != nil {
|
||||
dfs.Getwd = params.Getwd
|
||||
}
|
||||
if params.Chdir != nil {
|
||||
dfs.Chdir = params.Chdir
|
||||
}
|
||||
if params.Abs != nil {
|
||||
dfs.Abs = params.Abs
|
||||
}
|
||||
|
||||
return dfs
|
||||
}
|
||||
|
||||
func (filesystem *FileSystem) fileExistsAtDefault(path string) bool {
|
||||
fileInfo, err := filesystem.Stat(path)
|
||||
return err == nil && fileInfo.Mode().IsRegular()
|
||||
}
|
||||
|
||||
func (filesystem *FileSystem) fileExistsDefault(path string) (bool, error) {
|
||||
_, err := filesystem.Stat(path)
|
||||
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (filesystem *FileSystem) directoryExistsDefault(path string) bool {
|
||||
fileInfo, err := filesystem.Stat(path)
|
||||
return err == nil && fileInfo.Mode().IsDir()
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
package filesystem
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io/fs"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
type TestFileInfo struct {
|
||||
mode fs.FileMode
|
||||
}
|
||||
|
||||
func (tfi TestFileInfo) Name() string { return "" }
|
||||
func (tfi TestFileInfo) Size() int64 { return 0 }
|
||||
func (tfi TestFileInfo) Mode() fs.FileMode { return tfi.mode }
|
||||
func (tfi TestFileInfo) ModTime() time.Time { return time.Time{} }
|
||||
func (tfi TestFileInfo) IsDir() bool { return tfi.mode.IsDir() }
|
||||
func (tfi TestFileInfo) Sys() any { return nil }
|
||||
|
||||
func NewTestFileSystem() FileSystem {
|
||||
replaceffs := FileSystem{
|
||||
Stat: func(s string) (os.FileInfo, error) {
|
||||
if strings.HasPrefix(s, "existing_file") {
|
||||
return TestFileInfo{mode: 0}, nil
|
||||
}
|
||||
if strings.HasPrefix(s, "existing_dir") {
|
||||
return TestFileInfo{mode: fs.ModeDir}, nil
|
||||
}
|
||||
return nil, errors.New("Error")
|
||||
},
|
||||
}
|
||||
return *FromFileSystem(replaceffs)
|
||||
}
|
||||
|
||||
func TestFs_fileExistsDefault(t *testing.T) {
|
||||
ffs := NewTestFileSystem()
|
||||
var exists, _ = ffs.FileExists("existing_file.txt")
|
||||
if !exists {
|
||||
t.Errorf("Expected file %s, not found", "existing_file.txt")
|
||||
}
|
||||
|
||||
exists, _ = ffs.FileExists("non_existing_file.txt")
|
||||
if exists {
|
||||
t.Errorf("Not expected file %s, found", "non_existing_file.txt")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFs_fileExistsAtDefault(t *testing.T) {
|
||||
ffs := NewTestFileSystem()
|
||||
|
||||
var exists = ffs.FileExistsAt("existing_file.txt")
|
||||
if !exists {
|
||||
t.Errorf("Expected file %s, not found", "existing_file.txt")
|
||||
}
|
||||
|
||||
exists = ffs.FileExistsAt("non_existing_file.txt")
|
||||
if exists {
|
||||
t.Errorf("Not expected file %s, found", "non_existing_file.txt")
|
||||
}
|
||||
|
||||
exists = ffs.FileExistsAt("existing_dir")
|
||||
if exists {
|
||||
t.Errorf("Not expected file %s, found", "existing_dir")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFs_directoryExistsDefault(t *testing.T) {
|
||||
ffs := NewTestFileSystem()
|
||||
var exists = ffs.DirectoryExistsAt("existing_dir")
|
||||
if !exists {
|
||||
t.Errorf("Expected file %s, not found", "existing_dir")
|
||||
}
|
||||
|
||||
exists = ffs.DirectoryExistsAt("not_existing_dir")
|
||||
if exists {
|
||||
t.Errorf("Not expected file %s, found", "existing_dir")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFs_DefaultBuilder(t *testing.T) {
|
||||
ffs := DefaultFileSystem()
|
||||
if ffs.ReadFile == nil ||
|
||||
ffs.ReadDir == nil ||
|
||||
ffs.DeleteFile == nil ||
|
||||
ffs.FileExists == nil ||
|
||||
ffs.Glob == nil ||
|
||||
ffs.FileExistsAt == nil ||
|
||||
ffs.DirectoryExistsAt == nil ||
|
||||
ffs.Stat == nil ||
|
||||
ffs.Getwd == nil ||
|
||||
ffs.Chdir == nil ||
|
||||
ffs.Abs == nil {
|
||||
t.Errorf("Missing functions in DefaultFileSystem")
|
||||
}
|
||||
}
|
||||
|
|
@ -17,6 +17,7 @@ import (
|
|||
"gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/helmfile/helmfile/pkg/envvar"
|
||||
"github.com/helmfile/helmfile/pkg/filesystem"
|
||||
)
|
||||
|
||||
var disableInsecureFeatures bool
|
||||
|
|
@ -43,11 +44,9 @@ type Remote struct {
|
|||
// Getter is the underlying implementation of getter used for fetching remote files
|
||||
Getter Getter
|
||||
|
||||
// ReadFile is the implementation of the file reader that reads a local file from the specified path.
|
||||
// Filesystem abstraction
|
||||
// Inject any implementation of your choice, like an im-memory impl for testing, os.ReadFile for the real-world use.
|
||||
ReadFile func(string) ([]byte, error)
|
||||
DirExists func(string) bool
|
||||
FileExists func(string) bool
|
||||
fs *filesystem.FileSystem
|
||||
}
|
||||
|
||||
func (r *Remote) Unmarshal(src string, dst interface{}) error {
|
||||
|
|
@ -87,7 +86,7 @@ func (r *Remote) GetBytes(goGetterSrc string) ([]byte, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
bytes, err := r.ReadFile(f)
|
||||
bytes, err := r.fs.ReadFile(f)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read file: %v", err)
|
||||
}
|
||||
|
|
@ -99,7 +98,7 @@ func (r *Remote) GetBytes(goGetterSrc string) ([]byte, error) {
|
|||
// If the argument was an URL, it fetches the remote directory contained within the URL,
|
||||
// and returns the path to the file in the fetched directory
|
||||
func (r *Remote) Locate(urlOrPath string) (string, error) {
|
||||
if r.FileExists(urlOrPath) || r.DirExists(urlOrPath) {
|
||||
if r.fs.FileExistsAt(urlOrPath) || r.fs.DirectoryExistsAt(urlOrPath) {
|
||||
return urlOrPath, nil
|
||||
}
|
||||
fetched, err := r.Fetch(urlOrPath)
|
||||
|
|
@ -217,11 +216,11 @@ func (r *Remote) Fetch(goGetterSrc string, cacheDirOpt ...string) (string, error
|
|||
r.Logger.Debugf("cached dir: %s", cacheDirPath)
|
||||
|
||||
{
|
||||
if r.FileExists(cacheDirPath) {
|
||||
if r.fs.FileExistsAt(cacheDirPath) {
|
||||
return "", fmt.Errorf("%s is not directory. please remove it so that variant could use it for dependency caching", getterDst)
|
||||
}
|
||||
|
||||
if r.DirExists(cacheDirPath) {
|
||||
if r.fs.DirectoryExistsAt(cacheDirPath) {
|
||||
cached = true
|
||||
}
|
||||
}
|
||||
|
|
@ -285,17 +284,15 @@ func (g *GoGetter) Get(wd, src, dst string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func NewRemote(logger *zap.SugaredLogger, homeDir string, readFile func(string) ([]byte, error), dirExists func(string) bool, fileExists func(string) bool) *Remote {
|
||||
func NewRemote(logger *zap.SugaredLogger, homeDir string, fs *filesystem.FileSystem) *Remote {
|
||||
if disableInsecureFeatures {
|
||||
panic("Remote sources are disabled due to 'DISABLE_INSECURE_FEATURES'")
|
||||
}
|
||||
remote := &Remote{
|
||||
Logger: logger,
|
||||
Home: homeDir,
|
||||
Getter: &GoGetter{Logger: logger},
|
||||
ReadFile: readFile,
|
||||
DirExists: dirExists,
|
||||
FileExists: fileExists,
|
||||
Logger: logger,
|
||||
Home: homeDir,
|
||||
Getter: &GoGetter{Logger: logger},
|
||||
fs: fs,
|
||||
}
|
||||
|
||||
if remote.Home == "" {
|
||||
|
|
|
|||
|
|
@ -55,12 +55,10 @@ func TestRemote_HttpsGitHub(t *testing.T) {
|
|||
get: get,
|
||||
}
|
||||
remote := &Remote{
|
||||
Logger: helmexec.NewLogger(os.Stderr, "debug"),
|
||||
Home: CacheDir(),
|
||||
Getter: getter,
|
||||
ReadFile: testfs.ReadFile,
|
||||
FileExists: testfs.FileExistsAt,
|
||||
DirExists: testfs.DirectoryExistsAt,
|
||||
Logger: helmexec.NewLogger(os.Stderr, "debug"),
|
||||
Home: CacheDir(),
|
||||
Getter: getter,
|
||||
fs: testfs.ToFileSystem(),
|
||||
}
|
||||
|
||||
// FYI, go-getter in the `dir` mode accepts URL like the below. So helmfile expects URLs similar to it:
|
||||
|
|
@ -133,12 +131,10 @@ func TestRemote_SShGitHub(t *testing.T) {
|
|||
get: get,
|
||||
}
|
||||
remote := &Remote{
|
||||
Logger: helmexec.NewLogger(os.Stderr, "debug"),
|
||||
Home: CacheDir(),
|
||||
Getter: getter,
|
||||
ReadFile: testfs.ReadFile,
|
||||
FileExists: testfs.FileExistsAt,
|
||||
DirExists: testfs.DirectoryExistsAt,
|
||||
Logger: helmexec.NewLogger(os.Stderr, "debug"),
|
||||
Home: CacheDir(),
|
||||
Getter: getter,
|
||||
fs: testfs.ToFileSystem(),
|
||||
}
|
||||
|
||||
url := "git::ssh://git@github.com/cloudposse/helmfiles.git@releases/kiam.yaml?ref=0.40.0"
|
||||
|
|
@ -205,12 +201,10 @@ func TestRemote_SShGitHub_WithSshKey(t *testing.T) {
|
|||
get: get,
|
||||
}
|
||||
remote := &Remote{
|
||||
Logger: helmexec.NewLogger(os.Stderr, "debug"),
|
||||
Home: CacheDir(),
|
||||
Getter: getter,
|
||||
ReadFile: testfs.ReadFile,
|
||||
FileExists: testfs.FileExistsAt,
|
||||
DirExists: testfs.DirectoryExistsAt,
|
||||
Logger: helmexec.NewLogger(os.Stderr, "debug"),
|
||||
Home: CacheDir(),
|
||||
Getter: getter,
|
||||
fs: testfs.ToFileSystem(),
|
||||
}
|
||||
|
||||
url := "git::ssh://git@github.com/cloudposse/helmfiles.git@releases/kiam.yaml?ref=0.40.0&sshkey=ZWNkc2Etc2hhMi1uaXN0cDI1NiBBQUFBRTJWalpITmhMWE5vWVRJdGJtbHpkSEF5TlRZQUFBQUlibWx6ZEhBeU5UWUFBQUJCQkJTU3dOY2xoVzQ2Vm9VR3dMQ3JscVRHYUdOVWdRVUVEUEptc1ZzdUViL2RBNUcrQk9YMWxGaUVMYU9HQ2F6bS9KQkR2V3Y2Y0ZDQUtVRjVocVJOUjdJPSA="
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
ffs "github.com/helmfile/helmfile/pkg/filesystem"
|
||||
)
|
||||
|
||||
type TestFs struct {
|
||||
|
|
@ -13,6 +15,7 @@ type TestFs struct {
|
|||
files map[string]string
|
||||
|
||||
GlobFixtures map[string][]string
|
||||
DeleteFile func(string) error
|
||||
|
||||
fileReaderCalls int
|
||||
successfulReads []string
|
||||
|
|
@ -34,9 +37,26 @@ func NewTestFs(files map[string]string) *TestFs {
|
|||
successfulReads: []string{},
|
||||
|
||||
GlobFixtures: map[string][]string{},
|
||||
DeleteFile: func(string) (ret error) { return },
|
||||
}
|
||||
}
|
||||
|
||||
func (f *TestFs) ToFileSystem() *ffs.FileSystem {
|
||||
curfs := ffs.FileSystem{
|
||||
FileExistsAt: f.FileExistsAt,
|
||||
FileExists: f.FileExists,
|
||||
DirectoryExistsAt: f.DirectoryExistsAt,
|
||||
ReadFile: f.ReadFile,
|
||||
Glob: f.Glob,
|
||||
Getwd: f.Getwd,
|
||||
Chdir: f.Chdir,
|
||||
Abs: f.Abs,
|
||||
DeleteFile: f.DeleteFile,
|
||||
}
|
||||
trfs := ffs.FromFileSystem(curfs)
|
||||
return trfs
|
||||
}
|
||||
|
||||
func (f *TestFs) FileExistsAt(path string) bool {
|
||||
var ok bool
|
||||
if strings.HasPrefix(path, "/") {
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
package tmpl
|
||||
|
||||
import "io/fs"
|
||||
import (
|
||||
"github.com/helmfile/helmfile/pkg/filesystem"
|
||||
)
|
||||
|
||||
type Context struct {
|
||||
preRender bool
|
||||
basePath string
|
||||
readFile func(string) ([]byte, error)
|
||||
readDir func(string) ([]fs.DirEntry, error)
|
||||
fs *filesystem.FileSystem
|
||||
}
|
||||
|
||||
// SetBasePath sets the base path for the template
|
||||
|
|
@ -14,10 +15,6 @@ func (c *Context) SetBasePath(path string) {
|
|||
c.basePath = path
|
||||
}
|
||||
|
||||
func (c *Context) SetReadFile(f func(string) ([]byte, error)) {
|
||||
c.readFile = f
|
||||
}
|
||||
|
||||
func (c *Context) SetReadDir(f func(string) ([]fs.DirEntry, error)) {
|
||||
c.readDir = f
|
||||
func (c *Context) SetFileSystem(fs *filesystem.FileSystem) {
|
||||
c.fs = fs
|
||||
}
|
||||
|
|
|
|||
|
|
@ -220,11 +220,11 @@ func (c *Context) ReadFile(filename string) (string, error) {
|
|||
path = filepath.Join(c.basePath, filename)
|
||||
}
|
||||
|
||||
if c.readFile == nil {
|
||||
if c.fs.ReadFile == nil {
|
||||
return "", fmt.Errorf("readFile is not implemented")
|
||||
}
|
||||
|
||||
bytes, err := c.readFile(path)
|
||||
bytes, err := c.fs.ReadFile(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
|
@ -239,7 +239,7 @@ func (c *Context) ReadDir(path string) ([]string, error) {
|
|||
contextPath = filepath.Join(c.basePath, path)
|
||||
}
|
||||
|
||||
entries, err := c.readDir(contextPath)
|
||||
entries, err := c.fs.ReadDir(contextPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ReadDir %q: %w", contextPath, err)
|
||||
}
|
||||
|
|
@ -262,7 +262,7 @@ func (c *Context) ReadDirEntries(path string) ([]fs.DirEntry, error) {
|
|||
} else {
|
||||
contextPath = filepath.Join(c.basePath, path)
|
||||
}
|
||||
entries, err := c.readDir(contextPath)
|
||||
entries, err := c.fs.ReadDir(contextPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ReadDirEntries %q: %w", contextPath, err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/helmfile/helmfile/pkg/filesystem"
|
||||
)
|
||||
|
||||
func TestCreateFuncMap(t *testing.T) {
|
||||
|
|
@ -62,17 +64,23 @@ func TestCreateFuncMap_SkipInsecureTemplateFunctions(t *testing.T) {
|
|||
skipInsecureTemplateFunctions = currentVal
|
||||
}
|
||||
|
||||
func newFSExpecting(expectedFilename string, expected string) *filesystem.FileSystem {
|
||||
return filesystem.FromFileSystem(filesystem.FileSystem{
|
||||
ReadFile: func(filename string) ([]byte, error) {
|
||||
if filename != expectedFilename {
|
||||
return nil, fmt.Errorf("unexpected filename: expected=%v, actual=%s", expectedFilename, filename)
|
||||
}
|
||||
return []byte(expected), nil
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestReadFile(t *testing.T) {
|
||||
expected := `foo:
|
||||
bar: BAR
|
||||
`
|
||||
expectedFilename := "values.yaml"
|
||||
ctx := &Context{basePath: ".", readFile: func(filename string) ([]byte, error) {
|
||||
if filename != expectedFilename {
|
||||
return nil, fmt.Errorf("unexpected filename: expected=%v, actual=%s", expectedFilename, filename)
|
||||
}
|
||||
return []byte(expected), nil
|
||||
}}
|
||||
ctx := &Context{basePath: ".", fs: newFSExpecting(expectedFilename, expected)}
|
||||
actual, err := ctx.ReadFile(expectedFilename)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, expected, actual)
|
||||
|
|
@ -125,12 +133,12 @@ func TestReadDir(t *testing.T) {
|
|||
}
|
||||
|
||||
expectedDirname := "sampleDirectory"
|
||||
ctx := &Context{basePath: ".", readDir: func(dirname string) ([]fs.DirEntry, error) {
|
||||
ctx := &Context{basePath: ".", fs: filesystem.FromFileSystem(filesystem.FileSystem{ReadDir: func(dirname string) ([]fs.DirEntry, error) {
|
||||
if dirname != expectedDirname {
|
||||
return nil, fmt.Errorf("unexpected filename: expected=%v, actual=%s", expectedDirname, dirname)
|
||||
}
|
||||
return result, nil
|
||||
}}
|
||||
}})}
|
||||
|
||||
actual, err := ctx.ReadDir(expectedDirname)
|
||||
require.NoError(t, err)
|
||||
|
|
@ -146,12 +154,12 @@ func TestReadDirEntries(t *testing.T) {
|
|||
}
|
||||
|
||||
expectedDirname := "sampleDirectory"
|
||||
ctx := &Context{basePath: ".", readDir: func(dirname string) ([]fs.DirEntry, error) {
|
||||
ctx := &Context{basePath: ".", fs: filesystem.FromFileSystem(filesystem.FileSystem{ReadDir: func(dirname string) ([]fs.DirEntry, error) {
|
||||
if dirname != expectedDirname {
|
||||
return nil, fmt.Errorf("unexpected filename: expected=%v, actual=%s", expectedDirname, dirname)
|
||||
}
|
||||
return result, nil
|
||||
}}
|
||||
}})}
|
||||
|
||||
actual, err := ctx.ReadDirEntries(expectedDirname)
|
||||
require.NoError(t, err)
|
||||
|
|
@ -163,12 +171,7 @@ func TestReadFile_PassAbsPath(t *testing.T) {
|
|||
bar: BAR
|
||||
`
|
||||
expectedFilename, _ := filepath.Abs("values.yaml")
|
||||
ctx := &Context{basePath: ".", readFile: func(filename string) ([]byte, error) {
|
||||
if filename != expectedFilename {
|
||||
return nil, fmt.Errorf("unexpected filename: expected=%v, actual=%s", expectedFilename, filename)
|
||||
}
|
||||
return []byte(expected), nil
|
||||
}}
|
||||
ctx := &Context{basePath: ".", fs: newFSExpecting(expectedFilename, expected)}
|
||||
actual, err := ctx.ReadFile(expectedFilename)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, actual, expected)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ import (
|
|||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
ffs "github.com/helmfile/helmfile/pkg/filesystem"
|
||||
)
|
||||
|
||||
func TestRenderTemplate_Values(t *testing.T) {
|
||||
|
|
@ -14,12 +16,12 @@ func TestRenderTemplate_Values(t *testing.T) {
|
|||
bar: FOO_BAR
|
||||
`
|
||||
expectedFilename := "values.yaml"
|
||||
ctx := &Context{readFile: func(filename string) ([]byte, error) {
|
||||
ctx := &Context{fs: &ffs.FileSystem{ReadFile: func(filename string) ([]byte, error) {
|
||||
if filename != expectedFilename {
|
||||
return nil, fmt.Errorf("unexpected filename: expected=%v, actual=%s", expectedFilename, filename)
|
||||
}
|
||||
return []byte(valuesYamlContent), nil
|
||||
}}
|
||||
}}}
|
||||
buf, err := ctx.RenderTemplateToBuffer(`{{ readFile "values.yaml" | fromYaml | setValueAtPath "foo.bar" "FOO_BAR" | toYaml }}`)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
|
|
@ -43,12 +45,12 @@ func TestRenderTemplate_WithData(t *testing.T) {
|
|||
"bar": "FOO_BAR",
|
||||
},
|
||||
}
|
||||
ctx := &Context{readFile: func(filename string) ([]byte, error) {
|
||||
ctx := &Context{fs: &ffs.FileSystem{ReadFile: func(filename string) ([]byte, error) {
|
||||
if filename != expectedFilename {
|
||||
return nil, fmt.Errorf("unexpected filename: expected=%v, actual=%s", expectedFilename, filename)
|
||||
}
|
||||
return []byte(valuesYamlContent), nil
|
||||
}}
|
||||
}}}
|
||||
buf, err := ctx.RenderTemplateToBuffer(valuesYamlContent, data)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
|
|
@ -68,12 +70,12 @@ func TestRenderTemplate_AccessingMissingKeyWithGetOrNil(t *testing.T) {
|
|||
`
|
||||
expectedFilename := "values.yaml"
|
||||
data := map[string]interface{}{}
|
||||
ctx := &Context{readFile: func(filename string) ([]byte, error) {
|
||||
ctx := &Context{fs: &ffs.FileSystem{ReadFile: func(filename string) ([]byte, error) {
|
||||
if filename != expectedFilename {
|
||||
return nil, fmt.Errorf("unexpected filename: expected=%v, actual=%s", expectedFilename, filename)
|
||||
}
|
||||
return []byte(valuesYamlContent), nil
|
||||
}}
|
||||
}}}
|
||||
buf, err := ctx.RenderTemplateToBuffer(valuesYamlContent, data)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
|
|
@ -93,12 +95,12 @@ func TestRenderTemplate_Defaulting(t *testing.T) {
|
|||
`
|
||||
expectedFilename := "values.yaml"
|
||||
data := map[string]interface{}{}
|
||||
ctx := &Context{readFile: func(filename string) ([]byte, error) {
|
||||
ctx := &Context{fs: &ffs.FileSystem{ReadFile: func(filename string) ([]byte, error) {
|
||||
if filename != expectedFilename {
|
||||
return nil, fmt.Errorf("unexpected filename: expected=%v, actual=%s", expectedFilename, filename)
|
||||
}
|
||||
return []byte(valuesYamlContent), nil
|
||||
}}
|
||||
}}}
|
||||
buf, err := ctx.RenderTemplateToBuffer(valuesYamlContent, data)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
|
|
@ -110,9 +112,9 @@ func TestRenderTemplate_Defaulting(t *testing.T) {
|
|||
}
|
||||
|
||||
func renderTemplateToString(s string, data ...interface{}) (string, error) {
|
||||
ctx := &Context{readFile: func(filename string) ([]byte, error) {
|
||||
ctx := &Context{fs: &ffs.FileSystem{ReadFile: func(filename string) ([]byte, error) {
|
||||
return nil, fmt.Errorf("unexpected call to readFile: filename=%s", filename)
|
||||
}}
|
||||
}}}
|
||||
tplString, err := ctx.RenderTemplateToBuffer(s, data...)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
|
|||
|
|
@ -3,43 +3,43 @@ package tmpl
|
|||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/helmfile/helmfile/pkg/filesystem"
|
||||
)
|
||||
|
||||
type FileRenderer struct {
|
||||
ReadFile func(string) ([]byte, error)
|
||||
Context *Context
|
||||
Data interface{}
|
||||
fs *filesystem.FileSystem
|
||||
Context *Context
|
||||
Data interface{}
|
||||
}
|
||||
|
||||
func NewFileRenderer(readFile func(filename string) ([]byte, error), basePath string, data interface{}) *FileRenderer {
|
||||
func NewFileRenderer(fs *filesystem.FileSystem, basePath string, data interface{}) *FileRenderer {
|
||||
return &FileRenderer{
|
||||
ReadFile: readFile,
|
||||
fs: fs,
|
||||
Context: &Context{
|
||||
basePath: basePath,
|
||||
readFile: readFile,
|
||||
readDir: os.ReadDir,
|
||||
fs: fs,
|
||||
},
|
||||
Data: data,
|
||||
}
|
||||
}
|
||||
|
||||
func NewFirstPassRenderer(basePath string, data interface{}) *FileRenderer {
|
||||
fs := filesystem.DefaultFileSystem()
|
||||
return &FileRenderer{
|
||||
ReadFile: os.ReadFile,
|
||||
fs: fs,
|
||||
Context: &Context{
|
||||
preRender: true,
|
||||
basePath: basePath,
|
||||
readFile: os.ReadFile,
|
||||
readDir: os.ReadDir,
|
||||
fs: fs,
|
||||
},
|
||||
Data: data,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *FileRenderer) RenderTemplateFileToBuffer(file string) (*bytes.Buffer, error) {
|
||||
content, err := r.ReadFile(file)
|
||||
content, err := r.fs.ReadFile(file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -60,7 +60,7 @@ func (r *FileRenderer) RenderToBytes(path string) ([]byte, error) {
|
|||
yamlBytes = yamlBuf.Bytes()
|
||||
} else {
|
||||
var err error
|
||||
yamlBytes, err = r.ReadFile(path)
|
||||
yamlBytes, err = r.fs.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load [%s]: %v", path, err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/helmfile/helmfile/pkg/environment"
|
||||
"github.com/helmfile/helmfile/pkg/filesystem"
|
||||
)
|
||||
|
||||
var emptyEnvTmplData = map[string]interface{}{
|
||||
|
|
@ -23,7 +24,7 @@ func TestRenderToBytes_Gotmpl(t *testing.T) {
|
|||
`
|
||||
dataFile := "data.txt"
|
||||
valuesTmplFile := "values.yaml.gotmpl"
|
||||
r := NewFileRenderer(func(filename string) ([]byte, error) {
|
||||
r := NewFileRenderer(&filesystem.FileSystem{ReadFile: func(filename string) ([]byte, error) {
|
||||
switch filename {
|
||||
case valuesTmplFile:
|
||||
return []byte(valuesYamlTmplContent), nil
|
||||
|
|
@ -31,7 +32,7 @@ func TestRenderToBytes_Gotmpl(t *testing.T) {
|
|||
return []byte(dataFileContent), nil
|
||||
}
|
||||
return nil, fmt.Errorf("unexpected filename: expected=%v or %v, actual=%s", dataFile, valuesTmplFile, filename)
|
||||
}, "", emptyEnvTmplData)
|
||||
}}, "", emptyEnvTmplData)
|
||||
buf, err := r.RenderToBytes(valuesTmplFile)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
|
|
@ -50,12 +51,12 @@ func TestRenderToBytes_Yaml(t *testing.T) {
|
|||
bar: '{{ readFile "data.txt" }}'
|
||||
`
|
||||
valuesFile := "values.yaml"
|
||||
r := NewFileRenderer(func(filename string) ([]byte, error) {
|
||||
r := NewFileRenderer(&filesystem.FileSystem{ReadFile: func(filename string) ([]byte, error) {
|
||||
if filename == valuesFile {
|
||||
return []byte(valuesYamlContent), nil
|
||||
}
|
||||
return nil, fmt.Errorf("unexpected filename: expected=%v, actual=%s", valuesFile, filename)
|
||||
}, "", emptyEnvTmplData)
|
||||
}}, "", emptyEnvTmplData)
|
||||
buf, err := r.RenderToBytes(valuesFile)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
package tmpl
|
||||
|
||||
import (
|
||||
"github.com/helmfile/helmfile/pkg/filesystem"
|
||||
)
|
||||
|
||||
type templateTextRenderer struct {
|
||||
ReadText func(string) ([]byte, error)
|
||||
Context *Context
|
||||
|
|
@ -11,12 +15,12 @@ type TextRenderer interface {
|
|||
}
|
||||
|
||||
// nolint: golint
|
||||
func NewTextRenderer(readFile func(filename string) ([]byte, error), basePath string, data interface{}) *templateTextRenderer {
|
||||
func NewTextRenderer(fs *filesystem.FileSystem, basePath string, data interface{}) *templateTextRenderer {
|
||||
return &templateTextRenderer{
|
||||
ReadText: readFile,
|
||||
ReadText: fs.ReadFile,
|
||||
Context: &Context{
|
||||
basePath: basePath,
|
||||
readFile: readFile,
|
||||
fs: fs,
|
||||
},
|
||||
Data: data,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
package tmpl
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/helmfile/helmfile/pkg/filesystem"
|
||||
)
|
||||
|
||||
// TestTextRenderer tests the text renderer.
|
||||
|
|
@ -12,7 +13,7 @@ func TestNewTextRenderer(t *testing.T) {
|
|||
tData := map[string]interface{}{
|
||||
"foo": "bar",
|
||||
}
|
||||
tr := NewTextRenderer(os.ReadFile, ".", tData)
|
||||
tr := NewTextRenderer(filesystem.DefaultFileSystem(), ".", tData)
|
||||
require.Equal(t, tData, tr.Data)
|
||||
require.Equal(t, ".", tr.Context.basePath)
|
||||
}
|
||||
|
|
@ -22,7 +23,7 @@ func TestTextRender(t *testing.T) {
|
|||
tData := map[string]interface{}{
|
||||
"foot": "bart",
|
||||
}
|
||||
tr := NewTextRenderer(os.ReadFile, ".", tData)
|
||||
tr := NewTextRenderer(filesystem.DefaultFileSystem(), ".", tData)
|
||||
|
||||
tests := []struct {
|
||||
text string
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/helmfile/helmfile/pkg/filesystem"
|
||||
"github.com/helmfile/helmfile/pkg/tmpl"
|
||||
)
|
||||
|
||||
|
|
@ -276,7 +277,7 @@ func TestFileRendering(t *testing.T) {
|
|||
|
||||
filename := fmt.Sprintf("%s/%s.gotmpl", tempDir, tc.name)
|
||||
os.WriteFile(filename, []byte(tc.tmplString), 0644)
|
||||
fileRenderer := tmpl.NewFileRenderer(os.ReadFile, ".", tc.data)
|
||||
fileRenderer := tmpl.NewFileRenderer(filesystem.DefaultFileSystem(), ".", tc.data)
|
||||
tmpl_bytes, err := fileRenderer.RenderToBytes(filename)
|
||||
|
||||
if tc.wantErr {
|
||||
|
|
@ -294,8 +295,7 @@ func TestFileRendering(t *testing.T) {
|
|||
func TestTmplStrings(t *testing.T) {
|
||||
c := &tmpl.Context{}
|
||||
c.SetBasePath(".")
|
||||
c.SetReadFile(os.ReadFile)
|
||||
c.SetReadDir(os.ReadDir)
|
||||
c.SetFileSystem(filesystem.DefaultFileSystem())
|
||||
tmpl := template.New("stringTemplateTest").Funcs(c.CreateFuncMap())
|
||||
|
||||
tmplE2eTest.load()
|
||||
|
|
|
|||
Loading…
Reference in New Issue