Skip to content
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

Implement Path::try_exists #48

Merged
merged 3 commits into from
Nov 12, 2023

Conversation

schneems
Copy link
Contributor

Implements the Path::try_exists associated function mentioned in #46. The aliased function was stabilized in 1.63 so to preserve compatibility with older Rust versions (ci targets 1.40) a new feature flag was added.

Implements the `Path::try_exists` associated function mentioned in andrewhickman#46. The aliased function was stabilized in 1.63 so to preserve compatibility with older Rust versions (ci targets 1.40) a new feature flag was added.
@schneems schneems marked this pull request as ready for review October 17, 2023 23:34
# Adds I/O safety traits introduced in Rust 1.63
# Adds `fs_err_try_exists` to `Path`, introduced in Rust 1.6.3
path_try_exists = []
# Adds I/O safety traits, introduced in Rust 1.63
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure best practice on features. Other things I considered include:

Adding an all feature that loads all features:

all = ["path_try_exists", "io_safety"]

Alternatively making a feature named 1_63 that would enable all features on 1.63+.

1_63 = ["path_try_exists", "io_safety"]

@@ -23,6 +23,8 @@ pub(crate) enum ErrorKind {
Canonicalize,
ReadLink,
SymlinkMetadata,
#[allow(dead_code)]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In order to put the method behind a feature flag, I needed to get clippy to not complain about this unused variant. Maybe there's a better way or pattern.

@@ -1,3 +1,5 @@
#[allow(unused_imports)]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This import is only needed when path_try_exists feature is enabled. Without the allow unused imports clippy generates a warning. Maybe there's a better way to avoid it.

In this case I think it affects the whole file, not just this one import. Which is not ideal

#[cfg(feature = "path_try_exists")]
fn fs_err_try_exists(&self) -> io::Result<bool> {
self.try_exists()
.map_err(|source| Error::build(source, ErrorKind::FileExists, self))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Weirdly enough, try_exists on Path is stabilized by fs::try_exists is not. I couldn't follow the same pattern used by the rest of the associated trait functions.

@LPGhatguy
Copy link
Collaborator

Instead of a feature flag, what do you think about using one of the available crates that does feature or version detection of the running compiler?

I'm not sure what the other maintainers of fs-err would prefer, but I know that autocfg is a solution that would make this API available for new Rust versions without breaking older versions.

@andrewhickman
Copy link
Owner

I think using autocfg is a good idea too 👍

schneems pushed a commit to schneems/fs-err that referenced this pull request Nov 12, 2023
Per comments on andrewhickman#48 this moves from gating `try_exists` behind a feature to using `autocfg`. This is a build time library that inspects the current runtime and adds flags to the build so if a user is building with Rust 1.63 or higher then this feature will be enabled.
Per comments on andrewhickman#48 this moves from gating `try_exists` behind a feature to using `autocfg`. This is a build time library that inspects the current runtime and adds flags to the build so if a user is building with Rust 1.63 or higher then this feature will be enabled.
@schneems
Copy link
Contributor Author

I updated to use autocfg though I'm new to that library/approach so I might have missed something fundamental. I need approval for a new CI run, I've not actually tried it on an older rustc version. It compiles fine on my local machine.

I didn't remove the existing feature flag for io_safety, I think that would need a major version rev. This is scoped only to add support for this one function.

@andrewhickman andrewhickman merged commit 4dedcc5 into andrewhickman:main Nov 12, 2023
6 checks passed
@andrewhickman
Copy link
Owner

Thanks! I'll publish version 2.10.0 with this change

@schneems
Copy link
Contributor Author

Thanks a ton for the review and for this library!

schneems added a commit to heroku/buildpacks-ruby that referenced this pull request Nov 29, 2023
It's best practice to use `try_exists()` instead of `exists()` when checking if a file exists or not because if there's a problem with the file (such as a permissions issue) then the check might fail even though the file is on disk. This seems like not a big deal, but can be very confusing when telling users "we didn't do X because you are missing file Y" but when they debug they see file Y and don't realize that the real problem isn't "missing file" but it's the hidden error preventing `exists()` from returning a true.


This commit uses fs_err_try_exists() from fs-err library that was introduced in: andrewhickman/fs-err#48.

There are a few other places where `exists` is still called, those are nested in areas that don't already return a Result so they're harder to swap.
schneems added a commit to heroku/buildpacks-ruby that referenced this pull request Jan 15, 2024
It's best practice to use `try_exists()` instead of `exists()` when checking if a file exists or not because if there's a problem with the file (such as a permissions issue) then the check might fail even though the file is on disk. This seems like not a big deal, but can be very confusing when telling users "we didn't do X because you are missing file Y" but when they debug they see file Y and don't realize that the real problem isn't "missing file" but it's the hidden error preventing `exists()` from returning a true.


This commit uses fs_err_try_exists() from fs-err library that was introduced in: andrewhickman/fs-err#48.

There are a few other places where `exists` is still called, those are nested in areas that don't already return a Result so they're harder to swap.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants