From c3f4b0db2d96d080f2523d8ee5556468075b2b4c Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 9 Jan 2019 21:04:16 -0800 Subject: [PATCH] cargo metadata: Don't show `null` deps. If a package has a dependency without a library target, the "name" field was showing up as null in `resolve.nodes.deps`. At this time (AFAIK), binary-only dependencies are always ignored. Instead of making users filter out this entry (or more commonly, crash), just don't include it. --- src/cargo/ops/cargo_output_metadata.rs | 11 ++++----- src/doc/man/cargo-metadata.adoc | 2 +- src/doc/man/generated/cargo-metadata.html | 2 +- src/etc/man/cargo-metadata.1 | 2 +- tests/testsuite/metadata.rs | 29 +++++++++++++++++++++++ 5 files changed, 37 insertions(+), 9 deletions(-) diff --git a/src/cargo/ops/cargo_output_metadata.rs b/src/cargo/ops/cargo_output_metadata.rs index 0b05f667867..b3fed981a35 100644 --- a/src/cargo/ops/cargo_output_metadata.rs +++ b/src/cargo/ops/cargo_output_metadata.rs @@ -105,7 +105,7 @@ where { #[derive(Serialize)] struct Dep { - name: Option, + name: String, pkg: PackageId, } @@ -123,13 +123,12 @@ where dependencies: resolve.deps(id).map(|(pkg, _deps)| pkg).collect(), deps: resolve .deps(id) - .map(|(pkg, _deps)| { - let name = packages + .filter_map(|(pkg, _deps)| { + packages .get(&pkg) .and_then(|pkg| pkg.targets().iter().find(|t| t.is_lib())) - .and_then(|lib_target| resolve.extern_crate_name(id, pkg, lib_target).ok()); - - Dep { name, pkg } + .and_then(|lib_target| resolve.extern_crate_name(id, pkg, lib_target).ok()) + .map(|name| Dep { name, pkg }) }) .collect(), features: resolve.features_sorted(id), diff --git a/src/doc/man/cargo-metadata.adoc b/src/doc/man/cargo-metadata.adoc index 35e6926a834..760c8d4a9a9 100644 --- a/src/doc/man/cargo-metadata.adoc +++ b/src/doc/man/cargo-metadata.adoc @@ -212,7 +212,7 @@ The output has the following format: */ "deps": [ { - /* The name of the dependency. + /* The name of the dependency's library target. If this is a renamed dependency, this is the new name. */ diff --git a/src/doc/man/generated/cargo-metadata.html b/src/doc/man/generated/cargo-metadata.html index 271a8ea97ec..822e8d355fe 100644 --- a/src/doc/man/generated/cargo-metadata.html +++ b/src/doc/man/generated/cargo-metadata.html @@ -219,7 +219,7 @@

OUTPUT FORMAT

*/ "deps": [ { - /* The name of the dependency. + /* The name of the dependency's library target. If this is a renamed dependency, this is the new name. */ diff --git a/src/etc/man/cargo-metadata.1 b/src/etc/man/cargo-metadata.1 index b646ef7b25b..b639bc3bc04 100644 --- a/src/etc/man/cargo-metadata.1 +++ b/src/etc/man/cargo-metadata.1 @@ -233,7 +233,7 @@ The output has the following format: */ "deps": [ { - /* The name of the dependency. + /* The name of the dependency\(aqs library target. If this is a renamed dependency, this is the new name. */ diff --git a/tests/testsuite/metadata.rs b/tests/testsuite/metadata.rs index 7c5a2bf4ed5..33b3022200d 100644 --- a/tests/testsuite/metadata.rs +++ b/tests/testsuite/metadata.rs @@ -1669,3 +1669,32 @@ fn metadata_links() { ) .run() } + +#[test] +fn deps_with_bin_only() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + [dependencies] + bdep = { path = "bdep" } + "#, + ) + .file("src/lib.rs", "") + .file("bdep/Cargo.toml", &basic_bin_manifest("bdep")) + .file("bdep/src/main.rs", "fn main() {}") + .build(); + + let output = p + .cargo("metadata") + .exec_with_output() + .expect("cargo metadata failed"); + let stdout = std::str::from_utf8(&output.stdout).unwrap(); + let meta: serde_json::Value = serde_json::from_str(stdout).expect("failed to parse json"); + let nodes = &meta["resolve"]["nodes"]; + assert!(nodes[0]["deps"].as_array().unwrap().is_empty()); + assert!(nodes[1]["deps"].as_array().unwrap().is_empty()); +}