From af2ebbcc0acc93b9f98df36edff01f2b59076f32 Mon Sep 17 00:00:00 2001 From: Illyoung Choi Date: Tue, 17 Dec 2024 15:08:14 -0700 Subject: [PATCH] Fix a bug in getting parent dirs on Windows --- cmd/subcmd/bput.go | 4 +-- cmd/subcmd/cp.go | 4 +-- cmd/subcmd/get.go | 4 +-- cmd/subcmd/put.go | 4 +-- commons/path.go | 84 ++++++++++++++++++++++++++++++---------------- 5 files changed, 64 insertions(+), 36 deletions(-) diff --git a/cmd/subcmd/bput.go b/cmd/subcmd/bput.go index 9b64ccf..bb5610d 100644 --- a/cmd/subcmd/bput.go +++ b/cmd/subcmd/bput.go @@ -432,7 +432,7 @@ func (bput *BputCommand) putFile(sourceStat fs.FileInfo, sourcePath string) erro return xerrors.Errorf("failed to get target path for source %q: %w", sourcePath, err) } - commons.MarkPathMap(bput.updatedPathMap, targetPath) + commons.MarkIRODSPathMap(bput.updatedPathMap, targetPath) targetEntry, err := bput.filesystem.Stat(targetPath) if err != nil { @@ -596,7 +596,7 @@ func (bput *BputCommand) putDir(_ fs.FileInfo, sourcePath string) error { return xerrors.Errorf("failed to get target path for source %q: %w", sourcePath, err) } - commons.MarkPathMap(bput.updatedPathMap, targetPath) + commons.MarkIRODSPathMap(bput.updatedPathMap, targetPath) targetEntry, err := bput.filesystem.Stat(targetPath) if err != nil { diff --git a/cmd/subcmd/cp.go b/cmd/subcmd/cp.go index 5651f3f..1090e12 100644 --- a/cmd/subcmd/cp.go +++ b/cmd/subcmd/cp.go @@ -320,7 +320,7 @@ func (cp *CpCommand) copyFile(sourceEntry *irodsclient_fs.Entry, targetPath stri "function": "copyFile", }) - commons.MarkPathMap(cp.updatedPathMap, targetPath) + commons.MarkIRODSPathMap(cp.updatedPathMap, targetPath) targetEntry, err := cp.filesystem.Stat(targetPath) if err != nil { @@ -476,7 +476,7 @@ func (cp *CpCommand) copyFile(sourceEntry *irodsclient_fs.Entry, targetPath stri } func (cp *CpCommand) copyDir(sourceEntry *irodsclient_fs.Entry, targetPath string) error { - commons.MarkPathMap(cp.updatedPathMap, targetPath) + commons.MarkIRODSPathMap(cp.updatedPathMap, targetPath) targetEntry, err := cp.filesystem.Stat(targetPath) if err != nil { diff --git a/cmd/subcmd/get.go b/cmd/subcmd/get.go index 8442639..9ec9ca7 100644 --- a/cmd/subcmd/get.go +++ b/cmd/subcmd/get.go @@ -447,7 +447,7 @@ func (get *GetCommand) getFile(sourceEntry *irodsclient_fs.Entry, tempPath strin "function": "getFile", }) - commons.MarkPathMap(get.updatedPathMap, targetPath) + commons.MarkLocalPathMap(get.updatedPathMap, targetPath) targetStat, err := os.Stat(targetPath) if err != nil { @@ -617,7 +617,7 @@ func (get *GetCommand) getFile(sourceEntry *irodsclient_fs.Entry, tempPath strin } func (get *GetCommand) getDir(sourceEntry *irodsclient_fs.Entry, targetPath string) error { - commons.MarkPathMap(get.updatedPathMap, targetPath) + commons.MarkLocalPathMap(get.updatedPathMap, targetPath) targetStat, err := os.Stat(targetPath) if err != nil { diff --git a/cmd/subcmd/put.go b/cmd/subcmd/put.go index dfd6f52..24e0cac 100644 --- a/cmd/subcmd/put.go +++ b/cmd/subcmd/put.go @@ -455,7 +455,7 @@ func (put *PutCommand) putFile(sourceStat fs.FileInfo, sourcePath string, tempPa "function": "putFile", }) - commons.MarkPathMap(put.updatedPathMap, targetPath) + commons.MarkIRODSPathMap(put.updatedPathMap, targetPath) targetEntry, err := put.filesystem.Stat(targetPath) if err != nil { @@ -615,7 +615,7 @@ func (put *PutCommand) putFile(sourceStat fs.FileInfo, sourcePath string, tempPa } func (put *PutCommand) putDir(_ fs.FileInfo, sourcePath string, targetPath string, parentEncryption bool, parentEncryptionMode commons.EncryptionMode) error { - commons.MarkPathMap(put.updatedPathMap, targetPath) + commons.MarkIRODSPathMap(put.updatedPathMap, targetPath) targetEntry, err := put.filesystem.Stat(targetPath) if err != nil { diff --git a/commons/path.go b/commons/path.go index affd246..58acccc 100644 --- a/commons/path.go +++ b/commons/path.go @@ -10,6 +10,7 @@ import ( irodsclient_fs "github.com/cyverse/go-irodsclient/fs" irodsclient_types "github.com/cyverse/go-irodsclient/irods/types" + log "github.com/sirupsen/logrus" "golang.org/x/xerrors" ) @@ -102,7 +103,7 @@ func GetBasename(p string) string { return p[idx2+1:] } -// GetParentDirs returns all parent dirs +// GetParentIRODSDirs returns all parent dirs func GetParentIRODSDirs(p string) []string { parents := []string{} @@ -128,6 +129,48 @@ func GetParentIRODSDirs(p string) []string { return parents } +// GetParentLocalDirs returns all parent dirs +func GetParentLocalDirs(p string) []string { + logger := log.WithFields(log.Fields{ + "package": "commons", + "function": "GetParentLocalDirs", + }) + + parents := []string{} + + if p == string(os.PathSeparator) { + return parents + } + + absPath, _ := filepath.Abs(p) + if filepath.Dir(absPath) == absPath { + return parents + } + + curPath := absPath + logger.Infof("curPath = %s", curPath) + for len(curPath) > 0 { + curDir := filepath.Dir(curPath) + if curDir == curPath { + // root + break + } + + if len(curDir) > 0 { + parents = append(parents, curDir) + } + + curPath = curDir + } + + // sort + sort.Slice(parents, func(i int, j int) bool { + return len(parents[i]) < len(parents[j]) + }) + + return parents +} + func FirstDelimeterIndex(p string) int { idx1 := strings.Index(p, string(os.PathSeparator)) idx2 := strings.Index(p, "/") @@ -176,32 +219,6 @@ func GetDir(p string) string { return p[:idx2] } -// GetParentLocalDirs returns all parent dirs -func GetParentLocalDirs(p string) []string { - parents := []string{} - - if p == string(os.PathSeparator) || p == "." { - return parents - } - - curPath := p - for len(curPath) > 0 && curPath != string(os.PathSeparator) && curPath != "." { - curDir := filepath.Dir(curPath) - if len(curDir) > 0 && curDir != "." { - parents = append(parents, curDir) - } - - curPath = curDir - } - - // sort - sort.Slice(parents, func(i int, j int) bool { - return len(parents[i]) < len(parents[j]) - }) - - return parents -} - func commonPrefix(sep byte, paths ...string) string { // Handle special cases. switch len(paths) { @@ -311,8 +328,19 @@ func ExistFile(p string) bool { return false } -func MarkPathMap(pathMap map[string]bool, p string) { +func MarkLocalPathMap(pathMap map[string]bool, p string) { + dirs := GetParentLocalDirs(p) + + for _, dir := range dirs { + pathMap[dir] = true + } + + pathMap[p] = true +} + +func MarkIRODSPathMap(pathMap map[string]bool, p string) { dirs := GetParentIRODSDirs(p) + for _, dir := range dirs { pathMap[dir] = true }