main: Allow to pass a metadata file from the CLI.

This commit is contained in:
Emilio Cobos Álvarez
2020-06-19 16:19:36 +02:00
parent 229b714511
commit ce28fd7c8a
4 changed files with 52 additions and 34 deletions
+8 -17
View File
@@ -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() {
+2 -1
View File
@@ -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)
+26 -16
View File
@@ -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;
@@ -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;
@@ -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
View File
@@ -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
@@ -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")