feat: Add Builder::permissions() method.#273
Conversation
With it it's possible to change the default mode of tempfiles on unix systems. The example also doesn't hide the fact that it is currently only useful on Unix, but as the ecosystem matures, thanks to the usage of `std::fs::Permissions` it should be able grow into more platforms over time.
The implementation favors the least invasive solution even though its forced to pull platform dependent code up. The alternative would have been to alter the method signatures of `create_named()` on all platforms.
This way, permissions can be passed and handled by platform specific code, which avoid having to use platform dependent code in the top-level.
This comment was marked as off-topic.
This comment was marked as off-topic.
|
@NobodyXu I agree if you're only target is Linux, but it's still useful to have a platform-independent way to do this (to, e.g., support MacOS which hasn't seen any filesystem API improvements in, basically ever). |
| /// Permissions for directories aren't currently set even though it would | ||
| /// be possible on Unix systems. |
There was a problem hiding this comment.
We need to implement this before we merge this patch, unfortunately. This builder is used to create temporary directories as well, and I don't really trust users to read the docs.
There was a problem hiding this comment.
I took a look at this and saw that std::fs::create_dir() is used to create the directory, I don't think the standard library has a way to handle this.
Did you have an idea on how to do this? Maybe a rustix chmod call?
There was a problem hiding this comment.
I think we'll need to use rustix::fs::mkdir.
There was a problem hiding this comment.
This comment is now out of date.
|
Thanks! And yes, I prefer the final version (more invasive approach). |
8bb3386 to
c0c925d
Compare
|
Thanks for the quick review! If CI passes I have addressed the windows portion of it, but will definitely need some guidance to deal with the directory. If you have ideas and want to tinker, please feel free to push into this branch - sometimes that's easiest. @NobodyXu Thanks for sharing! It's definitely something to consider for the time when performance needs to be optimised further. Personally I am most interested in doing what Git does at first, which seems to be pretty much what's happening here. |
That way, there will be no surprises as would be the case with doing nothing.
8a172f4 to
19ec472
Compare
|
I have added mode-support for directories thanks to your hint with |
| imp::create(path, permissions) | ||
| } | ||
|
|
||
| mod imp { |
There was a problem hiding this comment.
I'd prefer it if we created the entire directory structure.
There was a problem hiding this comment.
I can do that, even though it's a change that might have performance implications. For that reason alone I wouldn't do it without also introducing a new method for it, and do so in a separate PR.
There was a problem hiding this comment.
Wait, no. I mean: put the modules in different files/directories (imp/...). Sorry, I realize that that was confusing.
There was a problem hiding this comment.
Ah, right, I could have guessed it. And it's done now. A note regarding naming: It feels like any should be other, but I decided not to do that as other means unsupported in the file folder, while here it is a catch-all.
There was a problem hiding this comment.
Hm. Yeah, I may go through and do a rename later but those are implementation details so.. meh.
|
So... somehow I missed this but: https://doc.rust-lang.org/std/fs/struct.DirBuilder.html#method.mode. We don't need to use rustix here. |
Oh my, I missed that too! I clearly was biased when researching this topic and "didn't believe in mode being available for directories" 🤦♂️. Lesson learned, and the code was adjusted to something much better. I made a note that recommends to not recursively create the directory by default but leave that to a separate PR along with a new flag in the builder maybe to control this, to keep the previous behaviour exactly the same. Right now, this still is the case. If CI is green, this PR should be ready for re-review. |
| pub(crate) struct PathError { | ||
| pub(crate) path: PathBuf, | ||
| pub(crate) err: io::Error, |
| } | ||
| dir_options | ||
| .create(&path) | ||
| .with_err_path(|| path.clone()) |
There was a problem hiding this comment.
| .with_err_path(|| path.clone()) | |
| .with_err_path(|| &path) |
(the path is cloned automatically if there's an error)
| /// Permissions for directories aren't currently set even though it would | ||
| /// be possible on Unix systems. |
There was a problem hiding this comment.
This comment is now out of date.
| imp::create(path, permissions) | ||
| } | ||
|
|
||
| mod imp { |
There was a problem hiding this comment.
Hm. Yeah, I may go through and do a rename later but those are implementation details so.. meh.
|
And with those changes, this should be good to go. Thanks! |
|
Thanks a lot for the QA and sorry for the sloppiness, at least 2 of 3 I should have caught. PS: A new release with these changes would help, as that way everything can trickle downstream to StackedGit. Thanks again. |
Don't be. That'll just make me feel worse about my PRs and that's why we have review 😆.
Will do. |
* feat: Add `Builder::permissions()` method. With it it's possible to change the default mode of tempfiles on unix systems. The example also doesn't hide the fact that it is currently only useful on Unix, but as the ecosystem matures, thanks to the usage of `std::fs::Permissions` it should be able grow into more platforms over time. * Use `permissions` field of `Builder` on Unix to affect file mode The implementation favors the least invasive solution even though its forced to pull platform dependent code up. The alternative would have been to alter the method signatures of `create_named()` on all platforms. * Respect module boundaries and make all platforms permissions aware. This way, permissions can be passed and handled by platform specific code, which avoid having to use platform dependent code in the top-level. * Fail on Windows if somebody tries to set permissions there. That way, there will be no surprises as would be the case with doing nothing. * Add support for setting permissions on directories as well.
This PR allows the user to control the file mode set for newly created
NameTempfileinstances.This is paramount for when tempfiles are used as scratch space that will be persisted and renamed into the final destination once all writes are completed. This is an effective way to prevent half-written files on disk and to assure that readers can only observe the final result of a change.
This paradigm is implemented in the
gix-lockcrate which is used by thegix-refcrate for editing Git references. Currently these are created with0o600permissions, which can cause issues when usingsudoin downstream applications.When this PR is merged,
gix-refcan be adjusted to allow setting the mode just like Git does.Review Notes
I did my best to adapt the least amount of code while staying true to the current organisation. Initially I named the new method
mode, but realized thatstd::fs::Permissionsexists which would allow the API to be more general, despite only one available platform for implementation.Let me explain the commits in some detail and why it's one more than needed:
Buildermethod without an implementation. CI is red to show it's not working.imp. CI is green.permissionscan be passed down to the platforms, which is more invasive, yet cleaner. CI is also green.Please let me know which way you prefer as its also a trade-off.