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

Matching Package or NodeDep to Dependency #84

Closed
l0calh05t opened this issue Jul 14, 2019 · 10 comments
Closed

Matching Package or NodeDep to Dependency #84

l0calh05t opened this issue Jul 14, 2019 · 10 comments

Comments

@l0calh05t
Copy link

l0calh05t commented Jul 14, 2019

While the Package contains a list of direct dependencies, how can I match a Dependency to a corresponding Package? I initially considered using NodeDep which contains a PackageId, but the names in NodeDep do not always match the names in Dependency (even if considering renames).

For example:
backtrace's list of NodeDeps contains "backtrace_sys", while it's list of Dependencys contains only "backtrace-sys" and rename is None.

This could also be a bug/issue with cargo metadata itself, or I'm just using it incorrectly - especially since the lengths of the two lists often don't match.

My current workaround (which feels quite hacky, but works so far), where root_node is a Node and root_package is the corresponding Package:

for dep in root_node.deps.iter() {
	let dependency = root_package.dependencies.iter().find(|dependency| {
		dependency.rename.as_ref() == Some(&dep.name)
			|| (dependency.rename == None && dependency.name == dep.name)
			|| format!("{}", dep.pkg).starts_with(&dependency.name)
	});
}
@l0calh05t l0calh05t changed the title Matching Package or NodeDeps Matching Package or NodeDep to Dependency Jul 14, 2019
@oli-obk
Copy link
Owner

oli-obk commented Jul 14, 2019

I do not know. This crate only exposes the information from cargo metadata without doing any significant additional processing. If you have any ideas on API improvements to improve the usability, I'm all ear.

@ehuss
Copy link
Contributor

ehuss commented Jul 14, 2019

You cannot (easily) go from a Dependency to a Package. That involves Cargo's resolver, which discards the Dependency information once it is resolved to a package. Your example workaround would also need to handle matching versionreq specifiers against version strings, for example (since there could be multiple matches). The name in NodeDep.name is the library crate name which does not have to be the same as the Package name.

Can you explain more about why you want to match them?

@l0calh05t
Copy link
Author

@ehuss I want to generate a transitive list of normal dependencies (excluding build/development dependencies, information that is stored in Dependency) and their licenses (stored in Package). If I just take the list of packages, I also get all build dependencies and their dependencies, as well as development dependencies of the root package. (I'm investigating if I can solve onur/cargo-license#18 myself)

@ehuss
Copy link
Contributor

ehuss commented Jul 14, 2019

Unfortunately I don't see a way to reliably do that with the current information. This is essentially rust-lang/cargo#5583 and rust-lang/cargo#4631.

I have created a PR to try to address this: rust-lang/cargo#7132. I'd appreciate it if you can take a look at it and provide feedback if it would work. I'm not familiar with cargo-license, but I would suspect it would run MetadataCommand with all features enabled. It could then iterate over Metadata.workspace_members to determine the root nodes. It would then search through Resolve.nodes to find those roots and look at all deps. It can filter those based on the kind as desired, and then recurse for each dependency package id. Presumably cargo-license wants all platforms to be included, correct?

@l0calh05t
Copy link
Author

From looking at it, it doesn't seem to look at Resolve at all, but instead simply lists all Packages and their licenses.

@ehuss
Copy link
Contributor

ehuss commented Jul 19, 2019

From looking at it, it doesn't seem to look at Resolve at all, but instead simply lists all Packages and their licenses.

Right. If you want to filter based on kind, you would need to change it to traverse the resolve graph, filtering based on kind.

@l0calh05t
Copy link
Author

Right. If you want to filter based on kind, you would need to change it to traverse the resolve graph, filtering based on kind.

Exactly, which is what I was attempting to do, but then failed at the point of matching the different representations due to the lack of package ID, leading to this PR.

@ehuss
Copy link
Contributor

ehuss commented Nov 30, 2019

It is still very difficult to correlate the resolve nodes with the package dependencies, but with #91, you can now detect the dependency kind (normal/build/devel) within the resolve graph.

@oli-obk
Copy link
Owner

oli-obk commented Jul 12, 2020

There's a higher level wrapper around cargo_metadata called guppy, maybe that works better for you?

@oli-obk
Copy link
Owner

oli-obk commented Feb 25, 2021

Closing as out of scope

@oli-obk oli-obk closed this as completed Feb 25, 2021
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

No branches or pull requests

3 participants