Skip to content

Commit

Permalink
main: Allow to pass a metadata file from the CLI.
Browse files Browse the repository at this point in the history
  • Loading branch information
emilio committed Jun 24, 2020
1 parent 229b714 commit ce28fd7
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 34 deletions.
25 changes: 8 additions & 17 deletions src/bindgen/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,23 +313,14 @@ impl Builder {
if let Some((lib_dir, binding_lib_name)) = self.lib.clone() {
let lockfile = self.lockfile.as_ref().and_then(|p| p.to_str());

let cargo = if let Some(binding_lib_name) = binding_lib_name {
Cargo::load(
&lib_dir,
lockfile,
Some(&binding_lib_name),
self.config.parse.parse_deps,
self.config.parse.clean,
)?
} else {
Cargo::load(
&lib_dir,
lockfile,
None,
self.config.parse.parse_deps,
self.config.parse.clean,
)?
};
let cargo = Cargo::load(
&lib_dir,
lockfile,
binding_lib_name.as_deref(),
self.config.parse.parse_deps,
self.config.parse.clean,
/* existing_metadata = */ None,
)?;

result.extend_with(&parser::parse_lib(cargo, &self.config)?);
} else if let Some(cargo) = self.lib_cargo.clone() {
Expand Down
3 changes: 2 additions & 1 deletion src/bindgen/cargo/cargo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,10 @@ impl Cargo {
binding_crate_name: Option<&str>,
use_cargo_lock: bool,
clean: bool,
existing_metadata_file: Option<&Path>,
) -> Result<Cargo, Error> {
let toml_path = crate_dir.join("Cargo.toml");
let metadata = cargo_metadata::metadata(&toml_path)
let metadata = cargo_metadata::metadata(&toml_path, existing_metadata_file)
.map_err(|x| Error::CargoMetadata(toml_path.to_str().unwrap().to_owned(), x))?;
let lock_path = lock_file
.map(PathBuf::from)
Expand Down
42 changes: 26 additions & 16 deletions src/bindgen/cargo/cargo_metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
// 3. Add `--all-features` argument
// 4. Remove the `--no-deps` argument

use std::borrow::Borrow;
use std::borrow::{Borrow, Cow};
use std::collections::{HashMap, HashSet};
use std::env;
use std::error;
Expand All @@ -18,7 +18,7 @@ use std::hash::{Hash, Hasher};
use std::io;
use std::path::Path;
use std::process::{Command, Output};
use std::str::{from_utf8, Utf8Error};
use std::str::Utf8Error;

use serde_json;

Expand Down Expand Up @@ -179,19 +179,29 @@ impl PartialEq for Dependency {
impl Eq for Dependency {}

/// The main entry point to obtaining metadata
pub fn metadata(manifest_path: &Path) -> Result<Metadata, Error> {
let cargo = env::var("CARGO").unwrap_or_else(|_| String::from("cargo"));
let mut cmd = Command::new(cargo);
cmd.arg("metadata");
cmd.arg("--all-features");
cmd.arg("--format-version").arg("1");
cmd.arg("--manifest-path");
cmd.arg(manifest_path);
let output = cmd.output()?;
if !output.status.success() {
return Err(Error::Metadata(output));
}
let stdout = from_utf8(&output.stdout)?;
let meta: Metadata = serde_json::from_str(stdout)?;
pub fn metadata(
manifest_path: &Path,
existing_metadata_file: Option<&Path>,
) -> Result<Metadata, Error> {
let output;
let metadata = match existing_metadata_file {
Some(path) => Cow::Owned(std::fs::read_to_string(path)?),
None => {
let cargo = env::var("CARGO").unwrap_or_else(|_| String::from("cargo"));
let mut cmd = Command::new(cargo);
cmd.arg("metadata");
cmd.arg("--all-features");
cmd.arg("--format-version").arg("1");
cmd.arg("--manifest-path");
cmd.arg(manifest_path);
output = cmd.output()?;
if !output.status.success() {
return Err(Error::Metadata(output));
}
Cow::Borrowed(std::str::from_utf8(&output.stdout)?)
}
};

let meta: Metadata = serde_json::from_str(&*metadata)?;
Ok(meta)
}
16 changes: 16 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ fn load_bindings<'a>(input: &Path, matches: &ArgMatches<'a>) -> Result<Bindings,
matches.value_of("crate"),
true,
matches.is_present("clean"),
matches.value_of("metadata").map(Path::new),
)?;

// Load any config specified or search in the binding crate directory
Expand Down Expand Up @@ -210,6 +211,21 @@ fn main() {
projects that use workspaces.")
.required(false),
)
.arg(
Arg::with_name("metadata")
.long("metadata")
.value_name("PATH")
.help(
"Specify the path to the output of a `cargo metadata` \
command that allows to get dependency information. \
This is useful because cargo metadata may be the longest \
part of cbindgen runtime, and you may want to share it \
across cbindgen invocations. By default cbindgen will run \
`cargo metadata --all-features --format-version 1 \
--manifest-path <path/to/crate/Cargo.toml>"
)
.required(false),
)
.arg(
Arg::with_name("quiet")
.short("q")
Expand Down

0 comments on commit ce28fd7

Please sign in to comment.