Skip to content

Commit 69982de

Browse files
Merge pull request #365 from rustwasm/fitzgen-lockfile-bindgen-version
Fitzgen lockfile bindgen version
2 parents 6f0a8b8 + 3856db2 commit 69982de

File tree

12 files changed

+342
-197
lines changed

12 files changed

+342
-197
lines changed

Cargo.lock

Lines changed: 24 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ categories = ["wasm"]
1010

1111
[dependencies]
1212
atty = "0.2.11"
13+
cargo_metadata = "0.6.0"
1314
console = "0.6.1"
1415
curl = "0.4.13"
1516
failure = "0.1.2"

src/command/build.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use command::utils::{create_pkg_dir, set_crate_path};
66
use emoji;
77
use error::Error;
88
use indicatif::HumanDuration;
9+
use lockfile::Lockfile;
910
use manifest;
1011
use progressbar::Step;
1112
use readme;
@@ -239,7 +240,8 @@ impl Build {
239240

240241
fn step_install_wasm_bindgen(&mut self, step: &Step, log: &Logger) -> Result<(), Error> {
241242
info!(&log, "Identifying wasm-bindgen dependency...");
242-
let bindgen_version = manifest::get_wasm_bindgen_version(&self.crate_path)?;
243+
let lockfile = Lockfile::new(&self.crate_path)?;
244+
let bindgen_version = lockfile.require_wasm_bindgen()?;
243245
info!(&log, "Installing wasm-bindgen-cli...");
244246
let install_permitted = match self.mode {
245247
BuildMode::Normal => true,

src/command/test.rs

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ use super::build::BuildMode;
44
use bindgen;
55
use build;
66
use command::utils::set_crate_path;
7+
use console::style;
78
use emoji;
89
use error::Error;
910
use indicatif::HumanDuration;
11+
use lockfile::Lockfile;
1012
use manifest;
1113
use progressbar::Step;
1214
use slog::Logger;
@@ -238,12 +240,33 @@ impl Test {
238240

239241
fn step_install_wasm_bindgen(&mut self, step: &Step, log: &Logger) -> Result<(), Error> {
240242
info!(&log, "Identifying wasm-bindgen dependency...");
241-
let bindgen_version = manifest::get_wasm_bindgen_version(&self.crate_path)?;
242-
info!(&log, "Installing wasm-bindgen-cli...");
243+
let lockfile = Lockfile::new(&self.crate_path)?;
244+
let bindgen_version = lockfile.require_wasm_bindgen()?;
245+
246+
// Unlike `wasm-bindgen` and `wasm-bindgen-cli`, `wasm-bindgen-test`
247+
// will work with any semver compatible `wasm-bindgen-cli`, so just make
248+
// sure that it is depended upon, so we can run tests on
249+
// `wasm32-unkown-unknown`. Don't enforce that it is the same version as
250+
// `wasm-bindgen`.
251+
if lockfile.wasm_bindgen_test_version().is_none() {
252+
let message = format!(
253+
"Ensure that you have \"{}\" as a dependency in your Cargo.toml file:\n\
254+
[dev-dependencies]\n\
255+
wasm-bindgen-test = \"0.2\"",
256+
style("wasm-bindgen").bold().dim(),
257+
);
258+
return Err(Error::CrateConfig { message });
259+
}
243260

244261
let install_permitted = match self.mode {
245-
BuildMode::Normal => true,
246-
BuildMode::Noinstall => false,
262+
BuildMode::Normal => {
263+
info!(&log, "Ensuring wasm-bindgen-cli is installed...");
264+
true
265+
}
266+
BuildMode::Noinstall => {
267+
info!(&log, "Searching for existing wasm-bindgen-cli install...");
268+
false
269+
}
247270
};
248271

249272
bindgen::install_wasm_bindgen(
@@ -257,7 +280,7 @@ impl Test {
257280
self.test_runner_path = Some(bindgen::wasm_bindgen_test_runner_path(log, &self.crate_path)
258281
.expect("if installing wasm-bindgen succeeded, then we should have wasm-bindgen-test-runner too"));
259282

260-
info!(&log, "Installing wasm-bindgen-cli was successful.");
283+
info!(&log, "Getting wasm-bindgen-cli was successful.");
261284
Ok(())
262285
}
263286

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
#![deny(missing_docs)]
44

5+
extern crate cargo_metadata;
56
extern crate console;
67
extern crate curl;
78
#[macro_use]
@@ -31,6 +32,7 @@ pub mod build;
3132
pub mod command;
3233
pub mod emoji;
3334
pub mod error;
35+
pub mod lockfile;
3436
pub mod logger;
3537
pub mod manifest;
3638
pub mod npm;

src/lockfile.rs

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
//! Reading Cargo.lock lock file.
2+
3+
use std::fs;
4+
use std::path::{Path, PathBuf};
5+
6+
use cargo_metadata;
7+
use console::style;
8+
use error::Error;
9+
use toml;
10+
11+
/// This struct represents the contents of `Cargo.lock`.
12+
#[derive(Clone, Debug, Deserialize)]
13+
pub struct Lockfile {
14+
package: Vec<Package>,
15+
}
16+
17+
/// This struct represents a single package entry in `Cargo.lock`
18+
#[derive(Clone, Debug, Deserialize)]
19+
struct Package {
20+
name: String,
21+
version: String,
22+
}
23+
24+
impl Lockfile {
25+
/// Read the `Cargo.lock` file for the crate at the given path.
26+
pub fn new(crate_path: &Path) -> Result<Lockfile, Error> {
27+
let lock_path = get_lockfile_path(crate_path)?;
28+
let lockfile = fs::read_to_string(lock_path)?;
29+
toml::from_str(&lockfile).map_err(Error::from)
30+
}
31+
32+
/// Get the version of `wasm-bindgen` dependency used in the `Cargo.lock`.
33+
pub fn wasm_bindgen_version(&self) -> Option<&str> {
34+
self.get_package_version("wasm-bindgen")
35+
}
36+
37+
/// Like `wasm_bindgen_version`, except it returns an error instead of
38+
/// `None`.
39+
pub fn require_wasm_bindgen(&self) -> Result<&str, Error> {
40+
self.wasm_bindgen_version().ok_or_else(|| {
41+
let message = format!(
42+
"Ensure that you have \"{}\" as a dependency in your Cargo.toml file:\n\
43+
[dependencies]\n\
44+
wasm-bindgen = \"0.2\"",
45+
style("wasm-bindgen").bold().dim(),
46+
);
47+
Error::CrateConfig { message }
48+
})
49+
}
50+
51+
/// Get the version of `wasm-bindgen` dependency used in the `Cargo.lock`.
52+
pub fn wasm_bindgen_test_version(&self) -> Option<&str> {
53+
self.get_package_version("wasm-bindgen-test")
54+
}
55+
56+
fn get_package_version(&self, package: &str) -> Option<&str> {
57+
self.package
58+
.iter()
59+
.find(|p| p.name == package)
60+
.map(|p| &p.version[..])
61+
}
62+
}
63+
64+
/// Given the path to the crate that we are buliding, return a `PathBuf`
65+
/// containing the location of the lock file, by finding the workspace root.
66+
fn get_lockfile_path(crate_path: &Path) -> Result<PathBuf, Error> {
67+
// Identify the crate's root directory, or return an error.
68+
let manifest = crate_path.join("Cargo.toml");
69+
let crate_root = cargo_metadata::metadata(Some(&manifest))
70+
.map_err(|_| Error::CrateConfig {
71+
message: String::from("Error while processing crate metadata"),
72+
})?.workspace_root;
73+
// Check that a lock file can be found in the directory. Return an error
74+
// if it cannot, otherwise return the path buffer.
75+
let lockfile_path = Path::new(&crate_root).join("Cargo.lock");
76+
if !lockfile_path.is_file() {
77+
Err(Error::CrateConfig {
78+
message: format!("Could not find lockfile at {:?}", lockfile_path),
79+
})
80+
} else {
81+
Ok(lockfile_path)
82+
}
83+
}

0 commit comments

Comments
 (0)