From 4ba241e958adcf9ddc3f32de24445eec65498e56 Mon Sep 17 00:00:00 2001 From: yxxhero Date: Sun, 27 Jul 2025 16:36:45 +0800 Subject: [PATCH] fix(state): conditionally prepare charts for local helmfile command Signed-off-by: yxxhero --- pkg/filesystem/fs.go | 118 ++----------------------------------------- pkg/state/state.go | 2 +- 2 files changed, 4 insertions(+), 116 deletions(-) diff --git a/pkg/filesystem/fs.go b/pkg/filesystem/fs.go index 0df2f83e..89bd55ce 100644 --- a/pkg/filesystem/fs.go +++ b/pkg/filesystem/fs.go @@ -5,8 +5,9 @@ import ( "io/fs" "os" "path/filepath" - "strings" "time" + + copyDir "github.com/otiai10/copy" ) type fileStat struct { @@ -189,118 +190,5 @@ func (filesystem *FileSystem) absDefault(path string) (string, error) { // copyDirDefault recursively copies a directory tree, preserving permissions. func (filesystem *FileSystem) copyDirDefault(src string, dst string) error { - src, err := filesystem.EvalSymlinks(src) - if err != nil { - return err - } - - walkFn := func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - - if path == src { - return nil - } - - if strings.HasPrefix(filepath.Base(path), ".") { - // Skip any dot files - if info.IsDir() { - return filepath.SkipDir - } else { - return nil - } - } - - // The "path" has the src prefixed to it. We need to join our - // destination with the path without the src on it. - dstPath := filepath.Join(dst, path[len(src):]) - - // we don't want to try and copy the same file over itself. - if eq, err := SameFile(path, dstPath); eq { - return nil - } else if err != nil { - return err - } - - // If we have a directory, make that subdirectory, then continue - // the walk. - if info.IsDir() { - if path == filepath.Join(src, dst) { - // dst is in src; don't walk it. - return nil - } - - if err := os.MkdirAll(dstPath, 0755); err != nil { - return err - } - - return nil - } - - // If the current path is a symlink, recreate the symlink relative to - // the dst directory - if info.Mode()&os.ModeSymlink == os.ModeSymlink { - target, err := os.Readlink(path) - if err != nil { - return err - } - - return os.Symlink(target, dstPath) - } - - // If we have a file, copy the contents. - srcF, err := os.Open(path) - if err != nil { - return err - } - defer func() { - _ = srcF.Close() - }() - - dstF, err := os.Create(dstPath) - if err != nil { - return err - } - defer func() { - _ = dstF.Close() - }() - - if _, err := io.Copy(dstF, srcF); err != nil { - return err - } - - // Chmod it - return os.Chmod(dstPath, info.Mode()) - } - - return filepath.Walk(src, walkFn) -} - -// SameFile returns true if the two given paths refer to the same physical -// file on disk, using the unique file identifiers from the underlying -// operating system. For example, on Unix systems this checks whether the -// two files are on the same device and have the same inode. -func SameFile(a, b string) (bool, error) { - if a == b { - return true, nil - } - - aInfo, err := os.Lstat(a) - if err != nil { - if os.IsNotExist(err) { - return false, nil - } - return false, err - } - - bInfo, err := os.Lstat(b) - if err != nil { - if os.IsNotExist(err) { - return false, nil - } - return false, err - } - - return os.SameFile(aInfo, bInfo), nil + return copyDir.Copy(src, dst, copyDir.Options{Sync: true}) } diff --git a/pkg/state/state.go b/pkg/state/state.go index fc26c77e..fa355b8f 100644 --- a/pkg/state/state.go +++ b/pkg/state/state.go @@ -1379,7 +1379,7 @@ func (st *HelmState) PrepareCharts(helm helmexec.Interface, dir string, concurre results <- &chartPrepareResult{err: err} return } - if err := st.fs.CopyDir(normalizedChart, chartPath); err != nil { + if err := st.fs.CopyDir(normalizedChart, filepath.Clean(chartPath)); err != nil { results <- &chartPrepareResult{err: err} return }