Skip to content

Commit

Permalink
Execute cargo metadata at most once
Browse files Browse the repository at this point in the history
This can be somewhat expensive, so make sure we don't have to chew
through too much!
  • Loading branch information
alexcrichton committed Sep 24, 2018
1 parent 3d1f528 commit 76a34b3
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 43 deletions.
6 changes: 4 additions & 2 deletions src/command/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use command::utils::{create_pkg_dir, set_crate_path};
use emoji;
use error::Error;
use indicatif::HumanDuration;
use lockfile;
use lockfile::Lockfile;
use manifest;
use progressbar::Step;
use readme;
Expand All @@ -19,6 +19,7 @@ use PBAR;
/// Everything required to configure and run the `wasm-pack init` command.
pub(crate) struct Build {
pub crate_path: PathBuf,
pub lockfile: Lockfile,
pub scope: Option<String>,
pub disable_dts: bool,
pub target: String,
Expand Down Expand Up @@ -101,6 +102,7 @@ impl Build {
let out_dir = crate_path.join(PathBuf::from(build_opts.out_dir));
// let build_config = manifest::xxx(&crate_path).xxx();
Ok(Build {
lockfile: Lockfile::new(&crate_path)?,
crate_path,
scope: build_opts.scope,
disable_dts: build_opts.disable_dts,
Expand Down Expand Up @@ -240,7 +242,7 @@ impl Build {

fn step_install_wasm_bindgen(&mut self, step: &Step, log: &Logger) -> Result<(), Error> {
info!(&log, "Identifying wasm-bindgen dependency...");
let bindgen_version = lockfile::get_wasm_bindgen_version(&self.crate_path)?;
let bindgen_version = self.lockfile.require_wasm_bindgen()?;
info!(&log, "Installing wasm-bindgen-cli...");
let install_permitted = match self.mode {
BuildMode::Normal => true,
Expand Down
17 changes: 14 additions & 3 deletions src/command/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ use super::build::BuildMode;
use bindgen;
use build;
use command::utils::set_crate_path;
use console::style;
use emoji;
use error::Error;
use indicatif::HumanDuration;
use lockfile;
use lockfile::Lockfile;
use manifest;
use progressbar::Step;
use slog::Logger;
Expand Down Expand Up @@ -91,6 +92,7 @@ pub struct Test {
headless: bool,
release: bool,
test_runner_path: Option<PathBuf>,
lockfile: Lockfile,
}

type TestStep = fn(&mut Test, &Step, &Logger) -> Result<(), Error>;
Expand Down Expand Up @@ -136,6 +138,7 @@ impl Test {
}

Ok(Test {
lockfile: Lockfile::new(&crate_path)?,
crate_path,
node,
mode,
Expand Down Expand Up @@ -239,14 +242,22 @@ impl Test {

fn step_install_wasm_bindgen(&mut self, step: &Step, log: &Logger) -> Result<(), Error> {
info!(&log, "Identifying wasm-bindgen dependency...");
let bindgen_version = lockfile::get_wasm_bindgen_version(&self.crate_path)?;
let bindgen_version = self.lockfile.require_wasm_bindgen()?;

// Unlike `wasm-bindgen` and `wasm-bindgen-cli`, `wasm-bindgen-test`
// will work with any semver compatible `wasm-bindgen-cli`, so just make
// sure that it is depended upon, so we can run tests on
// `wasm32-unkown-unknown`. Don't enforce that it is the same version as
// `wasm-bindgen`.
let _bindgen_test_version = lockfile::get_wasm_bindgen_test_version(&self.crate_path)?;
if self.lockfile.wasm_bindgen_test_version().is_none() {
let message = format!(
"Ensure that you have \"{}\" as a dependency in your Cargo.toml file:\n\
[dev-dependencies]\n\
wasm-bindgen-test = \"0.2\"",
style("wasm-bindgen").bold().dim(),
);
return Err(Error::CrateConfig { message })
}

let install_permitted = match self.mode {
BuildMode::Normal => {
Expand Down
66 changes: 29 additions & 37 deletions src/lockfile.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//! Reading Cargo.lock lock file.
use std::fs::File;
use std::io::Read;
use std::fs;
use std::path::{Path, PathBuf};

use cargo_metadata;
Expand All @@ -11,7 +10,7 @@ use toml;

/// This struct represents the contents of `Cargo.lock`.
#[derive(Clone, Debug, Deserialize)]
struct Lockfile {
pub struct Lockfile {
package: Vec<Package>,
}

Expand All @@ -23,50 +22,43 @@ struct Package {
}

impl Lockfile {
fn get_package_version(&self, package: &str) -> Option<String> {
self.package
.iter()
.find(|p| p.name == package)
.map(|p| p.version.clone())
/// Read the `Cargo.lock` file for the crate at the given path.
pub fn new(crate_path: &Path) -> Result<Lockfile, Error> {
let lock_path = get_lockfile_path(crate_path)?;
let lockfile = fs::read_to_string(lock_path)?;
toml::from_str(&lockfile).map_err(Error::from)
}
}

/// Get the version of `wasm-bindgen` dependency used in the `Cargo.lock`.
pub fn get_wasm_bindgen_version(path: &Path) -> Result<String, Error> {
let lockfile = read_cargo_lock(&path)?;
lockfile.get_package_version("wasm-bindgen").ok_or_else(|| {
let message = format!(
"Ensure that you have \"{}\" as a dependency in your Cargo.toml file:\n\
[dependencies]\n\
wasm-bindgen = \"0.2\"",
style("wasm-bindgen").bold().dim(),
);
Error::CrateConfig { message }
})
}
/// Get the version of `wasm-bindgen` dependency used in the `Cargo.lock`.
pub fn wasm_bindgen_version(&self) -> Option<&str> {
self.get_package_version("wasm-bindgen")
}

/// Get the version of `wasm-bindgen` dependency used in the `Cargo.lock`.
pub fn get_wasm_bindgen_test_version(path: &Path) -> Result<String, Error> {
let lockfile = read_cargo_lock(&path)?;
lockfile
.get_package_version("wasm-bindgen-test")
.ok_or_else(|| {
/// Like `wasm_bindgen_version`, except it returns an error instead of
/// `None`.
pub fn require_wasm_bindgen(&self) -> Result<&str, Error> {
self.wasm_bindgen_version().ok_or_else(|| {
let message = format!(
"Ensure that you have \"{}\" as a dependency in your Cargo.toml file:\n\
[dev-dependencies]\n\
wasm-bindgen-test = \"0.2\"",
[dependencies]\n\
wasm-bindgen = \"0.2\"",
style("wasm-bindgen").bold().dim(),
);
Error::CrateConfig { message }
})
}
}

/// Get the version of `wasm-bindgen` dependency used in the `Cargo.lock`.
pub fn wasm_bindgen_test_version(&self) -> Option<&str> {
self.get_package_version("wasm-bindgen-test")
}

/// Read the `Cargo.lock` file for the crate at the given path.
fn read_cargo_lock(crate_path: &Path) -> Result<Lockfile, Error> {
let lock_path = get_lockfile_path(crate_path)?;
let mut lockfile = String::new();
File::open(lock_path)?.read_to_string(&mut lockfile)?;
toml::from_str(&lockfile).map_err(Error::from)
fn get_package_version(&self, package: &str) -> Option<&str> {
self.package
.iter()
.find(|p| p.name == package)
.map(|p| &p.version[..])
}
}

/// Given the path to the crate that we are buliding, return a `PathBuf`
Expand Down
2 changes: 1 addition & 1 deletion tests/all/lockfile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ fn it_gets_wasm_bindgen_test_version() {
fixture.cargo_check();
assert_eq!(
lockfile::get_wasm_bindgen_test_version(&fixture.path).unwrap(),
"0.2.21"
Some("0.2.21".to_string())
);
}

Expand Down

0 comments on commit 76a34b3

Please sign in to comment.