-
Notifications
You must be signed in to change notification settings - Fork 62
find: Implement -[no]user
and -[no]group
predicates.
#368
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
Merged
Merged
Changes from all commits
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
2202c7a
impl -[no]user and -[no]group.
hanbings 7c13fa4
fix windows platform ci.
hanbings 464200a
add test for -user and -group predicate.
hanbings 3794688
run clippy.
hanbings 502d556
fix file not found error.
hanbings 914f231
fix file not found error.
hanbings 3bf788d
fix uid() -> gid() in group matcher.
hanbings f6e36a6
add empty name check in -user and -group.
hanbings 82c9255
Handle users and groups that do not exist.
hanbings ce27d17
Remove redundant Windows platform code.
hanbings 0097f6e
Reimplement -nouser and -nogroup.
hanbings 6d398b1
Add test for -nouser and - nogroup.
hanbings 248851c
Improve test coverage.
hanbings 8ba8173
Add license header.
hanbings 1409009
Merge branch 'main' into implement-7
sylvestre 0ca47b7
bump nix from 0.28.0 to 0.29.0
hanbings 4353503
Ignore tests for Windows platforms.
hanbings 7dc18b8
Consider macos default user group in group testing.
hanbings e5e73ec
Clean up duplicate code.
hanbings 0f1bf4e
Clean up duplicate code.
hanbings f196895
Merge branch 'main' into implement-7
sylvestre cf06ff4
Merge branch 'main' into implement-7
hanbings acb0383
Fix testing for Windows.
hanbings 31e2809
Merge branch 'main' into implement-7
hanbings File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
// This file is part of the uutils findutils package. | ||
// | ||
// For the full copyright and license information, please view the LICENSE | ||
// file that was distributed with this source code. | ||
|
||
use super::Matcher; | ||
|
||
#[cfg(unix)] | ||
use nix::unistd::Group; | ||
#[cfg(unix)] | ||
use std::os::unix::fs::MetadataExt; | ||
|
||
pub struct GroupMatcher { | ||
gid: Option<u32>, | ||
} | ||
|
||
impl GroupMatcher { | ||
#[cfg(unix)] | ||
pub fn new(group: String) -> GroupMatcher { | ||
// get gid from group name | ||
let Ok(group) = Group::from_name(group.as_str()) else { | ||
return GroupMatcher { gid: None }; | ||
}; | ||
|
||
let Some(group) = group else { | ||
// This if branch is to determine whether a certain group exists in the system. | ||
// If a certain group does not exist in the system, | ||
// the result will need to be returned according to | ||
// the flag bit of whether to invert the result. | ||
return GroupMatcher { gid: None }; | ||
}; | ||
|
||
GroupMatcher { | ||
gid: Some(group.gid.as_raw()), | ||
} | ||
} | ||
|
||
#[cfg(windows)] | ||
pub fn new(_group: String) -> GroupMatcher { | ||
GroupMatcher { gid: None } | ||
} | ||
|
||
pub fn gid(&self) -> &Option<u32> { | ||
&self.gid | ||
} | ||
} | ||
|
||
impl Matcher for GroupMatcher { | ||
#[cfg(unix)] | ||
fn matches(&self, file_info: &walkdir::DirEntry, _: &mut super::MatcherIO) -> bool { | ||
let Ok(metadata) = file_info.path().metadata() else { | ||
return false; | ||
}; | ||
|
||
let file_gid = metadata.gid(); | ||
|
||
// When matching the -group parameter in find/matcher/mod.rs, | ||
// it has been judged that the group does not exist and an error is returned. | ||
// So use unwarp() directly here. | ||
self.gid.unwrap() == file_gid | ||
} | ||
|
||
#[cfg(windows)] | ||
fn matches(&self, _file_info: &walkdir::DirEntry, _: &mut super::MatcherIO) -> bool { | ||
// The user group acquisition function for Windows systems is not implemented in MetadataExt, | ||
// so it is somewhat difficult to implement it. :( | ||
false | ||
} | ||
} | ||
|
||
pub struct NoGroupMatcher {} | ||
|
||
impl Matcher for NoGroupMatcher { | ||
#[cfg(unix)] | ||
fn matches(&self, file_info: &walkdir::DirEntry, _: &mut super::MatcherIO) -> bool { | ||
use nix::unistd::Gid; | ||
|
||
if file_info.path().is_symlink() { | ||
return false; | ||
} | ||
|
||
let Ok(metadata) = file_info.path().metadata() else { | ||
return true; | ||
}; | ||
|
||
let Ok(gid) = Group::from_gid(Gid::from_raw(metadata.gid())) else { | ||
return true; | ||
}; | ||
|
||
let Some(_group) = gid else { | ||
return true; | ||
}; | ||
|
||
false | ||
} | ||
|
||
#[cfg(windows)] | ||
fn matches(&self, _file_info: &walkdir::DirEntry, _: &mut super::MatcherIO) -> bool { | ||
false | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
#[test] | ||
#[cfg(unix)] | ||
fn test_group_matcher() { | ||
use crate::find::matchers::{group::GroupMatcher, tests::get_dir_entry_for, Matcher}; | ||
use crate::find::tests::FakeDependencies; | ||
use chrono::Local; | ||
use nix::unistd::{Gid, Group}; | ||
use std::fs::File; | ||
use std::os::unix::fs::MetadataExt; | ||
use tempfile::Builder; | ||
|
||
let deps = FakeDependencies::new(); | ||
let mut matcher_io = deps.new_matcher_io(); | ||
|
||
let temp_dir = Builder::new().prefix("group_matcher").tempdir().unwrap(); | ||
let foo_path = temp_dir.path().join("foo"); | ||
let _ = File::create(foo_path).expect("create temp file"); | ||
let file_info = get_dir_entry_for(&temp_dir.path().to_string_lossy(), "foo"); | ||
let file_gid = file_info.path().metadata().unwrap().gid(); | ||
let file_group = Group::from_gid(Gid::from_raw(file_gid)) | ||
.unwrap() | ||
.unwrap() | ||
.name; | ||
|
||
let matcher = super::GroupMatcher::new(file_group.clone()); | ||
assert!( | ||
matcher.matches(&file_info, &mut matcher_io), | ||
"group should match" | ||
); | ||
|
||
// Testing a non-existent group name | ||
let time_string = Local::now().format("%Y%m%d%H%M%S").to_string(); | ||
let matcher = GroupMatcher::new(time_string.clone()); | ||
assert!( | ||
matcher.gid().is_none(), | ||
"group name {} should not exist", | ||
time_string | ||
); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.