-
Notifications
You must be signed in to change notification settings - Fork 35
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 -follow
#420
base: main
Are you sure you want to change the base?
Implement -follow
#420
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #420 +/- ##
==========================================
- Coverage 66.03% 66.01% -0.03%
==========================================
Files 34 34
Lines 4004 4063 +59
Branches 910 924 +14
==========================================
+ Hits 2644 2682 +38
- Misses 996 1011 +15
- Partials 364 370 +6 ☔ View full report in Codecov by Sentry. |
Commit 93b5ae2 has GNU testsuite comparison:
|
Commit c1ebc0a has GNU testsuite comparison:
|
Commit 5abaed4 has GNU testsuite comparison:
|
Commit 1b4e25b has GNU testsuite comparison:
|
Commit e3911be has GNU testsuite comparison:
|
Commit 887d76c has GNU testsuite comparison:
|
Sorry, the test coverage is still not up to target. :( |
src/find/matchers/lname.rs
Outdated
} | ||
} | ||
|
||
impl Matcher for LinkNameMatcher { | ||
fn matches(&self, file_info: &DirEntry, _: &mut MatcherIO) -> bool { | ||
// -follow: causes the -lname and -ilname predicates always to return false. | ||
if self.follow { | ||
return false; |
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.
Not really:
tavianator@graphene $ ln -s nowhere broken
tavianator@graphene $ find -lname nowhere
./broken
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.
Sorry, could you please give me some more detailed steps?
I noticed that the -follow
parameter is missing, is that find -follow -lname nowhere
?
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.
Whoops I copy pasted the wrong part of my session, but yeah:
$ ln -s nowhere broken
$ find -follow -lname nowhere
./broken
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. I have fixed it to the actual behavior of the GNU version in a0d4e46
Commit 1e1846a has GNU testsuite comparison:
|
Commit a0d4e46 has GNU testsuite comparison:
|
Commit eed1c1e has GNU testsuite comparison:
|
FileAgeRangeMatcher::new( | ||
file_time_type, | ||
minutes, | ||
config.today_start, |
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.
It might be nicer to just pass &config
to the matcher constructors so we don't have to keep changing the parameters.
} | ||
|
||
impl NewerMatcher { | ||
pub fn new(path_to_file: &str) -> Result<Self, Box<dyn Error>> { | ||
pub fn new(path_to_file: &str, follow: bool) -> Result<Self, Box<dyn Error>> { | ||
let metadata = fs::metadata(path_to_file)?; |
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.
This should be symlink_metadata()
if follow
is false
. I'd recommend adding a Config::metadata()
method or something to centralize the logic.
}) | ||
} | ||
|
||
/// Implementation of matches that returns a result, allowing use to use try! | ||
/// to deal with the errors. | ||
fn matches_impl(&self, file_info: &DirEntry) -> Result<bool, Box<dyn Error>> { | ||
let this_time = file_info.metadata()?.modified()?; | ||
let path = file_info.path(); | ||
let this_time = if self.follow && path.is_symlink() { |
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.
Checking self.follow
here is wrong for command lines like
$ find foo -newer bar -follow
-follow
should apply here, but because NewerMatcher::new()
was called before -follow
was parsed, self.follow
will be false
. I think the right implementation would pass the final -follow
state to matches()
, possibly as part of MatcherIO
. There could be a convenience method like MatcherIO::metadata(file_info)
that handles following symlinks correctly.
(Also, it would be a good idea to cache the Metadata
so each matcher doesn't have to do its own stat()
call, but that's probably a separate refactoring.)
// 1. -type f searches not only for regular files, | ||
// but also for files pointed to by symbolic links. | ||
// 2. -type l will not return any results because -follow will follow symbolic links, | ||
// so the find command cannot find pure symbolic links. |
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.
Not true:
tavianator@tachyon $ ln -s nowhere broken
tavianator@tachyon $ find -follow -type l
./broken
assert!(!matcher.matches(&dir, &mut deps.new_matcher_io())); | ||
assert!(!matcher.matches(&file, &mut deps.new_matcher_io())); | ||
} | ||
[true, false].iter().for_each(|follow| { |
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.
Might as well write for follow in [true, false] {
to match the loop below
Closed #308
May conflict with #416, better merge #416 first. :)
There are changes as described in
man find
:(The following changes are: When matching files, match the file pointed to by the file link.)