github.com/cyverse/go-irodsclient@v0.13.2/irods/util/irods_path.go (about)

     1  package util
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path"
     7  	"path/filepath"
     8  	"sort"
     9  	"strings"
    10  
    11  	"golang.org/x/xerrors"
    12  )
    13  
    14  // MakeIRODSPath makes the path from collection and data object
    15  func MakeIRODSPath(collectionPath string, dataobjectName string) string {
    16  	if strings.HasSuffix(collectionPath, "/") {
    17  		return fmt.Sprintf("%s/%s", collectionPath[0:len(collectionPath)-1], dataobjectName)
    18  	}
    19  	return fmt.Sprintf("%s/%s", collectionPath, dataobjectName)
    20  }
    21  
    22  // SplitIRODSPath splits the path into dir and file
    23  func SplitIRODSPath(p string) (string, string) {
    24  	return path.Split(p)
    25  }
    26  
    27  // GetIRODSPathDirname returns the dir of the path
    28  func GetIRODSPathDirname(p string) string {
    29  	return path.Dir(p)
    30  }
    31  
    32  // GetIRODSPathFileName returns the filename of the path
    33  func GetIRODSPathFileName(p string) string {
    34  	return path.Base(p)
    35  }
    36  
    37  // GetIRODSZone returns the zone of the path
    38  func GetIRODSZone(p string) (string, error) {
    39  	if len(p) == 0 || p[0] != '/' {
    40  		return "", xerrors.Errorf("cannot extract Zone from path %s", p)
    41  	}
    42  
    43  	parts := strings.Split(p[1:], "/")
    44  	if len(parts) >= 1 {
    45  		return parts[0], nil
    46  	}
    47  	return "", xerrors.Errorf("cannot extract Zone from path %s", p)
    48  }
    49  
    50  // GetCorrectIRODSPath corrects the path
    51  func GetCorrectIRODSPath(p string) string {
    52  	if p == "" || p == "/" {
    53  		return "/"
    54  	}
    55  
    56  	newPath := path.Clean(p)
    57  	if !strings.HasPrefix(newPath, "/") {
    58  		newPath = fmt.Sprintf("/%s", newPath)
    59  		newPath = path.Clean(newPath)
    60  	}
    61  	return newPath
    62  }
    63  
    64  // GetIRODSPathDepth returns depth of the path
    65  // "/" returns 0
    66  // "abc" returns -1
    67  // "/abc" returns 0
    68  // "/a/b" returns 1
    69  // "/a/b/c" returns 2
    70  func GetIRODSPathDepth(p string) int {
    71  	if !strings.HasPrefix(p, "/") {
    72  		return -1
    73  	}
    74  
    75  	cleanPath := path.Clean(p)
    76  
    77  	if cleanPath == "/" {
    78  		return 0
    79  	}
    80  
    81  	pArr := strings.Split(p[1:], "/")
    82  	return len(pArr) - 1
    83  }
    84  
    85  // GetParentDirs returns all parent dirs
    86  func GetParentIRODSDirs(p string) []string {
    87  	parents := []string{}
    88  
    89  	if p == "/" {
    90  		return parents
    91  	}
    92  
    93  	curPath := p
    94  	for len(curPath) > 0 && curPath != "/" {
    95  		curDir := path.Dir(curPath)
    96  		if len(curDir) > 0 {
    97  			parents = append(parents, curDir)
    98  		}
    99  
   100  		curPath = curDir
   101  	}
   102  
   103  	// sort
   104  	sort.Slice(parents, func(i int, j int) bool {
   105  		return len(parents[i]) < len(parents[j])
   106  	})
   107  
   108  	return parents
   109  }
   110  
   111  // GetRelativePath returns relative path
   112  func GetRelativeIRODSPath(base string, target string) (string, error) {
   113  	osBase := strings.ReplaceAll(base, "/", string(os.PathSeparator))
   114  	osTarget := strings.ReplaceAll(target, "/", string(os.PathSeparator))
   115  
   116  	rel, err := filepath.Rel(osBase, osTarget)
   117  	if err != nil {
   118  		return "", xerrors.Errorf("failed to calculate relative path from %s to %s: %w", osBase, osTarget, err)
   119  	}
   120  	return filepath.ToSlash(rel), nil
   121  }