Documentation
¶
Index ¶
- Constants
- Variables
- func ExpandHome(path *string) (err error)
- func GetFirst(paths []string) (content []byte, isDir, ok bool)
- func GetFirstWithRef(paths []string) (content []byte, isDir, ok bool, idx int)
- func MakeDirIfNotExist(path string) (err error)
- func RealPath(path *string) (err error)
- func RealPathExists(path *string) (exists bool, err error)
- func RealPathExistsStat(path *string) (exists bool, stat os.FileInfo, err error)
- func SearchFsPathsAsync(matcher FsSearchCriteriaAsync)
- type FsSearchCriteria
- type FsSearchCriteriaAsync
- type FsSearchResult
Constants ¶
const ( MissNoMiss missReason = "" MissNoMeta missReason = "Could not determine metadata" MissBadBase missReason = "Base name does not match BasePtrn" MissBadPath missReason = "Path does not match PathPtrn" MissBadTime missReason = "Time(s) does not/do not match Age" MissFile missReason = "Object is a file and NoFiles is set" MissType missReason = "Object does not match TargetType" )
Miss reasons
const ( // TimeAccessed == atime TimeAccessed pathTimeType = 1 << iota // TimeCreated == "birth" time (*NOT* ctime! See TimeChanged) TimeCreated // TimeChanged == ctime TimeChanged // TimeModified == mtime TimeModified )
const TimeAny pathTimeType = 0
Times
Variables ¶
var ( ErrNilErrChan error = errors.New("an initialized error channel is required") ErrNilMatchChan error = errors.New("an initialized matches channel is required") ErrNilMismatchChan error = errors.New("an initialized mismatches channel is required") ErrNilWg error = errors.New("a non-nil sync.WaitGroup is required") )
Functions ¶
func ExpandHome ¶
ExpandHome will take a tilde(~)-prefixed path and resolve it to the actual path in-place. "Nested" user paths (~someuser/somechroot/~someotheruser) are not supported as home directories are expected to be absolute paths.
func GetFirst ¶ added in v1.2.0
GetFirst is the file equivalent of envs.GetFirst.
It iterates through paths, normalizing them along the way (so abstracted paths such as ~/foo/bar.txt and relative paths such as bar/baz.txt will still work), and returns the content of the first found existing file. If the first found path is a directory, content will be nil but isDir will be true (as will ok).
If no path exists, ok will be false.
As always, results are not guaranteed due to permissions, etc. potentially returning an inaccurate result.
This is a thin wrapper around GetFirstWithRef.
func GetFirstWithRef ¶ added in v1.2.0
GetFirstWithRef is the file equivalent of envs.GetFirstWithRef.
It behaves exactly like GetFirst, but with an additional returned value, idx, which specifies the index in paths in which a path was found.
As always, results are not guaranteed due to permissions, etc. potentially returning an inaccurate result.
func MakeDirIfNotExist ¶
MakeDirIfNotExist will create a directory at a given path if it doesn't exist.
See also the documentation for RealPath.
This is a bit more sane option than os.MkdirAll as it will normalize paths a little better.
func RealPath ¶
RealPath will transform a given path into the very best guess for an absolute path in-place.
It is recommended to check err (if not nil) for an invalid path error. If this is true, the path syntax/string itself is not supported on the runtime OS. This can be done via:
if errors.Is(err, fs.ErrInvalid) {...}
func RealPathExists ¶
RealPathExists is like RealPath, but will also return a boolean as to whether the path actually exists or not.
Note that err *may* be os.ErrPermission/fs.ErrPermission, in which case the exists value cannot be trusted as a permission error occurred when trying to stat the path - if the calling user/process does not have read permission on e.g. a parent directory, then exists may be false but the path may actually exist. This condition can be checked via via:
if errors.Is(err, fs.ErrPermission) {...}
See also the documentation for RealPath.
In those cases, it may be preferable to use RealPathExistsStat and checking stat for nil.
func RealPathExistsStat ¶
RealPathExistsStat is like RealPathExists except it will also return the os.FileInfo for the path (assuming it exists).
If stat is nil, it is highly recommended to check err via the methods suggested in the documentation for RealPath and RealPathExists.
func SearchFsPathsAsync ¶ added in v1.11.0
func SearchFsPathsAsync(matcher FsSearchCriteriaAsync)
SearchFsPathsAsync is exactly like SearchFsPaths, but dispatches off concurrent workers for the filtering logic instead of performing iteratively/recursively. It may, in some cases, be *slightly more* performant and *slightly less* in others. Note that unlike SearchFsPaths, the results written to the FsSearchCriteriaAsync.ResChan are not guaranteed to be in any predictable order.
All channels are expected to have already been initialized by the caller. They will not be closed by this function.
Types ¶
type FsSearchCriteria ¶ added in v1.12.0
type FsSearchCriteria struct { // Root indicates the root to search. Root string `json:"root" toml:"RootPath" yaml:"Root Path" xml:"root,attr" validate:"dir"` // NoMatch, if true, will not return matches. If NoMatch and NoMismatch are both true, no results will be returned. NoMatch bool `json:"no_match" toml:"NoMatch" yaml:"No Matches" xml:"noMatch,attr"` // NoMismatch, if true, will not return mismatches. If NoMatch and NoMismatch are both true, no results will be returned. NoMismatch bool `json:"no_miss" toml:"NoMismatch" yaml:"No Mismatches" xml:"noMiss,attr"` /* TargetType defines what types of filesystem objects should be matched. It can consist of one or more (io/)fs.FileMode types OR'd together (ensure they are part of (io/)fs.ModeType). (You can use 0 to match regular files explicitly, and/or NoFiles = true to exclude them.) */ TargetType fs.FileMode `json:"type_tgt" toml:"TargetType" yaml:"Target Type" xml:"typeTgt,attr"` // NoFiles excludes files from TargetType-matching (as there isn't a way to explicitly exclude files otherwise if a non-zero mode is given). NoFiles bool `json:"no_file" toml:"ExcludeFiles" yaml:"Exclude Files" xml:"noFile,attr"` // FollowSymlinks, if true and a path being tested is a symlink, will use metadata (age, etc.) of the symlink itself rather than the link target. FollowSymlinks bool `json:"follow_sym" toml:"FollowSymlinks" yaml:"Follow Symlinks" xml:"followSym,attr"` // BasePtrn, if specified, will apply to the *base name (that is, quux.txt rather than /foo/bar/baz/quux.txt). See also PathPtrn. BasePtrn *regexp.Regexp `json:"ptrn_base,omitempty" toml:"BaseNamePattern,omitempty" yaml:"Base Name Pattern,omitempty" xml:"ptrnBase,attr,omitempty"` // PathPtrn, if specified, will apply to the *full path* (e.g. /foo/bar/baz/quux.txt, not just quux.txt). See also BasePtrn. PathPtrn *regexp.Regexp `json:"ptrn_path,omitempty" toml:"PathPattern,omitempty" yaml:"Path Pattern,omitempty" xml:"ptrnPath,attr,omitempty"` /* Age, if specified, indicates the comparison of Now againt the AgeType of filesystem objects. Use OlderThan to indicate if it should be older or newer. */ Age *time.Duration `json:"age,omitempty" toml:"Age,omitempty" yaml:"Age,omitempty" xml:"age,attr,omitempty"` /* AgeType can be one (or more, OR'd together) of the Time* constants in this package (TimeAny, TimeAccessed, TimeCreated, TimeChanged, TimeModified) to indicate what timestamp(s) to use for comparing Age. The zero-value is TimeAny. The first matching timestamp will pass all time comparisons. Be mindful of timestamp type support/limitations per OS/filesystem of Root. Completely unused if Age is nil. */ AgeType pathTimeType `json:"type_age" toml:"AgeType" yaml:"Age Type" xml:"typeAge,attr"` /* OlderThan, if true (and Age is not nil), indicates that matching filesystem objects should have their AgeType older than Now. If false, their AgeType should be *newer* than Now. Completely unused if Age is nil. */ OlderThan bool `json:"older" toml:"OlderThan" yaml:"Older Than" xml:"older,attr"` /* Now expresses a time to compare to Age via AgeType and OlderThan. Note that it may be any valid time, not necessarily "now". If Age is specified but Now is nil, it will be populated with time.Now() when the search is invoked. Completely unused if Age is nil. */ Now *time.Time `json:"now,omitempty" toml:"Now,omitempty" yaml:"Now,omitempty" xml:"now,attr,omitempty"` }
FsSearchCriteria contains filter criteria for SearchFsPaths* functions.
func (*FsSearchCriteria) Match ¶ added in v1.12.0
func (f *FsSearchCriteria) Match(path string, d fs.DirEntry, fi fs.FileInfo) (match, miss *FsSearchResult, err error)
Match returns match (a ptr to a FsSearchResult if the specified path matches, otherwise nil), miss (ptr the specified path does not match, otherwise nil), and an fs.DirEntry and fs.FileInfo for path. d and/or fi may be nil.
If err is not nil, it represents an unexpected error and as such, both match and miss should be nil.
Match, miss, and err will all be nil if the filesystem object/path does not exist.
type FsSearchCriteriaAsync ¶ added in v1.12.0
type FsSearchCriteriaAsync struct { FsSearchCriteria /* WG should be a non-nil pointer to a sync.WaitGroup. This is used to manage searching completion to the caller. .Done() will be called once within the search function, but no .Add() will be called; .Add() should be done by the caller beforehand. */ WG *sync.WaitGroup // ResChan must be a non-nil channel for (positive) match results to be sent to. ResChan chan *FsSearchResult // MismatchChan, if not nil, will have negative matches/"misses" sent to it. MismatchChan chan *FsSearchResult /* ErrChan should be a non-nil error channel for any unexpected errors encountered. If nil, a panic will be raised. */ ErrChan chan error /* Semaphore is completely optional, but if non-nil it will be used to limit concurrent filesystem object processing. It is generally a Very Good Idea(TM) to use this, as the default is to dispatch all processing concurrently. This can lead to some heavy I/O and CPU wait. (See https://pkg.go.dev/golang.org/x/sync/semaphore for details.) */ Semaphore *semaphore.Weighted /* SemaphoreCtx is the context.Context to use for Semaphore. If nil (but Sempaphore is not), one will be created locally/internally. */ SemaphoreCtx context.Context }
FsSearchCriteriaAsync extends FsSearchCriteria for use in an asynchronous (goroutine) manner.
type FsSearchResult ¶ added in v1.12.0
type FsSearchResult struct { /* Path is the path to the object on the filesystem. It may or may not exist at the time of return, but will not be an empty string. */ Path string `json:"path" toml:"Path" yaml:"Path" xml:"path,attr"` // DirEntry is the fs.DirEntry for the Path; note that .Name() is the base name only. TODO: serialization? DirEntry fs.DirEntry `json:"-" toml:"-" yaml:"-" xml:"-"` // FileInfo is the fs.FileInfo for the Path; note that .Name() is the base name only. TODO: serialization? FileInfo fs.FileInfo `json:"-" toml:"-" yaml:"-" xml:"-"` // Criteria is the evaluated criteria specified that this FsSearchResult matched. Criteria *FsSearchCriteria `json:"criteria" toml:"Criteria" yaml:"Criteria" xml:"criteria"` // Times holds the mtime, ctime, etc. of the filesystem object (where supported). TODO: serialization? Times times.Timespec `json:"-" toml:"-" yaml:"-" xml:"-"` // MissReason contains the reason the result is a miss (MissNoMiss if a match); see the Miss* constants. MissReason missReason `json:"miss_reason" toml:"MissReason" yaml:"Miss Reason" xml:"miss,attr"` }
FsSearchResult contains a match/miss result for FsSearchCriteria and FsSearchCriteriaAsync.
func SearchFsPaths ¶ added in v1.10.0
func SearchFsPaths(matcher FsSearchCriteria) (found, miss []*FsSearchResult, err error)
SearchFsPaths gets a file/directory/etc. path list based on the provided criteria.