-
Notifications
You must be signed in to change notification settings - Fork 229
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
Fix support for FileIterator
when working directory is /
#865
base: main
Are you sure you want to change the base?
Conversation
Added an additional check that tests to see if the working directory is root. swiftlang#862
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.
Thanks for opening a PR and addressing this issue @macshome.
To test this, what do you think about making workingDirectory
an argument to FileIterator.init
and just default it to URL(fileURLWithPath: ".")
? That way you could set the working directory and we can also craft tests for Windows to ensure we don’t have any issues there.
@@ -145,7 +145,7 @@ public struct FileIterator: Sequence, IteratorProtocol { | |||
// be displayed as relative paths. Otherwise, they will still be displayed as absolute | |||
// paths. | |||
let relativePath = | |||
path.hasPrefix(workingDirectory.path) | |||
path.hasPrefix(workingDirectory.path) && path.first != "/" |
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.
Doesn’t this mean that we never relativize paths on Unix because all paths will start with a /
? Don’t you want to check that workingDirectory
is /
? I might be misunderstanding your change though.
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.
Hmm... You seem to be correct here. As far as I can tell the reason for using relative paths is just for nice diagnostic output.
// We attempt to relativize the URLs based on the current working directory, not the
// directory being iterated over, so that they can be displayed better in diagnostics. Thus,
// if the user passes paths that are relative to the current working directory, they will
// be displayed as relative paths. Otherwise, they will still be displayed as absolute
// paths.
And with workingDirectory
being a constant of .
this may take a bit more work. If we did change workingDirectory
to be passed in then it would also allow for easier testing. I'll work on it a bit more and see what I can come up with.
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.
Pushed a quick update to actually check if the current working directory is root or not rather than checking for a string of /
.
path.hasPrefix(workingDirectory.path) && FileManager.default.currentDirectoryPath != "/"
That's what I had thought about for setting a working directory, but that value is a constant in the code... private let workingDirectory = URL(fileURLWithPath: ".") Making it the default would probably work fine though. |
If you pass it in the initializer, you could make that the default value but then let tests specify whatever they want there. It's a member property, so it can certainly be changed by the initializer. |
Since just testing for the `/` character at the begining of a path will result in no path ever being relative, we should use `FileManager.default.currentDirectoryPath` to check and see if we are actually running in root.
I'll take a trip down this path and see about getting it covered with tests so it doesn't break again. |
I updated the tests to actually use `[URL]` instead of `[String]` when looking at the test results. For the working directory changes it was simplest to actually change the working directory and make sure we aren't dropping the first charcters from the paths.
@allevato I updated the tests to use It takes the coverage on |
@@ -145,7 +145,7 @@ public struct FileIterator: Sequence, IteratorProtocol { | |||
// be displayed as relative paths. Otherwise, they will still be displayed as absolute | |||
// paths. | |||
let relativePath = | |||
path.hasPrefix(workingDirectory.path) | |||
path.hasPrefix(workingDirectory.path) && FileManager.default.currentDirectoryPath != "/" |
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.
@compnerd What will this do on Windows? Probably not what's intended, I think?
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 was my concern, I don't know how Foundation will deal with that there.
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.
Actually it might be OK.
(Giving up on trying to make it look pretty here in the comment.)
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.
FileManager.default.currentDirectoryPath
will never be /
on Windows because Windows always has a drive letter, eg. C:\
. Checking if a URL is a root path on Windows is not quite trivial because you also need to account for networks shares eg. \\your-server\blah
and the only good way of doing it issuing the PathCchIsRoot
Windows API (eg. https://github.com/swiftlang/swift-tools-support-core/blob/5b130e04cc939373c4713b91704b0c47ceb36170/Sources/TSCBasic/Path.swift#L491).
But maybe it’s not really an issue on Windows anyway, depending on how test output looks like. This is why I suggested making workingDirectory
changeable from tests and then we can just check.
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 know that it is an issue on Windows either. Most people seem to have discovered it when using WASM. Are there Windows and Linux runners for CI so that we can see if this breaks anything? Otherwise I can install a toolchain on Windows here and check.
I can still make workingDirectory
changeable from tests, but at this point I'm worried about the validity of the entire approach on Windows.
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 suppose I could also implement the isRoot
property from the swift-tools-support-core as well in FileIterator
. That way it would work on Windows as well.
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.
These tests do fail on Windows when trying to change the working directory. I'll update everything and get it working.
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.
If you don’t have a Windows machine to test this on, just write code that works to the best of you knowledge and some test cases for it. We have Windows PR testing (we just need to approve runs) and I’m happy to get the Windows code over the finish line if there are minor issues.
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 set a toolchain up yesterday on my gaming machine so I will at least be sure that we pass the tests everywhere.
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.
Oh, that’s great. Let me know if you have any questions.
Added an additional check that tests to see if the working directory is root to solve #862.
Simple Fix
Simple check that looks to see if the working directory is root.
Testing
I couldn't find a non-intrusive way to simulate changing the working directory of the unit tests. This path remains uncovered as a result of that.
Manual testing with the debug build. The behavior of #862 is resolved.
Works from
/tmp
Now works from
/
as wellI'll need to spin up a linux VM to test if we get relative paths when running from root.