forked from nim-lang/Nim
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add globs.glob; fixed nim-lang/RFCs#261
- Loading branch information
1 parent
d1af958
commit 495637f
Showing
4 changed files
with
73 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import std/os | ||
|
||
type | ||
PathEntry* = object | ||
kind*: PathComponent | ||
path*: string | ||
|
||
iterator glob*(dir: string, follow: proc(entry: PathEntry): bool = nil, | ||
relative = false, checkDir = true): PathEntry {.tags: [ReadDirEffect].} = | ||
## Improved `os.walkDirRec`. | ||
#[ | ||
note: a yieldFilter isn't needed because caller can filter at call site, without | ||
loss of generality, unlike `follow`. | ||
Future work: | ||
* need to document | ||
* add a `sort` option, which can be implemented efficiently only here, not at call site. | ||
* provide a way to do error reporting, which is tricky because iteration cannot be resumed | ||
* `walkDirRec` can be implemented in terms of this to avoid duplication, | ||
modulo some refactoring. | ||
]# | ||
var stack = @["."] | ||
var checkDir = checkDir | ||
var entry: PathEntry | ||
while stack.len > 0: | ||
let d = stack.pop() | ||
for k, p in walkDir(dir / d, relative = true, checkDir = checkDir): | ||
let rel = d / p | ||
entry.kind = k | ||
if relative: entry.path = rel | ||
else: entry.path = dir / rel | ||
if k in {pcDir, pcLinkToDir}: | ||
if follow == nil or follow(entry): stack.add rel | ||
yield entry | ||
checkDir = false | ||
# We only check top-level dir, otherwise if a subdir is invalid (eg. wrong | ||
# permissions), it'll abort iteration and there would be no way to | ||
# continue iteration. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,54 +1,18 @@ | ||
##[ | ||
unstable API, internal use only for now. | ||
this can eventually be moved to std/os and `walkDirRec` can be implemented in terms of this | ||
to avoid duplication | ||
]## | ||
|
||
import std/[os,strutils] | ||
#[ | ||
this module should be renamed to reflect its scope, eg to osutils. | ||
]# | ||
|
||
type | ||
PathEntry* = object | ||
kind*: PathComponent | ||
path*: string | ||
import std/[os,strutils,globs] | ||
|
||
iterator walkDirRecFilter*(dir: string, follow: proc(entry: PathEntry): bool = nil, | ||
relative = false, checkDir = true): PathEntry {.tags: [ReadDirEffect].} = | ||
## Improved `os.walkDirRec`. | ||
#[ | ||
note: a yieldFilter isn't needed because caller can filter at call site, without | ||
loss of generality, unlike `follow`. | ||
Future work: | ||
* need to document | ||
* add a `sort` option, which can be implemented efficiently only here, not at call site. | ||
* provide a way to do error reporting, which is tricky because iteration cannot be resumed | ||
]# | ||
var stack = @["."] | ||
var checkDir = checkDir | ||
var entry: PathEntry | ||
while stack.len > 0: | ||
let d = stack.pop() | ||
for k, p in walkDir(dir / d, relative = true, checkDir = checkDir): | ||
let rel = d / p | ||
entry.kind = k | ||
if relative: entry.path = rel | ||
else: entry.path = dir / rel | ||
if k in {pcDir, pcLinkToDir}: | ||
if follow == nil or follow(entry): stack.add rel | ||
yield entry | ||
checkDir = false | ||
# We only check top-level dir, otherwise if a subdir is invalid (eg. wrong | ||
# permissions), it'll abort iteration and there would be no way to | ||
# continue iteration. | ||
{.deprecated: [walkDirRecFilter: glob].} | ||
|
||
proc nativeToUnixPath*(path: string): string = | ||
# pending https://github.com/nim-lang/Nim/pull/13265 | ||
doAssert not path.isAbsolute # not implemented here; absolute files need more care for the drive | ||
when DirSep == '\\': | ||
result = replace(path, '\\', '/') | ||
else: result = path | ||
|
||
when isMainModule: | ||
import sugar | ||
for a in walkDirRecFilter(".", follow = a=>a.path.lastPathPart notin ["nimcache", ".git", ".csources", "bin"]): | ||
echo a |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import std/[os] | ||
|
||
proc genTestPaths*(dir: string, paths: seq[string]) = | ||
## generates a filesystem rooted under `dir` from given relative `paths`. | ||
## `paths` ending in `/` are treated as directories. | ||
# xxx use this in tos.nim | ||
for a in paths: | ||
doAssert a.isRelativePath | ||
if a.endsWith("/"): | ||
createDir(a) | ||
else: | ||
createDir(a.parentDir) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import std/[sugar,globs,os,strutils] | ||
import stdtest/specialpaths | ||
|
||
block: # glob | ||
let dir = buildDir/"D20201013T100140" | ||
defer: removeDir(dir) | ||
let files = """ | ||
d1/f1.txt | ||
d1/d2/f2.txt | ||
d1/d2/f3.txt | ||
d1/d3/ | ||
d4/ | ||
""".splitLines | ||
for | ||
|
||
for a in walkDirRecFilter(".", follow = a=>a.path.lastPathPart notin ["nimcache", ".git", ".csources", "bin"]): | ||
echo a |