refactor(filesystem): add CopyDir method and optimize Fetch function
Signed-off-by: yxxhero <aiopsclub@163.com>
This commit is contained in:
parent
b0911ab1a2
commit
fb467f38c8
|
|
@ -45,7 +45,7 @@ linters:
|
||||||
lines: 280
|
lines: 280
|
||||||
statements: 140
|
statements: 140
|
||||||
gocognit:
|
gocognit:
|
||||||
min-complexity: 100
|
min-complexity: 110
|
||||||
goconst:
|
goconst:
|
||||||
min-len: 3
|
min-len: 3
|
||||||
min-occurrences: 8
|
min-occurrences: 8
|
||||||
|
|
|
||||||
|
|
@ -345,8 +345,7 @@ func (a *App) Fetch(c FetchConfigProvider) error {
|
||||||
OutputDir: c.OutputDir(),
|
OutputDir: c.OutputDir(),
|
||||||
OutputDirTemplate: c.OutputDirTemplate(),
|
OutputDirTemplate: c.OutputDirTemplate(),
|
||||||
Concurrency: c.Concurrency(),
|
Concurrency: c.Concurrency(),
|
||||||
}, func() {
|
}, func() {})
|
||||||
})
|
|
||||||
|
|
||||||
if prepErr != nil {
|
if prepErr != nil {
|
||||||
errs = append(errs, prepErr)
|
errs = append(errs, prepErr)
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -36,6 +37,7 @@ type FileSystem struct {
|
||||||
Chdir func(string) error
|
Chdir func(string) error
|
||||||
Abs func(string) (string, error)
|
Abs func(string) (string, error)
|
||||||
EvalSymlinks func(string) (string, error)
|
EvalSymlinks func(string) (string, error)
|
||||||
|
CopyDir func(src, dst string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func DefaultFileSystem() *FileSystem {
|
func DefaultFileSystem() *FileSystem {
|
||||||
|
|
@ -55,6 +57,7 @@ func DefaultFileSystem() *FileSystem {
|
||||||
dfs.DirectoryExistsAt = dfs.directoryExistsDefault
|
dfs.DirectoryExistsAt = dfs.directoryExistsDefault
|
||||||
dfs.FileExists = dfs.fileExistsDefault
|
dfs.FileExists = dfs.fileExistsDefault
|
||||||
dfs.Abs = dfs.absDefault
|
dfs.Abs = dfs.absDefault
|
||||||
|
dfs.CopyDir = dfs.copyDirDefault
|
||||||
return &dfs
|
return &dfs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -100,6 +103,9 @@ func FromFileSystem(params FileSystem) *FileSystem {
|
||||||
if params.Dir != nil {
|
if params.Dir != nil {
|
||||||
dfs.Dir = params.Dir
|
dfs.Dir = params.Dir
|
||||||
}
|
}
|
||||||
|
if params.CopyDir != nil {
|
||||||
|
dfs.CopyDir = params.CopyDir
|
||||||
|
}
|
||||||
return dfs
|
return dfs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -180,3 +186,121 @@ func (filesystem *FileSystem) absDefault(path string) (string, error) {
|
||||||
}
|
}
|
||||||
return filepath.Abs(path)
|
return filepath.Abs(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1372,6 +1372,18 @@ func (st *HelmState) PrepareCharts(helm helmexec.Interface, dir string, concurre
|
||||||
// for a remote chart, so that the user can notice/fix the issue in a local chart while
|
// for a remote chart, so that the user can notice/fix the issue in a local chart while
|
||||||
// a broken remote chart won't completely block their job.
|
// a broken remote chart won't completely block their job.
|
||||||
chartPath = normalizedChart
|
chartPath = normalizedChart
|
||||||
|
if helmfileCommand == "pull" {
|
||||||
|
// copy chart to a temporary directory
|
||||||
|
chartPath, err = generateChartPath(chartName, dir, release, opts.OutputDirTemplate)
|
||||||
|
if err != nil {
|
||||||
|
results <- &chartPrepareResult{err: err}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := st.fs.CopyDir(normalizedChart, chartPath); err != nil {
|
||||||
|
results <- &chartPrepareResult{err: err}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
buildDeps = !skipDeps
|
buildDeps = !skipDeps
|
||||||
} else if !opts.ForceDownload {
|
} else if !opts.ForceDownload {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue