v1.17.1
FIXED: * tplx/sprigx would throw errors on dnsx.IsPtr, because it returns a bool and net.IP instead of a boolen and optional error. Fixed by adding dnsx.IsPtrChk and using that instead.
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
package fsx
|
||||
|
||||
import (
|
||||
"go/types"
|
||||
"io/fs"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
/*
|
||||
FsPaths returns all paths in [io/fs.FS] `fsys`.
|
||||
|
||||
If `fsys` is nil, both `fsPaths` and `err` will be nil.
|
||||
|
||||
`t` should be an OR'd [io/fs.FileMode] containing all filetypes that should be included.
|
||||
Use [io/fs.ModeType] to match any non-regular-file object, or 0 to explicitly match regular files.
|
||||
If `t` is non-zero but you wish to ALSO include regular files, then specify `inclFiles` as true.
|
||||
(`inclFiles` is ignored if `t` == 0, as this inherently matches regular files only/explicitly.)
|
||||
See [HasType] for more information on this filtering.
|
||||
|
||||
`maxDepth` can be used to limit recursion depth.
|
||||
|
||||
- If `maxDepth` == 0, only direct [io/fs.DirEntry] descendants of `fsys`
|
||||
will be included in `fsPaths`.
|
||||
- If `maxDepth` < 0, ALL [io/fs.DirEntry] descendants of `fsys`
|
||||
will be included in `fsPaths`.
|
||||
- If `maxDepth` > 0, then only children at a depth of this level or lower
|
||||
("higher" in a hierarchy) will be included in `fsPaths`.
|
||||
*/
|
||||
func FsPaths(fsys fs.FS, t fs.FileMode, inclFiles bool, maxDepth int) (fsPaths map[string]fs.DirEntry, err error) {
|
||||
|
||||
var idx int
|
||||
var entries []fs.DirEntry
|
||||
var t fs.FileMode = types.Type()
|
||||
|
||||
if fsys == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if fsPaths, err = getEntries(fsys, t, inclFiles, maxDepth, "."); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
HasType is just a convenience wrapper for:
|
||||
|
||||
hasType = m & t != 0
|
||||
|
||||
The type(s) will be explicitly extracted from `m` and `t` first.
|
||||
|
||||
Note that if `t` is an OR'd set of filetypes, then HasType will return true if ANY of the types
|
||||
in `t` match `m`'s type (see [r00t2.io/goutils/bitmask] for more information on bitmasking).
|
||||
If you wish to check if `m` is A SINGLE type, either ensure that `t` is not OR'd
|
||||
(i.e. is a single fs.FileMode type) or use [IsType] instead.
|
||||
*/
|
||||
func HasType(m, t fs.FileMode) (hasType bool) { return m.Type()&t.Type() != 0 }
|
||||
|
||||
/*
|
||||
IsType is just a convenience wrapper for:
|
||||
|
||||
isType = m & t == t
|
||||
|
||||
The type(s) will be explicitly extracted from `m` and `t` first.
|
||||
|
||||
Note that if `t` is an OR'd set of filetypes, then IsType will *never* return true
|
||||
as its type is single-valued/not bitmasked (see [r00t2.io/goutils/bitmask] for more information
|
||||
on bitmasking).
|
||||
If you wish to check if `m` is ONE OF multiple types in `t`, use [HasType] instead.
|
||||
*/
|
||||
func IsType(m, t fs.FileMode) (isType bool) { return m&t == t }
|
||||
|
||||
/*
|
||||
getEntries is used to recursively fetch entries from `fsys`.
|
||||
|
||||
It mostly serves as the recursion for [FsPaths], and the arguments
|
||||
retain their exact meaning except that it requires `relPath`
|
||||
and `maxDepth` (if > 0) will be decremanted in each recursion.
|
||||
*/
|
||||
func getEntries(fsys fs.FS, t fs.FileMode, inclFiles bool, maxDepth int, relPath string) (fsPaths map[string]fs.DirEntry, err error) {
|
||||
|
||||
var idx int
|
||||
var p string
|
||||
var e []fs.DirEntry
|
||||
var subs map[string]fs.DirEntry = make(map[string]fs.DirEntry)
|
||||
|
||||
if e, err = fs.ReadDir(fsys, relPath); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for idx = range e {
|
||||
p = filepath.Join(relPath, e[idx].Name())
|
||||
if e[idx].IsDir() {
|
||||
if subs, err = getEntries(fsys, t, inclFiles, maxDepth, p); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user