-
Notifications
You must be signed in to change notification settings - Fork 29.8k
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
src: replace kPathSeparator
with std::filesystem
#53063
Conversation
Review requested:
|
85b1a5a
to
3b9bb49
Compare
Error on Windows:
|
699210a
to
deef67e
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.
LGTM once CI is green
src/permission/fs_permission.cc
Outdated
return res + "*"; | ||
} | ||
return res + node::kPathSeparator + "*"; | ||
|
||
return (std::filesystem::path(res) / "*").string(); |
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 didn't test it, but from std::filesystem::path::operator/=
it might cause an unexpected replacement:
// Where "//host" is a root-name
path("//host") / "foo" // the result is "//host/foo" (appends with separator)
path("//host/") / "foo" // the result is also "//host/foo" (appends without separator)
// On POSIX,
path("foo") / "" // the result is "foo/" (appends)
path("foo") / "/bar"; // the result is "/bar" (replaces)
Refs: https://en.cppreference.com/w/cpp/filesystem/path/append.
Possibly, the "*" append won't cause any error, but I would be more confident if we use path::preferred_separator
here.
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 can replace it, but FYI, we can use concat
and it will always work correctly.
#include <iostream>
#include <filesystem>
int main() {
auto path = std::filesystem::path("foo").concat("/bar");
printf("path -> %s\n", path.string().c_str());
return 0;
}
Prints:
path -> foo/bar
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 suspect it would cause more CPU cycles though. IMO the +
concat is easier
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.
Agreed. I'm changing this. Thank you for the review.
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.
Unfortunately there has been a complication. On Windows, preferred_separator returns "wchar_t*". Therefore, it is not possible to make a simple addition of wchar_t and std::string.
The solution to fix this is:
#ifdef _WIN32
// This is required for Windows since prefered separator is "wchar_t".
auto separator = std::filesystem::path::preferred_separator;
return res + std::string(separator.begin(), separator.end()) + "*";
#else
return res + std::filesystem::path::preferred_separator + "*";
#endif
}
But since we are talking about potential solutions, I thought what about just converting this whole function to use std::filesystem, rather than libuv, and make the whole code a 5 line function?
std::string WildcardIfDir(const std::string& res) noexcept {
auto path = std::filesystem::path(res);
auto file_status = std::filesystem::status(path);
if (file_status.type() == std::filesystem::file_type::directory) {
path /= "*";
}
return path.string();
}
I personally prefer the std::filesystem, but wanted to hear @RafaelGSS @tniessen and @jasnell's thoughts on this.
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.
For now I think the first change is better. I think we'll want to carefully consider switching too much to std::filesystem
until we can be certain it's implemented consistently across all the platforms we support (unless you're thinking of using this variation only 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 would not change it to the former either as std::filesystem
is very likely to perform syscalls and the Permission Model operates on non-existing paths and it would be more difficult to handle. That's why I used std::string_view
118b263
to
0c5afb1
Compare
auto path = std::filesystem::path(res); | ||
auto file_status = std::filesystem::status(path); | ||
if (file_status.type() == std::filesystem::file_type::directory) { | ||
path /= "*"; |
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.
As I previously mentioned ::operator/
might cause some unexpected results.
What's the status here? Is this ready to land? |
If @RafaelGSS's comment is a non-blocker, it is ready to land. |
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.
My comments aren't non-blocking. I can change it later if needed. LGTM.
Landed in c1dc307 |
PR-URL: #53063 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Stephen Belanger <[email protected]> Reviewed-By: Rafael Gonzaga <[email protected]>
PR-URL: #53063 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Stephen Belanger <[email protected]> Reviewed-By: Rafael Gonzaga <[email protected]>
This PR seems to be mostly incorrect - it's passing utf-8 encoded chars into the |
Another regression came up: #54991 I think we should consider reverting most of the changes here and other similar std::filesystem::path changes because:
Now on POSIX systems, it's fine to pretend that I think we should just keep it simple and prefer to always use |
From a Release POV Node.js 22 is due to become LTS next month (29 Oct) which likely means we'll only have at most two more current releases (possibly only one) for Node.js 22. The latest a Node.js 22 current release can go out is 15 Oct because we want "two weeks in current" (usual Release WG LTS policy) for commits in LTS (the 29 Oct release). I'm +1 for reverting the changes. |
I'm +1 on reverting as well. It has done more harm than good. |
I'll open a PR to revert it soon. |
By the way, I think we can still keep the original intent of the replacement, just do it as |
We don't need
kPathSeparator
anymore sincestd::filesystem::path::preferred_separator
exists.cc @nodejs/cpp-reviewers @nodejs/fs