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

Add --avoid-proc-macros. #76

Merged
merged 2 commits into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 28 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,24 @@
list.join(" OR ")
}

fn get_node_name_filter(metadata: &Metadata, opt: &GetDependenciesOpt) -> Result<HashSet<String>> {
fn get_proc_macro_node_names(metadata: &Metadata, opt: &GetDependenciesOpt) -> HashSet<String> {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This function name doesn't shows the result value is affected by opt.avoid_proc_macros.
How about removing if opt.avoid_proc_macros and adding it at the calling site of this function?

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 could, but I think it'll make things less clear. The pattern is being used elsewhere already. If we moved everything out to the calling site, it sort of defeats the purpose of the functions.

fn get_node_name_filter(metadata: &Metadata, opt: &GetDependenciesOpt) -> Result<HashSet<String>> {

let mut proc_macros = HashSet::new();
if opt.avoid_proc_macros {
for packages in &metadata.packages {
for target in &packages.targets {
if target.crate_types.contains(&String::from("proc-macro")) {
proc_macros.insert(target.name.clone());
for package in &packages.dependencies {
proc_macros.insert(package.name.clone());
}
}
}
}
}
proc_macros
}

fn get_node_name_filter(metadata: &Metadata, opt: &GetDependenciesOpt) -> HashSet<String> {
let mut filter = HashSet::new();

let roots = if let Some(root) = metadata.root_package() {
Expand All @@ -32,18 +49,18 @@
for root in roots {
filter.insert(root.name.clone());
}
return Ok(filter);
return filter;
}

if opt.direct_deps_only {
for root in roots {
filter.insert(root.name.clone());
for package in root.dependencies.iter() {

Check warning on line 58 in src/lib.rs

View workflow job for this annotation

GitHub Actions / Build

it is more concise to loop over references to containers instead of using explicit iteration methods
filter.insert(package.name.clone());
}
}
}
Ok(filter)
filter
}

#[derive(Debug, Serialize, Clone, Hash, Ord, PartialOrd, Eq, PartialEq)]
Expand All @@ -63,16 +80,16 @@
let authors = if package.authors.is_empty() {
None
} else {
Some(package.authors.to_owned().join("|"))

Check warning on line 83 in src/lib.rs

View workflow job for this annotation

GitHub Actions / Build

implicitly cloning a `Vec` by calling `to_owned` on its dereferenced type
};
Self {
name: package.name.to_owned(),

Check warning on line 86 in src/lib.rs

View workflow job for this annotation

GitHub Actions / Build

implicitly cloning a `String` by calling `to_owned` on its dereferenced type
version: package.version.to_owned(),

Check warning on line 87 in src/lib.rs

View workflow job for this annotation

GitHub Actions / Build

implicitly cloning a `Version` by calling `to_owned` on its dereferenced type
authors,
repository: package.repository.to_owned(),

Check warning on line 89 in src/lib.rs

View workflow job for this annotation

GitHub Actions / Build

implicitly cloning a `Option` by calling `to_owned` on its dereferenced type
license: package.license.as_ref().map(|s| normalize(s)),
license_file: package.license_file.to_owned().map(|f| f.into_string()),

Check warning on line 91 in src/lib.rs

View workflow job for this annotation

GitHub Actions / Build

redundant closure

Check warning on line 91 in src/lib.rs

View workflow job for this annotation

GitHub Actions / Build

implicitly cloning a `Option` by calling `to_owned` on its dereferenced type
description: package

Check warning on line 92 in src/lib.rs

View workflow job for this annotation

GitHub Actions / Build

implicitly cloning a `Option` by calling `to_owned` on its dereferenced type
.description
.to_owned()
.map(|s| s.trim().replace('\n', " ")),
Expand All @@ -98,15 +115,17 @@

impl GitlabLicense {
fn parse_licenses(dependency: &DependencyDetails) -> Result<HashSet<Self>> {
let Some(license) = &dependency.license else {return Ok(HashSet::new())};
let Some(license) = &dependency.license else {
return Ok(HashSet::new());
};
let expression = spdx::Expression::parse_mode(license, spdx::ParseMode::LAX)?;
Ok(expression
.requirements()
.flat_map(|req| {

Check warning on line 124 in src/lib.rs

View workflow job for this annotation

GitHub Actions / Build

used `flat_map` where `filter_map` could be used instead
req.req.license.id().map(|license| Self {
id: license.name,
name: license.full_name,
url: Default::default(),

Check warning on line 128 in src/lib.rs

View workflow job for this annotation

GitHub Actions / Build

calling `String::default()` is more clear than this expression
})
})
.collect())
Expand Down Expand Up @@ -153,6 +172,7 @@
pub struct GetDependenciesOpt {
pub avoid_dev_deps: bool,
pub avoid_build_deps: bool,
pub avoid_proc_macros: bool,
pub direct_deps_only: bool,
pub root_only: bool,
}
Expand All @@ -163,7 +183,8 @@
) -> Result<Vec<DependencyDetails>> {
let metadata = metadata_command.exec()?;

let filter = get_node_name_filter(&metadata, &opt)?;
let node_name_filter = get_node_name_filter(&metadata, &opt);
let proc_macro_exclusions = get_proc_macro_node_names(&metadata, &opt);

let connected = {
let resolve = metadata.resolve.as_ref().expect("missing `resolve`");
Expand Down Expand Up @@ -218,7 +239,8 @@
.packages
.iter()
.filter(|p| connected.contains(&p.id))
.filter(|p| filter.is_empty() || filter.contains(&p.name))
.filter(|p| node_name_filter.is_empty() || node_name_filter.contains(&p.name))
.filter(|p| !proc_macro_exclusions.contains(&p.name))
.map(DependencyDetails::new)
.collect::<Vec<_>>();
detailed_dependencies.sort_unstable();
Expand Down
5 changes: 5 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,10 @@ struct Opt {
/// Exclude build dependencies
avoid_build_deps: bool,

#[clap(long, display_order(0))]
/// Exclude `proc_macros` dependencies
avoid_proc_macros: bool,

#[clap(long = "features", value_name = "FEATURE", display_order(0))]
/// Space-separated list of features to activate.
features: Option<Vec<String>>,
Expand Down Expand Up @@ -246,6 +250,7 @@ fn run() -> Result<()> {
let get_opts = GetDependenciesOpt {
avoid_dev_deps: opt.avoid_dev_deps,
avoid_build_deps: opt.avoid_build_deps,
avoid_proc_macros: opt.avoid_proc_macros,
direct_deps_only: opt.direct_deps_only,
root_only: opt.root_only,
};
Expand Down
Loading