From 59ee3ce86224ea7332cedeee1c278040af430230 Mon Sep 17 00:00:00 2001 From: yxxhero <11087727+yxxhero@users.noreply.github.com> Date: Wed, 26 Jun 2024 13:03:09 +0800 Subject: [PATCH] fix windows glob issue (#1572) --- pkg/state/state.go | 3 +- pkg/state/storage.go | 16 +++++---- pkg/state/storage_test.go | 75 +++++++++++++++++++++++++++++++++++---- 3 files changed, 81 insertions(+), 13 deletions(-) diff --git a/pkg/state/state.go b/pkg/state/state.go index b0b57362..a7085610 100644 --- a/pkg/state/state.go +++ b/pkg/state/state.go @@ -11,6 +11,7 @@ import ( "os" "path/filepath" "regexp" + "runtime" "sort" "strconv" "strings" @@ -3230,7 +3231,7 @@ func (st *HelmState) setFlags(setValues []SetValue) ([]string, error) { } flags = append(flags, "--set", fmt.Sprintf("%s=%s", escape(set.Name), escape(renderedValue[0]))) } else if set.File != "" { - flags = append(flags, "--set-file", fmt.Sprintf("%s=%s", escape(set.Name), st.storage().normalizePath(set.File))) + flags = append(flags, "--set-file", fmt.Sprintf("%s=%s", escape(set.Name), st.storage().normalizeSetFilePath(set.File, runtime.GOOS))) } else if len(set.Values) > 0 { renderedValues, err := renderValsSecrets(st.valsRuntime, set.Values...) if err != nil { diff --git a/pkg/state/storage.go b/pkg/state/storage.go index 3a471c98..84ebd8c4 100644 --- a/pkg/state/storage.go +++ b/pkg/state/storage.go @@ -4,7 +4,6 @@ import ( "fmt" "net/url" "path/filepath" - "runtime" "sort" "strings" @@ -136,7 +135,7 @@ func (st *Storage) normalizePath(path string) string { if u != nil && (u.Scheme != "" || filepath.IsAbs(path)) { return path } else { - return st.JoinBase(path, runtime.GOOS) + return st.JoinBase(path) } } @@ -144,10 +143,15 @@ func (st *Storage) normalizePath(path string) string { // Helm's setFiles command does not support unescaped filepath separators (\) on Windows. // Instead, it requires double backslashes (\\) as filepath separators. // See https://github.com/helm/helm/issues/9537 -func (st *Storage) JoinBase(relPath, GOOS string) string { +func (st *Storage) JoinBase(relPath string) string { path := filepath.Join(st.basePath, relPath) - if GOOS == "windows" { - return strings.ReplaceAll(path, "\\", "\\\\") - } return path } + +func (st *Storage) normalizeSetFilePath(path, goos string) string { + normalizedPath := st.normalizePath(path) + if goos == "windows" { + return strings.ReplaceAll(normalizedPath, "\\", "\\\\") + } + return normalizedPath +} diff --git a/pkg/state/storage_test.go b/pkg/state/storage_test.go index 6bf66ad0..d84435da 100644 --- a/pkg/state/storage_test.go +++ b/pkg/state/storage_test.go @@ -3,6 +3,7 @@ package state import ( "fmt" "io" + "path/filepath" "reflect" "testing" @@ -176,39 +177,101 @@ func TestJoinBase(t *testing.T) { tests := []struct { name string base string - goos string path string want string }{ { name: "joinBase with non-root base", base: "/root", - goos: "linux", path: "local/timespan-application.yml", want: "/local/timespan-application.yml", }, { name: "joinBase with root path", base: "/", - goos: "linux", path: "data/timespan-application.yml", want: "/data/timespan-application.yml", }, { name: "windows joinBase", base: "", - goos: "windows", path: "data\\timespan-application.yml", - want: "data\\\\timespan-application.yml", + want: "data\\timespan-application.yml", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { storageIns := NewStorage(tt.base, helmexec.NewLogger(io.Discard, "debug"), filesystem.DefaultFileSystem()) - if got := storageIns.JoinBase(tt.path, tt.goos); got != tt.want { + if got := storageIns.JoinBase(tt.path); got != tt.want { t.Errorf("JoinBase() = %v, want %v", got, tt.want) } }) } } + +func TestNormalizeSetFilePath(t *testing.T) { + st := &Storage{ + basePath: "/base/path", + } + + tests := []struct { + name string + path string + expected string + osGOOS string + }{ + { + name: "Unix path on Unix", + path: "relative/path", + expected: "/base/path/relative/path", + osGOOS: "linux", + }, + { + name: "Windows path on Windows", + path: "relative\\path", + expected: "/base/path/relative\\\\path", + osGOOS: "windows", + }, + { + name: "Unix path on Windows", + path: "relative/path", + expected: "/base/path/relative/path", + osGOOS: "windows", + }, + { + name: "Absolute path on Unix", + path: "/absolute/path", + expected: "/absolute/path", + osGOOS: "linux", + }, + { + name: "Absolute path on Windows", + path: "C:\\absolute\\path", + expected: "C:\\\\absolute\\\\path", + osGOOS: "windows", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := st.normalizeSetFilePath(tt.path, tt.osGOOS) + if tt.osGOOS == "windows" { + if result != tt.expected { + t.Errorf("normalizeSetFilePath() = %v, want %v", result, tt.expected) + } + } else { + expectedPath := filepath.Join(st.basePath, tt.path) + if !filepath.IsAbs(tt.path) { + if result != expectedPath { + t.Errorf("normalizeSetFilePath() = %v, want %v", result, expectedPath) + } + } else { + if result != tt.path { + t.Errorf("normalizeSetFilePath() = %v, want %v", result, tt.path) + } + } + } + }) + } +}