Switch from failure to anyhow

master
printfn 3 years ago
parent bda7743942
commit f73b53c5ab
  1. 870
      Cargo.lock
  2. 6
      Cargo.toml
  3. 12
      src/bindgen.rs
  4. 14
      src/build/mod.rs
  5. 12
      src/build/wasm_target.rs
  6. 3
      src/cache.rs
  7. 6
      src/child.rs
  8. 34
      src/command/build.rs
  9. 9
      src/command/generate.rs
  10. 4
      src/command/login.rs
  11. 5
      src/command/mod.rs
  12. 7
      src/command/pack.rs
  13. 4
      src/command/publish/access.rs
  14. 7
      src/command/publish/mod.rs
  15. 30
      src/command/test.rs
  16. 8
      src/command/utils.rs
  17. 8
      src/generate.rs
  18. 3
      src/install/arch.rs
  19. 3
      src/install/krate.rs
  20. 33
      src/install/mod.rs
  21. 5
      src/install/mode.rs
  22. 3
      src/install/os.rs
  23. 12
      src/installer.rs
  24. 5
      src/lib.rs
  25. 18
      src/license.rs
  26. 14
      src/lockfile.rs
  27. 10
      src/main.rs
  28. 32
      src/manifest/mod.rs
  29. 12
      src/npm.rs
  30. 5
      src/progressbar.rs
  31. 4
      src/readme.rs
  32. 24
      src/stamps.rs
  33. 4
      src/test/mod.rs
  34. 4
      src/test/webdriver.rs
  35. 16
      src/test/webdriver/chromedriver.rs
  36. 22
      src/test/webdriver/geckodriver.rs
  37. 3
      src/test/webdriver/safaridriver.rs
  38. 13
      src/wasm_opt.rs
  39. 6
      tests/all/download.rs
  40. 2
      tests/all/license.rs
  41. 5
      tests/all/main.rs
  42. 2
      tests/all/readme.rs
  43. 3
      tests/all/test.rs
  44. 4
      tests/all/utils/file.rs
  45. 6
      tests/all/utils/manifest.rs
  46. 1
      tests/all/webdriver.rs

870
Cargo.lock generated

File diff suppressed because it is too large Load Diff

@ -10,13 +10,13 @@ categories = ["wasm"]
documentation = "https://rustwasm.github.io/wasm-pack/" documentation = "https://rustwasm.github.io/wasm-pack/"
[dependencies] [dependencies]
anyhow = "1.0.66"
atty = "0.2.11" atty = "0.2.11"
cargo_metadata = "0.8.0" cargo_metadata = "0.8.0"
console = "0.6.1" console = "0.6.1"
dialoguer = "0.3.0" dialoguer = "0.3.0"
curl = "0.4.13" curl = "0.4.13"
env_logger = { version = "0.5.13", default-features = false } env_logger = { version = "0.5.13", default-features = false }
failure = "0.1.2"
human-panic = "1.0.1" human-panic = "1.0.1"
glob = "0.2" glob = "0.2"
log = "0.4.6" log = "0.4.6"
@ -32,8 +32,8 @@ strsim = "0.8.0"
siphasher = "0.2.3" siphasher = "0.2.3"
structopt = "0.3" structopt = "0.3"
toml = "0.4" toml = "0.4"
which = "2.0.0" which = "4.3.0"
binary-install = "0.0.2" binary-install = { git = "https://github.com/rustwasm/binary-install", rev = "6d60f6731c8294000ea8f3a0260659b025cf7f94" }
walkdir = "2" walkdir = "2"
chrono = "0.4.6" chrono = "0.4.6"

@ -1,8 +1,8 @@
//! Functionality related to running `wasm-bindgen`. //! Functionality related to running `wasm-bindgen`.
use anyhow::{bail, Context, Result};
use child; use child;
use command::build::{BuildProfile, Target}; use command::build::{BuildProfile, Target};
use failure::{self, ResultExt};
use install::{self, Tool}; use install::{self, Tool};
use manifest::CrateData; use manifest::CrateData;
use semver; use semver;
@ -19,7 +19,7 @@ pub fn wasm_bindgen_build(
disable_dts: bool, disable_dts: bool,
target: Target, target: Target,
profile: BuildProfile, profile: BuildProfile,
) -> Result<(), failure::Error> { ) -> Result<()> {
let release_or_debug = match profile { let release_or_debug = match profile {
BuildProfile::Release | BuildProfile::Profiling => "release", BuildProfile::Release | BuildProfile::Profiling => "release",
BuildProfile::Dev => "debug", BuildProfile::Dev => "debug",
@ -75,7 +75,7 @@ pub fn wasm_bindgen_build(
} }
/// Check if the `wasm-bindgen` dependency is locally satisfied for the web target /// Check if the `wasm-bindgen` dependency is locally satisfied for the web target
fn supports_web_target(cli_path: &Path) -> Result<bool, failure::Error> { fn supports_web_target(cli_path: &Path) -> Result<bool> {
let cli_version = semver::Version::parse(&install::get_cli_version( let cli_version = semver::Version::parse(&install::get_cli_version(
&install::Tool::WasmBindgen, &install::Tool::WasmBindgen,
cli_path, cli_path,
@ -85,7 +85,7 @@ fn supports_web_target(cli_path: &Path) -> Result<bool, failure::Error> {
} }
/// Check if the `wasm-bindgen` dependency is locally satisfied for the --target flag /// Check if the `wasm-bindgen` dependency is locally satisfied for the --target flag
fn supports_dash_dash_target(cli_path: &Path) -> Result<bool, failure::Error> { fn supports_dash_dash_target(cli_path: &Path) -> Result<bool> {
let cli_version = semver::Version::parse(&install::get_cli_version( let cli_version = semver::Version::parse(&install::get_cli_version(
&install::Tool::WasmBindgen, &install::Tool::WasmBindgen,
cli_path, cli_path,
@ -94,7 +94,7 @@ fn supports_dash_dash_target(cli_path: &Path) -> Result<bool, failure::Error> {
Ok(cli_version >= expected_version) Ok(cli_version >= expected_version)
} }
fn build_target_arg(target: Target, cli_path: &Path) -> Result<String, failure::Error> { fn build_target_arg(target: Target, cli_path: &Path) -> Result<String> {
if !supports_dash_dash_target(cli_path)? { if !supports_dash_dash_target(cli_path)? {
Ok(build_target_arg_legacy(target, cli_path)?) Ok(build_target_arg_legacy(target, cli_path)?)
} else { } else {
@ -102,7 +102,7 @@ fn build_target_arg(target: Target, cli_path: &Path) -> Result<String, failure::
} }
} }
fn build_target_arg_legacy(target: Target, cli_path: &Path) -> Result<String, failure::Error> { fn build_target_arg_legacy(target: Target, cli_path: &Path) -> Result<String> {
log::info!("Your version of wasm-bindgen is out of date. You should consider updating your Cargo.toml to a version >= 0.2.40."); log::info!("Your version of wasm-bindgen is out of date. You should consider updating your Cargo.toml to a version >= 0.2.40.");
let target_arg = match target { let target_arg = match target {
Target::Nodejs => "--nodejs", Target::Nodejs => "--nodejs",

@ -1,9 +1,9 @@
//! Building a Rust crate into a `.wasm` binary. //! Building a Rust crate into a `.wasm` binary.
use anyhow::{bail, Context, Result};
use child; use child;
use command::build::BuildProfile; use command::build::BuildProfile;
use emoji; use emoji;
use failure::{Error, ResultExt};
use manifest::Crate; use manifest::Crate;
use std::path::Path; use std::path::Path;
use std::process::Command; use std::process::Command;
@ -23,7 +23,7 @@ pub struct WasmPackVersion {
} }
/// Ensure that `rustc` is present and that it is >= 1.30.0 /// Ensure that `rustc` is present and that it is >= 1.30.0
pub fn check_rustc_version() -> Result<String, Error> { pub fn check_rustc_version() -> Result<String> {
let local_minor_version = rustc_minor_version(); let local_minor_version = rustc_minor_version();
match local_minor_version { match local_minor_version {
Some(mv) => { Some(mv) => {
@ -60,7 +60,7 @@ fn rustc_minor_version() -> Option<u32> {
} }
/// Checks and returns local and latest versions of wasm-pack /// Checks and returns local and latest versions of wasm-pack
pub fn check_wasm_pack_versions() -> Result<WasmPackVersion, Error> { pub fn check_wasm_pack_versions() -> Result<WasmPackVersion> {
match wasm_pack_local_version() { match wasm_pack_local_version() {
Some(local) => Ok(WasmPackVersion {local, latest: Crate::return_wasm_pack_latest_version()?.unwrap_or_else(|| "".to_string())}), Some(local) => Ok(WasmPackVersion {local, latest: Crate::return_wasm_pack_latest_version()?.unwrap_or_else(|| "".to_string())}),
None => bail!("We can't figure out what your wasm-pack version is, make sure the installation path is correct.") None => bail!("We can't figure out what your wasm-pack version is, make sure the installation path is correct.")
@ -77,7 +77,7 @@ pub fn cargo_build_wasm(
path: &Path, path: &Path,
profile: BuildProfile, profile: BuildProfile,
extra_options: &[String], extra_options: &[String],
) -> Result<(), Error> { ) -> Result<()> {
let msg = format!("{}Compiling to Wasm...", emoji::CYCLONE); let msg = format!("{}Compiling to Wasm...", emoji::CYCLONE);
PBAR.info(&msg); PBAR.info(&msg);
@ -125,11 +125,7 @@ pub fn cargo_build_wasm(
/// * `path`: Path to the crate directory to build tests. /// * `path`: Path to the crate directory to build tests.
/// * `debug`: Whether to build tests in `debug` mode. /// * `debug`: Whether to build tests in `debug` mode.
/// * `extra_options`: Additional parameters to pass to `cargo` when building tests. /// * `extra_options`: Additional parameters to pass to `cargo` when building tests.
pub fn cargo_build_wasm_tests( pub fn cargo_build_wasm_tests(path: &Path, debug: bool, extra_options: &[String]) -> Result<()> {
path: &Path,
debug: bool,
extra_options: &[String],
) -> Result<(), Error> {
let mut cmd = Command::new("cargo"); let mut cmd = Command::new("cargo");
cmd.current_dir(path).arg("build").arg("--tests"); cmd.current_dir(path).arg("build").arg("--tests");

@ -1,8 +1,8 @@
//! Checking for the wasm32 target //! Checking for the wasm32 target
use anyhow::{anyhow, bail, Context, Result};
use child; use child;
use emoji; use emoji;
use failure::{Error, ResultExt};
use log::info; use log::info;
use std::fmt; use std::fmt;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
@ -52,7 +52,7 @@ impl fmt::Display for Wasm32Check {
/// Ensure that `rustup` has the `wasm32-unknown-unknown` target installed for /// Ensure that `rustup` has the `wasm32-unknown-unknown` target installed for
/// current toolchain /// current toolchain
pub fn check_for_wasm32_target() -> Result<(), Error> { pub fn check_for_wasm32_target() -> Result<()> {
let msg = format!("{}Checking for the Wasm target...", emoji::TARGET); let msg = format!("{}Checking for the Wasm target...", emoji::TARGET);
PBAR.info(&msg); PBAR.info(&msg);
@ -65,7 +65,7 @@ pub fn check_for_wasm32_target() -> Result<(), Error> {
} }
/// Get rustc's sysroot as a PathBuf /// Get rustc's sysroot as a PathBuf
fn get_rustc_sysroot() -> Result<PathBuf, Error> { fn get_rustc_sysroot() -> Result<PathBuf> {
let command = Command::new("rustc") let command = Command::new("rustc")
.args(&["--print", "sysroot"]) .args(&["--print", "sysroot"])
.output()?; .output()?;
@ -73,7 +73,7 @@ fn get_rustc_sysroot() -> Result<PathBuf, Error> {
if command.status.success() { if command.status.success() {
Ok(String::from_utf8(command.stdout)?.trim().into()) Ok(String::from_utf8(command.stdout)?.trim().into())
} else { } else {
Err(format_err!( Err(anyhow!(
"Getting rustc's sysroot wasn't successful. Got {}", "Getting rustc's sysroot wasn't successful. Got {}",
command.status command.status
)) ))
@ -97,7 +97,7 @@ fn is_wasm32_target_in_sysroot(sysroot: &Path) -> bool {
} }
} }
fn check_wasm32_target() -> Result<Wasm32Check, Error> { fn check_wasm32_target() -> Result<Wasm32Check> {
let sysroot = get_rustc_sysroot()?; let sysroot = get_rustc_sysroot()?;
let rustc_path = which::which("rustc")?; let rustc_path = which::which("rustc")?;
@ -132,7 +132,7 @@ fn check_wasm32_target() -> Result<Wasm32Check, Error> {
} }
/// Add wasm32-unknown-unknown using `rustup`. /// Add wasm32-unknown-unknown using `rustup`.
fn rustup_add_wasm_target() -> Result<(), Error> { fn rustup_add_wasm_target() -> Result<()> {
let mut cmd = Command::new("rustup"); let mut cmd = Command::new("rustup");
cmd.arg("target").arg("add").arg("wasm32-unknown-unknown"); cmd.arg("target").arg("add").arg("wasm32-unknown-unknown");
child::run(cmd, "rustup").context("Adding the wasm32-unknown-unknown target with rustup")?; child::run(cmd, "rustup").context("Adding the wasm32-unknown-unknown target with rustup")?;

@ -1,11 +1,12 @@
//! Getting and configuring wasm-pack's binary cache. //! Getting and configuring wasm-pack's binary cache.
use anyhow::Result;
use binary_install::Cache; use binary_install::Cache;
use std::env; use std::env;
use std::path::Path; use std::path::Path;
/// Get wasm-pack's binary cache. /// Get wasm-pack's binary cache.
pub fn get_wasm_pack_cache() -> Result<Cache, failure::Error> { pub fn get_wasm_pack_cache() -> Result<Cache> {
if let Ok(path) = env::var("WASM_PACK_CACHE") { if let Ok(path) = env::var("WASM_PACK_CACHE") {
Ok(Cache::at(Path::new(&path))) Ok(Cache::at(Path::new(&path)))
} else { } else {

@ -3,7 +3,7 @@
//! This module helps us ensure that all child processes that we spawn get //! This module helps us ensure that all child processes that we spawn get
//! properly logged and their output is logged as well. //! properly logged and their output is logged as well.
use failure::Error; use anyhow::{bail, Result};
use install::Tool; use install::Tool;
use log::info; use log::info;
use std::process::{Command, Stdio}; use std::process::{Command, Stdio};
@ -25,7 +25,7 @@ pub fn new_command(program: &str) -> Command {
} }
/// Run the given command and return on success. /// Run the given command and return on success.
pub fn run(mut command: Command, command_name: &str) -> Result<(), Error> { pub fn run(mut command: Command, command_name: &str) -> Result<()> {
info!("Running {:?}", command); info!("Running {:?}", command);
let status = command.status()?; let status = command.status()?;
@ -43,7 +43,7 @@ pub fn run(mut command: Command, command_name: &str) -> Result<(), Error> {
} }
/// Run the given command and return its stdout. /// Run the given command and return its stdout.
pub fn run_capture_stdout(mut command: Command, command_name: &Tool) -> Result<String, Error> { pub fn run_capture_stdout(mut command: Command, command_name: &Tool) -> Result<String> {
info!("Running {:?}", command); info!("Running {:?}", command);
let output = command let output = command

@ -1,13 +1,13 @@
//! Implementation of the `wasm-pack build` command. //! Implementation of the `wasm-pack build` command.
use crate::wasm_opt; use crate::wasm_opt;
use anyhow::{anyhow, bail, Error, Result};
use binary_install::Cache; use binary_install::Cache;
use bindgen; use bindgen;
use build; use build;
use cache; use cache;
use command::utils::{create_pkg_dir, get_crate_path}; use command::utils::{create_pkg_dir, get_crate_path};
use emoji; use emoji;
use failure::Error;
use install::{self, InstallMode, Tool}; use install::{self, InstallMode, Tool};
use license; use license;
use lockfile::Lockfile; use lockfile::Lockfile;
@ -81,7 +81,7 @@ impl fmt::Display for Target {
impl FromStr for Target { impl FromStr for Target {
type Err = Error; type Err = Error;
fn from_str(s: &str) -> Result<Self, Error> { fn from_str(s: &str) -> Result<Self> {
match s { match s {
"bundler" | "browser" => Ok(Target::Bundler), "bundler" | "browser" => Ok(Target::Bundler),
"web" => Ok(Target::Web), "web" => Ok(Target::Web),
@ -185,11 +185,11 @@ impl Default for BuildOptions {
} }
} }
type BuildStep = fn(&mut Build) -> Result<(), Error>; type BuildStep = fn(&mut Build) -> Result<()>;
impl Build { impl Build {
/// Construct a build command from the given options. /// Construct a build command from the given options.
pub fn try_from_opts(mut build_opts: BuildOptions) -> Result<Self, Error> { pub fn try_from_opts(mut build_opts: BuildOptions) -> Result<Self> {
if let Some(path) = &build_opts.path { if let Some(path) = &build_opts.path {
if path.to_string_lossy().starts_with("--") { if path.to_string_lossy().starts_with("--") {
let path = build_opts.path.take().unwrap(); let path = build_opts.path.take().unwrap();
@ -234,7 +234,7 @@ impl Build {
} }
/// Execute this `Build` command. /// Execute this `Build` command.
pub fn run(&mut self) -> Result<(), Error> { pub fn run(&mut self) -> Result<()> {
let process_steps = Build::get_process_steps(self.mode); let process_steps = Build::get_process_steps(self.mode);
let started = Instant::now(); let started = Instant::now();
@ -295,7 +295,7 @@ impl Build {
steps steps
} }
fn step_check_rustc_version(&mut self) -> Result<(), Error> { fn step_check_rustc_version(&mut self) -> Result<()> {
info!("Checking rustc version..."); info!("Checking rustc version...");
let version = build::check_rustc_version()?; let version = build::check_rustc_version()?;
let msg = format!("rustc version is {}.", version); let msg = format!("rustc version is {}.", version);
@ -303,21 +303,21 @@ impl Build {
Ok(()) Ok(())
} }
fn step_check_crate_config(&mut self) -> Result<(), Error> { fn step_check_crate_config(&mut self) -> Result<()> {
info!("Checking crate configuration..."); info!("Checking crate configuration...");
self.crate_data.check_crate_config()?; self.crate_data.check_crate_config()?;
info!("Crate is correctly configured."); info!("Crate is correctly configured.");
Ok(()) Ok(())
} }
fn step_check_for_wasm_target(&mut self) -> Result<(), Error> { fn step_check_for_wasm_target(&mut self) -> Result<()> {
info!("Checking for wasm-target..."); info!("Checking for wasm-target...");
build::wasm_target::check_for_wasm32_target()?; build::wasm_target::check_for_wasm32_target()?;
info!("Checking for wasm-target was successful."); info!("Checking for wasm-target was successful.");
Ok(()) Ok(())
} }
fn step_build_wasm(&mut self) -> Result<(), Error> { fn step_build_wasm(&mut self) -> Result<()> {
info!("Building wasm..."); info!("Building wasm...");
build::cargo_build_wasm(&self.crate_path, self.profile, &self.extra_options)?; build::cargo_build_wasm(&self.crate_path, self.profile, &self.extra_options)?;
@ -332,14 +332,14 @@ impl Build {
Ok(()) Ok(())
} }
fn step_create_dir(&mut self) -> Result<(), Error> { fn step_create_dir(&mut self) -> Result<()> {
info!("Creating a pkg directory..."); info!("Creating a pkg directory...");
create_pkg_dir(&self.out_dir)?; create_pkg_dir(&self.out_dir)?;
info!("Created a pkg directory at {:#?}.", &self.crate_path); info!("Created a pkg directory at {:#?}.", &self.crate_path);
Ok(()) Ok(())
} }
fn step_create_json(&mut self) -> Result<(), Error> { fn step_create_json(&mut self) -> Result<()> {
self.crate_data.write_package_json( self.crate_data.write_package_json(
&self.out_dir, &self.out_dir,
&self.scope, &self.scope,
@ -353,21 +353,21 @@ impl Build {
Ok(()) Ok(())
} }
fn step_copy_readme(&mut self) -> Result<(), Error> { fn step_copy_readme(&mut self) -> Result<()> {
info!("Copying readme from crate..."); info!("Copying readme from crate...");
readme::copy_from_crate(&self.crate_path, &self.out_dir)?; readme::copy_from_crate(&self.crate_path, &self.out_dir)?;
info!("Copied readme from crate to {:#?}.", &self.out_dir); info!("Copied readme from crate to {:#?}.", &self.out_dir);
Ok(()) Ok(())
} }
fn step_copy_license(&mut self) -> Result<(), failure::Error> { fn step_copy_license(&mut self) -> Result<()> {
info!("Copying license from crate..."); info!("Copying license from crate...");
license::copy_from_crate(&self.crate_data, &self.crate_path, &self.out_dir)?; license::copy_from_crate(&self.crate_data, &self.crate_path, &self.out_dir)?;
info!("Copied license from crate to {:#?}.", &self.out_dir); info!("Copied license from crate to {:#?}.", &self.out_dir);
Ok(()) Ok(())
} }
fn step_install_wasm_bindgen(&mut self) -> Result<(), failure::Error> { fn step_install_wasm_bindgen(&mut self) -> Result<()> {
info!("Identifying wasm-bindgen dependency..."); info!("Identifying wasm-bindgen dependency...");
let lockfile = Lockfile::new(&self.crate_data)?; let lockfile = Lockfile::new(&self.crate_data)?;
let bindgen_version = lockfile.require_wasm_bindgen()?; let bindgen_version = lockfile.require_wasm_bindgen()?;
@ -383,7 +383,7 @@ impl Build {
Ok(()) Ok(())
} }
fn step_run_wasm_bindgen(&mut self) -> Result<(), Error> { fn step_run_wasm_bindgen(&mut self) -> Result<()> {
info!("Building the wasm bindings..."); info!("Building the wasm bindings...");
bindgen::wasm_bindgen_build( bindgen::wasm_bindgen_build(
&self.crate_data, &self.crate_data,
@ -398,7 +398,7 @@ impl Build {
Ok(()) Ok(())
} }
fn step_run_wasm_opt(&mut self) -> Result<(), Error> { fn step_run_wasm_opt(&mut self) -> Result<()> {
let args = match self let args = match self
.crate_data .crate_data
.configured_profile(self.profile) .configured_profile(self.profile)
@ -414,7 +414,7 @@ impl Build {
&args, &args,
self.mode.install_permitted(), self.mode.install_permitted(),
).map_err(|e| { ).map_err(|e| {
format_err!( anyhow!(
"{}\nTo disable `wasm-opt`, add `wasm-opt = false` to your package metadata in your `Cargo.toml`.", e "{}\nTo disable `wasm-opt`, add `wasm-opt = false` to your package metadata in your `Cargo.toml`.", e
) )
}) })

@ -1,18 +1,13 @@
use anyhow::Result;
use cache; use cache;
use failure::Error;
use generate; use generate;
use install::{self, Tool}; use install::{self, Tool};
use log::info; use log::info;
use std::result;
use PBAR; use PBAR;
/// Executes the 'cargo-generate' command in the current directory /// Executes the 'cargo-generate' command in the current directory
/// which generates a new rustwasm project from a template. /// which generates a new rustwasm project from a template.
pub fn generate( pub fn generate(template: String, name: String, install_permitted: bool) -> Result<()> {
template: String,
name: String,
install_permitted: bool,
) -> result::Result<(), Error> {
info!("Generating a new rustwasm project..."); info!("Generating a new rustwasm project...");
let download = install::download_prebuilt_or_cargo_install( let download = install::download_prebuilt_or_cargo_install(
Tool::CargoGenerate, Tool::CargoGenerate,

@ -1,6 +1,6 @@
use anyhow::Result;
use log::info; use log::info;
use npm; use npm;
use std::result;
use PBAR; use PBAR;
pub fn login( pub fn login(
@ -8,7 +8,7 @@ pub fn login(
scope: &Option<String>, scope: &Option<String>,
always_auth: bool, always_auth: bool,
auth_type: &Option<String>, auth_type: &Option<String>,
) -> result::Result<(), failure::Error> { ) -> Result<()> {
let registry = registry.unwrap_or_else(|| npm::DEFAULT_NPM_REGISTRY.to_string()); let registry = registry.unwrap_or_else(|| npm::DEFAULT_NPM_REGISTRY.to_string());
info!("Logging in to npm..."); info!("Logging in to npm...");

@ -17,10 +17,9 @@ use self::pack::pack;
use self::publish::{access::Access, publish}; use self::publish::{access::Access, publish};
use self::test::{Test, TestOptions}; use self::test::{Test, TestOptions};
use crate::install::InstallMode; use crate::install::InstallMode;
use failure::Error; use anyhow::Result;
use log::info; use log::info;
use std::path::PathBuf; use std::path::PathBuf;
use std::result;
/// The various kinds of commands that `wasm-pack` can execute. /// The various kinds of commands that `wasm-pack` can execute.
#[derive(Debug, StructOpt)] #[derive(Debug, StructOpt)]
@ -113,7 +112,7 @@ pub enum Command {
} }
/// Run a command with the given logger! /// Run a command with the given logger!
pub fn run_wasm_pack(command: Command) -> result::Result<(), Error> { pub fn run_wasm_pack(command: Command) -> Result<()> {
// Run the correct command based off input and store the result of it so that we can clear // Run the correct command based off input and store the result of it so that we can clear
// the progress bar then return it // the progress bar then return it
match command { match command {

@ -1,19 +1,18 @@
use anyhow::{anyhow, Result};
use command::utils::{find_pkg_directory, get_crate_path}; use command::utils::{find_pkg_directory, get_crate_path};
use failure::Error;
use log::info; use log::info;
use npm; use npm;
use std::path::PathBuf; use std::path::PathBuf;
use std::result;
use PBAR; use PBAR;
/// Executes the 'npm pack' command on the 'pkg' directory /// Executes the 'npm pack' command on the 'pkg' directory
/// which creates a tarball that can be published to the NPM registry /// which creates a tarball that can be published to the NPM registry
pub fn pack(path: Option<PathBuf>) -> result::Result<(), Error> { pub fn pack(path: Option<PathBuf>) -> Result<()> {
let crate_path = get_crate_path(path)?; let crate_path = get_crate_path(path)?;
info!("Packing up the npm package..."); info!("Packing up the npm package...");
let pkg_directory = find_pkg_directory(&crate_path).ok_or_else(|| { let pkg_directory = find_pkg_directory(&crate_path).ok_or_else(|| {
format_err!( anyhow!(
"Unable to find the pkg directory at path {:#?}, or in a child directory of {:#?}", "Unable to find the pkg directory at path {:#?}, or in a child directory of {:#?}",
&crate_path, &crate_path,
&crate_path &crate_path

@ -1,4 +1,4 @@
use failure::Error; use anyhow::{bail, Error, Result};
use std::fmt; use std::fmt;
use std::str::FromStr; use std::str::FromStr;
@ -14,7 +14,7 @@ pub enum Access {
impl FromStr for Access { impl FromStr for Access {
type Err = Error; type Err = Error;
fn from_str(s: &str) -> Result<Self, Error> { fn from_str(s: &str) -> Result<Self> {
match s { match s {
"public" => Ok(Access::Public), "public" => Ok(Access::Public),
"restricted" => Ok(Access::Restricted), "restricted" => Ok(Access::Restricted),

@ -2,14 +2,13 @@
pub mod access; pub mod access;
use self::access::Access; use self::access::Access;
use anyhow::{anyhow, bail, Result};
use command::build::{Build, BuildOptions, Target}; use command::build::{Build, BuildOptions, Target};
use command::utils::{find_pkg_directory, get_crate_path}; use command::utils::{find_pkg_directory, get_crate_path};
use dialoguer::{Confirmation, Input, Select}; use dialoguer::{Confirmation, Input, Select};
use failure::Error;
use log::info; use log::info;
use npm; use npm;
use std::path::PathBuf; use std::path::PathBuf;
use std::result;
use std::str::FromStr; use std::str::FromStr;
use PBAR; use PBAR;
@ -20,7 +19,7 @@ pub fn publish(
path: Option<PathBuf>, path: Option<PathBuf>,
access: Option<Access>, access: Option<Access>,
tag: Option<String>, tag: Option<String>,
) -> result::Result<(), Error> { ) -> Result<()> {
let crate_path = get_crate_path(path)?; let crate_path = get_crate_path(path)?;
info!("Publishing the npm package..."); info!("Publishing the npm package...");
@ -58,7 +57,7 @@ pub fn publish(
.and_then(|mut build| build.run()) .and_then(|mut build| build.run())
.map(|()| crate_path.join(out_dir)) .map(|()| crate_path.join(out_dir))
.map_err(|_| { .map_err(|_| {
format_err!( anyhow!(
"Unable to find the pkg directory at path '{:#?}',\ "Unable to find the pkg directory at path '{:#?}',\
or in a child directory of '{:#?}'", or in a child directory of '{:#?}'",
&crate_path, &crate_path,

@ -1,11 +1,11 @@
//! Implementation of the `wasm-pack test` command. //! Implementation of the `wasm-pack test` command.
use anyhow::{bail, Result};
use binary_install::Cache; use binary_install::Cache;
use build; use build;
use cache; use cache;
use command::utils::get_crate_path; use command::utils::get_crate_path;
use console::style; use console::style;
use failure::Error;
use install::{self, InstallMode, Tool}; use install::{self, InstallMode, Tool};
use lockfile::Lockfile; use lockfile::Lockfile;
use log::info; use log::info;
@ -108,11 +108,11 @@ pub struct Test {
extra_options: Vec<String>, extra_options: Vec<String>,
} }
type TestStep = fn(&mut Test) -> Result<(), Error>; type TestStep = fn(&mut Test) -> Result<()>;
impl Test { impl Test {
/// Construct a test command from the given options. /// Construct a test command from the given options.
pub fn try_from_opts(test_opts: TestOptions) -> Result<Self, Error> { pub fn try_from_opts(test_opts: TestOptions) -> Result<Self> {
let TestOptions { let TestOptions {
node, node,
mode, mode,
@ -181,7 +181,7 @@ impl Test {
} }
/// Execute this test command. /// Execute this test command.
pub fn run(mut self) -> Result<(), Error> { pub fn run(mut self) -> Result<()> {
let process_steps = self.get_process_steps(); let process_steps = self.get_process_steps();
let started = Instant::now(); let started = Instant::now();
@ -249,21 +249,21 @@ impl Test {
} }
} }
fn step_check_rustc_version(&mut self) -> Result<(), Error> { fn step_check_rustc_version(&mut self) -> Result<()> {
info!("Checking rustc version..."); info!("Checking rustc version...");
let _ = build::check_rustc_version()?; let _ = build::check_rustc_version()?;
info!("Rustc version is correct."); info!("Rustc version is correct.");
Ok(()) Ok(())
} }
fn step_check_for_wasm_target(&mut self) -> Result<(), Error> { fn step_check_for_wasm_target(&mut self) -> Result<()> {
info!("Adding wasm-target..."); info!("Adding wasm-target...");
build::wasm_target::check_for_wasm32_target()?; build::wasm_target::check_for_wasm32_target()?;
info!("Adding wasm-target was successful."); info!("Adding wasm-target was successful.");
Ok(()) Ok(())
} }
fn step_build_tests(&mut self) -> Result<(), Error> { fn step_build_tests(&mut self) -> Result<()> {
info!("Compiling tests to wasm..."); info!("Compiling tests to wasm...");
// If the user has run `wasm-pack test -- --features "f1" -- test_name`, then we want to only pass through // If the user has run `wasm-pack test -- --features "f1" -- test_name`, then we want to only pass through
@ -280,7 +280,7 @@ impl Test {
Ok(()) Ok(())
} }
fn step_install_wasm_bindgen(&mut self) -> Result<(), Error> { fn step_install_wasm_bindgen(&mut self) -> Result<()> {
info!("Identifying wasm-bindgen dependency..."); info!("Identifying wasm-bindgen dependency...");
let lockfile = Lockfile::new(&self.crate_data)?; let lockfile = Lockfile::new(&self.crate_data)?;
let bindgen_version = lockfile.require_wasm_bindgen()?; let bindgen_version = lockfile.require_wasm_bindgen()?;
@ -315,7 +315,7 @@ impl Test {
Ok(()) Ok(())
} }
fn step_test_node(&mut self) -> Result<(), Error> { fn step_test_node(&mut self) -> Result<()> {
assert!(self.node); assert!(self.node);
info!("Running tests in node..."); info!("Running tests in node...");
test::cargo_test_wasm( test::cargo_test_wasm(
@ -334,7 +334,7 @@ impl Test {
Ok(()) Ok(())
} }
fn step_get_chromedriver(&mut self) -> Result<(), Error> { fn step_get_chromedriver(&mut self) -> Result<()> {
assert!(self.chrome && self.chromedriver.is_none()); assert!(self.chrome && self.chromedriver.is_none());
self.chromedriver = Some(webdriver::get_or_install_chromedriver( self.chromedriver = Some(webdriver::get_or_install_chromedriver(
@ -344,7 +344,7 @@ impl Test {
Ok(()) Ok(())
} }
fn step_test_chrome(&mut self) -> Result<(), Error> { fn step_test_chrome(&mut self) -> Result<()> {
let chromedriver = self.chromedriver.as_ref().unwrap().display().to_string(); let chromedriver = self.chromedriver.as_ref().unwrap().display().to_string();
let chromedriver = chromedriver.as_str(); let chromedriver = chromedriver.as_str();
info!( info!(
@ -359,7 +359,7 @@ impl Test {
Ok(()) Ok(())
} }
fn step_get_geckodriver(&mut self) -> Result<(), Error> { fn step_get_geckodriver(&mut self) -> Result<()> {
assert!(self.firefox && self.geckodriver.is_none()); assert!(self.firefox && self.geckodriver.is_none());
self.geckodriver = Some(webdriver::get_or_install_geckodriver( self.geckodriver = Some(webdriver::get_or_install_geckodriver(
@ -369,7 +369,7 @@ impl Test {
Ok(()) Ok(())
} }
fn step_test_firefox(&mut self) -> Result<(), Error> { fn step_test_firefox(&mut self) -> Result<()> {
let geckodriver = self.geckodriver.as_ref().unwrap().display().to_string(); let geckodriver = self.geckodriver.as_ref().unwrap().display().to_string();
let geckodriver = geckodriver.as_str(); let geckodriver = geckodriver.as_str();
info!( info!(
@ -384,14 +384,14 @@ impl Test {
Ok(()) Ok(())
} }
fn step_get_safaridriver(&mut self) -> Result<(), Error> { fn step_get_safaridriver(&mut self) -> Result<()> {
assert!(self.safari && self.safaridriver.is_none()); assert!(self.safari && self.safaridriver.is_none());
self.safaridriver = Some(webdriver::get_safaridriver()?); self.safaridriver = Some(webdriver::get_safaridriver()?);
Ok(()) Ok(())
} }
fn step_test_safari(&mut self) -> Result<(), Error> { fn step_test_safari(&mut self) -> Result<()> {
let safaridriver = self.safaridriver.as_ref().unwrap().display().to_string(); let safaridriver = self.safaridriver.as_ref().unwrap().display().to_string();
let safaridriver = safaridriver.as_str(); let safaridriver = safaridriver.as_str();
info!( info!(

@ -1,7 +1,7 @@
//! Utility functions for commands. //! Utility functions for commands.
#![allow(clippy::redundant_closure)] #![allow(clippy::redundant_closure)]
use failure; use anyhow::Result;
use std::fs; use std::fs;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::time::Duration; use std::time::Duration;
@ -9,7 +9,7 @@ use walkdir::WalkDir;
/// If an explicit path is given, then use it, otherwise assume the current /// If an explicit path is given, then use it, otherwise assume the current
/// directory is the crate path. /// directory is the crate path.
pub fn get_crate_path(path: Option<PathBuf>) -> Result<PathBuf, failure::Error> { pub fn get_crate_path(path: Option<PathBuf>) -> Result<PathBuf> {
match path { match path {
Some(p) => Ok(p), Some(p) => Ok(p),
None => find_manifest_from_cwd(), None => find_manifest_from_cwd(),
@ -19,7 +19,7 @@ pub fn get_crate_path(path: Option<PathBuf>) -> Result<PathBuf, failure::Error>
/// Search up the path for the manifest file from the current working directory /// Search up the path for the manifest file from the current working directory
/// If we don't find the manifest file then return back the current working directory /// If we don't find the manifest file then return back the current working directory
/// to provide the appropriate error /// to provide the appropriate error
fn find_manifest_from_cwd() -> Result<PathBuf, failure::Error> { fn find_manifest_from_cwd() -> Result<PathBuf> {
let mut parent_path = std::env::current_dir()?; let mut parent_path = std::env::current_dir()?;
let mut manifest_path = parent_path.join("Cargo.toml"); let mut manifest_path = parent_path.join("Cargo.toml");
loop { loop {
@ -36,7 +36,7 @@ fn find_manifest_from_cwd() -> Result<PathBuf, failure::Error> {
} }
/// Construct our `pkg` directory in the crate. /// Construct our `pkg` directory in the crate.
pub fn create_pkg_dir(out_dir: &Path) -> Result<(), failure::Error> { pub fn create_pkg_dir(out_dir: &Path) -> Result<()> {
let _ = fs::remove_file(out_dir.join("package.json")); // Clean up package.json from previous runs let _ = fs::remove_file(out_dir.join("package.json")); // Clean up package.json from previous runs
fs::create_dir_all(&out_dir)?; fs::create_dir_all(&out_dir)?;
fs::write(out_dir.join(".gitignore"), "*")?; fs::write(out_dir.join(".gitignore"), "*")?;

@ -1,18 +1,14 @@
//! Functionality related to running `cargo-generate`. //! Functionality related to running `cargo-generate`.
use anyhow::{Context, Result};
use child; use child;
use emoji; use emoji;
use failure::{self, ResultExt};
use install::{self, Tool}; use install::{self, Tool};
use std::process::Command; use std::process::Command;
/// Run `cargo generate` in the current directory to create a new /// Run `cargo generate` in the current directory to create a new
/// project from a template /// project from a template
pub fn generate( pub fn generate(template: &str, name: &str, install_status: &install::Status) -> Result<()> {
template: &str,
name: &str,
install_status: &install::Status,
) -> Result<(), failure::Error> {
let bin_path = install::get_tool_path(install_status, Tool::CargoGenerate)? let bin_path = install::get_tool_path(install_status, Tool::CargoGenerate)?
.binary(&Tool::CargoGenerate.to_string())?; .binary(&Tool::CargoGenerate.to_string())?;
let mut cmd = Command::new(&bin_path); let mut cmd = Command::new(&bin_path);

@ -1,3 +1,4 @@
use anyhow::{bail, Result};
use std::fmt; use std::fmt;
use crate::target; use crate::target;
@ -15,7 +16,7 @@ pub enum Arch {
impl Arch { impl Arch {
/// Gets the current architecture /// Gets the current architecture
pub fn get() -> Result<Self, failure::Error> { pub fn get() -> Result<Self> {
if target::x86_64 { if target::x86_64 {
Ok(Arch::X86_64) Ok(Arch::X86_64)
} else if target::x86 { } else if target::x86 {

@ -1,3 +1,4 @@
use anyhow::Result;
use install::Tool; use install::Tool;
use serde::Deserialize; use serde::Deserialize;
@ -13,7 +14,7 @@ pub struct KrateResponse {
} }
impl Krate { impl Krate {
pub fn new(name: &Tool) -> Result<Krate, failure::Error> { pub fn new(name: &Tool) -> Result<Krate> {
let krate_address = format!("https://crates.io/api/v1/crates/{}", name); let krate_address = format!("https://crates.io/api/v1/crates/{}", name);
let client = reqwest::Client::new(); let client = reqwest::Client::new();
let mut res = client.get(&krate_address).send()?; let mut res = client.get(&krate_address).send()?;

@ -1,10 +1,10 @@
//! Functionality related to installing prebuilt binaries and/or running cargo install. //! Functionality related to installing prebuilt binaries and/or running cargo install.
use self::krate::Krate; use self::krate::Krate;
use anyhow::{anyhow, bail, Context, Result};
use binary_install::{Cache, Download}; use binary_install::{Cache, Download};
use child; use child;
use emoji; use emoji;
use failure::{self, ResultExt};
use install; use install;
use log::debug; use log::debug;
use log::{info, warn}; use log::{info, warn};
@ -36,7 +36,7 @@ pub enum Status {
} }
/// Handles possible installs status and returns the download or a error message /// Handles possible installs status and returns the download or a error message
pub fn get_tool_path(status: &Status, tool: Tool) -> Result<&Download, failure::Error> { pub fn get_tool_path(status: &Status, tool: Tool) -> Result<&Download> {
match status { match status {
Status::Found(download) => Ok(download), Status::Found(download) => Ok(download),
Status::CannotInstall => bail!("Not able to find or install a local {}.", tool), Status::CannotInstall => bail!("Not able to find or install a local {}.", tool),
@ -57,7 +57,7 @@ pub fn download_prebuilt_or_cargo_install(
cache: &Cache, cache: &Cache,
version: &str, version: &str,
install_permitted: bool, install_permitted: bool,
) -> Result<Status, failure::Error> { ) -> Result<Status> {
// If the tool is installed globally and it has the right version, use // If the tool is installed globally and it has the right version, use
// that. Assume that other tools are installed next to it. // that. Assume that other tools are installed next to it.
// //
@ -89,11 +89,7 @@ pub fn download_prebuilt_or_cargo_install(
} }
/// Check if the tool dependency is locally satisfied. /// Check if the tool dependency is locally satisfied.
pub fn check_version( pub fn check_version(tool: &Tool, path: &Path, expected_version: &str) -> Result<bool> {
tool: &Tool,
path: &Path,
expected_version: &str,
) -> Result<bool, failure::Error> {
let expected_version = if expected_version == "latest" { let expected_version = if expected_version == "latest" {
let krate = Krate::new(tool)?; let krate = Krate::new(tool)?;
krate.max_version krate.max_version
@ -110,7 +106,7 @@ pub fn check_version(
} }
/// Fetches the version of a CLI tool /// Fetches the version of a CLI tool
pub fn get_cli_version(tool: &Tool, path: &Path) -> Result<String, failure::Error> { pub fn get_cli_version(tool: &Tool, path: &Path) -> Result<String> {
let mut cmd = Command::new(path); let mut cmd = Command::new(path);
cmd.arg("--version"); cmd.arg("--version");
let stdout = child::run_capture_stdout(cmd, tool)?; let stdout = child::run_capture_stdout(cmd, tool)?;
@ -127,7 +123,7 @@ pub fn download_prebuilt(
cache: &Cache, cache: &Cache,
version: &str, version: &str,
install_permitted: bool, install_permitted: bool,
) -> Result<Status, failure::Error> { ) -> Result<Status> {
let url = match prebuilt_url(tool, version) { let url = match prebuilt_url(tool, version) {
Ok(url) => url, Ok(url) => url,
Err(e) => bail!( Err(e) => bail!(
@ -164,19 +160,14 @@ pub fn download_prebuilt(
/// Returns the URL of a precompiled version of wasm-bindgen, if we have one /// Returns the URL of a precompiled version of wasm-bindgen, if we have one
/// available for our host platform. /// available for our host platform.
fn prebuilt_url(tool: &Tool, version: &str) -> Result<String, failure::Error> { fn prebuilt_url(tool: &Tool, version: &str) -> Result<String> {
let os = Os::get()?; let os = Os::get()?;
let arch = Arch::get()?; let arch = Arch::get()?;
prebuilt_url_for(tool, version, &arch, &os) prebuilt_url_for(tool, version, &arch, &os)
} }
/// Get the download URL for some tool at some version, architecture and operating system /// Get the download URL for some tool at some version, architecture and operating system
pub fn prebuilt_url_for( pub fn prebuilt_url_for(tool: &Tool, version: &str, arch: &Arch, os: &Os) -> Result<String> {
tool: &Tool,
version: &str,
arch: &Arch,
os: &Os,
) -> Result<String, failure::Error> {
let target = match (os, arch, tool) { let target = match (os, arch, tool) {
(Os::Linux, Arch::X86_64, Tool::WasmOpt) => "x86_64-linux", (Os::Linux, Arch::X86_64, Tool::WasmOpt) => "x86_64-linux",
(Os::Linux, Arch::X86_64, _) => "x86_64-unknown-linux-musl", (Os::Linux, Arch::X86_64, _) => "x86_64-unknown-linux-musl",
@ -220,7 +211,7 @@ pub fn cargo_install(
cache: &Cache, cache: &Cache,
version: &str, version: &str,
install_permitted: bool, install_permitted: bool,
) -> Result<Status, failure::Error> { ) -> Result<Status> {
debug!( debug!(
"Attempting to use a `cargo install`ed version of `{}={}`", "Attempting to use a `cargo install`ed version of `{}={}`",
tool, version, tool, version,
@ -275,7 +266,7 @@ pub fn cargo_install(
// just want them in `$root/*` directly (which matches how the tarballs are // just want them in `$root/*` directly (which matches how the tarballs are
// laid out, and where the rest of our code expects them to be). So we do a // laid out, and where the rest of our code expects them to be). So we do a
// little renaming here. // little renaming here.
let binaries: Result<Vec<&str>, failure::Error> = match tool { let binaries: Result<Vec<&str>> = match tool {
Tool::WasmBindgen => Ok(vec!["wasm-bindgen", "wasm-bindgen-test-runner"]), Tool::WasmBindgen => Ok(vec!["wasm-bindgen", "wasm-bindgen-test-runner"]),
Tool::CargoGenerate => Ok(vec!["cargo-generate"]), Tool::CargoGenerate => Ok(vec!["cargo-generate"]),
Tool::WasmOpt => bail!("Cannot install wasm-opt with cargo."), Tool::WasmOpt => bail!("Cannot install wasm-opt with cargo."),
@ -287,8 +278,8 @@ pub fn cargo_install(
.join(b) .join(b)
.with_extension(env::consts::EXE_EXTENSION); .with_extension(env::consts::EXE_EXTENSION);
let to = tmp.join(from.file_name().unwrap()); let to = tmp.join(from.file_name().unwrap());
fs::rename(&from, &to).with_context(|_| { fs::rename(&from, &to).with_context(|| {
format!( anyhow!(
"failed to move {} to {} for `cargo install`ed `{}`", "failed to move {} to {} for `cargo install`ed `{}`",
from.display(), from.display(),
to.display(), to.display(),

@ -1,3 +1,4 @@
use anyhow::{bail, Error, Result};
use std::str::FromStr; use std::str::FromStr;
/// The `InstallMode` determines which mode of initialization we are running, and /// The `InstallMode` determines which mode of initialization we are running, and
@ -20,8 +21,8 @@ impl Default for InstallMode {
} }
impl FromStr for InstallMode { impl FromStr for InstallMode {
type Err = failure::Error; type Err = Error;
fn from_str(s: &str) -> Result<Self, failure::Error> { fn from_str(s: &str) -> Result<Self> {
match s { match s {
"no-install" => Ok(InstallMode::Noinstall), "no-install" => Ok(InstallMode::Noinstall),
"normal" => Ok(InstallMode::Normal), "normal" => Ok(InstallMode::Normal),

@ -1,3 +1,4 @@
use anyhow::{bail, Result};
use std::fmt; use std::fmt;
use crate::target; use crate::target;
@ -15,7 +16,7 @@ pub enum Os {
impl Os { impl Os {
/// Get the current operating system /// Get the current operating system
pub fn get() -> Result<Self, failure::Error> { pub fn get() -> Result<Self> {
if target::LINUX { if target::LINUX {
Ok(Os::Linux) Ok(Os::Linux)
} else if target::MACOS { } else if target::MACOS {

@ -22,14 +22,14 @@ use std::io;
use std::path::Path; use std::path::Path;
use std::process; use std::process;
use anyhow::{anyhow, bail, Context, Result};
use atty; use atty;
use failure::{self, ResultExt};
use which; use which;
pub fn install() -> ! { pub fn install() -> ! {
if let Err(e) = do_install() { if let Err(e) = do_install() {
eprintln!("{}", e); eprintln!("{}", e);
for cause in e.iter_causes() { for cause in e.chain() {
eprintln!("Caused by: {}", cause); eprintln!("Caused by: {}", cause);
} }
} }
@ -47,7 +47,7 @@ pub fn install() -> ! {
process::exit(0); process::exit(0);
} }
fn do_install() -> Result<(), failure::Error> { fn do_install() -> Result<()> {
// Find `rustup.exe` in PATH, we'll be using its installation directory as // Find `rustup.exe` in PATH, we'll be using its installation directory as
// our installation directory. // our installation directory.
let rustup = match which::which("rustup") { let rustup = match which::which("rustup") {
@ -74,7 +74,7 @@ fn do_install() -> Result<(), failure::Error> {
// Our relatively simple install step! // Our relatively simple install step!
let me = env::current_exe()?; let me = env::current_exe()?;
fs::copy(&me, &destination) fs::copy(&me, &destination)
.with_context(|_| format!("failed to copy executable to `{}`", destination.display()))?; .with_context(|| anyhow!("failed to copy executable to `{}`", destination.display()))?;
println!( println!(
"info: successfully installed wasm-pack to `{}`", "info: successfully installed wasm-pack to `{}`",
destination.display() destination.display()
@ -85,7 +85,7 @@ fn do_install() -> Result<(), failure::Error> {
Ok(()) Ok(())
} }
fn confirm_can_overwrite(dst: &Path) -> Result<(), failure::Error> { fn confirm_can_overwrite(dst: &Path) -> Result<()> {
// If the `-f` argument was passed, we can always overwrite everything. // If the `-f` argument was passed, we can always overwrite everything.
if env::args().any(|arg| arg == "-f") { if env::args().any(|arg| arg == "-f") {
return Ok(()); return Ok(());
@ -112,7 +112,7 @@ fn confirm_can_overwrite(dst: &Path) -> Result<(), failure::Error> {
let mut line = String::new(); let mut line = String::new();
io::stdin() io::stdin()
.read_line(&mut line) .read_line(&mut line)
.with_context(|_| "failed to read stdin")?; .context("failed to read stdin")?;
if line.starts_with('y') || line.starts_with('Y') { if line.starts_with('y') || line.starts_with('Y') {
return Ok(()); return Ok(());

@ -2,15 +2,14 @@
#![deny(missing_docs)] #![deny(missing_docs)]
extern crate anyhow;
extern crate cargo_metadata; extern crate cargo_metadata;
extern crate console; extern crate console;
extern crate strsim;
#[macro_use]
extern crate failure;
extern crate glob; extern crate glob;
extern crate parking_lot; extern crate parking_lot;
extern crate semver; extern crate semver;
extern crate serde; extern crate serde;
extern crate strsim;
extern crate which; extern crate which;
#[macro_use] #[macro_use]
extern crate serde_derive; extern crate serde_derive;

@ -1,6 +1,6 @@
//! Copy `LICENSE` file(s) for the packaged wasm. //! Copy `LICENSE` file(s) for the packaged wasm.
use failure; use anyhow::{anyhow, Result};
use std::fs; use std::fs;
use std::path::Path; use std::path::Path;
@ -8,14 +8,12 @@ use glob::glob;
use manifest::CrateData; use manifest::CrateData;
use PBAR; use PBAR;
fn glob_license_files(path: &Path) -> Result<Vec<String>, failure::Error> { fn glob_license_files(path: &Path) -> Result<Vec<String>> {
let mut license_files: Vec<String> = Vec::new(); let mut license_files: Vec<String> = Vec::new();
let path_string = match path.join("LICENSE*").to_str() { let path_string = match path.join("LICENSE*").to_str() {
Some(path_string) => path_string.to_owned(), Some(path_string) => path_string.to_owned(),
None => { None => {
return Err(format_err!( return Err(anyhow!("Could not convert joined license path to String"));
"Could not convert joined license path to String"
));
} }
}; };
@ -24,11 +22,11 @@ fn glob_license_files(path: &Path) -> Result<Vec<String>, failure::Error> {
Ok(globed_path) => { Ok(globed_path) => {
let file_name = match globed_path.file_name() { let file_name = match globed_path.file_name() {
Some(file_name) => file_name, Some(file_name) => file_name,
None => return Err(format_err!("Could not get file name from path")), None => return Err(anyhow!("Could not get file name from path")),
}; };
let file_name_string = match file_name.to_str() { let file_name_string = match file_name.to_str() {
Some(file_name_string) => file_name_string.to_owned(), Some(file_name_string) => file_name_string.to_owned(),
None => return Err(format_err!("Could not convert filename to String")), None => return Err(anyhow!("Could not convert filename to String")),
}; };
license_files.push(file_name_string); license_files.push(file_name_string);
} }
@ -39,11 +37,7 @@ fn glob_license_files(path: &Path) -> Result<Vec<String>, failure::Error> {
} }
/// Copy the crate's license into the `pkg` directory. /// Copy the crate's license into the `pkg` directory.
pub fn copy_from_crate( pub fn copy_from_crate(crate_data: &CrateData, path: &Path, out_dir: &Path) -> Result<()> {
crate_data: &CrateData,
path: &Path,
out_dir: &Path,
) -> Result<(), failure::Error> {
assert!( assert!(
fs::metadata(path).ok().map_or(false, |m| m.is_dir()), fs::metadata(path).ok().map_or(false, |m| m.is_dir()),
"crate directory should exist" "crate directory should exist"

@ -5,8 +5,8 @@
use std::fs; use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
use anyhow::{anyhow, bail, Context, Result};
use console::style; use console::style;
use failure::{Error, ResultExt};
use manifest::CrateData; use manifest::CrateData;
use toml; use toml;
@ -25,12 +25,12 @@ struct Package {
impl Lockfile { impl Lockfile {
/// Read the `Cargo.lock` file for the crate at the given path. /// Read the `Cargo.lock` file for the crate at the given path.
pub fn new(crate_data: &CrateData) -> Result<Lockfile, Error> { pub fn new(crate_data: &CrateData) -> Result<Lockfile> {
let lock_path = get_lockfile_path(crate_data)?; let lock_path = get_lockfile_path(crate_data)?;
let lockfile = fs::read_to_string(&lock_path) let lockfile = fs::read_to_string(&lock_path)
.with_context(|_| format!("failed to read: {}", lock_path.display()))?; .with_context(|| anyhow!("failed to read: {}", lock_path.display()))?;
let lockfile = toml::from_str(&lockfile) let lockfile = toml::from_str(&lockfile)
.with_context(|_| format!("failed to parse: {}", lock_path.display()))?; .with_context(|| anyhow!("failed to parse: {}", lock_path.display()))?;
Ok(lockfile) Ok(lockfile)
} }
@ -41,9 +41,9 @@ impl Lockfile {
/// Like `wasm_bindgen_version`, except it returns an error instead of /// Like `wasm_bindgen_version`, except it returns an error instead of
/// `None`. /// `None`.
pub fn require_wasm_bindgen(&self) -> Result<&str, Error> { pub fn require_wasm_bindgen(&self) -> Result<&str> {
self.wasm_bindgen_version().ok_or_else(|| { self.wasm_bindgen_version().ok_or_else(|| {
format_err!( anyhow!(
"Ensure that you have \"{}\" as a dependency in your Cargo.toml file:\n\ "Ensure that you have \"{}\" as a dependency in your Cargo.toml file:\n\
[dependencies]\n\ [dependencies]\n\
wasm-bindgen = \"0.2\"", wasm-bindgen = \"0.2\"",
@ -67,7 +67,7 @@ impl Lockfile {
/// Given the path to the crate that we are buliding, return a `PathBuf` /// Given the path to the crate that we are buliding, return a `PathBuf`
/// containing the location of the lock file, by finding the workspace root. /// containing the location of the lock file, by finding the workspace root.
fn get_lockfile_path(crate_data: &CrateData) -> Result<PathBuf, Error> { fn get_lockfile_path(crate_data: &CrateData) -> Result<PathBuf> {
// Check that a lock file can be found in the directory. Return an error // Check that a lock file can be found in the directory. Return an error
// if it cannot, otherwise return the path buffer. // if it cannot, otherwise return the path buffer.
let lockfile_path = crate_data.workspace_root().join("Cargo.lock"); let lockfile_path = crate_data.workspace_root().join("Cargo.lock");

@ -1,15 +1,15 @@
#![allow(clippy::redundant_closure, clippy::redundant_pattern_matching)] #![allow(clippy::redundant_closure, clippy::redundant_pattern_matching)]
extern crate anyhow;
extern crate atty; extern crate atty;
extern crate env_logger; extern crate env_logger;
#[macro_use]
extern crate failure;
extern crate human_panic; extern crate human_panic;
extern crate log; extern crate log;
extern crate structopt; extern crate structopt;
extern crate wasm_pack; extern crate wasm_pack;
extern crate which; extern crate which;
use anyhow::Result;
use std::env; use std::env;
use std::panic; use std::panic;
use std::sync::mpsc; use std::sync::mpsc;
@ -23,7 +23,7 @@ use wasm_pack::{
mod installer; mod installer;
fn background_check_for_updates() -> mpsc::Receiver<Result<WasmPackVersion, failure::Error>> { fn background_check_for_updates() -> mpsc::Receiver<Result<WasmPackVersion>> {
let (sender, receiver) = mpsc::channel(); let (sender, receiver) = mpsc::channel();
let _detached_thread = thread::spawn(move || { let _detached_thread = thread::spawn(move || {
@ -51,14 +51,14 @@ fn main() {
if let Err(e) = run() { if let Err(e) = run() {
eprintln!("Error: {}", e); eprintln!("Error: {}", e);
for cause in e.iter_causes() { for cause in e.chain() {
eprintln!("Caused by: {}", cause); eprintln!("Caused by: {}", cause);
} }
::std::process::exit(1); ::std::process::exit(1);
} }
} }
fn run() -> Result<(), failure::Error> { fn run() -> Result<()> {
let wasm_pack_version = background_check_for_updates(); let wasm_pack_version = background_check_for_updates();
// Deprecate `init` // Deprecate `init`

@ -6,6 +6,7 @@
clippy::redundant_closure clippy::redundant_closure
)] )]
use anyhow::{anyhow, bail, Context, Result};
mod npm; mod npm;
use std::path::Path; use std::path::Path;
@ -19,7 +20,6 @@ use chrono::offset;
use chrono::DateTime; use chrono::DateTime;
use command::build::{BuildProfile, Target}; use command::build::{BuildProfile, Target};
use curl::easy; use curl::easy;
use failure::{Error, ResultExt};
use serde::{self, Deserialize}; use serde::{self, Deserialize};
use serde_json; use serde_json;
use std::collections::BTreeSet; use std::collections::BTreeSet;
@ -149,7 +149,7 @@ struct CrateInformation {
impl Crate { impl Crate {
/// Returns latest wasm-pack version /// Returns latest wasm-pack version
pub fn return_wasm_pack_latest_version() -> Result<Option<String>, failure::Error> { pub fn return_wasm_pack_latest_version() -> Result<Option<String>> {
let current_time = chrono::offset::Local::now(); let current_time = chrono::offset::Local::now();
let old_metadata_file = Self::return_wasm_pack_file(); let old_metadata_file = Self::return_wasm_pack_file();
@ -172,9 +172,7 @@ impl Crate {
} }
} }
fn return_api_call_result( fn return_api_call_result(current_time: DateTime<offset::Local>) -> Result<String> {
current_time: DateTime<offset::Local>,
) -> Result<String, failure::Error> {
let version = Self::return_latest_wasm_pack_version(); let version = Self::return_latest_wasm_pack_version();
// We always override the stamp file with the current time because we don't // We always override the stamp file with the current time because we don't
@ -192,7 +190,7 @@ impl Crate {
fn override_stamp_file( fn override_stamp_file(
current_time: DateTime<offset::Local>, current_time: DateTime<offset::Local>,
version: Option<&str>, version: Option<&str>,
) -> Result<(), failure::Error> { ) -> Result<()> {
let path = env::current_exe()?; let path = env::current_exe()?;
let mut file = fs::OpenOptions::new() let mut file = fs::OpenOptions::new()
@ -224,7 +222,7 @@ impl Crate {
} }
/// Returns wasm-pack latest version (if it's received) by executing check_wasm_pack_latest_version function. /// Returns wasm-pack latest version (if it's received) by executing check_wasm_pack_latest_version function.
fn return_latest_wasm_pack_version() -> Result<String, failure::Error> { fn return_latest_wasm_pack_version() -> Result<String> {
Self::check_wasm_pack_latest_version().map(|crt| crt.crt.max_version) Self::check_wasm_pack_latest_version().map(|crt| crt.crt.max_version)
} }
@ -239,7 +237,7 @@ impl Crate {
} }
/// Call to the crates.io api and return the latest version of `wasm-pack` /// Call to the crates.io api and return the latest version of `wasm-pack`
fn check_wasm_pack_latest_version() -> Result<Crate, Error> { fn check_wasm_pack_latest_version() -> Result<Crate> {
let url = "https://crates.io/api/v1/crates/wasm-pack"; let url = "https://crates.io/api/v1/crates/wasm-pack";
let mut easy = easy::Easy2::new(Collector(Vec::new())); let mut easy = easy::Easy2::new(Collector(Vec::new()));
@ -403,7 +401,7 @@ pub struct ManifestAndUnsedKeys {
impl CrateData { impl CrateData {
/// Reads all metadata for the crate whose manifest is inside the directory /// Reads all metadata for the crate whose manifest is inside the directory
/// specified by `path`. /// specified by `path`.
pub fn new(crate_path: &Path, out_name: Option<String>) -> Result<CrateData, Error> { pub fn new(crate_path: &Path, out_name: Option<String>) -> Result<CrateData> {
let manifest_path = crate_path.join("Cargo.toml"); let manifest_path = crate_path.join("Cargo.toml");
if !manifest_path.is_file() { if !manifest_path.is_file() {
bail!( bail!(
@ -428,7 +426,7 @@ impl CrateData {
pkg.name == manifest.package.name pkg.name == manifest.package.name
&& CrateData::is_same_path(&pkg.manifest_path, &manifest_path) && CrateData::is_same_path(&pkg.manifest_path, &manifest_path)
}) })
.ok_or_else(|| format_err!("failed to find package in metadata"))?; .ok_or_else(|| anyhow!("failed to find package in metadata"))?;
Ok(CrateData { Ok(CrateData {
data, data,
@ -454,9 +452,9 @@ impl CrateData {
/// # Errors /// # Errors
/// Will return Err if the file (manifest_path) couldn't be read or /// Will return Err if the file (manifest_path) couldn't be read or
/// if deserialize to `CargoManifest` fails. /// if deserialize to `CargoManifest` fails.
pub fn parse_crate_data(manifest_path: &Path) -> Result<ManifestAndUnsedKeys, Error> { pub fn parse_crate_data(manifest_path: &Path) -> Result<ManifestAndUnsedKeys> {
let manifest = fs::read_to_string(&manifest_path) let manifest = fs::read_to_string(&manifest_path)
.with_context(|_| format!("failed to read: {}", manifest_path.display()))?; .with_context(|| anyhow!("failed to read: {}", manifest_path.display()))?;
let manifest = &mut toml::Deserializer::new(&manifest); let manifest = &mut toml::Deserializer::new(&manifest);
let mut unused_keys = BTreeSet::new(); let mut unused_keys = BTreeSet::new();
@ -472,7 +470,7 @@ impl CrateData {
unused_keys.insert(path_string); unused_keys.insert(path_string);
} }
}) })
.with_context(|_| format!("failed to parse manifest: {}", manifest_path.display()))?; .with_context(|| anyhow!("failed to parse manifest: {}", manifest_path.display()))?;
Ok(ManifestAndUnsedKeys { Ok(ManifestAndUnsedKeys {
manifest, manifest,
@ -501,12 +499,12 @@ impl CrateData {
} }
/// Check that the crate the given path is properly configured. /// Check that the crate the given path is properly configured.
pub fn check_crate_config(&self) -> Result<(), Error> { pub fn check_crate_config(&self) -> Result<()> {
self.check_crate_type()?; self.check_crate_type()?;
Ok(()) Ok(())
} }
fn check_crate_type(&self) -> Result<(), Error> { fn check_crate_type(&self) -> Result<()> {
let pkg = &self.data.packages[self.current_idx]; let pkg = &self.data.packages[self.current_idx];
let any_cdylib = pkg let any_cdylib = pkg
.targets .targets
@ -573,7 +571,7 @@ impl CrateData {
scope: &Option<String>, scope: &Option<String>,
disable_dts: bool, disable_dts: bool,
target: Target, target: Target,
) -> Result<(), Error> { ) -> Result<()> {
let pkg_file_path = out_dir.join("package.json"); let pkg_file_path = out_dir.join("package.json");
// Check if a `package.json` was already generated by wasm-bindgen, if so // Check if a `package.json` was already generated by wasm-bindgen, if so
// we merge the NPM dependencies already specified in it. // we merge the NPM dependencies already specified in it.
@ -597,7 +595,7 @@ impl CrateData {
let npm_json = serde_json::to_string_pretty(&npm_data)?; let npm_json = serde_json::to_string_pretty(&npm_data)?;
fs::write(&pkg_file_path, npm_json) fs::write(&pkg_file_path, npm_json)
.with_context(|_| format!("failed to write: {}", pkg_file_path.display()))?; .with_context(|| anyhow!("failed to write: {}", pkg_file_path.display()))?;
Ok(()) Ok(())
} }

@ -1,15 +1,15 @@
//! Functionality related to publishing to npm. //! Functionality related to publishing to npm.
use anyhow::{bail, Context, Result};
use child; use child;
use command::publish::access::Access; use command::publish::access::Access;
use failure::{self, ResultExt};
use log::info; use log::info;
/// The default npm registry used when we aren't working with a custom registry. /// The default npm registry used when we aren't working with a custom registry.
pub const DEFAULT_NPM_REGISTRY: &str = "https://registry.npmjs.org/"; pub const DEFAULT_NPM_REGISTRY: &str = "https://registry.npmjs.org/";
/// Run the `npm pack` command. /// Run the `npm pack` command.
pub fn npm_pack(path: &str) -> Result<(), failure::Error> { pub fn npm_pack(path: &str) -> Result<()> {
let mut cmd = child::new_command("npm"); let mut cmd = child::new_command("npm");
cmd.current_dir(path).arg("pack"); cmd.current_dir(path).arg("pack");
child::run(cmd, "npm pack").context("Packaging up your code failed")?; child::run(cmd, "npm pack").context("Packaging up your code failed")?;
@ -17,11 +17,7 @@ pub fn npm_pack(path: &str) -> Result<(), failure::Error> {
} }
/// Run the `npm publish` command. /// Run the `npm publish` command.
pub fn npm_publish( pub fn npm_publish(path: &str, access: Option<Access>, tag: Option<String>) -> Result<()> {
path: &str,
access: Option<Access>,
tag: Option<String>,
) -> Result<(), failure::Error> {
let mut cmd = child::new_command("npm"); let mut cmd = child::new_command("npm");
match access { match access {
Some(a) => cmd.current_dir(path).arg("publish").arg(&a.to_string()), Some(a) => cmd.current_dir(path).arg("publish").arg(&a.to_string()),
@ -41,7 +37,7 @@ pub fn npm_login(
scope: &Option<String>, scope: &Option<String>,
always_auth: bool, always_auth: bool,
auth_type: &Option<String>, auth_type: &Option<String>,
) -> Result<(), failure::Error> { ) -> Result<()> {
let mut args = vec!["login".to_string(), format!("--registry={}", registry)]; let mut args = vec!["login".to_string(), format!("--registry={}", registry)];
if let Some(scope) = scope { if let Some(scope) = scope {

@ -1,5 +1,6 @@
//! Fancy progress bar functionality. //! Fancy progress bar functionality.
use anyhow::{bail, Error, Result};
use console::style; use console::style;
use emoji; use emoji;
use std::sync::atomic::{AtomicBool, AtomicU8, Ordering}; use std::sync::atomic::{AtomicBool, AtomicU8, Ordering};
@ -19,8 +20,8 @@ pub enum LogLevel {
} }
impl std::str::FromStr for LogLevel { impl std::str::FromStr for LogLevel {
type Err = failure::Error; type Err = Error;
fn from_str(s: &str) -> Result<Self, failure::Error> { fn from_str(s: &str) -> Result<Self> {
match s { match s {
"error" => Ok(LogLevel::Error), "error" => Ok(LogLevel::Error),
"warn" => Ok(LogLevel::Warn), "warn" => Ok(LogLevel::Warn),

@ -1,13 +1,13 @@
//! Generating `README` files for the packaged wasm. //! Generating `README` files for the packaged wasm.
use failure::{self, ResultExt}; use anyhow::{Context, Result};
use std::fs; use std::fs;
use std::path::Path; use std::path::Path;
use PBAR; use PBAR;
/// Copy the crate's README into the `pkg` directory. /// Copy the crate's README into the `pkg` directory.
pub fn copy_from_crate(path: &Path, out_dir: &Path) -> Result<(), failure::Error> { pub fn copy_from_crate(path: &Path, out_dir: &Path) -> Result<()> {
assert!( assert!(
fs::metadata(path).ok().map_or(false, |m| m.is_dir()), fs::metadata(path).ok().map_or(false, |m| m.is_dir()),
"crate directory should exist" "crate directory should exist"

@ -1,33 +1,25 @@
//! Key-value store in `*.stamps` file. //! Key-value store in `*.stamps` file.
use failure::{self, ResultExt}; use anyhow::{anyhow, Context, Result};
use std::{env, fs, path::PathBuf}; use std::{env, fs, path::PathBuf};
/// Get a value corresponding to the key from the JSON value. /// Get a value corresponding to the key from the JSON value.
/// ///
/// You should use return value of function `read_stamps_file_to_json()` as `json` argument. /// You should use return value of function `read_stamps_file_to_json()` as `json` argument.
pub fn get_stamp_value( pub fn get_stamp_value(key: impl AsRef<str>, json: &serde_json::Value) -> Result<String> {
key: impl AsRef<str>,
json: &serde_json::Value,
) -> Result<String, failure::Error> {
json.get(key.as_ref()) json.get(key.as_ref())
.and_then(|value| value.as_str().map(ToOwned::to_owned)) .and_then(|value| value.as_str().map(ToOwned::to_owned))
.ok_or_else(|| { .ok_or_else(|| anyhow!("cannot get stamp value for key '{}'", key.as_ref()))
failure::err_msg(format!("cannot get stamp value for key '{}'", key.as_ref()))
})
} }
/// Save the key-value pair to the store. /// Save the key-value pair to the store.
pub fn save_stamp_value( pub fn save_stamp_value(key: impl Into<String>, value: impl AsRef<str>) -> Result<()> {
key: impl Into<String>,
value: impl AsRef<str>,
) -> Result<(), failure::Error> {
let mut json = read_stamps_file_to_json().unwrap_or_else(|_| serde_json::Map::new().into()); let mut json = read_stamps_file_to_json().unwrap_or_else(|_| serde_json::Map::new().into());
{ {
let stamps = json let stamps = json
.as_object_mut() .as_object_mut()
.ok_or_else(|| failure::err_msg("stamps file doesn't contain JSON object"))?; .ok_or_else(|| anyhow!("stamps file doesn't contain JSON object"))?;
stamps.insert(key.into(), value.as_ref().into()); stamps.insert(key.into(), value.as_ref().into());
} }
@ -35,7 +27,7 @@ pub fn save_stamp_value(
} }
/// Get the path of the `*.stamps` file that is used as the store. /// Get the path of the `*.stamps` file that is used as the store.
pub fn get_stamps_file_path() -> Result<PathBuf, failure::Error> { pub fn get_stamps_file_path() -> Result<PathBuf> {
let path = env::current_exe() let path = env::current_exe()
.map(|path| path.with_extension("stamps")) .map(|path| path.with_extension("stamps"))
.context("cannot get stamps file path")?; .context("cannot get stamps file path")?;
@ -43,7 +35,7 @@ pub fn get_stamps_file_path() -> Result<PathBuf, failure::Error> {
} }
/// Read `*.stamps` file and convert its content to the JSON value. /// Read `*.stamps` file and convert its content to the JSON value.
pub fn read_stamps_file_to_json() -> Result<serde_json::Value, failure::Error> { pub fn read_stamps_file_to_json() -> Result<serde_json::Value> {
let stamps_file_path = get_stamps_file_path()?; let stamps_file_path = get_stamps_file_path()?;
let stamps_file_content = let stamps_file_content =
fs::read_to_string(stamps_file_path).context("cannot find or read stamps file")?; fs::read_to_string(stamps_file_path).context("cannot find or read stamps file")?;
@ -52,7 +44,7 @@ pub fn read_stamps_file_to_json() -> Result<serde_json::Value, failure::Error> {
Ok(json) Ok(json)
} }
fn write_to_stamps_file(json: serde_json::Value) -> Result<(), failure::Error> { fn write_to_stamps_file(json: serde_json::Value) -> Result<()> {
let stamps_file_path = get_stamps_file_path()?; let stamps_file_path = get_stamps_file_path()?;
let pretty_json = serde_json::to_string_pretty(&json).context("JSON serialization failed")?; let pretty_json = serde_json::to_string_pretty(&json).context("JSON serialization failed")?;
fs::write(stamps_file_path, pretty_json).context("cannot write to stamps file")?; fs::write(stamps_file_path, pretty_json).context("cannot write to stamps file")?;

@ -3,8 +3,8 @@
pub mod webdriver; pub mod webdriver;
use crate::PBAR; use crate::PBAR;
use anyhow::{Context, Result};
use child; use child;
use failure::{self, ResultExt};
use std::ffi::OsStr; use std::ffi::OsStr;
use std::path::Path; use std::path::Path;
use std::process::Command; use std::process::Command;
@ -16,7 +16,7 @@ pub fn cargo_test_wasm<I, K, V>(
release: bool, release: bool,
envs: I, envs: I,
extra_options: &[String], extra_options: &[String],
) -> Result<(), failure::Error> ) -> Result<()>
where where
I: IntoIterator<Item = (K, V)>, I: IntoIterator<Item = (K, V)>,
K: AsRef<OsStr>, K: AsRef<OsStr>,

@ -4,8 +4,8 @@ mod chromedriver;
mod geckodriver; mod geckodriver;
mod safaridriver; mod safaridriver;
use anyhow::Result;
use binary_install::Cache; use binary_install::Cache;
use failure;
use std::path::PathBuf; use std::path::PathBuf;
use PBAR; use PBAR;
@ -22,7 +22,7 @@ fn get_and_notify(
installation_allowed: bool, installation_allowed: bool,
name: &str, name: &str,
url: &str, url: &str,
) -> Result<Option<PathBuf>, failure::Error> { ) -> Result<Option<PathBuf>> {
if let Some(dl) = cache.download(false, name, &[name], url)? { if let Some(dl) = cache.download(false, name, &[name], url)? {
return Ok(Some(dl.binary(name)?)); return Ok(Some(dl.binary(name)?));
} }

@ -1,7 +1,7 @@
use super::{get_and_notify, Collector}; use super::{get_and_notify, Collector};
use anyhow::{bail, Context, Result};
use binary_install::Cache; use binary_install::Cache;
use chrono::DateTime; use chrono::DateTime;
use failure::{self, ResultExt};
use install::InstallMode; use install::InstallMode;
use stamps; use stamps;
use std::path::PathBuf; use std::path::PathBuf;
@ -16,10 +16,7 @@ const CHROMEDRIVER_VERSION_STAMP: &str = "chromedriver_version";
/// Get the path to an existing `chromedriver`, or install it if no existing /// Get the path to an existing `chromedriver`, or install it if no existing
/// binary is found or if there is a new binary version. /// binary is found or if there is a new binary version.
pub fn get_or_install_chromedriver( pub fn get_or_install_chromedriver(cache: &Cache, mode: InstallMode) -> Result<PathBuf> {
cache: &Cache,
mode: InstallMode,
) -> Result<PathBuf, failure::Error> {
if let Ok(path) = which::which("chromedriver") { if let Ok(path) = which::which("chromedriver") {
return Ok(path); return Ok(path);
} }
@ -27,10 +24,7 @@ pub fn get_or_install_chromedriver(
} }
/// Download and install a pre-built `chromedriver` binary. /// Download and install a pre-built `chromedriver` binary.
pub fn install_chromedriver( pub fn install_chromedriver(cache: &Cache, installation_allowed: bool) -> Result<PathBuf> {
cache: &Cache,
installation_allowed: bool,
) -> Result<PathBuf, failure::Error> {
let target = if target::LINUX && target::x86_64 { let target = if target::LINUX && target::x86_64 {
"linux64" "linux64"
} else if target::MACOS && target::x86_64 { } else if target::MACOS && target::x86_64 {
@ -99,7 +93,7 @@ fn get_chromedriver_url(target: &str) -> String {
// ------ `get_chromedriver_url` helpers ------ // ------ `get_chromedriver_url` helpers ------
fn save_chromedriver_version(version: String) -> Result<String, failure::Error> { fn save_chromedriver_version(version: String) -> Result<String> {
stamps::save_stamp_value(CHROMEDRIVER_VERSION_STAMP, &version)?; stamps::save_stamp_value(CHROMEDRIVER_VERSION_STAMP, &version)?;
let current_time = chrono::offset::Local::now().to_rfc3339(); let current_time = chrono::offset::Local::now().to_rfc3339();
@ -122,7 +116,7 @@ fn should_load_chromedriver_version_from_stamp(json: &serde_json::Value) -> bool
} }
} }
fn fetch_chromedriver_version() -> Result<String, failure::Error> { fn fetch_chromedriver_version() -> Result<String> {
let mut handle = curl::easy::Easy2::new(Collector(Vec::new())); let mut handle = curl::easy::Easy2::new(Collector(Vec::new()));
handle handle
.url("https://chromedriver.storage.googleapis.com/LATEST_RELEASE") .url("https://chromedriver.storage.googleapis.com/LATEST_RELEASE")

@ -1,7 +1,7 @@
use super::{get_and_notify, Collector}; use super::{get_and_notify, Collector};
use anyhow::{anyhow, bail, Context, Result};
use binary_install::Cache; use binary_install::Cache;
use chrono::DateTime; use chrono::DateTime;
use failure::{self, ResultExt};
use install::InstallMode; use install::InstallMode;
use stamps; use stamps;
use std::path::PathBuf; use std::path::PathBuf;
@ -17,10 +17,7 @@ const GECKODRIVER_VERSION_STAMP: &str = "geckodriver_version";
/// Get the path to an existing `geckodriver`, or install it if no existing /// Get the path to an existing `geckodriver`, or install it if no existing
/// binary is found or if there is a new binary version. /// binary is found or if there is a new binary version.
pub fn get_or_install_geckodriver( pub fn get_or_install_geckodriver(cache: &Cache, mode: InstallMode) -> Result<PathBuf> {
cache: &Cache,
mode: InstallMode,
) -> Result<PathBuf, failure::Error> {
// geckodriver Windows binaries >v0.24.0 have an additional // geckodriver Windows binaries >v0.24.0 have an additional
// runtime dependency that we cannot be sure is present on the // runtime dependency that we cannot be sure is present on the
// user's machine // user's machine
@ -38,10 +35,7 @@ pub fn get_or_install_geckodriver(
} }
/// Download and install a pre-built `geckodriver` binary. /// Download and install a pre-built `geckodriver` binary.
pub fn install_geckodriver( pub fn install_geckodriver(cache: &Cache, installation_allowed: bool) -> Result<PathBuf> {
cache: &Cache,
installation_allowed: bool,
) -> Result<PathBuf, failure::Error> {
let (target, ext) = if target::LINUX && target::x86 { let (target, ext) = if target::LINUX && target::x86 {
("linux32", "tar.gz") ("linux32", "tar.gz")
} else if target::LINUX && target::x86_64 { } else if target::LINUX && target::x86_64 {
@ -124,7 +118,7 @@ fn get_geckodriver_url(target: &str, ext: &str) -> String {
// ------ `get_geckodriver_url` helpers ------ // ------ `get_geckodriver_url` helpers ------
fn save_geckodriver_version(version: String) -> Result<String, failure::Error> { fn save_geckodriver_version(version: String) -> Result<String> {
stamps::save_stamp_value(GECKODRIVER_VERSION_STAMP, &version)?; stamps::save_stamp_value(GECKODRIVER_VERSION_STAMP, &version)?;
let current_time = chrono::offset::Local::now().to_rfc3339(); let current_time = chrono::offset::Local::now().to_rfc3339();
@ -147,7 +141,7 @@ fn should_load_geckodriver_version_from_stamp(json: &serde_json::Value) -> bool
} }
} }
fn fetch_latest_geckodriver_tag_json() -> Result<String, failure::Error> { fn fetch_latest_geckodriver_tag_json() -> Result<String> {
let mut headers = curl::easy::List::new(); let mut headers = curl::easy::List::new();
headers headers
.append("Accept: application/json") .append("Accept: application/json")
@ -176,14 +170,12 @@ fn fetch_latest_geckodriver_tag_json() -> Result<String, failure::Error> {
} }
/// JSON example: `{"id":15227534,"tag_name":"v0.24.0","update_url":"/mozzila...` /// JSON example: `{"id":15227534,"tag_name":"v0.24.0","update_url":"/mozzila...`
fn get_version_from_json(json: impl AsRef<str>) -> Result<String, failure::Error> { fn get_version_from_json(json: impl AsRef<str>) -> Result<String> {
let json: serde_json::Value = serde_json::from_str(json.as_ref()) let json: serde_json::Value = serde_json::from_str(json.as_ref())
.context("geckodriver's latest release data is not valid JSON")?; .context("geckodriver's latest release data is not valid JSON")?;
json.get("tag_name") json.get("tag_name")
.and_then(|tag_name| tag_name.as_str().map(ToOwned::to_owned)) .and_then(|tag_name| tag_name.as_str().map(ToOwned::to_owned))
.ok_or_else(|| { .ok_or_else(|| anyhow!("cannot get `tag_name` from geckodriver's latest release data"))
failure::err_msg("cannot get `tag_name` from geckodriver's latest release data")
})
} }
fn assemble_geckodriver_url(tag: &str, target: &str, ext: &str) -> String { fn assemble_geckodriver_url(tag: &str, target: &str, ext: &str) -> String {

@ -1,3 +1,4 @@
use anyhow::{bail, Result};
use std::path::PathBuf; use std::path::PathBuf;
/// Get the path to an existing `safaridriver`. /// Get the path to an existing `safaridriver`.
@ -5,7 +6,7 @@ use std::path::PathBuf;
/// We can't install `safaridriver` if an existing one is not found because /// We can't install `safaridriver` if an existing one is not found because
/// Apple does not provide pre-built binaries. However, `safaridriver` *should* /// Apple does not provide pre-built binaries. However, `safaridriver` *should*
/// be present by default. /// be present by default.
pub fn get_safaridriver() -> Result<PathBuf, failure::Error> { pub fn get_safaridriver() -> Result<PathBuf> {
match which::which("safaridriver") { match which::which("safaridriver") {
Ok(p) => Ok(p), Ok(p) => Ok(p),
Err(_) => bail!("could not find `safaridriver` on the `$PATH`"), Err(_) => bail!("could not find `safaridriver` on the `$PATH`"),

@ -3,18 +3,14 @@
use crate::child; use crate::child;
use crate::install::{self, Tool}; use crate::install::{self, Tool};
use crate::PBAR; use crate::PBAR;
use anyhow::Result;
use binary_install::{Cache, Download}; use binary_install::{Cache, Download};
use std::path::Path; use std::path::Path;
use std::process::Command; use std::process::Command;
/// Execute `wasm-opt` over wasm binaries found in `out_dir`, downloading if /// Execute `wasm-opt` over wasm binaries found in `out_dir`, downloading if
/// necessary into `cache`. Passes `args` to each invocation of `wasm-opt`. /// necessary into `cache`. Passes `args` to each invocation of `wasm-opt`.
pub fn run( pub fn run(cache: &Cache, out_dir: &Path, args: &[String], install_permitted: bool) -> Result<()> {
cache: &Cache,
out_dir: &Path,
args: &[String],
install_permitted: bool,
) -> Result<(), failure::Error> {
let wasm_opt = match find_wasm_opt(cache, install_permitted)? { let wasm_opt = match find_wasm_opt(cache, install_permitted)? {
install::Status::Found(path) => path, install::Status::Found(path) => path,
install::Status::CannotInstall => { install::Status::CannotInstall => {
@ -55,10 +51,7 @@ pub fn run(
/// Returns `None` if a binary wasn't found in `PATH` and this platform doesn't /// Returns `None` if a binary wasn't found in `PATH` and this platform doesn't
/// have precompiled binaries. Returns an error if we failed to download the /// have precompiled binaries. Returns an error if we failed to download the
/// binary. /// binary.
pub fn find_wasm_opt( pub fn find_wasm_opt(cache: &Cache, install_permitted: bool) -> Result<install::Status> {
cache: &Cache,
install_permitted: bool,
) -> Result<install::Status, failure::Error> {
// First attempt to look up in PATH. If found assume it works. // First attempt to look up in PATH. If found assume it works.
if let Ok(path) = which::which("wasm-opt") { if let Ok(path) = which::which("wasm-opt") {
PBAR.info(&format!("found wasm-opt at {:?}", path)); PBAR.info(&format!("found wasm-opt at {:?}", path));

@ -35,10 +35,8 @@ fn downloading_prebuilt_wasm_bindgen_handles_http_errors() {
assert!(result.is_err()); assert!(result.is_err());
let error = result.err().unwrap(); let error = result.err().unwrap();
assert!(error.iter_chain().any(|e| e.to_string().contains("404"))); assert!(error.chain().any(|e| e.to_string().contains("404")));
assert!(error assert!(error.chain().any(|e| e.to_string().contains(bad_version)));
.iter_chain()
.any(|e| e.to_string().contains(bad_version)));
} }
#[test] #[test]

@ -1,4 +1,4 @@
extern crate failure; extern crate anyhow;
extern crate wasm_pack; extern crate wasm_pack;
use std::fs; use std::fs;

@ -1,8 +1,7 @@
extern crate anyhow;
extern crate assert_cmd; extern crate assert_cmd;
extern crate failure;
extern crate predicates;
#[macro_use]
extern crate lazy_static; extern crate lazy_static;
extern crate predicates;
#[macro_use] #[macro_use]
extern crate serde_derive; extern crate serde_derive;
extern crate binary_install; extern crate binary_install;

@ -1,4 +1,4 @@
extern crate failure; extern crate anyhow;
extern crate wasm_pack; extern crate wasm_pack;
use std::fs; use std::fs;

@ -33,6 +33,7 @@ fn it_can_run_tests_with_different_wbg_test_and_wbg_versions() {
#[cfg(any( #[cfg(any(
all(target_os = "linux", target_arch = "x86_64"), all(target_os = "linux", target_arch = "x86_64"),
all(target_os = "macos", target_arch = "x86_64"), all(target_os = "macos", target_arch = "x86_64"),
all(target_os = "macos", target_arch = "aarch64"),
all(target_os = "windows", target_arch = "x86"), all(target_os = "windows", target_arch = "x86"),
all(target_os = "windows", target_arch = "x86_64") all(target_os = "windows", target_arch = "x86_64")
))] ))]
@ -44,6 +45,7 @@ fn it_can_run_browser_tests() {
all(target_os = "linux", target_arch = "x86"), all(target_os = "linux", target_arch = "x86"),
all(target_os = "linux", target_arch = "x86_64"), all(target_os = "linux", target_arch = "x86_64"),
all(target_os = "macos", target_arch = "x86_64"), all(target_os = "macos", target_arch = "x86_64"),
all(target_os = "macos", target_arch = "aarch64"),
all(target_os = "windows", target_arch = "x86"), all(target_os = "windows", target_arch = "x86"),
all(target_os = "windows", target_arch = "x86_64") all(target_os = "windows", target_arch = "x86_64")
)); ));
@ -104,6 +106,7 @@ fn it_can_run_failing_tests() {
all(target_os = "linux", target_arch = "x86"), all(target_os = "linux", target_arch = "x86"),
all(target_os = "linux", target_arch = "x86_64"), all(target_os = "linux", target_arch = "x86_64"),
all(target_os = "macos", target_arch = "x86_64"), all(target_os = "macos", target_arch = "x86_64"),
all(target_os = "macos", target_arch = "aarch64"),
all(target_os = "windows", target_arch = "x86"), all(target_os = "windows", target_arch = "x86"),
all(target_os = "windows", target_arch = "x86_64") all(target_os = "windows", target_arch = "x86_64")
))] ))]

@ -2,9 +2,9 @@ use std::fs::File;
use std::io::Read; use std::io::Read;
use std::path::Path; use std::path::Path;
use failure::Error; use anyhow::Result;
pub fn read_file(path: &Path) -> Result<String, Error> { pub fn read_file(path: &Path) -> Result<String> {
let mut file = File::open(path)?; let mut file = File::open(path)?;
let mut contents = String::new(); let mut contents = String::new();
file.read_to_string(&mut contents)?; file.read_to_string(&mut contents)?;

@ -2,7 +2,7 @@ use std::io::prelude::*;
use std::path::Path; use std::path::Path;
use std::{collections::HashMap, fs::File}; use std::{collections::HashMap, fs::File};
use failure::Error; use anyhow::Result;
use serde_json; use serde_json;
#[derive(Deserialize)] #[derive(Deserialize)]
@ -43,7 +43,7 @@ pub struct Repository {
pub url: String, pub url: String,
} }
pub fn read_package_json(path: &Path, out_dir: &Path) -> Result<NpmPackage, Error> { pub fn read_package_json(path: &Path, out_dir: &Path) -> Result<NpmPackage> {
let manifest_path = path.join(out_dir).join("package.json"); let manifest_path = path.join(out_dir).join("package.json");
let mut pkg_file = File::open(manifest_path)?; let mut pkg_file = File::open(manifest_path)?;
let mut pkg_contents = String::new(); let mut pkg_contents = String::new();
@ -52,7 +52,7 @@ pub fn read_package_json(path: &Path, out_dir: &Path) -> Result<NpmPackage, Erro
Ok(serde_json::from_str(&pkg_contents)?) Ok(serde_json::from_str(&pkg_contents)?)
} }
pub fn create_wbg_package_json(out_dir: &Path, contents: &str) -> Result<(), Error> { pub fn create_wbg_package_json(out_dir: &Path, contents: &str) -> Result<()> {
let manifest_path = out_dir.join("package.json"); let manifest_path = out_dir.join("package.json");
Ok(std::fs::write(manifest_path, contents)?) Ok(std::fs::write(manifest_path, contents)?)
} }

@ -20,6 +20,7 @@ fn can_install_chromedriver() {
all(target_os = "linux", target_arch = "x86"), all(target_os = "linux", target_arch = "x86"),
all(target_os = "linux", target_arch = "x86_64"), all(target_os = "linux", target_arch = "x86_64"),
all(target_os = "macos", target_arch = "x86_64"), all(target_os = "macos", target_arch = "x86_64"),
all(target_os = "macos", target_arch = "aarch64"),
all(target_os = "windows", target_arch = "x86"), all(target_os = "windows", target_arch = "x86"),
all(target_os = "windows", target_arch = "x86_64") all(target_os = "windows", target_arch = "x86_64")
))] ))]

Loading…
Cancel
Save