Repository: oli-obk/cargo_metadata
Pull request #9 (2017-06-11 18:21:38)

 Include dependencies graph in the `Metadata`
I plan to use this for https://github.com/Manishearth/rust-clippy/issues/1797.


Patch:
diff --git a/Cargo.toml b/Cargo.toml
index 30c5b7e..fae58d6 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "cargo_metadata"
-version = "0.2.1"
+version = "0.2.2"
 authors = ["Oliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>"]
 repository = "https://github.com/oli-obk/cargo_metadata"
 description = "structured access to the output of `cargo metadata`"
diff --git a/src/lib.rs b/src/lib.rs
index 9df05c7..6cfa05e 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -23,10 +23,27 @@ use std::io;
 pub struct Metadata {
     /// A list of all crates referenced by this crate (and the crate itself)
     pub packages: Vec<Package>,
-    resolve: Option<()>,
+    /// Dependencies graph
+    pub resolve: Option<Resolve>,
     version: usize,
 }
 
+#[derive(Clone, Deserialize, Debug)]
+/// A dependency graph
+pub struct Resolve {
+    /// Nodes in a dependencies graph
+    pub nodes: Vec<Node>,
+}
+
+#[derive(Clone, Deserialize, Debug)]
+/// A node in a dependencies graph
+pub struct Node {
+    /// An opaque identifier for a package
+    pub id: String,
+    /// List of opaque identifiers for this node's dependencies
+    pub dependencies: Vec<String>,
+}
+
 #[derive(Clone, Deserialize, Debug)]
 /// A crate
 pub struct Package {
@@ -34,14 +51,15 @@ pub struct Package {
     pub name: String,
     /// Version given in the `Cargo.toml`
     pub version: String,
-    id: String,
+    /// An opaque identifier for a package
+    pub id: String,
     source: Option<String>,
     /// List of dependencies of this particular package
     pub dependencies: Vec<Dependency>,
     /// Targets provided by the crate (lib, bin, example, test, ...)
     pub targets: Vec<Target>,
     features: HashMap<String, Vec<String>>,
-    /// path containing the `Cargo.toml`
+    /// Path containing the `Cargo.toml`
     pub manifest_path: String,
 }
 
@@ -102,11 +120,30 @@ impl From<serde_json::Error> for Error {
     }
 }
 
-/// The main entry point to obtaining metadata
+/// Obtain metadata only about the root package and don't fetch dependencies
+///
+/// # Parameters
+///
+/// - `manifest_path_arg`: Path to the manifest.
 pub fn metadata(manifest_path_arg: Option<&str>) -> Result<Metadata, Error> {
+    metadata_deps(manifest_path_arg, false)
+}
+
+/// The main entry point to obtaining metadata
+///
+/// # Parameters
+///
+/// - `manifest_path_arg`: Path to the manifest.
+/// - `deps`: Whether to include dependencies.
+pub fn metadata_deps(manifest_path_arg: Option<&str>, deps: bool) -> Result<Metadata, Error> {
     let cargo = env::var("CARGO").unwrap_or_else(|_| String::from("cargo"));
     let mut cmd = Command::new(cargo);
-    cmd.arg("metadata").arg("--no-deps");
+    cmd.arg("metadata");
+
+    if !deps {
+        cmd.arg("--no-deps");
+    }
+
     cmd.arg("--format-version").arg("1");
     if let Some(mani) = manifest_path_arg {
         cmd.arg(mani);


Test patch:
diff --git a/tests/selftest.rs b/tests/selftest.rs
index 43f0fd9..4f7148a 100644
--- a/tests/selftest.rs
+++ b/tests/selftest.rs
@@ -1,8 +1,9 @@
 extern crate cargo_metadata;
 
 #[test]
-fn foo() {
+fn metadata() {
     let metadata = cargo_metadata::metadata(None).unwrap();
+
     assert_eq!(metadata.packages[0].name, "cargo_metadata");
     assert_eq!(metadata.packages[0].targets.len(), 2);
 
@@ -14,3 +15,20 @@ fn foo() {
     assert_eq!(metadata.packages[0].targets[1].kind[0], "test");
     assert_eq!(metadata.packages[0].targets[1].crate_types[0], "bin");
 }
+
+#[test]
+fn metadata_deps() {
+    let metadata = cargo_metadata::metadata_deps(None, true).unwrap();
+    let this = metadata.packages.iter().find(|package| package.name == "cargo_metadata").expect("Did not find ourselves");
+
+    assert_eq!(this.name, "cargo_metadata");
+    assert_eq!(this.targets.len(), 2);
+
+    assert_eq!(this.targets[0].name, "cargo_metadata");
+    assert_eq!(this.targets[0].kind[0], "lib");
+    assert_eq!(this.targets[0].crate_types[0], "lib");
+
+    assert_eq!(this.targets[1].name, "selftest");
+    assert_eq!(this.targets[1].kind[0], "test");
+    assert_eq!(this.targets[1].crate_types[0], "bin");
+}