github.com/haraldrudell/parl@v0.4.176/pfs/root2.go (about) 1 /* 2 © 2021–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/) 3 ISC License 4 */ 5 6 package pfs 7 8 import ( 9 "path/filepath" 10 11 "github.com/haraldrudell/parl/perrors" 12 ) 13 14 // Root2 is a file system hierarchy 15 type Root2 struct { 16 // path as provided that may be easier to read 17 // - may be implicitly relative to current directory: “subdir/file.txt” 18 // - may have no directory or extension part: “README.css” “z” 19 // - may be relative: “../file.txt” 20 // - may contain symlinks, unnecessary “.” and “..” or 21 // multiple separators in sequence 22 // - may be empty string for current working directory 23 ProvidedPath string 24 // Abs is required for relating roots 25 // - equivalent of Path: absolute, symlink-free, clean 26 // - may not exist 27 Abs string 28 } 29 30 var _ = filepath.Clean 31 32 // NewRoot returns a file-system starting point for traversal 33 // - path is as-provided path that may be: 34 // - — absolute or relative 35 // - — unclean 36 // - — contain symlinks 37 func NewRoot2(path string) (root2 *Root2) { return &Root2{ProvidedPath: path} } 38 39 func NewAbsRoot2(abs string) (root2 *Root2) { return &Root2{ProvidedPath: abs, Abs: abs} } 40 41 // Load obtain the absolute, symlink-resolved path for the root 42 func (r *Root2) Load() (err error) { 43 if r.Abs != "" { 44 return // abs already present return 45 } 46 // absolute version of providedPath 47 var abs string 48 if abs, err = filepath.Abs(r.ProvidedPath); perrors.IsPF(&err, "filepath.Abs %w", err) { 49 // Abs returns error if working directory cannot be determined 50 return // error return 51 } else if r.Abs, err = filepath.EvalSymlinks(abs); perrors.IsPF(&err, "filepath.EvalSymlinks %w", err) { 52 // EvalSymlinks returns error if readlink fails 53 return // error return 54 } 55 56 return // has r.Abs return 57 }