From 0ba6e5ee2a84c2f10676110e9769ece76ec39a30 Mon Sep 17 00:00:00 2001 From: data-pup Date: Mon, 18 Jun 2018 20:01:51 -0400 Subject: [PATCH] Solves #146. Check locally installed wasm-bindgen dependency. --- src/bindgen.rs | 56 ++++++++++++++++++++++++++++++++++++++++----- src/build.rs | 9 +++++--- src/command/init.rs | 12 +++++++--- src/emoji.rs | 1 + src/error.rs | 12 +++++----- src/manifest.rs | 44 ++++++++++++++++++++++++----------- src/npm.rs | 7 +++--- 7 files changed, 107 insertions(+), 34 deletions(-) diff --git a/src/bindgen.rs b/src/bindgen.rs index dece43f8a..59d29c4c3 100644 --- a/src/bindgen.rs +++ b/src/bindgen.rs @@ -1,16 +1,59 @@ use emoji; use error::Error; use progressbar::Step; -use std::process::Command; +use std::{path, process::Command}; use PBAR; -pub fn cargo_install_wasm_bindgen(step: &Step) -> Result<(), Error> { +#[cfg(not(target_family = "windows"))] +static LOCAL_BINDGEN_PATH: &str = "bin/wasm-bindgen"; + +#[cfg(target_family = "windows")] +static LOCAL_BINDGEN_PATH: &str = "bin\\wasm-bindgen"; + +fn local_wasm_bindgen_path_str(crate_path: &str) -> String { + #[cfg(not(target_family = "windows"))] + return format!("{}/{}", crate_path, LOCAL_BINDGEN_PATH); + #[cfg(target_family = "windows")] + return format!("{}\\{}", crate_path, LOCAL_BINDGEN_PATH); +} + +pub fn wasm_bindgen_version_check( + crate_path: &str, + dep_version: &str, + step: &Step, +) -> Result { + let msg = format!("{}Checking WASM-bindgen dependency...", emoji::CHECK); + PBAR.step(step, &msg); + + let wasm_bindgen = local_wasm_bindgen_path_str(crate_path); + if !path::Path::new(&wasm_bindgen).is_file() { + return Ok(false); + } + + let output = Command::new(wasm_bindgen).arg("--version").output()?; + if output.status.success() { + let s = String::from_utf8_lossy(&output.stdout); + let installed_version = s.trim(); + Ok(installed_version == dep_version) + } else { + let error_msg = "Could not find version of local wasm-bindgen"; + let s = String::from_utf8_lossy(&output.stderr); + let e = Error::cli(error_msg, s); + Err(e) + } +} + +pub fn cargo_install_wasm_bindgen(path: &str, version: &str, step: &Step) -> Result<(), Error> { let msg = format!("{}Installing WASM-bindgen...", emoji::DOWN_ARROW); PBAR.step(step, &msg); let output = Command::new("cargo") .arg("install") - .arg("wasm-bindgen-cli") .arg("--force") + .arg("wasm-bindgen-cli") + .arg("--version") + .arg(version) + .arg("--root") + .arg(path) .output()?; if !output.status.success() { let s = String::from_utf8_lossy(&output.stderr); @@ -18,7 +61,7 @@ pub fn cargo_install_wasm_bindgen(step: &Step) -> Result<(), Error> { PBAR.info("wasm-bindgen already installed"); return Ok(()); } - Error::cli("Installing wasm-bindgen failed", s) + Err(Error::cli("Installing wasm-bindgen failed", s)) } else { Ok(()) } @@ -51,7 +94,8 @@ pub fn wasm_bindgen_build( _ => "--browser", }; - let output = Command::new("wasm-bindgen") + let wasm_bindgen = local_wasm_bindgen_path_str(path); + let output = Command::new(wasm_bindgen) .current_dir(path) .arg(&wasm_path) .arg("--out-dir") @@ -61,7 +105,7 @@ pub fn wasm_bindgen_build( .output()?; if !output.status.success() { let s = String::from_utf8_lossy(&output.stderr); - Error::cli("wasm-bindgen failed to execute properly", s) + Err(Error::cli("wasm-bindgen failed to execute properly", s)) } else { Ok(()) } diff --git a/src/build.rs b/src/build.rs index 61d02d26d..8d5d1f42d 100644 --- a/src/build.rs +++ b/src/build.rs @@ -17,7 +17,10 @@ pub fn rustup_add_wasm_target(step: &Step) -> Result<(), Error> { .output()?; if !output.status.success() { let s = String::from_utf8_lossy(&output.stderr); - Error::cli("Adding the wasm32-unknown-unknown target failed", s) + Err(Error::cli( + "Adding the wasm32-unknown-unknown target failed", + s, + )) } else { Ok(()) } @@ -33,7 +36,7 @@ fn ensure_nightly() -> Result<(), Error> { .output()?; if !res.status.success() { let s = String::from_utf8_lossy(&res.stderr); - return Error::cli("Adding the nightly toolchain failed", s); + return Err(Error::cli("Adding the nightly toolchain failed", s)); } } Ok(()) @@ -54,7 +57,7 @@ pub fn cargo_build_wasm(path: &str, debug: bool, step: &Step) -> Result<(), Erro if !output.status.success() { let s = String::from_utf8_lossy(&output.stderr); - Error::cli("Compilation of your program failed", s) + Err(Error::cli("Compilation of your program failed", s)) } else { Ok(()) } diff --git a/src/command/init.rs b/src/command/init.rs index b65c7e3f9..5ccb679c1 100644 --- a/src/command/init.rs +++ b/src/command/init.rs @@ -192,9 +192,15 @@ impl Init { } fn step_install_wasm_bindgen(&mut self, step: &Step, log: &Logger) -> Result<(), Error> { - info!(&log, "Installing wasm-bindgen-cli..."); - bindgen::cargo_install_wasm_bindgen(step)?; - info!(&log, "Installing wasm-bindgen-cli was successful."); + info!(&log, "Checking WASM-bindgen version..."); + let bindgen_version = manifest::get_wasm_bindgen_version(&self.crate_path)?; + let bindgen_installed = + bindgen::wasm_bindgen_version_check(&self.crate_path, &bindgen_version, step)?; + if !bindgen_installed { + info!(&log, "Installing wasm-bindgen-cli..."); + bindgen::cargo_install_wasm_bindgen(&self.crate_path, &bindgen_version, step)?; + info!(&log, "Installing wasm-bindgen-cli was successful."); + } info!(&log, "Getting the crate name from the manifest..."); self.crate_name = manifest::get_crate_name(&self.crate_path)?; diff --git a/src/emoji.rs b/src/emoji.rs index e93119c9d..5a6b6fb6f 100644 --- a/src/emoji.rs +++ b/src/emoji.rs @@ -13,3 +13,4 @@ pub static DANCERS: Emoji = Emoji("đŸ‘¯ ", ""); pub static ERROR: Emoji = Emoji("⛔ ", ""); pub static INFO: Emoji = Emoji("ℹī¸ ", ""); pub static WRENCH: Emoji = Emoji("🔧 ", ""); +pub static CHECK: Emoji = Emoji("✓ ", ""); diff --git a/src/error.rs b/src/error.rs index 0bd2ba672..e0bb680f1 100644 --- a/src/error.rs +++ b/src/error.rs @@ -20,17 +20,17 @@ pub enum Error { } impl Error { - pub fn cli(message: &str, stderr: Cow) -> Result<(), Self> { - Err(Error::Cli { + pub fn cli(message: &str, stderr: Cow) -> Self { + Error::Cli { message: message.to_string(), stderr: stderr.to_string(), - }) + } } - pub fn crate_config(message: &str) -> Result<(), Self> { - Err(Error::CrateConfig { + pub fn crate_config(message: &str) -> Self { + Error::CrateConfig { message: message.to_string(), - }) + } } pub fn error_type(&self) -> String { diff --git a/src/manifest.rs b/src/manifest.rs index 7addfb5bb..05946b606 100644 --- a/src/manifest.rs +++ b/src/manifest.rs @@ -148,6 +148,30 @@ pub fn get_crate_name(path: &str) -> Result { Ok(read_cargo_toml(path)?.package.name) } +pub fn get_wasm_bindgen_version(path: &str) -> Result { + match read_cargo_toml(path)? + .dependencies + .and_then(|deps| deps.wasm_bindgen) + { + Some(ref version) if version.is_empty() => { + let msg = format!( + "\"{}\" dependency is missing its version number", + style("wasm-bindgen").bold().dim() + ); + let e = Error::crate_config(&msg); + Err(e) + } + Some(version) => Ok(version), + None => { + let msg = format!( + "Ensure that you have \"{}\" as a dependency in your Cargo.toml file:\n[dependencies]\nwasm-bindgen = \"0.2\"", + style("wasm-bindgen").bold().dim()); + let e = Error::crate_config(&msg); + Err(e) + } + } +} + pub fn check_crate_config(path: &str, step: &Step) -> Result<(), Error> { let msg = format!("{}Checking crate configuration...", emoji::WRENCH); PBAR.step(&step, &msg); @@ -157,15 +181,8 @@ pub fn check_crate_config(path: &str, step: &Step) -> Result<(), Error> { } fn check_wasm_bindgen(path: &str) -> Result<(), Error> { - if read_cargo_toml(path)?.dependencies.map_or(false, |x| { - !x.wasm_bindgen.unwrap_or("".to_string()).is_empty() - }) { - return Ok(()); - } - Error::crate_config(&format!( - "Ensure that you have \"{}\" as a dependency in your Cargo.toml file:\n[dependencies]\nwasm-bindgen = \"0.2\"", - style("wasm-bindgen").bold().dim() - )) + let _ = get_wasm_bindgen_version(path)?; + Ok(()) } fn check_crate_type(path: &str) -> Result<(), Error> { @@ -173,9 +190,10 @@ fn check_crate_type(path: &str) -> Result<(), Error> { lib.crate_type .map_or(false, |types| types.iter().any(|s| s == "cdylib")) }) { - return Ok(()); + Ok(()) + } else { + let msg = "crate-type must be cdylib to compile to wasm32-unknown-unknown. Add the following to your Cargo.toml file:\n\n[lib]\ncrate-type = [\"cdylib\"]"; + let e = Error::crate_config(msg); + Err(e) } - Error::crate_config( - "crate-type must be cdylib to compile to wasm32-unknown-unknown. Add the following to your Cargo.toml file:\n\n[lib]\ncrate-type = [\"cdylib\"]" - ) } diff --git a/src/npm.rs b/src/npm.rs index 3ea414dea..5e01e0706 100644 --- a/src/npm.rs +++ b/src/npm.rs @@ -11,7 +11,7 @@ pub fn npm_pack(path: &str) -> Result<(), Error> { .output()?; if !output.status.success() { let s = String::from_utf8_lossy(&output.stderr); - Error::cli("Packaging up your code failed", s) + Err(Error::cli("Packaging up your code failed", s)) } else { Ok(()) } @@ -25,7 +25,7 @@ pub fn npm_publish(path: &str) -> Result<(), Error> { .output()?; if !output.status.success() { let s = String::from_utf8_lossy(&output.stderr); - Error::cli("Publishing to npm failed", s) + Err(Error::cli("Publishing to npm failed", s)) } else { Ok(()) } @@ -61,8 +61,9 @@ pub fn npm_login( .output()?; if !output.status.success() { + let message = format!("Login to registry {} failed", registry); let s = String::from_utf8_lossy(&output.stderr); - Error::cli(&format!("Login to registry {} failed", registry), s) + Err(Error::cli(&message, s)) } else { Ok(()) }