-
-
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
[superseded] [os] fix #8734, #8353: parentDir, parentDirs now work reliably #10545
Conversation
708be8a
to
9ffaf16
Compare
4e6d505
to
d2ffb23
Compare
d2ffb23
to
bb4401d
Compare
bb4401d
to
d891765
Compare
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.
#8734 is arguably not a bug. Especially not if you keep the behaviour that an empty string signals a wrong usage.
#8734 is not 1 bug but multiple bugs and as discussed here https://irclogs.nim-lang.org/04-02-2019.html#10:56:02 and elsewhere in this conversation thread some of the items are indeed bugs, and 1 of them is being debated. |
@Araq PTAL all comments addressed |
("/a.txt", "/"), | ||
] | ||
|
||
doAssert runTestCases("parentDir", examples, parentDir(it)) |
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.
That is cargo-cult programming. Now I can look at a list of tuples all day long before I can see it's about parentDir
. DRY and meta programming are for creating higher abstractions, not to save keystrokes.
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.
Now I can look at a list of tuples all day long before I can see it's about
parentDir
I just pushed a commit that adds documentation to make everything clear.
I had initially started with the one doAssert per test case
but that became quickly un-manageable with the number of test cases, in particular:
- the important part of each test case was lost in noise of the repetitive surrounding code, eg
doAssert parentDir("/usr/local/bin".unixToNativePath) == "/usr/local".unixToNativePath
; instead, I'm only highlighting the part that changes - on failure, it doesn't tell you what
parentDir
produced as output (because you don't likeassertEquals
for some reason) - it stops on 1st error instead of showing all errors, making it terrible when you need to change the implementation of
parentDirs
; instead I'm showing all errors before failing - if you have to change something, you have to change it everywhere; unlike here where I need to change it in only one place. yes, it's
DRY
, it's notcargo cult
note:
the lack of this kind of thorough testing as done here for parentDir
is the root cause for all those issues and regressions I keep running into when using std/os
procs (eg #10018 , #10047 , etc)
I have other PR's in the pipeline that fix other bugs in std/os (eg "/a" /../ "d"
should be "/d"
, not "d"
+ other bugs with other procs) so let's please move on with this PR
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.
the lack of this kind of thorough testing as done here for
parentDir
is the root cause for all those issues and regressions I keep running into when usingstd/os
procs (eg #10018 , #10047 , etc)
Maybe but it's just you. Most people don't use double slashes in all their paths. And your improved implementation adds plenty of its own, new problems.
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 don't understand your comment. [os] fix #10017 regression, fix #10025 regression #10018, fix #8255 numerous issues with splitFile #10047, [superseded] [os] fix #8734, #8353: parentDir, parentDirs now work reliably #10545 and other PRs I wrote for path handling fix bugs and regressions unrelated to double slashes; incorrect handling of paths with double slashes were just one of the issues I've fixed.
- all languages I've worked with correctly handle paths with double slashes, eg: C++(boost), D, python, java, js(node) etc...; as I already explained
- Double slashes can occur from a variety of reasons, eg:
export buildDir=/path/to/build/
export logFile=$buildDir/log.txt # => expands to a path with double slash (`${buildDir}log.txt` in contrast only works if `buildDir` ends with a slash)
To be on the safe side, include the slash. This can lead to multiple slashes when concatenating the paths, but at least you avoid problems.
Multiple slashes are allowed and are equivalent to a single slash
And your improved implementation adds plenty of its own, new problems
I'm not sure which are these new problems you're referring to, after this PR was updated to return ""
instead of /
for parentDir("/")
, more precisely: what previously valid code would become incorrect as a result of this PR.
In any case, as mentioned below, I'm following up with #10633
tests/stdlib/tos.nim
Outdated
@@ -26,6 +26,31 @@ Raises | |||
# test os path creation, iteration, and deletion | |||
|
|||
import os, strutils, pathnorm | |||
import "$nim/compiler/unittest_light" |
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.
unittest is bad because it's full of when compiles
. Guess what, unittest_light repeats the mistake. The tests were fine before without this import.
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 removed that import for the sake of moving fwd with this PR, but please explain what is wrong with unittest_light
having compiles
?
- assertEquals is written as
if lhs!=rhs: doAssert false, mismatch(lhs, rhs)
so thecompiles
is just used for printing the error msg (insidemismatch
), not for correctness validation - theres is already a test for that tests/compiler/tunittest_light.nim which tests
assertEquals
usingdoAssert
so ifassertEquals
had bugs,doAssert
would catch it
If it's a compilation speed issue, there are easy options.
More generally, for assertEquals
, unittest.check
, fmt
, and sequtils
: 1 argument I heard against more widespread use in testament was "who is guarding the guardian" argument; I'm all for adding more thorough testing (as needed) for these but we shouldn't use FUD
arguments that they may have bugs that would render testament useless;
If a bug ever slips through existing checks, it'll eventually be found in the wild, reported, and fixed;
note, outside of testament, these are pretty popular tools for testing in nimble packages, for a reason.
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.
nim-regex doesn't compile with devel because it uses unittest and unittest does nasty stuff. Yeah, these are compiler regressions, but still, a testing infrastructure shouldn't stress the compiler so much that it becomes hard to debug itself. No FUD here, just lots of experience with unittest.
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.
the concerns you're raising seem specific to unittest
, not unittest_light
, as I described here #10545 (comment)
@Araq comments addressed and green, PTAL |
assert parentDir("/") == "" | ||
if path == "": return "" | ||
result = path | ||
while true: |
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.
Convoluted. What's wrong with fixing parentDirPos
?
result = path | ||
while true: | ||
normalizePathEnd(result) | ||
let (dir, name, ext) = splitFile(result) |
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.
Why would I do that? What has ext
to do with anything?
while true: | ||
normalizePathEnd(result) | ||
let (dir, name, ext) = splitFile(result) | ||
if name == ".." or (name.len == 0 and ext.len == 0): return "" |
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.
parentDir("bar/baz/foo/..") could just work...
normalizePathEnd(result) | ||
let (dir, name, ext) = splitFile(result) | ||
if name == ".." or (name.len == 0 and ext.len == 0): return "" | ||
if name == ".": |
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.
Ah so silly single dots are allowed.
result = dir | ||
continue | ||
if dir == "" and name != "": | ||
return "." |
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.
Really? What is this "." directory and if it is one why is ".." not a directory?
continue | ||
if dir == "" and name != "": | ||
return "." | ||
return dir |
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.
At this point in the control flow it's not obvious if it shouldn't have been return result
.
too long didn't read. |
instead of addressing remaining comments in this PR I'm opening #10633 which has a different, simpler implementation (some edge cases are treated differently) and should address the remaining comments from here; if #10633 gets merged I'll close this PR but preferably not before because github doesn't allow re-opening a closed PR after a force push. |
this I am closing this in favor of #10633 |
parentDir, parentDirs now work reliably
I also added extensive unittests so you can now see exactly what
parentDir
andparentDirs
returnto view the diff and not get confused by code that was only moved, see instructions here https://github.com/nim-lang/Nim/pull/10435/files
note
the
# todo: fix
is a (commented out) test case for a pre-existing failure from #8395 which i can fix after this PR