Merge pull request #1188 from printfn/fix-binaryen

Fix binaryen URL and use updated `binary-install` to fix installation on macOS (adding to @matheus23's PR)
master
Jesper Håkansson 2 years ago committed by GitHub
commit bbc539e972
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      .github/workflows/book.yml
  2. 2051
      Cargo.lock
  3. 65
      Cargo.toml
  4. 2
      docs/src/tutorials/npm-browser-packages/getting-started/manual-setup.md
  5. 20
      src/bindgen.rs
  6. 24
      src/build/mod.rs
  7. 18
      src/build/wasm_target.rs
  8. 3
      src/cache.rs
  9. 8
      src/child.rs
  10. 56
      src/command/build.rs
  11. 17
      src/command/generate.rs
  12. 8
      src/command/login.rs
  13. 5
      src/command/mod.rs
  14. 13
      src/command/pack.rs
  15. 4
      src/command/publish/access.rs
  16. 21
      src/command/publish/mod.rs
  17. 44
      src/command/test.rs
  18. 8
      src/command/utils.rs
  19. 14
      src/generate.rs
  20. 41
      src/install/arch.rs
  21. 9
      src/install/krate.rs
  22. 92
      src/install/mod.rs
  23. 5
      src/install/mode.rs
  24. 41
      src/install/os.rs
  25. 12
      src/installer.rs
  26. 7
      src/lib.rs
  27. 22
      src/license.rs
  28. 16
      src/lockfile.rs
  29. 10
      src/main.rs
  30. 38
      src/manifest/mod.rs
  31. 2
      src/manifest/npm/commonjs.rs
  32. 2
      src/manifest/npm/esmodules.rs
  33. 2
      src/manifest/npm/nomodules.rs
  34. 16
      src/npm.rs
  35. 7
      src/progressbar.rs
  36. 6
      src/readme.rs
  37. 24
      src/stamps.rs
  38. 6
      src/test/mod.rs
  39. 6
      src/test/webdriver.rs
  40. 22
      src/test/webdriver/chromedriver.rs
  41. 28
      src/test/webdriver/geckodriver.rs
  42. 3
      src/test/webdriver/safaridriver.rs
  43. 20
      src/wasm_opt.rs
  44. 2
      tests/all/build.rs
  45. 69
      tests/all/download.rs
  46. 2
      tests/all/generate.rs
  47. 4
      tests/all/license.rs
  48. 2
      tests/all/lockfile.rs
  49. 2
      tests/all/log_level.rs
  50. 5
      tests/all/main.rs
  51. 2
      tests/all/manifest.rs
  52. 4
      tests/all/readme.rs
  53. 5
      tests/all/test.rs
  54. 4
      tests/all/utils/file.rs
  55. 5
      tests/all/utils/fixture.rs
  56. 6
      tests/all/utils/manifest.rs
  57. 2
      tests/all/wasm_opt.rs
  58. 3
      tests/all/webdriver.rs

@ -31,7 +31,7 @@ jobs:
- name: Install mdbook - name: Install mdbook
run: | run: |
(test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update) (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update)
(test -x $HOME/.cargo/bin/mdbook || cargo install --vers "^0.3" mdbook) (test -x $HOME/.cargo/bin/mdbook || cargo install --vers "^0.4" mdbook)
cargo install-update -a cargo install-update -a
- name: Build book - name: Build book

2051
Cargo.lock generated

File diff suppressed because it is too large Load Diff

@ -4,45 +4,46 @@ description = "📦✨ your favorite rust -> wasm workflow tool!"
version = "0.10.3" version = "0.10.3"
authors = ["Ashley Williams <ashley666ashley@gmail.com>", "Jesper Håkansson <jesper@jesperh.se>"] authors = ["Ashley Williams <ashley666ashley@gmail.com>", "Jesper Håkansson <jesper@jesperh.se>"]
repository = "https://github.com/rustwasm/wasm-pack.git" repository = "https://github.com/rustwasm/wasm-pack.git"
license = "MIT/Apache-2.0" license = "MIT OR Apache-2.0"
edition = "2021"
readme = "README.md" readme = "README.md"
categories = ["wasm"] categories = ["wasm"]
documentation = "https://rustwasm.github.io/wasm-pack/" documentation = "https://rustwasm.github.io/wasm-pack/"
[dependencies] [dependencies]
atty = "0.2.11" anyhow = "1.0.68"
cargo_metadata = "0.8.0" atty = "0.2.14"
console = "0.6.1" cargo_metadata = "0.15.2"
dialoguer = "0.3.0" console = "0.6.2"
curl = "0.4.13" dialoguer = "0.10.2"
env_logger = { version = "0.5.13", default-features = false } curl = "0.4.44"
failure = "0.1.2" env_logger = { version = "0.10.0", default-features = false }
human-panic = "1.0.1" human-panic = "1.0.3"
glob = "0.2" glob = "0.3.1"
log = "0.4.6" log = "0.4.17"
openssl = { version = '0.10.11', optional = true } openssl = { version = '0.10.45', optional = true }
parking_lot = "0.6" parking_lot = "0.12.1"
reqwest = "0.9.14" reqwest = { version = "0.11.13", features = ["blocking"] }
semver = "0.9.0" semver = "1.0.16"
serde = "1.0.74" serde = "1.0.152"
serde_derive = "1.0.74" serde_derive = "1.0.152"
serde_ignored = "0.0.4" serde_ignored = "0.1.7"
serde_json = "1.0.26" serde_json = "1.0.91"
strsim = "0.8.0" strsim = "0.10.0"
siphasher = "0.2.3" siphasher = "0.3.10"
structopt = "0.3" structopt = "0.3.26"
toml = "0.4" toml = "0.5.10"
which = "2.0.0" which = "4.3.0"
binary-install = "0.0.2" binary-install = "0.1.0"
walkdir = "2" walkdir = "2.3.2"
chrono = "0.4.6" chrono = "0.4.23"
[dev-dependencies] [dev-dependencies]
assert_cmd = "0.11" assert_cmd = "2.0.8"
lazy_static = "1.1.0" lazy_static = "1.4.0"
predicates = "1.0.0" predicates = "2.1.5"
serial_test = "0.3" serial_test = "0.10.0"
tempfile = "3" tempfile = "3.3.0"
[features] [features]
# OpenSSL is vendored by default, can use system OpenSSL through feature flag. # OpenSSL is vendored by default, can use system OpenSSL through feature flag.

@ -44,7 +44,7 @@ name = "hello-wasm"
version = "0.1.0" version = "0.1.0"
authors = ["Ashley Williams <ashley666ashley@gmail.com>"] authors = ["Ashley Williams <ashley666ashley@gmail.com>"]
description = "babby's first wasm package" description = "babby's first wasm package"
license = "MIT/Apache-2.0" license = "MIT OR Apache-2.0"
repository = "https://github.com/ashleygwilliams/hello-wasm" repository = "https://github.com/ashleygwilliams/hello-wasm"
[lib] [lib]

@ -1,10 +1,10 @@
//! Functionality related to running `wasm-bindgen`. //! Functionality related to running `wasm-bindgen`.
use child; use crate::child;
use command::build::{BuildProfile, Target}; use crate::command::build::{BuildProfile, Target};
use failure::{self, ResultExt}; use crate::install::{self, Tool};
use install::{self, Tool}; use crate::manifest::CrateData;
use manifest::CrateData; use anyhow::{bail, Context, Result};
use semver; use semver;
use std::path::Path; use std::path::Path;
use std::process::Command; use std::process::Command;
@ -22,7 +22,7 @@ pub fn wasm_bindgen_build(
target: Target, target: Target,
profile: BuildProfile, profile: BuildProfile,
extra_options: &Vec<String>, extra_options: &Vec<String>,
) -> 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",
@ -97,7 +97,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,
@ -107,7 +107,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,
@ -116,7 +116,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 {
@ -124,7 +124,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,14 +1,14 @@
//! Building a Rust crate into a `.wasm` binary. //! Building a Rust crate into a `.wasm` binary.
use child; use crate::child;
use command::build::BuildProfile; use crate::command::build::BuildProfile;
use emoji; use crate::emoji;
use failure::{Error, ResultExt}; use crate::manifest::Crate;
use manifest::Crate; use crate::PBAR;
use anyhow::{bail, Context, Result};
use std::path::Path; use std::path::Path;
use std::process::Command; use std::process::Command;
use std::str; use std::str;
use PBAR;
pub mod wasm_target; pub mod wasm_target;
@ -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,13 +1,13 @@
//! Checking for the wasm32 target //! Checking for the wasm32 target
use child; use crate::child;
use emoji; use crate::emoji;
use failure::{Error, ResultExt}; use crate::PBAR;
use anyhow::{anyhow, bail, Context, Result};
use log::info; use log::info;
use std::fmt; use std::fmt;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::process::Command; use std::process::Command;
use PBAR;
struct Wasm32Check { struct Wasm32Check {
rustc_path: PathBuf, rustc_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,8 +3,8 @@
//! 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 crate::install::Tool;
use install::Tool; use anyhow::{bail, Result};
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,25 +1,25 @@
//! Implementation of the `wasm-pack build` command. //! Implementation of the `wasm-pack build` command.
use crate::bindgen;
use crate::build;
use crate::cache;
use crate::command::utils::{create_pkg_dir, get_crate_path};
use crate::emoji;
use crate::install::{self, InstallMode, Tool};
use crate::license;
use crate::lockfile::Lockfile;
use crate::manifest;
use crate::readme;
use crate::wasm_opt; use crate::wasm_opt;
use crate::PBAR;
use anyhow::{anyhow, bail, Error, Result};
use binary_install::Cache; use binary_install::Cache;
use bindgen;
use build;
use cache;
use command::utils::{create_pkg_dir, get_crate_path};
use emoji;
use failure::Error;
use install::{self, InstallMode, Tool};
use license;
use lockfile::Lockfile;
use log::info; use log::info;
use manifest;
use readme;
use std::fmt; use std::fmt;
use std::path::PathBuf; use std::path::PathBuf;
use std::str::FromStr; use std::str::FromStr;
use std::time::Instant; use std::time::Instant;
use structopt::clap::AppSettings; use structopt::clap::AppSettings;
use PBAR;
/// Everything required to configure and run the `wasm-pack build` command. /// Everything required to configure and run the `wasm-pack build` command.
#[allow(missing_docs)] #[allow(missing_docs)]
@ -83,7 +83,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),
@ -197,11 +197,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();
@ -248,7 +248,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();
@ -309,7 +309,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);
@ -317,21 +317,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)?;
@ -346,14 +346,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,
@ -367,21 +367,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()?;
@ -397,7 +397,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,
@ -415,7 +415,7 @@ impl Build {
Ok(()) Ok(())
} }
fn step_run_wasm_opt(&mut self) -> Result<(), Error> { fn step_run_wasm_opt(&mut self) -> Result<()> {
let mut args = match self let mut args = match self
.crate_data .crate_data
.configured_profile(self.profile) .configured_profile(self.profile)
@ -434,7 +434,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 cache; use crate::cache;
use failure::Error; use crate::generate;
use generate; use crate::install::{self, Tool};
use install::{self, Tool}; use crate::PBAR;
use anyhow::Result;
use log::info; use log::info;
use std::result;
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,14 +1,14 @@
use crate::npm;
use crate::PBAR;
use anyhow::Result;
use log::info; use log::info;
use npm;
use std::result;
use PBAR;
pub fn login( pub fn login(
registry: Option<String>, registry: Option<String>,
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 command::utils::{find_pkg_directory, get_crate_path}; use crate::command::utils::{find_pkg_directory, get_crate_path};
use failure::Error; use crate::npm;
use crate::PBAR;
use anyhow::{anyhow, Result};
use log::info; use log::info;
use npm;
use std::path::PathBuf; use std::path::PathBuf;
use std::result;
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,16 +2,15 @@
pub mod access; pub mod access;
use self::access::Access; use self::access::Access;
use command::build::{Build, BuildOptions, Target}; use crate::command::build::{Build, BuildOptions, Target};
use command::utils::{find_pkg_directory, get_crate_path}; use crate::command::utils::{find_pkg_directory, get_crate_path};
use dialoguer::{Confirmation, Input, Select}; use crate::npm;
use failure::Error; use crate::PBAR;
use anyhow::{anyhow, bail, Result};
use dialoguer::{Confirm, Input, Select};
use log::info; use log::info;
use npm;
use std::path::PathBuf; use std::path::PathBuf;
use std::result;
use std::str::FromStr; use std::str::FromStr;
use PBAR;
/// Creates a tarball from a 'pkg' directory /// Creates a tarball from a 'pkg' directory
/// and publishes it to the NPM registry /// and publishes it to the NPM registry
@ -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...");
@ -31,8 +30,8 @@ pub fn publish(
None => { None => {
// while `wasm-pack publish`, if the pkg directory cannot be found, // while `wasm-pack publish`, if the pkg directory cannot be found,
// then try to `wasm-pack build` // then try to `wasm-pack build`
if Confirmation::new() if Confirm::new()
.with_text("Your package hasn't been built, build it?") .with_prompt("Your package hasn't been built, build it?")
.interact()? .interact()?
{ {
let out_dir = Input::new() let out_dir = Input::new()
@ -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,20 +1,20 @@
//! Implementation of the `wasm-pack test` command. //! Implementation of the `wasm-pack test` command.
use crate::build;
use crate::cache;
use crate::command::utils::get_crate_path;
use crate::install::{self, InstallMode, Tool};
use crate::lockfile::Lockfile;
use crate::manifest;
use crate::test::{self, webdriver};
use anyhow::{bail, Result};
use binary_install::Cache; use binary_install::Cache;
use build;
use cache;
use command::utils::get_crate_path;
use console::style; use console::style;
use failure::Error;
use install::{self, InstallMode, Tool};
use lockfile::Lockfile;
use log::info; use log::info;
use manifest;
use std::path::PathBuf; use std::path::PathBuf;
use std::str::FromStr; use std::str::FromStr;
use std::time::Instant; use std::time::Instant;
use structopt::clap::AppSettings; use structopt::clap::AppSettings;
use test::{self, webdriver};
#[derive(Debug, Default, StructOpt)] #[derive(Debug, Default, StructOpt)]
#[structopt( #[structopt(
@ -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 child; use crate::child;
use emoji; use crate::emoji;
use failure::{self, ResultExt}; use crate::install::{self, Tool};
use install::{self, Tool}; use anyhow::{Context, Result};
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);

@ -0,0 +1,41 @@
use anyhow::{bail, Result};
use std::fmt;
use crate::target;
/// An enum representing supported architectures
#[derive(Clone, PartialEq, Eq)]
pub enum Arch {
/// x86 64-bit
X86_64,
/// x86 32-bit
X86,
/// ARM 64-bit
AArch64,
}
impl Arch {
/// Gets the current architecture
pub fn get() -> Result<Self> {
if target::x86_64 {
Ok(Arch::X86_64)
} else if target::x86 {
Ok(Arch::X86)
} else if target::aarch64 {
Ok(Arch::AArch64)
} else {
bail!("Unrecognized target!")
}
}
}
impl fmt::Display for Arch {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let s = match self {
Arch::X86_64 => "x86-64",
Arch::X86 => "x86",
Arch::AArch64 => "aarch64",
};
write!(f, "{}", s)
}
}

@ -1,4 +1,5 @@
use install::Tool; use crate::install::Tool;
use anyhow::Result;
use serde::Deserialize; use serde::Deserialize;
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
@ -13,10 +14,10 @@ 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::blocking::Client::new();
let mut res = client.get(&krate_address).send()?; let res = client.get(&krate_address).send()?;
let kr: KrateResponse = serde_json::from_str(&res.text()?)?; let kr: KrateResponse = serde_json::from_str(&res.text()?)?;
Ok(kr.krate) Ok(kr.krate)

@ -1,25 +1,28 @@
//! 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 crate::child;
use crate::emoji;
use crate::install;
use crate::PBAR;
use anyhow::{anyhow, bail, Context, Result};
use binary_install::{Cache, Download}; use binary_install::{Cache, Download};
use child;
use emoji;
use failure::{self, ResultExt};
use install;
use log::debug; use log::debug;
use log::{info, warn}; use log::{info, warn};
use std::env; use std::env;
use std::fs; use std::fs;
use std::path::Path; use std::path::Path;
use std::process::Command; use std::process::Command;
use target;
use which::which; use which::which;
use PBAR;
mod arch;
mod krate; mod krate;
mod mode; mod mode;
mod os;
mod tool; mod tool;
pub use self::arch::Arch;
pub use self::mode::InstallMode; pub use self::mode::InstallMode;
pub use self::os::Os;
pub use self::tool::Tool; pub use self::tool::Tool;
/// Possible outcomes of attempting to find/install a tool /// Possible outcomes of attempting to find/install a tool
@ -33,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),
@ -54,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.
// //
@ -86,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
@ -107,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)?;
@ -124,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!(
@ -149,7 +148,11 @@ pub fn download_prebuilt(
} }
} }
Tool::WasmOpt => { Tool::WasmOpt => {
let binaries = &["wasm-opt"]; let binaries: &[&str] = match Os::get()? {
Os::MacOS => &["bin/wasm-opt", "lib/libbinaryen.dylib"],
Os::Linux => &["bin/wasm-opt"],
Os::Windows => &["bin/wasm-opt.exe"],
};
match cache.download(install_permitted, "wasm-opt", binaries, &url)? { match cache.download(install_permitted, "wasm-opt", binaries, &url)? {
Some(download) => Ok(Status::Found(download)), Some(download) => Ok(Status::Found(download)),
// TODO(ag_dubs): why is this different? i forget... // TODO(ag_dubs): why is this different? i forget...
@ -161,33 +164,25 @@ 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 target = if target::LINUX && target::x86_64 { let os = Os::get()?;
match tool { let arch = Arch::get()?;
Tool::WasmOpt => "x86-linux", prebuilt_url_for(tool, version, &arch, &os)
_ => "x86_64-unknown-linux-musl", }
}
} else if target::LINUX && target::x86 {
match tool {
Tool::WasmOpt => "x86-linux",
_ => bail!("Unrecognized target!"),
}
} else if target::MACOS && (target::x86_64 || target::aarch64) {
"x86_64-apple-darwin"
} else if target::WINDOWS && target::x86_64 {
match tool {
Tool::WasmOpt => "x86-windows",
_ => "x86_64-pc-windows-msvc",
}
} else if target::WINDOWS && target::x86 {
match tool {
Tool::WasmOpt => "x86-windows",
_ => bail!("Unrecognized target!"),
}
} else {
bail!("Unrecognized target!")
};
/// Get the download URL for some tool at some version, architecture and operating system
pub fn prebuilt_url_for(tool: &Tool, version: &str, arch: &Arch, os: &Os) -> Result<String> {
let target = match (os, arch, tool) {
(Os::Linux, Arch::X86_64, Tool::WasmOpt) => "x86_64-linux",
(Os::Linux, Arch::X86_64, _) => "x86_64-unknown-linux-musl",
(Os::MacOS, Arch::X86_64, Tool::WasmOpt) => "x86_64-macos",
(Os::MacOS, Arch::X86_64, _) => "x86_64-apple-darwin",
(Os::MacOS, Arch::AArch64, Tool::CargoGenerate) => "aarch64-apple-darwin",
(Os::MacOS, Arch::AArch64, Tool::WasmOpt) => "arm64-macos",
(Os::Windows, Arch::X86_64, Tool::WasmOpt) => "x86_64-windows",
(Os::Windows, Arch::X86_64, _) => "x86_64-pc-windows-msvc",
_ => bail!("Unrecognized target!"),
};
match tool { match tool {
Tool::WasmBindgen => { Tool::WasmBindgen => {
Ok(format!( Ok(format!(
@ -199,15 +194,14 @@ fn prebuilt_url(tool: &Tool, version: &str) -> Result<String, failure::Error> {
Tool::CargoGenerate => { Tool::CargoGenerate => {
Ok(format!( Ok(format!(
"https://github.com/cargo-generate/cargo-generate/releases/download/v{0}/cargo-generate-v{0}-{1}.tar.gz", "https://github.com/cargo-generate/cargo-generate/releases/download/v{0}/cargo-generate-v{0}-{1}.tar.gz",
// Krate::new(&Tool::CargoGenerate)?.max_version, "0.17.3",
"0.5.1", // latest released binary [#907](https://github.com/rustwasm/wasm-pack/issues/907)
target target
)) ))
}, },
Tool::WasmOpt => { Tool::WasmOpt => {
Ok(format!( Ok(format!(
"https://github.com/WebAssembly/binaryen/releases/download/{vers}/binaryen-{vers}-{target}.tar.gz", "https://github.com/WebAssembly/binaryen/releases/download/{vers}/binaryen-{vers}-{target}.tar.gz",
vers = "version_108", vers = "version_111",
target = target, target = target,
)) ))
} }
@ -221,7 +215,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,
@ -276,7 +270,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."),
@ -288,8 +282,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),

@ -0,0 +1,41 @@
use anyhow::{bail, Result};
use std::fmt;
use crate::target;
/// An enum representing supported operating systems
#[derive(Clone, PartialEq, Eq)]
pub enum Os {
/// Linux operating system
Linux,
/// Macos operating system
MacOS,
/// Windows operating system
Windows,
}
impl Os {
/// Get the current operating system
pub fn get() -> Result<Self> {
if target::LINUX {
Ok(Os::Linux)
} else if target::MACOS {
Ok(Os::MacOS)
} else if target::WINDOWS {
Ok(Os::Windows)
} else {
bail!("Unrecognized target!")
}
}
}
impl fmt::Display for Os {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let s = match self {
Os::Linux => "linux",
Os::MacOS => "macOS",
Os::Windows => "windows",
};
write!(f, "{}", s)
}
}

@ -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;
@ -45,7 +44,7 @@ pub mod target;
pub mod test; pub mod test;
pub mod wasm_opt; pub mod wasm_opt;
use progressbar::{LogLevel, ProgressOutput}; use crate::progressbar::{LogLevel, ProgressOutput};
/// The global progress bar and user-facing message output. /// The global progress bar and user-facing message output.
pub static PBAR: ProgressOutput = ProgressOutput::new(); pub static PBAR: ProgressOutput = ProgressOutput::new();

@ -1,21 +1,19 @@
//! 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;
use crate::manifest::CrateData;
use crate::PBAR;
use glob::glob; use glob::glob;
use manifest::CrateData;
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,9 +5,9 @@
use std::fs; use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
use crate::manifest::CrateData;
use anyhow::{anyhow, bail, Context, Result};
use console::style; use console::style;
use failure::{Error, ResultExt};
use manifest::CrateData;
use toml; use toml;
/// This struct represents the contents of `Cargo.lock`. /// This struct represents the contents of `Cargo.lock`.
@ -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;
@ -14,12 +15,12 @@ use std::{collections::HashMap, fs};
use self::npm::{ use self::npm::{
repository::Repository, CommonJSPackage, ESModulesPackage, NoModulesPackage, NpmPackage, repository::Repository, CommonJSPackage, ESModulesPackage, NoModulesPackage, NpmPackage,
}; };
use crate::command::build::{BuildProfile, Target};
use crate::PBAR;
use cargo_metadata::Metadata; use cargo_metadata::Metadata;
use chrono::offset; use chrono::offset;
use chrono::DateTime; use chrono::DateTime;
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;
@ -27,7 +28,6 @@ use std::env;
use std::io::Write; use std::io::Write;
use strsim::levenshtein; use strsim::levenshtein;
use toml; use toml;
use PBAR;
const WASM_PACK_METADATA_KEY: &str = "package.metadata.wasm-pack"; const WASM_PACK_METADATA_KEY: &str = "package.metadata.wasm-pack";
const WASM_PACK_VERSION: Option<&'static str> = option_env!("CARGO_PKG_VERSION"); const WASM_PACK_VERSION: Option<&'static str> = option_env!("CARGO_PKG_VERSION");
@ -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!(
@ -426,9 +424,9 @@ impl CrateData {
.iter() .iter()
.position(|pkg| { .position(|pkg| {
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.as_std_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,6 +1,6 @@
use std::collections::HashMap; use std::collections::HashMap;
use manifest::npm::repository::Repository; use crate::manifest::npm::repository::Repository;
#[derive(Serialize)] #[derive(Serialize)]
pub struct CommonJSPackage { pub struct CommonJSPackage {

@ -1,6 +1,6 @@
use std::collections::HashMap; use std::collections::HashMap;
use manifest::npm::repository::Repository; use crate::manifest::npm::repository::Repository;
#[derive(Serialize)] #[derive(Serialize)]
pub struct ESModulesPackage { pub struct ESModulesPackage {

@ -1,6 +1,6 @@
use std::collections::HashMap; use std::collections::HashMap;
use manifest::npm::repository::Repository; use crate::manifest::npm::repository::Repository;
#[derive(Serialize)] #[derive(Serialize)]
pub struct NoModulesPackage { pub struct NoModulesPackage {

@ -1,15 +1,15 @@
//! Functionality related to publishing to npm. //! Functionality related to publishing to npm.
use child; use crate::child;
use command::publish::access::Access; use crate::command::publish::access::Access;
use failure::{self, ResultExt}; use anyhow::{bail, Context, Result};
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,7 +1,8 @@
//! Fancy progress bar functionality. //! Fancy progress bar functionality.
use crate::emoji;
use anyhow::{bail, Error, Result};
use console::style; use console::style;
use emoji;
use std::sync::atomic::{AtomicBool, AtomicU8, Ordering}; use std::sync::atomic::{AtomicBool, AtomicU8, Ordering};
#[repr(u8)] #[repr(u8)]
@ -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 crate::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")?;

@ -2,9 +2,9 @@
pub mod webdriver; pub mod webdriver;
use crate::child;
use crate::PBAR; use crate::PBAR;
use child; use anyhow::{Context, Result};
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,10 +4,10 @@ mod chromedriver;
mod geckodriver; mod geckodriver;
mod safaridriver; mod safaridriver;
use crate::PBAR;
use anyhow::Result;
use binary_install::Cache; use binary_install::Cache;
use failure;
use std::path::PathBuf; use std::path::PathBuf;
use PBAR;
pub use self::{ pub use self::{
chromedriver::{get_or_install_chromedriver, install_chromedriver}, chromedriver::{get_or_install_chromedriver, install_chromedriver},
@ -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,11 +1,11 @@
use super::{get_and_notify, Collector}; use super::{get_and_notify, Collector};
use crate::install::InstallMode;
use crate::stamps;
use crate::target;
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 stamps;
use std::path::PathBuf; use std::path::PathBuf;
use target;
// Keep it up to date with each `wasm-pack` release. // Keep it up to date with each `wasm-pack` release.
// https://chromedriver.storage.googleapis.com/LATEST_RELEASE // https://chromedriver.storage.googleapis.com/LATEST_RELEASE
@ -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,11 +1,11 @@
use super::{get_and_notify, Collector}; use super::{get_and_notify, Collector};
use crate::install::InstallMode;
use crate::stamps;
use crate::target;
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 stamps;
use std::path::PathBuf; use std::path::PathBuf;
use target;
// Keep it up to date with each `wasm-pack` release. // Keep it up to date with each `wasm-pack` release.
// https://github.com/mozilla/geckodriver/releases/latest // https://github.com/mozilla/geckodriver/releases/latest
@ -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`"),

@ -1,20 +1,16 @@
//! Support for downloading and executing `wasm-opt` //! Support for downloading and executing `wasm-opt`
use crate::child; use crate::child;
use crate::install::{self, Tool}; use crate::install;
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 => {
@ -27,7 +23,7 @@ pub fn run(
} }
}; };
let wasm_opt_path = wasm_opt.binary(&Tool::WasmOpt.to_string())?; let wasm_opt_path = wasm_opt.binary("bin/wasm-opt")?;
PBAR.info("Optimizing wasm binaries with `wasm-opt`..."); PBAR.info("Optimizing wasm binaries with `wasm-opt`...");
for file in out_dir.read_dir()? { for file in out_dir.read_dir()? {
@ -54,10 +50,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));
@ -68,11 +61,10 @@ pub fn find_wasm_opt(
} }
} }
let version = "version_78";
Ok(install::download_prebuilt( Ok(install::download_prebuilt(
&install::Tool::WasmOpt, &install::Tool::WasmOpt,
cache, cache,
version, "latest",
install_permitted, install_permitted,
)?) )?)
} }

@ -1,7 +1,7 @@
use crate::utils;
use assert_cmd::prelude::*; use assert_cmd::prelude::*;
use std::fs; use std::fs;
use std::path::Path; use std::path::Path;
use utils;
#[test] #[test]
fn build_in_non_crate_directory_doesnt_panic() { fn build_in_non_crate_directory_doesnt_panic() {

@ -1,6 +1,4 @@
use binary_install::Cache; use wasm_pack::install::{self, Arch, Os, Tool};
use tempfile;
use wasm_pack::install::{self, Tool};
#[test] #[test]
#[cfg(any( #[cfg(any(
@ -10,7 +8,7 @@ use wasm_pack::install::{self, Tool};
))] ))]
fn can_download_prebuilt_wasm_bindgen() { fn can_download_prebuilt_wasm_bindgen() {
let dir = tempfile::TempDir::new().unwrap(); let dir = tempfile::TempDir::new().unwrap();
let cache = Cache::at(dir.path()); let cache = binary_install::Cache::at(dir.path());
if let install::Status::Found(dl) = if let install::Status::Found(dl) =
install::download_prebuilt(&Tool::WasmBindgen, &cache, "0.2.74", true).unwrap() install::download_prebuilt(&Tool::WasmBindgen, &cache, "0.2.74", true).unwrap()
{ {
@ -30,15 +28,13 @@ fn can_download_prebuilt_wasm_bindgen() {
fn downloading_prebuilt_wasm_bindgen_handles_http_errors() { fn downloading_prebuilt_wasm_bindgen_handles_http_errors() {
let dir = tempfile::TempDir::new().unwrap(); let dir = tempfile::TempDir::new().unwrap();
let bad_version = "0.2.74-some-trailing-version-stuff-that-does-not-exist"; let bad_version = "0.2.74-some-trailing-version-stuff-that-does-not-exist";
let cache = Cache::at(dir.path()); let cache = binary_install::Cache::at(dir.path());
let result = install::download_prebuilt(&Tool::WasmBindgen, &cache, bad_version, true); let result = install::download_prebuilt(&Tool::WasmBindgen, &cache, bad_version, true);
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]
@ -49,7 +45,7 @@ fn downloading_prebuilt_wasm_bindgen_handles_http_errors() {
))] ))]
fn can_download_prebuilt_cargo_generate() { fn can_download_prebuilt_cargo_generate() {
let dir = tempfile::TempDir::new().unwrap(); let dir = tempfile::TempDir::new().unwrap();
let cache = Cache::at(dir.path()); let cache = binary_install::Cache::at(dir.path());
if let install::Status::Found(dl) = if let install::Status::Found(dl) =
install::download_prebuilt(&Tool::CargoGenerate, &cache, "latest", true).unwrap() install::download_prebuilt(&Tool::CargoGenerate, &cache, "latest", true).unwrap()
{ {
@ -58,3 +54,56 @@ fn can_download_prebuilt_cargo_generate() {
assert!(false, "Download Failed"); assert!(false, "Download Failed");
} }
} }
#[test]
#[cfg(any(
all(target_os = "linux", target_arch = "x86_64"),
all(target_os = "macos", target_arch = "x86_64"),
all(target_os = "macos", target_arch = "aarch64"),
all(windows, target_arch = "x86_64"),
))]
fn can_download_prebuilt_wasm_opt() {
let dir = tempfile::TempDir::new().unwrap();
let cache = binary_install::Cache::at(dir.path());
if let install::Status::Found(dl) =
install::download_prebuilt(&Tool::WasmOpt, &cache, "latest", true).unwrap()
{
assert!(dl.binary("bin/wasm-opt").unwrap().is_file());
} else {
assert!(false, "Download Failed");
}
}
#[test]
fn all_latest_tool_download_urls_valid() {
let mut errors = Vec::new();
for tool in [Tool::CargoGenerate, Tool::WasmBindgen, Tool::WasmOpt] {
for arch in [Arch::X86_64, Arch::X86, Arch::AArch64] {
for os in [Os::Linux, Os::MacOS, Os::Windows] {
// For all valid tool, arch & os combinations,
// error out when any of them is a 404 or similar
if let Ok(url) = install::prebuilt_url_for(&tool, "0.2.82", &arch, &os) {
let client = reqwest::blocking::Client::new();
// Use HTTP HEAD instead of GET to avoid fetching lots of stuff
let res = client.head(&url).send().unwrap();
if res.status().is_client_error() {
errors.push(format!(
"Can't download URL {} for {} on {}: {}",
url,
arch,
os,
res.status()
));
}
}
}
}
}
if !errors.is_empty() {
panic!(
"Some URLs for prebuild tools were unavailable:\n{}",
errors.join("\n")
);
}
}

@ -1,5 +1,5 @@
use crate::utils;
use assert_cmd::prelude::*; use assert_cmd::prelude::*;
use utils;
#[test] #[test]
fn new_with_no_name_errors() { fn new_with_no_name_errors() {

@ -1,9 +1,9 @@
extern crate failure; extern crate anyhow;
extern crate wasm_pack; extern crate wasm_pack;
use std::fs; use std::fs;
use utils::{self, fixture}; use crate::utils::{self, fixture};
use wasm_pack::license; use wasm_pack::license;
use wasm_pack::manifest::CrateData; use wasm_pack::manifest::CrateData;

@ -1,4 +1,4 @@
use utils::fixture; use crate::utils::fixture;
use wasm_pack::lockfile::Lockfile; use wasm_pack::lockfile::Lockfile;
use wasm_pack::manifest::CrateData; use wasm_pack::manifest::CrateData;

@ -1,9 +1,9 @@
use crate::utils;
use assert_cmd::prelude::*; use assert_cmd::prelude::*;
use predicates::boolean::PredicateBooleanExt; use predicates::boolean::PredicateBooleanExt;
use predicates::prelude::predicate::str::contains; use predicates::prelude::predicate::str::contains;
use predicates::reflection::PredicateReflection; use predicates::reflection::PredicateReflection;
use predicates::Predicate; use predicates::Predicate;
use utils;
fn matches_info() -> impl Predicate<str> + PredicateReflection { fn matches_info() -> impl Predicate<str> + PredicateReflection {
contains("[INFO]: Checking for the Wasm target...") contains("[INFO]: Checking for the Wasm target...")

@ -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,8 +1,8 @@
use crate::utils::{self, fixture};
use assert_cmd::prelude::*; use assert_cmd::prelude::*;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::fs; use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
use utils::{self, fixture};
use wasm_pack::command::build::Target; use wasm_pack::command::build::Target;
use wasm_pack::command::utils::get_crate_path; use wasm_pack::command::utils::get_crate_path;
use wasm_pack::{self, license, manifest}; use wasm_pack::{self, license, manifest};

@ -1,9 +1,9 @@
extern crate failure; extern crate anyhow;
extern crate wasm_pack; extern crate wasm_pack;
use std::fs; use std::fs;
use utils::{self, fixture}; use crate::utils::{self, fixture};
use wasm_pack::readme; use wasm_pack::readme;
#[test] #[test]

@ -1,7 +1,7 @@
use crate::utils::fixture;
use assert_cmd::prelude::*; use assert_cmd::prelude::*;
use predicates::prelude::*; use predicates::prelude::*;
use std::env; use std::env;
use utils::fixture;
#[test] #[test]
fn it_can_run_node_tests() { fn it_can_run_node_tests() {
@ -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)?;

@ -1,4 +1,5 @@
use binary_install::Cache; use binary_install::Cache;
use lazy_static::lazy_static;
use std::env; use std::env;
use std::fs; use std::fs;
use std::mem::ManuallyDrop; use std::mem::ManuallyDrop;
@ -321,7 +322,9 @@ impl Fixture {
} }
pub fn cache(&self) -> Cache { pub fn cache(&self) -> Cache {
Cache::at(&self.cache_dir()) let cache_dir = self.cache_dir();
fs::create_dir_all(&cache_dir).unwrap();
Cache::at(&cache_dir)
} }
/// The `step_install_wasm_bindgen` and `step_run_wasm_bindgen` steps only /// The `step_install_wasm_bindgen` and `step_run_wasm_bindgen` steps only

@ -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)?)
} }

@ -1,6 +1,6 @@
use crate::utils;
use assert_cmd::prelude::*; use assert_cmd::prelude::*;
use predicates::prelude::*; use predicates::prelude::*;
use utils;
#[test] #[test]
fn off_in_dev() { fn off_in_dev() {

@ -1,5 +1,5 @@
use crate::utils::fixture;
use binary_install::Cache; use binary_install::Cache;
use utils::fixture;
use wasm_pack::test::webdriver; use wasm_pack::test::webdriver;
#[test] #[test]
@ -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