Merge pull request #4360 from jyapayne/add_walktree
Add walkPattern to list both directories and files
This commit is contained in:
commit
f5096076b2
4 changed files with 136 additions and 19 deletions
|
|
@ -778,12 +778,26 @@ iterator envPairs*(): tuple[key, value: TaintedString] {.tags: [ReadEnvEffect].}
|
||||||
yield (TaintedString(substr(environment[i], 0, p-1)),
|
yield (TaintedString(substr(environment[i], 0, p-1)),
|
||||||
TaintedString(substr(environment[i], p+1)))
|
TaintedString(substr(environment[i], p+1)))
|
||||||
|
|
||||||
iterator walkFiles*(pattern: string): string {.tags: [ReadDirEffect].} =
|
# Templates for filtering directories and files
|
||||||
## Iterate over all the files that match the `pattern`. On POSIX this uses
|
when defined(windows):
|
||||||
## the `glob`:idx: call.
|
template isDir(f: WIN32_FIND_DATA): bool =
|
||||||
##
|
(f.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) != 0'i32
|
||||||
## `pattern` is OS dependent, but at least the "\*.ext"
|
template isFile(f: WIN32_FIND_DATA): bool =
|
||||||
## notation is supported.
|
not isDir(f)
|
||||||
|
else:
|
||||||
|
template isDir(f: string): bool =
|
||||||
|
dirExists(f)
|
||||||
|
template isFile(f: string): bool =
|
||||||
|
fileExists(f)
|
||||||
|
|
||||||
|
template defaultWalkFilter(item): bool =
|
||||||
|
## Walk filter used to return true on both
|
||||||
|
## files and directories
|
||||||
|
true
|
||||||
|
|
||||||
|
template walkCommon(pattern: string, filter) =
|
||||||
|
## Common code for getting the files and directories with the
|
||||||
|
## specified `pattern`
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
var
|
var
|
||||||
f: WIN32_FIND_DATA
|
f: WIN32_FIND_DATA
|
||||||
|
|
@ -792,8 +806,7 @@ iterator walkFiles*(pattern: string): string {.tags: [ReadDirEffect].} =
|
||||||
if res != -1:
|
if res != -1:
|
||||||
defer: findClose(res)
|
defer: findClose(res)
|
||||||
while true:
|
while true:
|
||||||
if not skipFindData(f) and
|
if not skipFindData(f) and filter(f):
|
||||||
(f.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) == 0'i32:
|
|
||||||
# Windows bug/gotcha: 't*.nim' matches 'tfoo.nims' -.- so we check
|
# Windows bug/gotcha: 't*.nim' matches 'tfoo.nims' -.- so we check
|
||||||
# that the file extensions have the same length ...
|
# that the file extensions have the same length ...
|
||||||
let ff = getFilename(f)
|
let ff = getFilename(f)
|
||||||
|
|
@ -816,10 +829,33 @@ iterator walkFiles*(pattern: string): string {.tags: [ReadDirEffect].} =
|
||||||
for i in 0.. f.gl_pathc - 1:
|
for i in 0.. f.gl_pathc - 1:
|
||||||
assert(f.gl_pathv[i] != nil)
|
assert(f.gl_pathv[i] != nil)
|
||||||
let path = $f.gl_pathv[i]
|
let path = $f.gl_pathv[i]
|
||||||
# Make sure it's a file and not a directory
|
if filter(path):
|
||||||
if fileExists(path):
|
|
||||||
yield path
|
yield path
|
||||||
|
|
||||||
|
iterator walkPattern*(pattern: string): string {.tags: [ReadDirEffect].} =
|
||||||
|
## Iterate over all the files and directories that match the `pattern`.
|
||||||
|
## On POSIX this uses the `glob`:idx: call.
|
||||||
|
##
|
||||||
|
## `pattern` is OS dependent, but at least the "\*.ext"
|
||||||
|
## notation is supported.
|
||||||
|
walkCommon(pattern, defaultWalkFilter)
|
||||||
|
|
||||||
|
iterator walkFiles*(pattern: string): string {.tags: [ReadDirEffect].} =
|
||||||
|
## Iterate over all the files that match the `pattern`. On POSIX this uses
|
||||||
|
## the `glob`:idx: call.
|
||||||
|
##
|
||||||
|
## `pattern` is OS dependent, but at least the "\*.ext"
|
||||||
|
## notation is supported.
|
||||||
|
walkCommon(pattern, isFile)
|
||||||
|
|
||||||
|
iterator walkDirs*(pattern: string): string {.tags: [ReadDirEffect].} =
|
||||||
|
## Iterate over all the directories that match the `pattern`.
|
||||||
|
## On POSIX this uses the `glob`:idx: call.
|
||||||
|
##
|
||||||
|
## `pattern` is OS dependent, but at least the "\*.ext"
|
||||||
|
## notation is supported.
|
||||||
|
walkCommon(pattern, isDir)
|
||||||
|
|
||||||
type
|
type
|
||||||
PathComponent* = enum ## Enumeration specifying a path component.
|
PathComponent* = enum ## Enumeration specifying a path component.
|
||||||
pcFile, ## path refers to a file
|
pcFile, ## path refers to a file
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,88 @@
|
||||||
# test some things of the os module
|
discard """
|
||||||
|
output: '''true
|
||||||
|
true
|
||||||
|
true
|
||||||
|
true
|
||||||
|
true
|
||||||
|
true
|
||||||
|
true
|
||||||
|
true
|
||||||
|
true
|
||||||
|
All:
|
||||||
|
__really_obscure_dir_name/are.x
|
||||||
|
__really_obscure_dir_name/created
|
||||||
|
__really_obscure_dir_name/dirs
|
||||||
|
__really_obscure_dir_name/files.q
|
||||||
|
__really_obscure_dir_name/some
|
||||||
|
__really_obscure_dir_name/test
|
||||||
|
__really_obscure_dir_name/testing.r
|
||||||
|
__really_obscure_dir_name/these.txt
|
||||||
|
Files:
|
||||||
|
__really_obscure_dir_name/are.x
|
||||||
|
__really_obscure_dir_name/files.q
|
||||||
|
__really_obscure_dir_name/testing.r
|
||||||
|
__really_obscure_dir_name/these.txt
|
||||||
|
Dirs:
|
||||||
|
__really_obscure_dir_name/created
|
||||||
|
__really_obscure_dir_name/dirs
|
||||||
|
__really_obscure_dir_name/some
|
||||||
|
__really_obscure_dir_name/test
|
||||||
|
false
|
||||||
|
false
|
||||||
|
false
|
||||||
|
false
|
||||||
|
false
|
||||||
|
false
|
||||||
|
false
|
||||||
|
false
|
||||||
|
false
|
||||||
|
'''
|
||||||
|
"""
|
||||||
|
# test os path creation, iteration, and deletion
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
proc walkDirTree(root: string) =
|
let files = @["these.txt", "are.x", "testing.r", "files.q"]
|
||||||
for k, f in walkDir(root):
|
let dirs = @["some", "created", "test", "dirs"]
|
||||||
case k
|
|
||||||
of pcFile, pcLinkToFile: echo(f)
|
|
||||||
of pcDir: walkDirTree(f)
|
|
||||||
of pcLinkToDir: discard
|
|
||||||
|
|
||||||
walkDirTree(".")
|
let dname = "__really_obscure_dir_name"
|
||||||
|
|
||||||
|
createDir(dname)
|
||||||
|
echo dirExists(dname)
|
||||||
|
|
||||||
|
# Test creating files and dirs
|
||||||
|
for dir in dirs:
|
||||||
|
createDir(dname/dir)
|
||||||
|
echo dirExists(dname/dir)
|
||||||
|
|
||||||
|
for file in files:
|
||||||
|
let fh = open(dname/file, fmReadWrite)
|
||||||
|
fh.close()
|
||||||
|
echo fileExists(dname/file)
|
||||||
|
|
||||||
|
echo "All:"
|
||||||
|
|
||||||
|
for path in walkPattern(dname/"*"):
|
||||||
|
echo path
|
||||||
|
|
||||||
|
echo "Files:"
|
||||||
|
|
||||||
|
for path in walkFiles(dname/"*"):
|
||||||
|
echo path
|
||||||
|
|
||||||
|
echo "Dirs:"
|
||||||
|
|
||||||
|
for path in walkDirs(dname/"*"):
|
||||||
|
echo path
|
||||||
|
|
||||||
|
# Test removal of files dirs
|
||||||
|
for dir in dirs:
|
||||||
|
removeDir(dname/dir)
|
||||||
|
echo dirExists(dname/dir)
|
||||||
|
|
||||||
|
for file in files:
|
||||||
|
removeFile(dname/file)
|
||||||
|
echo fileExists(dname/file)
|
||||||
|
|
||||||
|
removeDir(dname)
|
||||||
|
echo dirExists(dname)
|
||||||
|
|
|
||||||
|
|
@ -253,7 +253,7 @@ proc addFiles(s: var seq[string], patterns: seq[string]) =
|
||||||
walkDirRecursively(s, p, p, false)
|
walkDirRecursively(s, p, p, false)
|
||||||
else:
|
else:
|
||||||
var i = 0
|
var i = 0
|
||||||
for f in walkFiles(p):
|
for f in walkPattern(p):
|
||||||
if existsDir(f):
|
if existsDir(f):
|
||||||
walkDirRecursively(s, f, p, false)
|
walkDirRecursively(s, f, p, false)
|
||||||
elif not ignoreFile(f, p, false):
|
elif not ignoreFile(f, p, false):
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,11 @@ Library Additions
|
||||||
operations. Currently contains ``partition``, ``rpartition``
|
operations. Currently contains ``partition``, ``rpartition``
|
||||||
and ``expandTabs``.
|
and ``expandTabs``.
|
||||||
|
|
||||||
|
- Split out ``walkFiles`` in ``os.nim`` to three separate procs in order
|
||||||
|
to make a clear distinction of functionality. ``walkPattern`` iterates
|
||||||
|
over both files and directories, while ``walkFiles`` now only iterates
|
||||||
|
over files and ``walkDirs`` only iterates over directories.
|
||||||
|
|
||||||
Compiler Additions
|
Compiler Additions
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue