pfs

package
v0.4.171 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 12, 2024 License: ISC Imports: 12 Imported by: 3

Documentation

Overview

Package pfs provides a symlink-following file-systemtraverser and other file-system functions.

Index

Constants

View Source
const (
	// AllModeBits is all known github.com/fsnotify/fsevents.EventFlags
	AllModeBits fs.FileMode = fs.ModeDir | fs.ModeAppend | fs.ModeExclusive |
		fs.ModeTemporary | fs.ModeSymlink | fs.ModeDevice | fs.ModeNamedPipe |
		fs.ModeSocket | fs.ModeSetuid | fs.ModeSetgid | fs.ModeCharDevice |
		fs.ModeSticky | fs.ModeIrregular
)
View Source
const (
	// [DirectoryOrder]
	NoSorting = false
)
View Source
const (
	// do not evaluate symlinks argument to [AbsEval]
	RetainSymlinks = true
)

Variables

This section is empty.

Functions

func Abs added in v0.4.23

func Abs(dir string) (out string)

Abs ensures a file system path is fully qualified. Abs is single-return-value and panics on troubles

func AbsEval

func AbsEval(path string, retainSymlinks ...bool) (absPath string, err error)

AbsEval returns an absolute path with resolved symlinks

  • if symlinks are evaluated, the path must exist
  • non-existing path is checked using punix.IsENOENT(err)
  • if path is relative, the process’ current directory is used to make path absolute. path empty returns the process’ current directory as absolute evaled path
  • absPath is absolute and only empty on error
  • absPath is clean:
  • — no multiple Separators in sequence
  • — no “.” path name elements
  • — no infix or postfix “..” path name element or to path above root
  • when evaluating symlinks, the path is verified to exist
  • if retainSymlinks is RetainSymlinks, symlinks are returned
  • errors originate from:
  • os.Lstat os.Readlink os.Getwd or
  • — infix path-segment not directory or
  • — encountering more than 255 symlinks

func AddDirEntry added in v0.4.138

func AddDirEntry(abs string) (dirEntry fs.DirEntry, err error)

AddDirEntry returns an fs.DirEntry with fs.FileInfo available

func AddStatDirEntry added in v0.4.138

func AddStatDirEntry(abs string) (dirEntry fs.DirEntry, err error)

AddDirEntry returns an fs.DirEntry for the target of a symbolic link

func Exists

func Exists(path string) (fileInfo fs.FileInfo)

Exists determines if a path exists If the path exists, fileInfo is non-nil if the path does not exist, fileInfo is nil panic on troubles

func Exists2 added in v0.4.127

func Exists2(path string) (fileInfo fs.FileInfo, isNotExist bool, err error)

Exists2 determines if a path exists

  • fileInfo non-nil: does exist
  • isNotExists true, fileInfo nil, err non-nil: does not exist
  • isNotExist false, fileInfo nil, err non-nil: some error

func GetModeBitValues

func GetModeBitValues() (s string)

func IsDirectory

func IsDirectory(path string, flags IsDirectoryArg) (isDirectory bool, err error)

IsDirectory determines if path exists, is directory or another type of file-system entry

  • path may be relative, contain symlinks or be unclean
  • isDirectory is true if path exists and is directory. Non-existing path is not an error.
  • if IsDirectoryNonExistentIsError is present, non-existing path returns error
  • if IsDirectoryNotDirIsError is present, a file-system entry that is not directory returns error
  • flags is bitfield: IsDirectoryNonExistentIsError | IsDirectoryNotDirIsError
  • symlinks are followed os.Stat

func NewDirEntryIterator added in v0.4.148

func NewDirEntryIterator(path string) (iterator iters.Iterator[DirEntry])

func NewDirIterator added in v0.4.141

func NewDirIterator(path string) (iterator iters.Iterator[ResultEntry])

NewIterator returns an iterator for a file-system entry and any child entries if directory

  • path is the initial path for the file-system walk. it may be relative or absolute, contain symlinks and point to a file, directory or special file
  • only directories are returned. if directories are not skipped, they descended into.
  • symlinks are followed. Broken symlinks are ignored.
  • any errored file-system entry cancels the iterator with error.

func NewIterator added in v0.4.138

func NewIterator(path string) (iterator iters.Iterator[ResultEntry])

NewIterator returns an iterator for a file-system entry and any child entries if directory

  • path is the initial path for the file-system walk. it may be relative or absolute, contain symlinks and point to a file, directory or special file
  • if symlinks and directories are not skipped, they are followed
  • all errors during traversal are provided as is

func ReadDir added in v0.4.148

func ReadDir(abs string, sort ...bool) (entries []fs.DirEntry, err error)

directoryOrder returns unsorted entries, most with deferred fs.FileInfo

func Stat

func Stat(path string) (fileInfo fs.FileInfo, err error)

Types

type DeferringDirEntry added in v0.4.138

type DeferringDirEntry struct {
	// contains filtered or unexported fields
}

func NewDeferringDirEntry added in v0.4.138

func NewDeferringDirEntry(abs string) (entry *DeferringDirEntry)

NewDeferringDirEntry returns fs.DirEntry with fs.FileInfo deferred

  • abs is absolute path that maybe does not exist

func (*DeferringDirEntry) Info added in v0.4.138

func (e *DeferringDirEntry) Info() (fileInfo fs.FileInfo, err error)

Info returns the FileInfo for the file or subdirectory described by the entry

func (*DeferringDirEntry) IsDir added in v0.4.138

func (e *DeferringDirEntry) IsDir() (isDir bool)

IsDir reports whether the entry is a directory, ie. ModeDir bit being set

  • may panic unless Info has successfully completed

func (*DeferringDirEntry) Name added in v0.4.138

func (e *DeferringDirEntry) Name() (base string)

base name of the file

func (*DeferringDirEntry) Type added in v0.4.138

func (e *DeferringDirEntry) Type() (modeType fs.FileMode)

Type returns ModeType bits, 0 for regular file

  • ModeDir ModeSymlink ModeNamedPipe ModeSocket ModeDevice ModeCharDevice ModeIrregular

type DirEntry added in v0.4.148

type DirEntry struct {
	fs.DirEntry
	ProvidedPath string
}

type DirEntryIterator added in v0.4.148

type DirEntryIterator struct {
	iters.BaseIterator[DirEntry]
	// contains filtered or unexported fields
}

func (*DirEntryIterator) Init added in v0.4.148

func (i *DirEntryIterator) Init() (result DirEntry, iterator iters.Iterator[DirEntry])

Init implements the right-hand side of a short variable declaration in the init statement of a Go “for” clause

	for i, iterator := iters.NewSlicePointerIterator(someSlice).Init(); iterator.Cond(&i); {
   // i is pointer to slice element

type DirIterator added in v0.4.141

type DirIterator struct {

	// BaseIterator provides iterator methods:
	// [iters.Iterator.Cancel] [iters.Iterator.Cond] [iters.Iterator.Next]
	iters.BaseIterator[ResultEntry]
	// contains filtered or unexported fields
}

DirIterator traverses file-system directories

func (*DirIterator) Init added in v0.4.141

func (i *DirIterator) Init() (result ResultEntry, iterator iters.Iterator[ResultEntry])

Init implements the right-hand side of a short variable declaration in the init statement of a Go “for” clause

	for i, iterator := iters.NewSlicePointerIterator(someSlice).Init(); iterator.Cond(&i); {
   // i is pointer to slice element

type FileMode

type FileMode struct {
	fs.FileMode
}

func (FileMode) Ch

func (fm FileMode) Ch() (s string)

func (FileMode) Check

func (fm FileMode) Check() (str string)

Check returns hex string of unknown bits, empty string if no unknown bits

func (FileMode) Hex

func (fm FileMode) Hex() (s string)

func (FileMode) Hex8

func (fm FileMode) Hex8() (s string)

func (FileMode) Or

func (fm FileMode) Or() (s string)

func (FileMode) String

func (fm FileMode) String() (s string)

type IsDirectoryArg

type IsDirectoryArg uint8

bitfield argument to IsDirectory

  • IsDirectoryNonExistentIsError IsDirectoryNotDirIsError
const (
	// if path does not exist, return the error [IsDirectory]
	IsDirectoryNonExistentIsError IsDirectoryArg = 1 << iota
	// if existing path is not directory, return an error [IsDirectory]
	//	- symlinks are followed, so a symlink pointing ot directory is ok
	IsDirectoryNotDirIsError
)

type Iterator added in v0.4.138

type Iterator struct {

	// BaseIterator provides iterator methods:
	// [iters.Iterator.Cancel] [iters.Iterator.Cond] [iters.Iterator.Next]
	iters.BaseIterator[ResultEntry]
	// contains filtered or unexported fields
}

Iterator traverses file-system entries and errors

func (*Iterator) Init added in v0.4.138

func (i *Iterator) Init() (result ResultEntry, iterator iters.Iterator[ResultEntry])

Init implements the right-hand side of a short variable declaration in the init statement of a Go “for” clause

	for i, iterator := iters.NewSlicePointerIterator(someSlice).Init(); iterator.Cond(&i); {
   // i is pointer to slice element

type Registry added in v0.4.138

type Registry[V any] struct {
	// contains filtered or unexported fields
}

Registry stores values that are accessible by index or by absolute path

func NewRegistry added in v0.4.138

func NewRegistry[V any]() (registry *Registry[V])

NewRegistry returns a registry of values by absolute path

func (*Registry[V]) Add added in v0.4.138

func (r *Registry[V]) Add(abs string, value *V)

Add adds a value to the registry

func (*Registry[V]) GetValue added in v0.4.138

func (r *Registry[V]) GetValue(index int) (value *V)

GetValue retrieves value by index

  • if index is less than 0 or too large or for a removed value, nil is returned

func (*Registry[V]) HasAbs added in v0.4.138

func (r *Registry[V]) HasAbs(abs string) (hasAbs bool)

HasAbs check whether an absolute path is stored in the registry as a key to a value

func (*Registry[V]) ListLength added in v0.4.138

func (r *Registry[V]) ListLength() (length int)

ListLength returns the length of the value slice

  • a value can still be nil for a discarded root

func (*Registry[V]) ObsoleteIndex added in v0.4.138

func (r *Registry[V]) ObsoleteIndex(index int)

type ResultEntry added in v0.4.138

type ResultEntry struct {
	//	- always non-nil
	//	- may be deferred-info executing [os.Lstat] every time, ie. only invoke Info once
	//	- if Err is non-nil, Info may return error
	fs.DirEntry
	// path as provided that may be easier to read
	//   - may be implicitly relative to current directory: “subdir/file.txt”
	//   - may have no directory or extension part: “README.css” “z”
	//   - may be relative: “../file.txt”
	//   - may contain symlinks, unnecessary “.” and “..” or
	//		multiple separators in sequence
	//	- may be empty string for current working directory
	ProvidedPath string
	//	- equivalent of Path: absolute, symlink-free, clean
	//	- if Err non-nil, may be empty
	//	- if the entry is symbolic link:
	//	- — ProvidedPath is the symbolic link location
	//	- — Abs is what the symbolic link points to
	Abs string
	// function to skip descending into directory or following symlink
	SkipEntry func(no uint64)
	// skippable serial number
	No uint64
	// any error associated with this entry
	Err error
	// why this entry was provided
	//	- REnd REntry RSkippable RDirBad RSymlinkBad RError
	Reason ResultReason
}

ResultEntry is an existing file-system entry, traversal-end marker or an error-entry during file-system traversal

  • non-error non-end file-system entries have been proven to exist
  • ResultEntry.IsEnd or Reason == REnd indicates end
  • Reson indicates why the ResultEntry was returned:
  • REnd REntry RSkippable RDirBad RSymlinkBad RError
  • ResultEntry is a value-container that as a local variable, function argument or result is a tuple not causing allocation by using temporary stack storage
  • taking the address of a &ResultEntry causes allocation

func (ResultEntry) IsEnd added in v0.4.138

func (e ResultEntry) IsEnd() (isEnd bool)

IsEnd indicates that this ResultEntry is an end of entries marker

func (ResultEntry) Skip added in v0.4.138

func (e ResultEntry) Skip()

Skip marks the returned entry to be skipped

  • the entry is directory or symbolic link
  • can only be invoked when [ResultEntry.Reason] is RSkippable

func (ResultEntry) String added in v0.4.145

func (e ResultEntry) String() (s string)

resultEntry path: "…" abs"/…" err ‘OK’ reason ‘non-symlink non-directory non-error entry’

type ResultReason added in v0.4.138

type ResultReason uint8

Why a directory entry was provided by Traverser

  • REnd REntry RSkippable RDirBad RSymlinkBad RError
const (
	// the filesystem traversal completed all entries
	REnd ResultReason = iota
	// a non-symlink non-directory non-error entry
	REntry
	// a directory or symlink about to be traversed
	RSkippable
	// a directory whose listing failed [os.Open] [os.File.ReadDir]
	RDirBad
	// a broken symlink [os.Stat]
	RSymlinkBad
	// failure in [os.Lstat] [os.Readlink] [os.Getwd]
	RError
)

func (ResultReason) String added in v0.4.138

func (r ResultReason) String() (s string)

type Root2 added in v0.4.138

type Root2 struct {
	// path as provided that may be easier to read
	//   - may be implicitly relative to current directory: “subdir/file.txt”
	//   - may have no directory or extension part: “README.css” “z”
	//   - may be relative: “../file.txt”
	//   - may contain symlinks, unnecessary “.” and “..” or
	//		multiple separators in sequence
	//	- may be empty string for current working directory
	ProvidedPath string
	// Abs is required for relating roots
	//	- equivalent of Path: absolute, symlink-free, clean
	//	- may not exist
	Abs string
}

Root2 is a file system hierarchy

func NewAbsRoot2 added in v0.4.138

func NewAbsRoot2(abs string) (root2 *Root2)

func NewRoot2 added in v0.4.138

func NewRoot2(path string) (root2 *Root2)

NewRoot returns a file-system starting point for traversal

  • path is as-provided path that may be:
  • — absolute or relative
  • — unclean
  • — contain symlinks

func (*Root2) Load added in v0.4.138

func (r *Root2) Load() (err error)

Load obtain the absolute, symlink-resolved path for the root

type Traverser added in v0.4.138

type Traverser struct {
	// contains filtered or unexported fields
}

Traverser represents a file system that is scanned following symlinks

  • each file system entry is returned exactly once except:
  • — error reading a directory returns the directory a second time
  • directories and symlinks are returned before they are read so that they can be more efficiently skipped by invoking ResultEntry.Skip
  • directory entries are returned in 8-bit character order
  • returned entries may not exist, such entries have [ResultEntry.Err] non-nil
  • result.ProvidedPath is based on the initial path and may be relative, unclean and contain symlinks
  • if [ResultEntry.Err] is nil, Abs is absolute, symlink-free clean path
  • ResultEntry.DirEntry.Info typically invokes os.Lstat every time, so this value should be cached
  • because symlinks may point to parents or separate trees, the file system scan may involve multiple roots which may affect the order of return entries
  • symlinks are followed and not returned. Therefore, a symlink pointing to a scanned location is effectively ignored
  • the returned struct is by value. If its address is not taken, no allocation will occur

func NewTraverser added in v0.4.138

func NewTraverser(path string) (traverser *Traverser)

NewTraverser returns a file-system traverser

  • typically used via pfs.Iterator or pfs.DirIterator
  • path is the initial path. Path may be relative or absolute, contain symlinks and be unclean. Path may be of any modeType: file, directory or special file. Empty string means process’ current directory
  • the Next method is used to obtain file-system entries and errors
  • consider using pfs iterators:
  • Iterator for all entries and errors
  • DirIterator for error-free directories

Usage:

var traverser = pfs.NewTraverser(path)
for {
  var result = traverser.Next()
  if result.IsEnd() || result.Err != nil {
    break
  }
  println(result.Abs)
}

func (*Traverser) Next added in v0.4.138

func (t *Traverser) Next() (result ResultEntry)

Next returns the next file-system entry

  • Next ends with [ResultEntry.DirEntry] nil, ie. ResultEntry.IsEnd returns true or ResultEntry.Reason == REnd
  • symlinks and directories can be skipped by invoking ResultEntry.Skip. Those have ResultEntry.Reason == RSkippable
  • symlinks have information based on the symlink source but [ResultEntry.Abs] is the fully resolved symlink target
  • [ResultEntry.ProvidedPath] is a path to the entry based upon the initially provided path. May be empty string
  • [ResultEntry.Abs] is an absolute symlink-free clean path but only available when [ResultEntry.Err] is nil
  • [ResultEntry.Err] holds any error associated with the returned entry
  • result.Err is from:
  • — process working directory cannot be read
  • — directory read error or os.Readlink or os.Lstat failed

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL