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  }