-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add error-checked version of walkDir #13163
Conversation
Being Nim a typed lang with overload and all, I dont think we need to add |
I like this idea much better than #13011 |
Needs a |
What about |
will |
Indeed, please rename it to |
When Can you write signle yield per when branch code?
|
That would break code, code can contain exhaustive case statements, in fact, I generally encourage people to do that.
No, we only need one non-recursive iterator as the building block for custom walks that can live outside the stdlib. |
For discussion: an updated version, slightly more generalized + some fixes: for step in tryWalkDir(dir):
case step.kind
of wiOpenDir:
if step.openStatus != odOpenOk:
echo "directory " & dir & " could not be opened " &
$step.openStatus & " / " & osErrorMsg(step.code)
of wiEntryOk: echo "found " & step.path & " of kind " & $step.entryType
of wiEntryBad: echo "bad symlink " & step.path & " with error " &
osErrorMsg(step.code)
of wiInterrupted:
echo "traversal interrupted with error: " & osErrorMsg(step.code) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left a few comments, but I don't think this should be accepted into the stdlib for various reasons:
- I don't see this seeing enough use to be included in the stdlib
- The API for this should be modelled via something more generic, like a
Either[T, E]
type or something instead of this custom WalkStep object. - The code being introduced in this PR is convoluted and hard to read, which will make it hard to maintain
The solution of using closure iterators would be much simpler and more elegant (return proc `=destroy`(m: var ptr DIR) =
echo "Destruct"
Error: signature for '=destroy' must be proc[T: object](x: var T) I can try using wrapper object for the handle. |
I've asked for an implementation like this because our current means are insufficient for handling errors. |
It looks a bit bulky but there is a bright side: recursive version is straightforward for implementation, because iterator tryWalkDirRec*(dir: string,
yieldFilter = {pcFile}, followFilter = {pcDir},
relative = false):
WalkStep {.tags: [ReadDirEffect].} =
var stack = @[""]
while stack.len > 0:
let d = stack.pop()
for s in tryWalkDir(dir / d, relative = true):
let rel = d / s.path
case s.kind
of wsEntryOk:
if s.entryType in {pcDir, pcLinkToDir} and
s.entryType in followFilter:
stack.add rel
if s.entryType in yieldFilter:
var step = s
step.path = if relative: rel else: dir / rel
yield step
of wsEntryBad, wsInterrupted, wsOpenDir:
var step = s
step.path = if relative: rel else: dir / rel
yield step |
multiple yield statements in inline iterators cause code bloat and must be avoided, as explained here: #10553 see #10557 (which was closed but is relevant) for an example of how to convert multiple yield into a single yield both current PR and #13163 (comment) suffer from this One possibility would be to use a 1st class iterator instead of inline iterator, given cost of file system operations, the overhead of 1st class iterators would be negligible |
it was rewritten to use single yield. I'm using multiple yield only in examples for the sake of clarity. |
This definitely goes in the right direction, but:
I understand that iterating over directories properly in 2020 involves some black magic, but this seems overly excessive. |
I combined OpenDirStatus into WalkStepKind. And I tried to simplify the code further, with limited success though. It's hard to do that with inline iterator using single yield statement. |
This pull request has been automatically marked as stale because it has not had recent activity. If you think it is still a valid PR, please rebase it on the latest devel; otherwise it will be closed. Thank you for your contributions. |
filewalks (nim-lang/fusion#32) does this; IMO filewalks belongs squarely in stdlib. |
IMHO nim-results should be a part of stdlib for the tasks like this PR. |
This pull request has been automatically marked as stale because it has not had recent activity. If you think it is still a valid PR, please rebase it on the latest devel; otherwise it will be closed. Thank you for your contributions. |
Alternative solution w.r.t. #13011, #12960.
New iterator
walkDirErr
with error-checking, use like this:Other iterators remain unchecked.
Tested manually on Linux & Windows.