refactor(cli): clean up code around codeowners (#1099)

This commit is contained in:
Boshen 2023-10-30 11:21:41 +08:00 committed by GitHub
parent cef075df17
commit 4e218331c2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 48 deletions

View file

@ -136,11 +136,11 @@ impl LintFilter {
#[derive(Debug, Clone, Bpaf)]
pub struct CodeownerOptions {
/// Path to CODEOWNERS file
#[bpaf(argument("PATH"))]
#[bpaf(argument("PATH"), hide_usage)]
pub codeowners_file: Option<OsString>,
/// Code owner names, e.g. @Boshen
#[bpaf(argument("NAME"))]
#[bpaf(argument("NAME"), hide_usage)]
pub codeowners: Vec<String>,
}

View file

@ -12,51 +12,6 @@ pub struct LintRunner {
options: CliLintOptions,
}
fn apply_codeowners_file(
options: &CodeownerOptions,
paths: Vec<Box<Path>>,
) -> Result<Vec<Box<Path>>, CliRunResult> {
if options.codeowners_file.is_some() && options.codeowners.is_empty() {
return Err(CliRunResult::InvalidOptions {
message: "No wanted codeowners provided.".to_string(),
});
}
let maybe_codeowners_file = options.codeowners_file.as_ref().map(codeowners::from_path);
if let Some(owners) = maybe_codeowners_file {
return Ok(paths
.into_iter()
.filter(|path_being_checked| {
// Strips the prefix of "./", because paths will look like "./foo/bar.js"
// however owners.of() will not match against these relative paths.
// So instead we simply strp the prefix and check against "foo/bar.js".
let path_to_check = path_being_checked
.strip_prefix("./")
.unwrap_or(path_being_checked)
.to_path_buf();
owners.of(path_to_check).map_or(false, |owners_of_path| {
owners_of_path
.iter()
.map(|owner| match owner {
codeowners::Owner::Email(s)
| codeowners::Owner::Team(s)
| codeowners::Owner::Username(s) => s,
})
.any(|owner| options.codeowners.contains(owner))
})
})
.collect::<Vec<_>>());
} else if options.codeowners_file.is_some() {
return Err(CliRunResult::InvalidOptions {
message: "Codeowners file could not be read or parsed.".to_string(),
});
}
Ok(paths)
}
impl Runner for LintRunner {
type Options = CliLintOptions;
@ -90,7 +45,7 @@ impl Runner for LintRunner {
let paths = Walk::new(&paths, &ignore_options).paths();
let paths = match apply_codeowners_file(&codeowner_options, paths) {
let paths = match Self::apply_codeowners_file(&codeowner_options, paths) {
Ok(new_paths) => new_paths,
Err(err) => return err,
};
@ -132,6 +87,53 @@ impl Runner for LintRunner {
}
}
impl LintRunner {
fn apply_codeowners_file(
options: &CodeownerOptions,
paths: Vec<Box<Path>>,
) -> Result<Vec<Box<Path>>, CliRunResult> {
if options.codeowners_file.is_some() && options.codeowners.is_empty() {
return Err(CliRunResult::InvalidOptions {
message: "No wanted codeowners provided.".to_string(),
});
}
let maybe_codeowners_file = options.codeowners_file.as_ref().map(codeowners::from_path);
if let Some(owners) = maybe_codeowners_file {
return Ok(paths
.into_iter()
.filter(|path_being_checked| {
// Strips the prefix of "./", because paths will look like "./foo/bar.js"
// however owners.of() will not match against these relative paths.
// So instead we simply strp the prefix and check against "foo/bar.js".
let path_to_check = path_being_checked
.strip_prefix("./")
.unwrap_or(path_being_checked)
.to_path_buf();
owners.of(path_to_check).map_or(false, |owners_of_path| {
owners_of_path
.iter()
.map(|owner| match owner {
codeowners::Owner::Email(s)
| codeowners::Owner::Team(s)
| codeowners::Owner::Username(s) => s,
})
.any(|owner| options.codeowners.contains(owner))
})
})
.collect::<Vec<_>>());
} else if options.codeowners_file.is_some() {
return Err(CliRunResult::InvalidOptions {
message: "Codeowners file could not be read or parsed.".to_string(),
});
}
Ok(paths)
}
}
#[cfg(all(test, not(target_os = "windows")))]
mod test {
use super::LintRunner;