Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
oli-obk committed Jan 24, 2017
0 parents commit 9b00917
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
target
Cargo.lock
12 changes: 12 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "cargo_metadata"
version = "0.1.0"
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`"
license = "MIT"

[dependencies]
serde = "0.9.0-rc3"
serde_json = "0.9.0-rc2"
serde_derive = "0.9.0-rc3"
110 changes: 110 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
#![deny(missing_docs)]
//! Structured access to the output of `cargo metadata`
//! Usually used from within a `cargo-*` executable
//!
//! ```rust
//! let manifest_path_arg = std::env::args().skip(2).find(|val| val.starts_with("--manifest-path="));
//! let mut metadata = cargo::metadata(manifest_path_arg.as_ref().map(AsRef::as_ref)).unwrap();
//! ```
extern crate serde;
extern crate serde_json;
#[macro_use] extern crate serde_derive;

use std::collections::HashMap;
use std::process::Command;
use std::str::{from_utf8, Utf8Error};
use std::io;

#[derive(Deserialize, Debug)]
/// Starting point for metadata returned by `cargo metadata`
pub struct Metadata {
/// A list of all crates referenced by this crate (and the crate itself)
pub packages: Vec<Package>,
resolve: Option<()>,
version: usize,
}

#[derive(Deserialize, Debug)]
/// A crate
pub struct Package {
/// Name as given in the `Cargo.toml`
pub name: String,
/// Version given in the `Cargo.toml`
pub version: String,
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`
pub manifest_path: String,
}

#[derive(Deserialize, Debug)]
/// A dependency of the main crate
pub struct Dependency {
/// Name as given in the `Cargo.toml`
pub name: String,
source: Option<String>,
/// Whether this is required or optional
pub req: String,
kind: Option<String>,
optional: bool,
uses_default_features: bool,
features: Vec<String>,
target: Option<String>,
}

#[derive(Deserialize, Debug)]
/// A single target (lib, bin, example, ...) provided by a crate
pub struct Target {
/// Name as given in the `Cargo.toml` or generated from the file name
pub name: String,
/// Kind of target ("bin", "example", "test", "bench", "lib")
pub kind: Vec<String>,
src_path: String,
}

#[derive(Debug)]
/// Possible errors that can occur during metadata parsing.
pub enum Error {
/// Error during execution of `cargo metadata`
Io(io::Error),
/// Output of `cargo metadata` was not valid utf8
Utf8(Utf8Error),
/// Deserialization error (structure of json did not match expected structure)
Json(serde_json::Error),
}

impl From<io::Error> for Error {
fn from(err: io::Error) -> Self {
Error::Io(err)
}
}
impl From<Utf8Error> for Error {
fn from(err: Utf8Error) -> Self {
Error::Utf8(err)
}
}
impl From<serde_json::Error> for Error {
fn from(err: serde_json::Error) -> Self {
Error::Json(err)
}
}

/// The main entry point to obtaining metadata
pub fn metadata(manifest_path_arg: Option<&str>) -> Result<Metadata, Error> {
let mut cmd = Command::new("cargo");
cmd.arg("metadata").arg("--no-deps");
if let Some(mani) = manifest_path_arg {
cmd.arg(mani);
}
let output = cmd.output()?;
let stdout = from_utf8(&output.stdout)?;
let meta: Metadata = serde_json::from_str(&stdout)?;
assert_eq!(meta.version, 1, "please update your `cargo_metadata` dependency to support the new metadata version");

This comment has been minimized.

Copy link
@matklad

matklad Mar 17, 2017

Contributor

I think it would be better to pass --format-version 1 explicitly when invoking cargo metadata. If the second version is added, cargo should support both versions for some time.

This comment has been minimized.

Copy link
@oli-obk

oli-obk Mar 17, 2017

Author Owner

Ah cool, I didn't know about that.

This comment has been minimized.

Copy link
@matklad

matklad Mar 17, 2017

Contributor
Ok(meta)
}

0 comments on commit 9b00917

Please sign in to comment.