Merge pull request #1 from daubaris/wasm-pack-version

Addition of stamp file and additional thread for running version checks
master
daubaris 7 years ago committed by GitHub
commit ed074e7d72
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 7
      .appveyor.yml
  2. 18
      .travis.yml
  3. 390
      Cargo.lock
  4. 4
      Cargo.toml
  5. 1
      docs/src/SUMMARY.md
  6. 29
      docs/src/cargo-toml-configuration.md
  7. 27
      docs/src/commands/build.md
  8. 422
      src/binaries.rs
  9. 214
      src/bindgen.rs
  10. 78
      src/build.rs
  11. 9
      src/child.rs
  12. 154
      src/command/build.rs
  13. 37
      src/command/mod.rs
  14. 13
      src/command/pack.rs
  15. 4
      src/command/publish/access.rs
  16. 13
      src/command/publish/mod.rs
  17. 97
      src/command/test.rs
  18. 10
      src/command/utils.rs
  19. 240
      src/error.rs
  20. 6
      src/lib.rs
  21. 40
      src/lockfile.rs
  22. 2
      src/main.rs
  23. 703
      src/manifest/mod.rs
  24. 6
      src/test/mod.rs
  25. 137
      src/test/webdriver.rs
  26. 33
      tests/all/bindgen.rs
  27. 218
      tests/all/build.rs
  28. 13
      tests/all/lockfile.rs
  29. 2
      tests/all/main.rs
  30. 183
      tests/all/manifest.rs
  31. 2
      tests/all/readme.rs
  32. 197
      tests/all/test.rs
  33. 310
      tests/all/utils/fixture.rs
  34. 7
      tests/all/webdriver.rs

@ -5,17 +5,18 @@ environment:
install:
- ps: Install-Product node 10
- appveyor-retry appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe
- rustup-init.exe -y --default-host x86_64-pc-windows-msvc --default-toolchain nightly
- rustup-init.exe -y --default-host x86_64-pc-windows-msvc --default-toolchain stable
- set PATH=%PATH%;C:\Users\appveyor\.cargo\bin
- set RUST_BACKTRACE=1
- rustup target add wasm32-unknown-unknown --toolchain nightly
- rustup target add wasm32-unknown-unknown --toolchain stable
- rustc -V
- cargo -V
build: false
test_script:
- cargo test --release --locked
- cargo test --release --tests --locked
- cargo test --release --doc
before_deploy:
- ps: |

@ -38,8 +38,8 @@ DEPLOY_TO_GITHUB: &DEPLOY_TO_GITHUB
matrix:
include:
# tests pass
- env: JOB=test RUST_BACKTRACE=1
- name: Tests
env: RUST_BACKTRACE=1
rust: nightly
addons:
firefox: latest
@ -49,14 +49,14 @@ matrix:
script:
- cargo test --locked
- rustup component add rustfmt-preview
- cargo fmt --version
- cargo fmt --all -- --check
# book
- env: JOB=book
- name: Book
rust: stable
before_script:
- (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update)
- (test -x $HOME/.cargo/bin/mdbook || cargo install --vers "^0.1" mdbook)
- (test -x $HOME/.cargo/bin/mdbook || cargo install --vers "^0.2" mdbook)
- cargo install-update -a
script:
- (cd docs && mdbook build)
@ -71,8 +71,8 @@ matrix:
on:
branch: master
# dist linux binary
- env: JOB=dist-linux TARGET=x86_64-unknown-linux-musl
- name: Linux Binary
env: TARGET=x86_64-unknown-linux-musl
rust: nightly
before_script: rustup target add $TARGET
script: cargo build --release --target $TARGET --locked --features vendored-openssl
@ -82,8 +82,8 @@ matrix:
- musl-tools
<<: *DEPLOY_TO_GITHUB
# dist OSX binary
- env: JOB=dist-osx MACOSX_DEPLOYMENT_TARGET=10.7 TARGET=x86_64-apple-darwin
- name: macOS Binary
env: MACOSX_DEPLOYMENT_TARGET=10.7 TARGET=x86_64-apple-darwin
os: osx
rust: nightly
script: cargo build --release --target $TARGET --locked

390
Cargo.lock generated

@ -5,10 +5,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "aho-corasick"
version = "0.6.8"
version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -19,6 +19,23 @@ dependencies = [
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "argon2rs"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
"scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "arrayvec"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "atty"
version = "0.2.11"
@ -35,7 +52,7 @@ version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -55,6 +72,15 @@ name = "bitflags"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "blake2-rfc"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "build_const"
version = "0.2.1"
@ -62,7 +88,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "byteorder"
version = "1.2.6"
version = "1.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -85,13 +111,13 @@ dependencies = [
[[package]]
name = "cargo_metadata"
version = "0.6.0"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -102,7 +128,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cfg-if"
version = "0.1.5"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -155,15 +181,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"clicolors-control 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "constant_time_eq"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "crc"
version = "1.8.1"
@ -174,14 +205,14 @@ dependencies = [
[[package]]
name = "curl"
version = "0.4.18"
version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"curl-sys 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)",
"curl-sys 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.36 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.39 (registry+https://github.com/rust-lang/crates.io-index)",
"schannel 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"socket2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
@ -189,18 +220,28 @@ dependencies = [
[[package]]
name = "curl-sys"
version = "0.4.13"
version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libz-sys 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.36 (registry+https://github.com/rust-lang/crates.io-index)",
"libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.39 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "dirs"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_users 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "error-chain"
version = "0.12.0"
@ -211,42 +252,42 @@ dependencies = [
[[package]]
name = "failure"
version = "0.1.2"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"failure_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "failure_derive"
version = "0.1.2"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
"synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.21 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.18 (registry+https://github.com/rust-lang/crates.io-index)",
"synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "filetime"
version = "0.2.1"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "flate2"
version = "1.0.3"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"miniz_oxide_c_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"miniz-sys 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"miniz_oxide_c_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -276,16 +317,29 @@ name = "fuchsia-zircon-sys"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "heck"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "hex"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "human-panic"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"os_type 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
@ -308,7 +362,7 @@ name = "isatty"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -335,11 +389,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "lazy_static"
version = "1.1.0"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "libc"
@ -348,7 +399,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libz-sys"
version = "1.0.23"
version = "1.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
@ -368,17 +419,17 @@ dependencies = [
[[package]]
name = "memchr"
version = "2.1.0"
version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "miniz-sys"
version = "0.1.10"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
@ -387,22 +438,21 @@ dependencies = [
[[package]]
name = "miniz_oxide"
version = "0.1.3"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "miniz_oxide_c_api"
version = "0.1.3"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"miniz_oxide 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"miniz_oxide 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -414,6 +464,11 @@ dependencies = [
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "nodrop"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "num-integer"
version = "0.1.39"
@ -429,15 +484,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "openssl"
version = "0.10.12"
version = "0.10.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.36 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.39 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -447,7 +502,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "openssl-src"
version = "110.0.7+1.1.0i"
version = "111.0.1+1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
@ -455,12 +510,12 @@ dependencies = [
[[package]]
name = "openssl-sys"
version = "0.9.36"
version = "0.9.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-src 110.0.7+1.1.0i (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-src 111.0.1+1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -470,7 +525,7 @@ name = "os_type"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -514,7 +569,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "proc-macro2"
version = "0.4.20"
version = "0.4.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -522,10 +577,10 @@ dependencies = [
[[package]]
name = "quote"
version = "0.6.8"
version = "0.6.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.21 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -576,28 +631,39 @@ dependencies = [
"redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "redox_users"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"argon2rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "regex"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"utf8-ranges 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "regex"
version = "1.0.5"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"utf8-ranges 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -605,15 +671,15 @@ name = "regex-syntax"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"ucd-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "regex-syntax"
version = "0.6.2"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"ucd-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -647,10 +713,15 @@ name = "schannel"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "scoped_threadpool"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "scopeguard"
version = "0.3.3"
@ -662,7 +733,7 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -672,17 +743,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde"
version = "1.0.79"
version = "1.0.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde_derive"
version = "1.0.79"
version = "1.0.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.9 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.21 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.18 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -692,9 +763,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "siphasher"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "slog"
version = "2.4.1"
@ -735,7 +811,7 @@ name = "socket2"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -753,51 +829,42 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "structopt"
version = "0.2.11"
version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
"structopt-derive 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"structopt-derive 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "structopt-derive"
version = "0.2.11"
version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.9 (registry+https://github.com/rust-lang/crates.io-index)",
"heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.21 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.18 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "syn"
version = "0.14.9"
version = "0.15.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "syn"
version = "0.15.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.21 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "synstructure"
version = "0.9.0"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.21 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.18 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -808,10 +875,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "tar"
version = "0.4.17"
version = "0.4.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"filetime 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
"xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -831,7 +898,7 @@ name = "tempfile"
version = "3.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
@ -844,7 +911,7 @@ name = "term"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -887,7 +954,7 @@ name = "thread_local"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -905,12 +972,17 @@ name = "toml"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ucd-util"
version = "0.1.1"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicode-segmentation"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -933,7 +1005,7 @@ dependencies = [
[[package]]
name = "utf8-ranges"
version = "1.0.1"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -941,7 +1013,7 @@ name = "uuid"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -970,24 +1042,27 @@ name = "wasm-pack"
version = "0.5.1"
dependencies = [
"atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"cargo_metadata 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cargo_metadata 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"console 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"curl 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"curl 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
"dirs 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"flate2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"human-panic 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"indicatif 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl 0.10.12 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl 0.10.15 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
"siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"slog-async 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"slog-term 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"structopt 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"tar 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)",
"structopt 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
"tar 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)",
"tempfile 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"which 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -999,7 +1074,7 @@ name = "which"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1054,7 +1129,7 @@ version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bzip2 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"flate2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"msdos_time 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"podio 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1062,86 +1137,97 @@ dependencies = [
[metadata]
"checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c"
"checksum aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "68f56c7353e5a9547cbd76ed90f7bb5ffc3ba09d4ea9bd1d8c06c8b1142eeb5a"
"checksum aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1e9a933f4e58658d7b12defcf96dc5c720f20832deebe3e0a19efd3b6aaeeb9e"
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
"checksum argon2rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3f67b0b6a86dae6e67ff4ca2b6201396074996379fba2b92ff649126f37cb392"
"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef"
"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
"checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a"
"checksum backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c66d56ac8dabd07f6aacdaf633f4b8262f5b3601a810a0dcddffd5c22c69daa0"
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
"checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400"
"checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39"
"checksum byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "90492c5858dd7d2e78691cfb89f90d273a2800fc11d98f60786e5d87e2f83781"
"checksum byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "94f88df23a25417badc922ab0f5716cc1330e87f71ddd9203b3a3ccd9cedf75d"
"checksum bzip2 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "42b7c3cbf0fa9c1b82308d57191728ca0256cb821220f4e2fd410a72ade26e3b"
"checksum bzip2-sys 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2c5162604199bbb17690ede847eaa6120a3f33d5ab4dcc8e7c25b16d849ae79b"
"checksum cargo_metadata 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d6809b327f87369e6f3651efd2c5a96c49847a3ed2559477ecba79014751ee1"
"checksum cargo_metadata 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1aaa1a9856ae2d188340526d0986feb6899c9ad11c5dfd73453c784fed6e373d"
"checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16"
"checksum cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4e7bb64a8ebb0d856483e1e682ea3422f883c5f5615a90d51a2c82fe87fdd3"
"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4"
"checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878"
"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"
"checksum clicolors-control 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1f84dec9bc083ce2503908cd305af98bd363da6f54bf8d4bf0ac14ee749ad5d1"
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
"checksum console 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ecd48adf136733979b49e15bc3b4c43cc0d3c85ece7bd08e6daa414c6fcb13e6"
"checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e"
"checksum crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb"
"checksum curl 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)" = "a9e5285b49b44401518c947d3b808d14d99a538a6c9ffb3ec0205c11f9fc4389"
"checksum curl-sys 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "08459503c415173da1ce6b41036a37b8bfdd86af46d45abb9964d4c61fe670ef"
"checksum curl 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "c7c9d851c825e0c033979d4516c9173bc19a78a96eb4d6ae51d4045440eafa16"
"checksum curl-sys 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)" = "721c204978be2143fab0a84b708c49d79d1f6100b8785610f456043a90708870"
"checksum dirs 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "88972de891f6118092b643d85a0b28e0678e0f948d7f879aa32f2d5aafe97d2a"
"checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02"
"checksum failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7efb22686e4a466b1ec1a15c2898f91fa9cb340452496dca654032de20ff95b9"
"checksum failure_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "946d0e98a50d9831f5d589038d2ca7f8f455b1c21028c0db0e84116a12696426"
"checksum filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "da4b9849e77b13195302c174324b5ba73eec9b236b24c221a61000daefb95c5f"
"checksum flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4af030962d89d62aa52cd9492083b1cd9b2d1a77764878102a6c0f86b4d5444d"
"checksum failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6dd377bcc1b1b7ce911967e3ec24fa19c3224394ec05b54aa7b083d498341ac7"
"checksum failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "64c2d913fe8ed3b6c6518eedf4538255b989945c14c2a7d5cbff62a5e2120596"
"checksum filetime 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6f57e64bf5eae62efd4efed005ae81a7115012a61f522bba54542e1a556af921"
"checksum flate2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3b0c7353385f92079524de3b7116cf99d73947c08a7472774e9b3b04bff3b901"
"checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
"checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
"checksum heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea04fa3ead4e05e51a7c806fc07271fdbde4e246a6c6d1efd52e72230b771b82"
"checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
"checksum human-panic 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "21638c5955a6daf3ecc42cae702335fc37a72a4abcc6959ce457b31a7d43bbdd"
"checksum indicatif 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a29b2fa6f00010c268bface64c18bb0310aaa70d46a195d5382d288c477fb016"
"checksum isatty 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e31a8281fc93ec9693494da65fbf28c0c2aa60a2eaec25dc58e2f31952e95edc"
"checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
"checksum lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca488b89a5657b0a2ecd45b95609b3e848cf1755da332a0da46e2b2b1cb371a7"
"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1"
"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d"
"checksum libz-sys 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)" = "c7bdca442aa002a930e6eb2a71916cabe46d91ffec8df66db0abfb1bc83469ab"
"checksum libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe"
"checksum lock_api 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "775751a3e69bde4df9b38dd00a1b5d6ac13791e4223d4a0506577f0dd27cfb7a"
"checksum memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4b3629fe9fdbff6daa6c33b90f7c08355c1aca05a3d01fa8063b822fcf185f3b"
"checksum miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "609ce024854aeb19a0ef7567d348aaa5a746b32fb72e336df7fcc16869d7e2b4"
"checksum miniz_oxide 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9ba430291c9d6cedae28bcd2d49d1c32fc57d60cd49086646c5dd5673a870eb5"
"checksum miniz_oxide_c_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5a5b8234d6103ebfba71e29786da4608540f862de5ce980a1c94f86a40ca0d51"
"checksum memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0a3eb002f0535929f1199681417029ebea04aadc0c7a4224b46be99c7f5d6a16"
"checksum miniz-sys 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0300eafb20369952951699b68243ab4334f4b10a88f411c221d444b36c40e649"
"checksum miniz_oxide 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ad30a47319c16cde58d0314f5d98202a80c9083b5f61178457403dfb14e509c"
"checksum miniz_oxide_c_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "28edaef377517fd9fe3e085c37d892ce7acd1fbeab9239c5a36eec352d8a8b7e"
"checksum msdos_time 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "aad9dfe950c057b1bfe9c1f2aa51583a8468ef2a5baba2ebbe06d775efeb7729"
"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"
"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea"
"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
"checksum openssl 0.10.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5e2e79eede055813a3ac52fb3915caf8e1c9da2dec1587871aec9f6f7b48508d"
"checksum openssl 0.10.15 (registry+https://github.com/rust-lang/crates.io-index)" = "5e1309181cdcbdb51bc3b6bedb33dfac2a83b3d585033d3f6d9e22e8c1928613"
"checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
"checksum openssl-src 110.0.7+1.1.0i (registry+https://github.com/rust-lang/crates.io-index)" = "c02d15268b7d1b3f0c83a2358f3d981139b54079440f1e2a29c60c1818ad5516"
"checksum openssl-sys 0.9.36 (registry+https://github.com/rust-lang/crates.io-index)" = "409d77eeb492a1aebd6eb322b2ee72ff7c7496b4434d98b3bf8be038755de65e"
"checksum openssl-src 111.0.1+1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d1edaed888fd85a54a2646bf02992931ddefdda3b1a748fc79f088a8db27fcbe"
"checksum openssl-sys 0.9.39 (registry+https://github.com/rust-lang/crates.io-index)" = "278c1ad40a89aa1e741a1eed089a2f60b18fab8089c3139b542140fc7d674106"
"checksum os_type 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7edc011af0ae98b7f88cf7e4a83b70a54a75d2b8cb013d6efd02e5956207e9eb"
"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
"checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5"
"checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c"
"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c"
"checksum podio 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "780fb4b6698bbf9cf2444ea5d22411cef2953f0824b98f33cf454ec5615645bd"
"checksum proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)" = "3d7b7eaaa90b4a90a932a9ea6666c95a389e424eff347f0f793979289429feee"
"checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5"
"checksum proc-macro2 0.4.21 (registry+https://github.com/rust-lang/crates.io-index)" = "ab2fc21ba78ac73e4ff6b3818ece00be4e175ffbef4d0a717d978b48b24150c4"
"checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c"
"checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd"
"checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c"
"checksum rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1961a422c4d189dfb50ffa9320bf1f2a9bd54ecb92792fb9477f99a1045f3372"
"checksum rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0905b6b7079ec73b314d4c748701f6931eb79fd97c668caa3f1899b22b32c6db"
"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1"
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
"checksum redox_users 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "214a97e49be64fd2c86f568dd0cb2c757d2cc53de95b273b6ad0a1c908482f26"
"checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384"
"checksum regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2069749032ea3ec200ca51e4a31df41759190a88edca0d2d86ee8bedf7073341"
"checksum regex 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ee84f70c8c08744ea9641a731c7fadb475bf2ecc52d7f627feb833e0b3990467"
"checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7"
"checksum regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "747ba3b235651f6e2f67dfa8bcdcd073ddb7c243cb21c442fc12395dfcac212d"
"checksum regex-syntax 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fbc557aac2b708fe84121caf261346cc2eed71978024337e42eb46b8a252ac6e"
"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5"
"checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395"
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
"checksum ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7153dd96dade874ab973e098cb62fcdbb89a03682e46b144fd09550998d4a4a7"
"checksum schannel 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "0e1a231dc10abf6749cfa5d7767f25888d484201accbd919b66ab5413c502d56"
"checksum scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)" = "84257ccd054dc351472528c8587b4de2dbf0dc0fe2e634030c1a90bfdacebaa9"
"checksum serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)" = "31569d901045afbff7a9479f793177fe9259819aff10ab4f89ef69bbc5f567fe"
"checksum serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)" = "15c141fc7027dd265a47c090bf864cf62b42c4d228bbcf4e51a0c9e2b0d3f7ef"
"checksum serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)" = "225de307c6302bec3898c51ca302fc94a7a1697ef0845fcee6448f33c032249c"
"checksum serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "43344e7ce05d0d8280c5940cabb4964bea626aa58b1ec0e8c73fa2a8512a38ce"
"checksum siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac"
"checksum slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1e1a2eec401952cd7b12a84ea120e2d57281329940c3f93c2bf04f462539508e"
"checksum slog-async 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e544d16c6b230d84c866662fe55e31aacfca6ae71e6fc49ae9a311cb379bfc2f"
"checksum slog-term 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5951a808c40f419922ee014c15b6ae1cd34d963538b57d8a4778b9ca3fff1e0b"
@ -1149,13 +1235,12 @@ dependencies = [
"checksum socket2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c4d11a52082057d87cb5caa31ad812f4504b97ab44732cd8359df2e9ff9f48e7"
"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
"checksum structopt 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "ca85f2c9a5a1e2d5ac686fc0be48e40f8ad803f5bbe31f692ff71eb2dd8aad45"
"checksum structopt-derive 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "1383e5db585da799a5c4acc496c5c868e18bf82e658c00c75cc91038fa26b55f"
"checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741"
"checksum syn 0.15.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b10ee269228fb723234fce98e9aac0eaed2bd5f1ad2f6930e8d5b93f04445a1a"
"checksum synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "85bb9b7550d063ea184027c9b8c20ac167cd36d3e06b3a40bceb9d746dc1a7b7"
"checksum structopt 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "41c4a2479a078509940d82773d90ff824a8c89533ab3b59cd3ce8b0c0e369c02"
"checksum structopt-derive 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "5352090cfae7a2c85e1a31146268b53396106c88ca5d6ccee2e3fae83b6e35c2"
"checksum syn 0.15.18 (registry+https://github.com/rust-lang/crates.io-index)" = "90c39a061e2f412a9f869540471ab679e85e50c6b05604daf28bc3060f75c430"
"checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015"
"checksum take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60"
"checksum tar 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)" = "83b0d14b53dbfd62681933fadd651e815f99e6084b649e049ab99296e05ab3de"
"checksum tar 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)" = "89b518542272d9c12195e72885c7a4c142b89226f681bb129e4a922ba1b1ee74"
"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
"checksum tempfile 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "55c1195ef8513f3273d55ff59fe5da6940287a0d7a98331254397f464833675b"
"checksum term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e6b677dd1e8214ea1ef4297f85dbcbed8e8cdddb561040cc998ca2551c37561"
@ -1166,11 +1251,12 @@ dependencies = [
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
"checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b"
"checksum toml 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "4a2ecc31b0351ea18b3fe11274b8db6e4d82bce861bbb22e6dbed40417902c65"
"checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d"
"checksum ucd-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d0f8bfa9ff0cadcd210129ad9d2c5f145c13e9ced3d3e5d948a6213487d52444"
"checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1"
"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
"checksum utf8-ranges 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd70f467df6810094968e2fce0ee1bd0e87157aceb026a8c083bcf5e25b9efe4"
"checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737"
"checksum uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e1436e58182935dcd9ce0add9ea0b558e8a87befe01c1a301e6020aeb0876363"
"checksum vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "def296d3eb3b12371b2c7d0e83bfe1403e4db2d7a0bba324a12b21c4ee13143d"
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"

@ -14,8 +14,10 @@ atty = "0.2.11"
cargo_metadata = "0.6.0"
console = "0.6.1"
curl = "0.4.13"
dirs = "1.0.4"
failure = "0.1.2"
flate2 = "1.0.2"
hex = "0.3"
human-panic = "1.0.1"
indicatif = "0.9.0"
lazy_static = "1.1.0"
@ -24,6 +26,7 @@ parking_lot = "0.6"
serde = "1.0.74"
serde_derive = "1.0.74"
serde_json = "1.0.26"
siphasher = "0.2.3"
slog = "2.3"
slog-term = "2.4"
slog-async = "2.3"
@ -32,6 +35,7 @@ tar = "0.4.16"
toml = "0.4"
which = "2.0.0"
zip = "0.4.2"
chrono = "0.4.6"
[dev-dependencies]
tempfile = "3"

@ -18,4 +18,5 @@
- [`src/utils.rs`](./tutorial/template-deep-dive/src-utils-rs.md)
- [Packaging and Publishing](./tutorial/packaging-and-publishing.md)
- [Using your Library](./tutorial/using-your-library.md)
- [`Cargo.toml` Configuration](./cargo-toml-configuration.md)
- [Contributing](./contributing.md)

@ -0,0 +1,29 @@
# `Cargo.toml` Configuration
`wasm-pack` can be configured via the `package.metadata.wasm-pack` key in
`Cargo.toml`. Every option has a default, and is not required.
There are three profiles: `dev`, `profiling`, and `release`. These correspond to
the `--dev`, `--profiling`, and `--release` flags passed to `wasm-pack build`.
The available configuration options and their default values are shown below:
```toml
[package.metadata.wasm-pack.profile.dev.wasm-bindgen]
# Should we enable wasm-bindgen's debug assertions in its generated JS glue?
debug-js-glue = true
# Should wasm-bindgen demangle the symbols in the "name" custom section?
demangle-name-section = true
# Should we emit the DWARF debug info custom sections?
dwarf-debug-info = false
[package.metadata.wasm-pack.profile.profiling.wasm-bindgen]
debug-js-glue = false
demangle-name-section = true
dwarf-debug-info = false
[package.metadata.wasm-pack.profile.release.wasm-bindgen]
debug-js-glue = false
demangle-name-section = true
dwarf-debug-info = false
```

@ -16,15 +16,28 @@ wasm-pack build examples/js-hello-world
This path should point to a directory that contains a `Cargo.toml` file. If no
path is given, the `build` command will run in the current directory.
## Debug
## Profile
The init command accepts an optional `--debug` argument. This will build the
output package using cargo's
[default non-release profile][cargo-profile-sections-documentation]. Building
this way is faster but applies few optimizations to the output, and enables
debug assertions and other runtime correctness checks.
The `build` command accepts an optional profile argument: one of `--dev`,
`--profiling`, or `--release`. If none is supplied, then `--release` is used.
The exact meaning of this flag may evolve as the platform matures.
Th controls whether debug assertions are enabled, debug info is generated, and
which (if any) optimizations are enabled.
| Profile | Debug Assertions | Debug Info | Optimizations | Notes |
|---------------|------------------|------------|---------------|---------------------------------------|
| `--dev` | Yes | Yes | No | Useful for development and debugging. |
| `--profiling` | No | Yes | Yes | Useful when profiling and investigating performance issues. |
| `--release` | No | No | Yes | Useful for shipping to production. |
The `--dev` profile will build the output package using cargo's [default
non-release profile][cargo-profile-sections-documentation]. Building this way is
faster but applies few optimizations to the output, and enables debug assertions
and other runtime correctness checks. The `--profiling` and `--release` profiles
use cargo's release profile, but the former enables debug info as well, which
helps when investigating performance issues in a profiler.
The exact meaning of the profile flags may evolve as the platform matures.
[cargo-profile-sections-documentation]: https://doc.rust-lang.org/cargo/reference/manifest.html#the-profile-sections

@ -1,247 +1,257 @@
//! Utilities for finding and installing binaries that we depend on.
use curl;
use error::Error;
use failure;
use dirs;
use failure::{Error, ResultExt};
use flate2;
use slog::Logger;
use hex;
use siphasher::sip::SipHasher13;
use std::collections::HashSet;
use std::env;
use std::ffi;
use std::fs;
use std::hash::{Hash, Hasher};
use std::io;
use std::path::{Path, PathBuf};
use tar;
use target;
use which::which;
use zip;
/// Get the path for a crate's directory of locally-installed binaries.
///
/// This does not check whether or ensure that the directory exists.
pub fn local_bin_dir(crate_path: &Path) -> PathBuf {
crate_path.join("bin")
/// Global cache for wasm-pack, currently containing binaries downloaded from
/// urls like wasm-bindgen and such.
pub struct Cache {
destination: PathBuf,
}
/// Ensure that the crate's directory for locally-installed binaries exists.
pub fn ensure_local_bin_dir(crate_path: &Path) -> io::Result<()> {
fs::create_dir_all(local_bin_dir(crate_path))
/// Representation of a downloaded tarball/zip
pub struct Download {
root: PathBuf,
}
/// Get the path for where `bin` would be if we have a crate-local install for
/// it.
///
/// This does *not* check whether there is a file at that path or not.
///
/// This will automatically add the `.exe` extension for windows.
pub fn local_bin_path(crate_path: &Path, bin: &str) -> PathBuf {
let mut p = local_bin_dir(crate_path).join(bin);
if target::WINDOWS {
p.set_extension("exe");
impl Cache {
/// Returns the global cache directory, as inferred from env vars and such.
///
/// This function may return an error if a cache directory cannot be
/// determined.
pub fn new() -> Result<Cache, Error> {
let destination = dirs::cache_dir()
.map(|p| p.join("wasm-pack"))
.or_else(|| {
let home = dirs::home_dir()?;
Some(home.join(".wasm-pack"))
})
.ok_or_else(|| format_err!("couldn't find your home directory, is $HOME not set?"))?;
Ok(Cache::at(&destination))
}
p
}
/// Get the local (at `$CRATE/bin/$BIN`; preferred) or global (on `$PATH`) path
/// for the given binary.
///
/// If this function returns `Some(path)`, then a file at that path exists (or
/// at least existed when we checked! In general, we aren't really worried about
/// racing with an uninstall of a tool that we rely on.)
pub fn bin_path(log: &Logger, crate_path: &Path, bin: &str) -> Option<PathBuf> {
assert!(!bin.ends_with(".exe"));
debug!(log, "Searching for {} binary...", bin);
// Return the path to the local binary, if it exists.
let local_path = |crate_path: &Path| -> Option<PathBuf> {
let p = local_bin_path(crate_path, bin);
debug!(log, "Checking for local {} binary at {}", bin, p.display());
if p.is_file() {
Some(p)
} else {
None
/// Creates a new cache specifically at a particular directory, useful in
/// testing and such.
pub fn at(path: &Path) -> Cache {
Cache {
destination: path.to_path_buf(),
}
};
}
// Return the path to the global binary, if it exists.
let global_path = || -> Option<PathBuf> {
debug!(log, "Looking for global {} binary on $PATH", bin);
if let Ok(p) = which(bin) {
Some(p)
} else {
None
/// Joins a path to the destination of this cache, returning the result
pub fn join(&self, path: &Path) -> PathBuf {
self.destination.join(path)
}
/// Downloads a tarball or zip file from the specified url, extracting it
/// locally and returning the directory that the contents were extracted
/// into.
///
/// Note that this function requries that the contents of `url` never change
/// as the contents of the url are globally cached on the system and never
/// invalidated.
///
/// The `name` is a human-readable name used to go into the folder name of
/// the destination, and `binaries` is a list of binaries expected to be at
/// the url. If the URL's extraction doesn't contain all the binaries this
/// function will return an error.
pub fn download(
&self,
install_permitted: bool,
name: &str,
binaries: &[&str],
url: &str,
) -> Result<Option<Download>, Error> {
let mut hasher = SipHasher13::new();
url.hash(&mut hasher);
let result = hasher.finish();
let hex = hex::encode(&[
(result >> 0) as u8,
(result >> 8) as u8,
(result >> 16) as u8,
(result >> 24) as u8,
(result >> 32) as u8,
(result >> 40) as u8,
(result >> 48) as u8,
(result >> 56) as u8,
]);
let dirname = format!("{}-{}", name, hex);
let destination = self.destination.join(&dirname);
if destination.exists() {
return Ok(Some(Download { root: destination }));
}
};
local_path(crate_path)
.or_else(global_path)
.map(|p| {
let p = p.canonicalize().unwrap_or(p);
debug!(log, "Using {} binary at {}", bin, p.display());
p
})
.or_else(|| {
debug!(log, "Could not find {} binary.", bin);
None
})
}
fn with_url_context<T, E>(url: &str, r: Result<T, E>) -> Result<T, impl failure::Fail>
where
Result<T, E>: failure::ResultExt<T, E>,
{
use failure::ResultExt;
r.with_context(|_| format!("when requesting {}", url))
}
if !install_permitted {
return Ok(None);
}
fn transfer(
url: &str,
easy: &mut curl::easy::Easy,
data: &mut Vec<u8>,
) -> Result<(), failure::Error> {
let mut transfer = easy.transfer();
with_url_context(
url,
transfer.write_function(|part| {
data.extend_from_slice(part);
Ok(part.len())
}),
)?;
with_url_context(url, transfer.perform())?;
Ok(())
}
let data = curl(&url).with_context(|_| format!("failed to download from {}", url))?;
fn curl(url: &str) -> Result<Vec<u8>, failure::Error> {
let mut data = Vec::new();
// Extract everything in a temporary directory in case we're ctrl-c'd.
// Don't want to leave around corrupted data!
let temp = self.destination.join(&format!(".{}", dirname));
drop(fs::remove_dir_all(&temp));
fs::create_dir_all(&temp)?;
let mut easy = curl::easy::Easy::new();
with_url_context(url, easy.follow_location(true))?;
with_url_context(url, easy.url(url))?;
transfer(url, &mut easy, &mut data)?;
if url.ends_with(".tar.gz") {
self.extract_tarball(&data, &temp, binaries)
.with_context(|_| format!("failed to extract tarball from {}", url))?;
} else if url.ends_with(".zip") {
self.extract_zip(&data, &temp, binaries)
.with_context(|_| format!("failed to extract zip from {}", url))?;
} else {
// panic instead of runtime error as it's a static violation to
// download a different kind of url, all urls should be encoded into
// the binary anyway
panic!("don't know how to extract {}", url)
}
let status_code = with_url_context(url, easy.response_code())?;
if 200 <= status_code && status_code < 300 {
Ok(data)
} else {
Err(Error::http(&format!(
"received a bad HTTP status code ({}) when requesting {}",
status_code, url
))
.into())
// Now that everything is ready move this over to our destination and
// we're good to go.
fs::rename(&temp, &destination)?;
Ok(Some(Download { root: destination }))
}
}
/// Download the `.tar.gz` file at the given URL and unpack the given binaries
/// from it into the given crate.
///
/// Upon success, every `$BIN` in `binaries` will be at `$CRATE/bin/$BIN`.
pub fn install_binaries_from_targz_at_url<'a, I>(
crate_path: &Path,
url: &str,
binaries: I,
) -> Result<(), failure::Error>
where
I: IntoIterator<Item = &'a str>,
{
let mut binaries: HashSet<_> = binaries.into_iter().map(ffi::OsStr::new).collect();
let tarball = curl(&url).map_err(|e| Error::http(&e.to_string()))?;
let mut archive = tar::Archive::new(flate2::read::GzDecoder::new(&tarball[..]));
ensure_local_bin_dir(crate_path)?;
let bin = local_bin_dir(crate_path);
for entry in archive.entries()? {
let mut entry = entry?;
let dest = match entry.path()?.file_stem() {
Some(f) if binaries.contains(f) => {
binaries.remove(f);
bin.join(entry.path()?.file_name().unwrap())
}
_ => continue,
};
entry.unpack(dest)?;
}
fn extract_tarball(&self, tarball: &[u8], dst: &Path, binaries: &[&str]) -> Result<(), Error> {
let mut binaries: HashSet<_> = binaries.into_iter().map(ffi::OsStr::new).collect();
let mut archive = tar::Archive::new(flate2::read::GzDecoder::new(tarball));
for entry in archive.entries()? {
let mut entry = entry?;
let dest = match entry.path()?.file_stem() {
Some(f) if binaries.contains(f) => {
binaries.remove(f);
dst.join(entry.path()?.file_name().unwrap())
}
_ => continue,
};
entry.unpack(dest)?;
}
if !binaries.is_empty() {
bail!(
"the tarball was missing expected executables: {}",
binaries
.into_iter()
.map(|s| s.to_string_lossy())
.collect::<Vec<_>>()
.join(", "),
)
}
if binaries.is_empty() {
Ok(())
} else {
Err(Error::archive(&format!(
"the tarball at {} was missing expected executables: {}",
url,
binaries
.into_iter()
.map(|s| s.to_string_lossy())
.collect::<Vec<_>>()
.join(", "),
))
.into())
}
fn extract_zip(&self, zip: &[u8], dst: &Path, binaries: &[&str]) -> Result<(), Error> {
let mut binaries: HashSet<_> = binaries.into_iter().map(ffi::OsStr::new).collect();
let data = io::Cursor::new(zip);
let mut zip = zip::ZipArchive::new(data)?;
for i in 0..zip.len() {
let mut entry = zip.by_index(i).unwrap();
let entry_path = entry.sanitized_name();
match entry_path.file_stem() {
Some(f) if binaries.contains(f) => {
binaries.remove(f);
let mut dest = bin_open_options()
.write(true)
.create_new(true)
.open(dst.join(entry_path.file_name().unwrap()))?;
io::copy(&mut entry, &mut dest)?;
}
_ => continue,
};
}
if !binaries.is_empty() {
bail!(
"the zip was missing expected executables: {}",
binaries
.into_iter()
.map(|s| s.to_string_lossy())
.collect::<Vec<_>>()
.join(", "),
)
}
return Ok(());
#[cfg(unix)]
fn bin_open_options() -> fs::OpenOptions {
use std::os::unix::fs::OpenOptionsExt;
let mut opts = fs::OpenOptions::new();
opts.mode(0o755);
opts
}
#[cfg(not(unix))]
fn bin_open_options() -> fs::OpenOptions {
fs::OpenOptions::new()
}
}
}
/// Install binaries from within the given zip at the given URL.
///
/// Upon success, the binaries will be at the `$CRATE/bin/$BIN` path.
pub fn install_binaries_from_zip_at_url<'a, I>(
crate_path: &Path,
url: &str,
binaries: I,
) -> Result<(), failure::Error>
where
I: IntoIterator<Item = &'a str>,
{
let mut binaries: HashSet<_> = binaries.into_iter().map(ffi::OsStr::new).collect();
let data = curl(&url).map_err(|e| Error::http(&e.to_string()))?;
let data = io::Cursor::new(data);
let mut zip = zip::ZipArchive::new(data)?;
ensure_local_bin_dir(crate_path)?;
let bin = local_bin_dir(crate_path);
for i in 0..zip.len() {
let mut entry = zip.by_index(i).unwrap();
let entry_path = entry.sanitized_name();
match entry_path.file_stem() {
Some(f) if binaries.contains(f) => {
binaries.remove(f);
let mut dest = bin_open_options()
.write(true)
.create_new(true)
.open(bin.join(entry_path.file_name().unwrap()))?;
io::copy(&mut entry, &mut dest)?;
}
_ => continue,
};
impl Download {
/// Manually constructs a download at the specified path
pub fn at(path: &Path) -> Download {
Download {
root: path.to_path_buf(),
}
}
if binaries.is_empty() {
Ok(())
} else {
Err(Error::archive(&format!(
"the zip at {} was missing expected executables: {}",
url,
binaries
.into_iter()
.map(|s| s.to_string_lossy())
.collect::<Vec<_>>()
.join(", "),
))
.into())
/// Returns the path to the binary `name` within this download
pub fn binary(&self, name: &str) -> PathBuf {
let ret = self
.root
.join(name)
.with_extension(env::consts::EXE_EXTENSION);
assert!(ret.exists(), "binary {} doesn't exist", ret.display());
return ret;
}
}
#[cfg(unix)]
fn bin_open_options() -> fs::OpenOptions {
use std::os::unix::fs::OpenOptionsExt;
fn curl(url: &str) -> Result<Vec<u8>, Error> {
let mut data = Vec::new();
let mut opts = fs::OpenOptions::new();
opts.mode(0o755);
opts
}
let mut easy = curl::easy::Easy::new();
easy.follow_location(true)?;
easy.url(url)?;
easy.get(true)?;
{
let mut transfer = easy.transfer();
transfer.write_function(|part| {
data.extend_from_slice(part);
Ok(part.len())
})?;
transfer.perform()?;
}
#[cfg(not(unix))]
fn bin_open_options() -> fs::OpenOptions {
fs::OpenOptions::new()
let status_code = easy.response_code()?;
if 200 <= status_code && status_code < 300 {
Ok(data)
} else {
bail!(
"received a bad HTTP status code ({}) when requesting {}",
status_code,
url
)
}
}

@ -1,15 +1,18 @@
//! Functionality related to installing and running `wasm-bindgen`.
use binaries::{self, bin_path, install_binaries_from_targz_at_url};
use binaries::{Cache, Download};
use child;
use command::build::BuildProfile;
use emoji;
use error::Error;
use failure::{self, ResultExt};
use manifest::CrateData;
use progressbar::Step;
use slog::Logger;
use std::fs;
use std::path::{Path, PathBuf};
use std::process::Command;
use target;
use which::which;
use PBAR;
/// Install the `wasm-bindgen` CLI.
@ -19,46 +22,66 @@ use PBAR;
/// tarball from the GitHub releases page, if this target has prebuilt
/// binaries. Finally, falls back to `cargo install`.
pub fn install_wasm_bindgen(
root_path: &Path,
cache: &Cache,
version: &str,
install_permitted: bool,
step: &Step,
log: &Logger,
) -> Result<(), failure::Error> {
// If the `wasm-bindgen` dependency is already met, print a message and return.
if wasm_bindgen_path(log, root_path)
.map(|bindgen_path| wasm_bindgen_version_check(&bindgen_path, version, log))
.unwrap_or(false)
{
let msg = format!("{}wasm-bindgen already installed...", emoji::DOWN_ARROW);
PBAR.step(step, &msg);
return Ok(());
}
// If the `wasm-bindgen` dependency was not met, and installs are not
// permitted, return a configuration error.
if !install_permitted {
let msg = format!("wasm-bindgen v{} is not installed!", version);
return Err(Error::crate_config(&msg).into());
) -> Result<Download, failure::Error> {
// If `wasm-bindgen` is installed globally and it has the right version, use
// that. Assume that other tools are installed next to it.
//
// This situation can arise if `wasm-bindgen` is already installed via
// `cargo install`, for example.
if let Ok(path) = which("wasm-bindgen") {
debug!(
log,
"found global wasm-bindgen binary at: {}",
path.display()
);
if wasm_bindgen_version_check(&path, version, log) {
return Ok(Download::at(path.parent().unwrap()));
}
}
let msg = format!("{}Installing wasm-bindgen...", emoji::DOWN_ARROW);
PBAR.step(step, &msg);
download_prebuilt_wasm_bindgen(root_path, version).or_else(|e| {
warn!(
log,
"could not download pre-built `wasm-bindgen`: {}. Falling back to `cargo install`.", e
);
cargo_install_wasm_bindgen(log, root_path, version)
})
let dl = download_prebuilt_wasm_bindgen(&cache, version, install_permitted);
match dl {
Ok(dl) => return Ok(dl),
Err(e) => {
warn!(
log,
"could not download pre-built `wasm-bindgen`: {}. Falling back to `cargo install`.",
e
);
}
}
cargo_install_wasm_bindgen(log, &cache, version, install_permitted)
}
/// Download a tarball containing a pre-built `wasm-bindgen` binary.
/// Downloads a precompiled copy of wasm-bindgen, if available.
pub fn download_prebuilt_wasm_bindgen(
root_path: &Path,
cache: &Cache,
version: &str,
) -> Result<(), failure::Error> {
install_permitted: bool,
) -> Result<Download, failure::Error> {
let url = match prebuilt_url(version) {
Some(url) => url,
None => bail!("no prebuilt wasm-bindgen binaries are available for this platform"),
};
let binaries = &["wasm-bindgen", "wasm-bindgen-test-runner"];
match cache.download(install_permitted, "wasm-bindgen", binaries, &url)? {
Some(download) => Ok(download),
None => bail!("wasm-bindgen v{} is not installed!", version),
}
}
/// Returns the URL of a precompiled version of wasm-bindgen, if we have one
/// available for our host platform.
fn prebuilt_url(version: &str) -> Option<String> {
let target = if target::LINUX && target::x86_64 {
"x86_64-unknown-linux-musl"
} else if target::MACOS && target::x86_64 {
@ -66,32 +89,40 @@ pub fn download_prebuilt_wasm_bindgen(
} else if target::WINDOWS && target::x86_64 {
"x86_64-pc-windows-msvc"
} else {
return Err(Error::unsupported(
"there are no pre-built `wasm-bindgen` binaries for this target",
)
.into());
return None;
};
let url = format!(
Some(format!(
"https://github.com/rustwasm/wasm-bindgen/releases/download/{0}/wasm-bindgen-{0}-{1}.tar.gz",
version,
target
);
install_binaries_from_targz_at_url(
root_path,
&url,
vec!["wasm-bindgen", "wasm-bindgen-test-runner"],
)
))
}
/// Use `cargo install` to install the `wasm-bindgen` CLI locally into the given
/// crate.
pub fn cargo_install_wasm_bindgen(
logger: &Logger,
crate_path: &Path,
cache: &Cache,
version: &str,
) -> Result<(), failure::Error> {
install_permitted: bool,
) -> Result<Download, failure::Error> {
let dirname = format!("wasm-bindgen-cargo-install-{}", version);
let destination = cache.join(dirname.as_ref());
if destination.exists() {
return Ok(Download::at(&destination));
}
if !install_permitted {
bail!("wasm-bindgen v{} is not installed!", version)
}
// Run `cargo install` to a temporary location to handle ctrl-c gracefully
// and ensure we don't accidentally use stale files in the future
let tmp = cache.join(format!(".{}", dirname).as_ref());
drop(fs::remove_dir_all(&tmp));
fs::create_dir_all(&tmp)?;
let mut cmd = Command::new("cargo");
cmd.arg("install")
.arg("--force")
@ -99,66 +130,74 @@ pub fn cargo_install_wasm_bindgen(
.arg("--version")
.arg(version)
.arg("--root")
.arg(crate_path);
.arg(&tmp);
child::run(logger, cmd, "cargo install").context("Installing wasm-bindgen with cargo")?;
assert!(binaries::local_bin_path(crate_path, "wasm-bindgen").is_file());
Ok(())
fs::rename(&tmp, &destination)?;
Ok(Download::at(&destination))
}
/// Run the `wasm-bindgen` CLI to generate bindings for the current crate's
/// `.wasm`.
pub fn wasm_bindgen_build(
path: &Path,
data: &CrateData,
bindgen: &Download,
out_dir: &Path,
name: &str,
disable_dts: bool,
target: &str,
debug: bool,
profile: BuildProfile,
step: &Step,
log: &Logger,
) -> Result<(), failure::Error> {
let msg = format!("{}Running WASM-bindgen...", emoji::RUNNER);
PBAR.step(step, &msg);
let binary_name = name.replace("-", "_");
let release_or_debug = if debug { "debug" } else { "release" };
let release_or_debug = match profile {
BuildProfile::Release | BuildProfile::Profiling => "release",
BuildProfile::Dev => "debug",
};
let out_dir = out_dir.to_str().unwrap();
if let Some(wasm_bindgen_path) = wasm_bindgen_path(log, path) {
let wasm_path = format!(
"target/wasm32-unknown-unknown/{}/{}.wasm",
release_or_debug, binary_name
);
let dts_arg = if disable_dts {
"--no-typescript"
} else {
"--typescript"
};
let target_arg = match target {
"nodejs" => "--nodejs",
"no-modules" => "--no-modules",
_ => "--browser",
};
let bindgen_path = Path::new(&wasm_bindgen_path);
let mut cmd = Command::new(bindgen_path);
cmd.current_dir(path)
.arg(&wasm_path)
.arg("--out-dir")
.arg(out_dir)
.arg(dts_arg)
.arg(target_arg);
if debug {
cmd.arg("--debug");
}
let wasm_path = data
.target_directory()
.join("wasm32-unknown-unknown")
.join(release_or_debug)
.join(data.crate_name())
.with_extension("wasm");
child::run(log, cmd, "wasm-bindgen").context("Running the wasm-bindgen CLI")?;
Ok(())
let dts_arg = if disable_dts {
"--no-typescript"
} else {
Err(Error::crate_config("Could not find `wasm-bindgen`").into())
"--typescript"
};
let target_arg = match target {
"nodejs" => "--nodejs",
"no-modules" => "--no-modules",
_ => "--browser",
};
let bindgen_path = bindgen.binary("wasm-bindgen");
let mut cmd = Command::new(bindgen_path);
cmd.arg(&wasm_path)
.arg("--out-dir")
.arg(out_dir)
.arg(dts_arg)
.arg(target_arg);
let profile = data.configured_profile(profile);
if profile.wasm_bindgen_debug_js_glue() {
cmd.arg("--debug");
}
if !profile.wasm_bindgen_demangle_name_section() {
cmd.arg("--no-demangle");
}
if profile.wasm_bindgen_dwarf_debug_info() {
cmd.arg("--keep-debug");
}
child::run(log, cmd, "wasm-bindgen").context("Running the wasm-bindgen CLI")?;
Ok(())
}
/// Check if the `wasm-bindgen` dependency is locally satisfied.
@ -184,16 +223,3 @@ fn wasm_bindgen_version_check(bindgen_path: &PathBuf, dep_version: &str, log: &L
})
.unwrap_or(false)
}
/// Return a `PathBuf` containing the path to either the local wasm-bindgen
/// version, or the globally installed version if there is no local version.
fn wasm_bindgen_path(log: &Logger, crate_path: &Path) -> Option<PathBuf> {
bin_path(log, crate_path, "wasm-bindgen")
}
/// Return a `PathBuf` containing the path to either the local
/// wasm-bindgen-test-runner version, or the globally installed version if there
/// is no local version.
pub fn wasm_bindgen_test_runner_path(log: &Logger, crate_path: &Path) -> Option<PathBuf> {
bin_path(log, crate_path, "wasm-bindgen-test-runner")
}

@ -1,9 +1,9 @@
//! Building a Rust crate into a `.wasm` binary.
use child;
use command::build::BuildProfile;
use emoji;
use error::Error;
use failure::ResultExt;
use failure::{Error, ResultExt};
use manifest::Crate;
use progressbar::Step;
use slog::Logger;
@ -13,47 +13,35 @@ use std::str;
use PBAR;
/// Ensure that `rustc` is present and that it is >= 1.30.0
pub fn check_rustc_version(step: &Step) -> Result<String, failure::Error> {
pub fn check_rustc_version(step: &Step) -> Result<String, Error> {
let msg = format!("{}Checking `rustc` version...", emoji::CRAB);
PBAR.step(step, &msg);
let local_minor_version = rustc_minor_version();
match local_minor_version {
Some(mv) => {
if mv < 30 {
return Err(Error::RustcVersion {
message: format!(
"Your version of Rust, '1.{}', is not supported. Please install Rust version 1.30.0 or higher.",
mv.to_string()
),
local_minor_version: mv.to_string(),
}.into())
bail!(
"Your version of Rust, '1.{}', is not supported. Please install Rust version 1.30.0 or higher.",
mv.to_string()
)
} else {
Ok(mv.to_string())
Ok(mv.to_string())
}
},
None => Err(Error::RustcMissing {
message: "We can't figure out what your Rust version is- which means you might not have Rust installed. Please install Rust version 1.30.0 or higher.".to_string(),
}.into()),
},
None => bail!("We can't figure out what your Rust version is- which means you might not have Rust installed. Please install Rust version 1.30.0 or higher."),
}
}
/// Checks if `wasm-pack` is updated to the latest version
pub fn check_wasm_pack_version(step: &Step) -> Result<(), failure::Error> {
let msg = format!("{}Checking `wasm-pack` version...", emoji::PACKAGE);
PBAR.step(step, &msg);
let wasm_pack_local_version = wasm_pack_local_version();
let wasm_pack_latest_version = Crate::return_wasm_pack_latest_version();
match wasm_pack_local_version {
Some(lv) => {
if !(lv == wasm_pack_latest_version) {
Ok(PBAR.info(&format!("There's a newer version of wasm-pack available, the new version is: {}, you are using: {}", wasm_pack_latest_version, lv)))
} else {
Ok(())
pub fn check_wasm_pack_versions() -> Result<(String, String), Error> {
match wasm_pack_local_version() {
Some(local) => {
match Crate::return_wasm_pack_latest_version() {
Some(latest) => Ok((local, latest)),
None => Ok((local, "".to_string()))
}
},
None => Err(Error::WasmPackMissing {
message: "We can't figure out what your wasm-pack version is, make sure the installation path is correct.".to_string(),
}.into()),
None => bail!("We can't figure out what your wasm-pack version is, make sure the installation path is correct.")
}
}
@ -101,7 +89,7 @@ fn wasm_pack_local_version() -> Option<String> {
/// Ensure that `rustup` has the `wasm32-unknown-unknown` target installed for
/// current toolchain
pub fn rustup_add_wasm_target(log: &Logger, step: &Step) -> Result<(), failure::Error> {
pub fn rustup_add_wasm_target(log: &Logger, step: &Step) -> Result<(), Error> {
let msg = format!("{}Adding WASM target...", emoji::TARGET);
PBAR.step(step, &msg);
let mut cmd = Command::new("rustup");
@ -115,27 +103,37 @@ pub fn rustup_add_wasm_target(log: &Logger, step: &Step) -> Result<(), failure::
pub fn cargo_build_wasm(
log: &Logger,
path: &Path,
debug: bool,
profile: BuildProfile,
step: &Step,
) -> Result<(), failure::Error> {
) -> Result<(), Error> {
let msg = format!("{}Compiling to WASM...", emoji::CYCLONE);
PBAR.step(step, &msg);
let mut cmd = Command::new("cargo");
cmd.current_dir(path).arg("build").arg("--lib");
if !debug {
cmd.arg("--release");
match profile {
BuildProfile::Profiling => {
// Once there are DWARF debug info consumers, force enable debug
// info, because builds that use the release cargo profile disables
// debug info.
//
// cmd.env("RUSTFLAGS", "-g");
cmd.arg("--release");
}
BuildProfile::Release => {
cmd.arg("--release");
}
BuildProfile::Dev => {
// Plain cargo builds use the dev cargo profile, which includes
// debug info by default.
}
}
cmd.arg("--target").arg("wasm32-unknown-unknown");
child::run(log, cmd, "cargo build").context("Compiling your crate to WebAssembly")?;
child::run(log, cmd, "cargo build").context("Compiling your crate to WebAssembly failed")?;
Ok(())
}
/// Run `cargo build --tests` targetting `wasm32-unknown-unknown`.
pub fn cargo_build_wasm_tests(
log: &Logger,
path: &Path,
debug: bool,
) -> Result<(), failure::Error> {
pub fn cargo_build_wasm_tests(log: &Logger, path: &Path, debug: bool) -> Result<(), Error> {
let mut cmd = Command::new("cargo");
cmd.current_dir(path).arg("build").arg("--tests");
if !debug {

@ -3,8 +3,7 @@
//! This module helps us ensure that all child processes that we spawn get
//! properly logged and their output is logged as well.
use error::Error;
use failure;
use failure::Error;
use slog::Logger;
use std::{
io::{self, Read},
@ -120,7 +119,7 @@ pub fn run(
logger: &Logger,
mut command: process::Command,
command_name: &str,
) -> Result<String, failure::Error> {
) -> Result<String, Error> {
info!(logger, "Running {:?}", command);
let mut child = command
@ -171,7 +170,7 @@ pub fn run(
if exit.success() {
return Ok(stdout);
} else {
let msg = format!("`{}` did not exit successfully", command_name);
return Err(Error::cli(&msg, stdout.into(), stderr.into(), exit).into());
drop((stdout, stderr));
bail!("failed to execute `{}`: exited with {}", command_name, exit)
}
}

@ -1,10 +1,11 @@
//! Implementation of the `wasm-pack build` command.
use binaries::{Cache, Download};
use bindgen;
use build;
use command::utils::{create_pkg_dir, set_crate_path};
use emoji;
use error::Error;
use failure::Error;
use indicatif::HumanDuration;
use lockfile::Lockfile;
use manifest;
@ -17,16 +18,18 @@ use std::time::Instant;
use PBAR;
/// Everything required to configure and run the `wasm-pack init` command.
pub(crate) struct Build {
#[allow(missing_docs)]
pub struct Build {
pub crate_path: PathBuf,
pub crate_data: manifest::CrateData,
pub scope: Option<String>,
pub disable_dts: bool,
pub target: String,
pub debug: bool,
pub profile: BuildProfile,
pub mode: BuildMode,
// build_config: Option<BuildConfig>,
pub crate_name: String,
pub out_dir: PathBuf,
pub bindgen: Option<Download>,
pub cache: Cache,
}
/// The `BuildMode` determines which mode of initialization we are running, and
@ -55,11 +58,23 @@ impl FromStr for BuildMode {
"no-install" => Ok(BuildMode::Noinstall),
"normal" => Ok(BuildMode::Normal),
"force" => Ok(BuildMode::Force),
_ => Err(Error::crate_config(&format!("Unknown build mode: {}", s))),
_ => bail!("Unknown build mode: {}", s),
}
}
}
/// The build profile controls whether optimizations, debug info, and assertions
/// are enabled or disabled.
#[derive(Clone, Copy, Debug)]
pub enum BuildProfile {
/// Enable assertions and debug info. Disable optimizations.
Dev,
/// Enable optimizations. Disable assertions and debug info.
Release,
/// Enable optimizations and debug info. Disable assertions.
Profiling,
}
/// Everything required to configure and run the `wasm-pack build` command.
#[derive(Debug, StructOpt)]
pub struct BuildOptions {
@ -81,43 +96,71 @@ pub struct BuildOptions {
pub disable_dts: bool,
#[structopt(long = "target", short = "t", default_value = "browser")]
/// Sets the target environment. [possible values: browser, nodejs]
/// Sets the target environment. [possible values: browser, nodejs, no-modules]
pub target: String,
#[structopt(long = "debug")]
/// Build without --release.
/// Deprecated. Renamed to `--dev`.
debug: bool,
// build config from manifest
// build_config: Option<BuildConfig>,
#[structopt(long = "dev")]
/// Create a development build. Enable debug info, and disable
/// optimizations.
dev: bool,
#[structopt(long = "release")]
/// Create a release build. Enable optimizations and disable debug info.
release: bool,
#[structopt(long = "profiling")]
/// Create a profiling build. Enable optimizations and debug info.
profiling: bool,
#[structopt(long = "out-dir", short = "d", default_value = "pkg")]
/// Sets the output directory with a relative path.
pub out_dir: String,
}
type BuildStep = fn(&mut Build, &Step, &Logger) -> Result<(), failure::Error>;
type BuildStep = fn(&mut Build, &Step, &Logger) -> Result<(), Error>;
impl Build {
/// Construct a build command from the given options.
pub fn try_from_opts(build_opts: BuildOptions) -> Result<Self, failure::Error> {
pub fn try_from_opts(build_opts: BuildOptions) -> Result<Self, Error> {
let crate_path = set_crate_path(build_opts.path)?;
let crate_name = manifest::get_crate_name(&crate_path)?;
let crate_data = manifest::CrateData::new(&crate_path)?;
let out_dir = crate_path.join(PathBuf::from(build_opts.out_dir));
// let build_config = manifest::xxx(&crate_path).xxx();
let dev = build_opts.dev || build_opts.debug;
let profile = match (dev, build_opts.release, build_opts.profiling) {
(false, false, false) | (false, true, false) => BuildProfile::Release,
(true, false, false) => BuildProfile::Dev,
(false, false, true) => BuildProfile::Profiling,
// Unfortunately, `structopt` doesn't expose clap's `conflicts_with`
// functionality yet, so we have to implement it ourselves.
_ => bail!("Can only supply one of the --dev, --release, or --profiling flags"),
};
Ok(Build {
crate_path,
crate_data,
scope: build_opts.scope,
disable_dts: build_opts.disable_dts,
target: build_opts.target,
debug: build_opts.debug,
profile,
mode: build_opts.mode,
// build_config,
crate_name,
out_dir,
bindgen: None,
cache: Cache::new()?,
})
}
/// Configures the global binary cache used for this build
pub fn set_cache(&mut self, cache: Cache) {
self.cache = cache;
}
/// Execute this `Build` command.
pub fn run(&mut self, log: &Logger) -> Result<(), failure::Error> {
pub fn run(&mut self, log: &Logger) -> Result<(), Error> {
let process_steps = Build::get_process_steps(&self.mode);
let mut step_counter = Step::new(process_steps.len());
@ -160,7 +203,6 @@ impl Build {
match &mode {
BuildMode::Normal => steps![
step_check_rustc_version,
step_check_wasm_pack_version,
step_check_crate_config,
step_add_wasm_target,
step_build_wasm,
@ -172,7 +214,6 @@ impl Build {
],
BuildMode::Noinstall => steps![
step_check_rustc_version,
step_check_wasm_pack_version,
step_check_crate_config,
step_build_wasm,
step_create_dir,
@ -190,11 +231,13 @@ impl Build {
}
}
fn step_check_rustc_version(
&mut self,
step: &Step,
log: &Logger,
) -> Result<(), failure::Error> {
/// Returns local and latest versions of wasm-pack
pub fn return_wasm_pack_versions() -> Result<(String, String), Error> {
let (local, latest) = build::check_wasm_pack_versions()?;
Ok((local, latest))
}
fn step_check_rustc_version(&mut self, step: &Step, log: &Logger) -> Result<(), Error> {
info!(&log, "Checking rustc version...");
let version = build::check_rustc_version(step)?;
let msg = format!("rustc version is {}.", version);
@ -202,35 +245,23 @@ impl Build {
Ok(())
}
fn step_check_wasm_pack_version(
&mut self,
step: &Step,
log: &Logger,
) -> Result<(), failure::Error> {
info!(&log, "Checking wasm-pack version...");
let version = build::check_wasm_pack_version(step)?;
let msg = format!("wasm-pack version is: {:?}.", version);
info!(&log, "{}", &msg);
Ok(())
}
fn step_check_crate_config(&mut self, step: &Step, log: &Logger) -> Result<(), failure::Error> {
fn step_check_crate_config(&mut self, step: &Step, log: &Logger) -> Result<(), Error> {
info!(&log, "Checking crate configuration...");
manifest::check_crate_config(&self.crate_path, step)?;
self.crate_data.check_crate_config(step)?;
info!(&log, "Crate is correctly configured.");
Ok(())
}
fn step_add_wasm_target(&mut self, step: &Step, log: &Logger) -> Result<(), failure::Error> {
fn step_add_wasm_target(&mut self, step: &Step, log: &Logger) -> Result<(), Error> {
info!(&log, "Adding wasm-target...");
build::rustup_add_wasm_target(log, step)?;
info!(&log, "Adding wasm-target was successful.");
Ok(())
}
fn step_build_wasm(&mut self, step: &Step, log: &Logger) -> Result<(), failure::Error> {
fn step_build_wasm(&mut self, step: &Step, log: &Logger) -> Result<(), Error> {
info!(&log, "Building wasm...");
build::cargo_build_wasm(log, &self.crate_path, self.debug, step)?;
build::cargo_build_wasm(log, &self.crate_path, self.profile, step)?;
info!(
&log,
@ -244,17 +275,16 @@ impl Build {
Ok(())
}
fn step_create_dir(&mut self, step: &Step, log: &Logger) -> Result<(), failure::Error> {
fn step_create_dir(&mut self, step: &Step, log: &Logger) -> Result<(), Error> {
info!(&log, "Creating a pkg directory...");
create_pkg_dir(&self.out_dir, step)?;
info!(&log, "Created a pkg directory at {:#?}.", &self.crate_path);
Ok(())
}
fn step_create_json(&mut self, step: &Step, log: &Logger) -> Result<(), failure::Error> {
fn step_create_json(&mut self, step: &Step, log: &Logger) -> Result<(), Error> {
info!(&log, "Writing a package.json...");
manifest::write_package_json(
&self.crate_path,
self.crate_data.write_package_json(
&self.out_dir,
&self.scope,
self.disable_dts,
@ -269,20 +299,16 @@ impl Build {
Ok(())
}
fn step_copy_readme(&mut self, step: &Step, log: &Logger) -> Result<(), failure::Error> {
fn step_copy_readme(&mut self, step: &Step, log: &Logger) -> Result<(), Error> {
info!(&log, "Copying readme from crate...");
readme::copy_from_crate(&self.crate_path, &self.out_dir, step)?;
info!(&log, "Copied readme from crate to {:#?}.", &self.out_dir);
Ok(())
}
fn step_install_wasm_bindgen(
&mut self,
step: &Step,
log: &Logger,
) -> Result<(), failure::Error> {
fn step_install_wasm_bindgen(&mut self, step: &Step, log: &Logger) -> Result<(), Error> {
info!(&log, "Identifying wasm-bindgen dependency...");
let lockfile = Lockfile::new(&self.crate_path)?;
let lockfile = Lockfile::new(&self.crate_data)?;
let bindgen_version = lockfile.require_wasm_bindgen()?;
info!(&log, "Installing wasm-bindgen-cli...");
let install_permitted = match self.mode {
@ -290,35 +316,27 @@ impl Build {
BuildMode::Force => true,
BuildMode::Noinstall => false,
};
bindgen::install_wasm_bindgen(
&self.crate_path,
let bindgen = bindgen::install_wasm_bindgen(
&self.cache,
&bindgen_version,
install_permitted,
step,
log,
)?;
self.bindgen = Some(bindgen);
info!(&log, "Installing wasm-bindgen-cli was successful.");
info!(&log, "Getting the crate name from the manifest...");
self.crate_name = manifest::get_crate_name(&self.crate_path)?;
info!(
&log,
"Got crate name {:#?} from the manifest at {:#?}.",
&self.crate_name,
&self.crate_path.join("Cargo.toml")
);
Ok(())
}
fn step_run_wasm_bindgen(&mut self, step: &Step, log: &Logger) -> Result<(), failure::Error> {
fn step_run_wasm_bindgen(&mut self, step: &Step, log: &Logger) -> Result<(), Error> {
info!(&log, "Building the wasm bindings...");
bindgen::wasm_bindgen_build(
&self.crate_path,
&self.crate_data,
self.bindgen.as_ref().unwrap(),
&self.out_dir,
&self.crate_name,
self.disable_dts,
&self.target,
self.debug,
self.profile,
step,
log,
)?;

@ -13,11 +13,12 @@ use self::login::login;
use self::pack::pack;
use self::publish::{access::Access, publish};
use self::test::{Test, TestOptions};
use error::Error;
use failure::Error;
use slog::Logger;
use std::path::PathBuf;
use std::result;
use PBAR;
use std::sync::mpsc;
use std::thread;
/// The various kinds of commands that `wasm-pack` can execute.
#[derive(Debug, StructOpt)]
@ -83,10 +84,27 @@ pub enum Command {
Test(TestOptions),
}
/// Spawn a thread for wasm-pack version check
fn background_check_for_updates() -> mpsc::Receiver<(String, String)> {
let (sender, receiver) = mpsc::channel();
let _detached_thread = thread::spawn(move || {
if let Ok((local, latest)) = Build::return_wasm_pack_versions() {
if !local.is_empty() && !latest.is_empty() && local != latest {
sender.send((local, latest)).unwrap();
}
}
});
receiver
}
/// Run a command with the given logger!
pub fn run_wasm_pack(command: Command, log: &Logger) -> result::Result<(), failure::Error> {
pub fn run_wasm_pack(command: Command, log: &Logger) -> result::Result<(), Error> {
// Run the correct command based off input and store the result of it so that we can clear
// the progress bar then return it
let update_available = background_check_for_updates();
let status = match command {
Command::Build(build_opts) => {
info!(&log, "Running build command...");
@ -125,17 +143,8 @@ pub fn run_wasm_pack(command: Command, log: &Logger) -> result::Result<(), failu
}
};
match status {
Ok(_) => {}
Err(ref e) => {
error!(&log, "{}", e);
for c in e.iter_chain() {
if let Some(e) = c.downcast_ref::<Error>() {
PBAR.error(e.error_type());
break;
}
}
}
if let Ok(update_available) = update_available.try_recv() {
println!("There's a newer version of wasm-pack available, the new version is: {}, you are using: {}", update_available.1, update_available.0);
}
// Return the actual status of the program to the main function

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

@ -1,4 +1,4 @@
use error::Error;
use failure::Error;
use std::fmt;
use std::str::FromStr;
@ -19,7 +19,7 @@ impl FromStr for Access {
"public" => Ok(Access::Public),
"restricted" => Ok(Access::Restricted),
"private" => Ok(Access::Restricted),
_ => Err(Error::Unsupported { message: format!("{} is not a supported access level. See https://docs.npmjs.com/cli/access for more information on npm package access levels.", s)}),
_ => bail!("{} is not a supported access level. See https://docs.npmjs.com/cli/access for more information on npm package access levels.", s),
}
}
}

@ -3,7 +3,7 @@ pub mod access;
use self::access::Access;
use command::utils::{find_pkg_directory, set_crate_path};
use error::Error;
use failure::Error;
use npm;
use slog::Logger;
use std::path::PathBuf;
@ -16,16 +16,17 @@ pub fn publish(
path: Option<PathBuf>,
access: Option<Access>,
log: &Logger,
) -> result::Result<(), failure::Error> {
) -> result::Result<(), Error> {
let crate_path = set_crate_path(path)?;
info!(&log, "Publishing the npm package...");
info!(&log, "npm info located in the npm debug log");
let pkg_directory = find_pkg_directory(&crate_path).ok_or(Error::PkgNotFound {
message: format!(
let pkg_directory = find_pkg_directory(&crate_path).ok_or_else(|| {
format_err!(
"Unable to find the pkg directory at path '{:#?}', or in a child directory of '{:#?}'",
&crate_path, &crate_path
),
&crate_path,
&crate_path
)
})?;
npm::npm_publish(log, &pkg_directory.to_string_lossy(), access)?;

@ -1,12 +1,13 @@
//! Implementation of the `wasm-pack test` command.
use super::build::BuildMode;
use binaries::Cache;
use bindgen;
use build;
use command::utils::set_crate_path;
use console::style;
use emoji;
use error::Error;
use failure::Error;
use indicatif::HumanDuration;
use lockfile::Lockfile;
use manifest;
@ -81,6 +82,8 @@ pub struct TestOptions {
/// A configured `wasm-pack test` command.
pub struct Test {
crate_path: PathBuf,
crate_data: manifest::CrateData,
cache: Cache,
node: bool,
mode: BuildMode,
firefox: bool,
@ -94,11 +97,11 @@ pub struct Test {
test_runner_path: Option<PathBuf>,
}
type TestStep = fn(&mut Test, &Step, &Logger) -> Result<(), failure::Error>;
type TestStep = fn(&mut Test, &Step, &Logger) -> Result<(), Error>;
impl Test {
/// Construct a test command from the given options.
pub fn try_from_opts(test_opts: TestOptions) -> Result<Self, failure::Error> {
pub fn try_from_opts(test_opts: TestOptions) -> Result<Self, Error> {
let TestOptions {
path,
node,
@ -114,32 +117,24 @@ impl Test {
} = test_opts;
let crate_path = set_crate_path(path)?;
// let geckodriver = get_web_driver("geckodriver", test_opts.geckodriver, test_opts.firefox)?;
// let chromedriver =
// get_web_driver("chromedriver", test_opts.chromedriver, test_opts.chrome)?;
// let safaridriver =
// get_web_driver("safaridriver", test_opts.safaridriver, test_opts.safari)?;
let crate_data = manifest::CrateData::new(&crate_path)?;
let any_browser = chrome || firefox || safari;
if !node && !any_browser {
return Err(Error::crate_config(
"Must specify at least one of `--node`, `--chrome`, `--firefox`, or `--safari`",
)
.into());
bail!("Must specify at least one of `--node`, `--chrome`, `--firefox`, or `--safari`")
}
if headless && !any_browser {
return Err(Error::crate_config(
bail!(
"The `--headless` flag only applies to browser tests. Node does not provide a UI, \
so it doesn't make sense to talk about a headless version of Node tests.",
so it doesn't make sense to talk about a headless version of Node tests."
)
.into());
}
Ok(Test {
cache: Cache::new()?,
crate_path,
crate_data,
node,
mode,
chrome,
@ -154,8 +149,13 @@ impl Test {
})
}
/// Configures the cache that this test command uses
pub fn set_cache(&mut self, cache: Cache) {
self.cache = cache;
}
/// Execute this test command.
pub fn run(mut self, log: &Logger) -> Result<(), failure::Error> {
pub fn run(mut self, log: &Logger) -> Result<(), Error> {
let process_steps = self.get_process_steps();
let mut step_counter = Step::new(process_steps.len());
@ -188,7 +188,6 @@ impl Test {
match self.mode {
BuildMode::Normal => steps![
step_check_rustc_version,
step_check_crate_config,
step_add_wasm_target,
step_build_tests,
step_install_wasm_bindgen,
@ -213,7 +212,6 @@ impl Test {
step_test_safari if self.safari,
],
BuildMode::Noinstall => steps![
step_check_crate_config,
step_build_tests,
step_install_wasm_bindgen,
step_test_node if self.node,
@ -227,32 +225,21 @@ impl Test {
}
}
fn step_check_rustc_version(
&mut self,
step: &Step,
log: &Logger,
) -> Result<(), failure::Error> {
fn step_check_rustc_version(&mut self, step: &Step, log: &Logger) -> Result<(), Error> {
info!(log, "Checking rustc version...");
let _ = build::check_rustc_version(step)?;
info!(log, "Rustc version is correct.");
Ok(())
}
fn step_check_crate_config(&mut self, step: &Step, log: &Logger) -> Result<(), failure::Error> {
info!(log, "Checking crate configuration...");
manifest::check_crate_config(&self.crate_path, step)?;
info!(log, "Crate is correctly configured.");
Ok(())
}
fn step_add_wasm_target(&mut self, step: &Step, log: &Logger) -> Result<(), failure::Error> {
fn step_add_wasm_target(&mut self, step: &Step, log: &Logger) -> Result<(), Error> {
info!(&log, "Adding wasm-target...");
build::rustup_add_wasm_target(log, step)?;
info!(&log, "Adding wasm-target was successful.");
Ok(())
}
fn step_build_tests(&mut self, step: &Step, log: &Logger) -> Result<(), failure::Error> {
fn step_build_tests(&mut self, step: &Step, log: &Logger) -> Result<(), Error> {
info!(log, "Compiling tests to wasm...");
let msg = format!("{}Compiling tests to WASM...", emoji::CYCLONE);
@ -264,13 +251,9 @@ impl Test {
Ok(())
}
fn step_install_wasm_bindgen(
&mut self,
step: &Step,
log: &Logger,
) -> Result<(), failure::Error> {
fn step_install_wasm_bindgen(&mut self, step: &Step, log: &Logger) -> Result<(), Error> {
info!(&log, "Identifying wasm-bindgen dependency...");
let lockfile = Lockfile::new(&self.crate_path)?;
let lockfile = Lockfile::new(&self.crate_data)?;
let bindgen_version = lockfile.require_wasm_bindgen()?;
// Unlike `wasm-bindgen` and `wasm-bindgen-cli`, `wasm-bindgen-test`
@ -279,13 +262,12 @@ impl Test {
// `wasm32-unkown-unknown`. Don't enforce that it is the same version as
// `wasm-bindgen`.
if lockfile.wasm_bindgen_test_version().is_none() {
let message = format!(
bail!(
"Ensure that you have \"{}\" as a dependency in your Cargo.toml file:\n\
[dev-dependencies]\n\
wasm-bindgen-test = \"0.2\"",
style("wasm-bindgen-test").bold().dim(),
);
return Err(Error::CrateConfig { message }.into());
)
}
let install_permitted = match self.mode {
@ -303,22 +285,21 @@ impl Test {
}
};
bindgen::install_wasm_bindgen(
&self.crate_path,
let dl = bindgen::install_wasm_bindgen(
&self.cache,
&bindgen_version,
install_permitted,
step,
log,
)?;
self.test_runner_path = Some(bindgen::wasm_bindgen_test_runner_path(log, &self.crate_path)
.expect("if installing wasm-bindgen succeeded, then we should have wasm-bindgen-test-runner too"));
self.test_runner_path = Some(dl.binary("wasm-bindgen-test-runner"));
info!(&log, "Getting wasm-bindgen-cli was successful.");
Ok(())
}
fn step_test_node(&mut self, step: &Step, log: &Logger) -> Result<(), failure::Error> {
fn step_test_node(&mut self, step: &Step, log: &Logger) -> Result<(), Error> {
assert!(self.node);
info!(log, "Running tests in node...");
PBAR.step(step, "Running tests in node...");
@ -335,19 +316,18 @@ impl Test {
Ok(())
}
fn step_get_chromedriver(&mut self, step: &Step, log: &Logger) -> Result<(), failure::Error> {
fn step_get_chromedriver(&mut self, step: &Step, _log: &Logger) -> Result<(), Error> {
PBAR.step(step, "Getting chromedriver...");
assert!(self.chrome && self.chromedriver.is_none());
self.chromedriver = Some(webdriver::get_or_install_chromedriver(
log,
&self.crate_path,
&self.cache,
self.mode,
)?);
Ok(())
}
fn step_test_chrome(&mut self, step: &Step, log: &Logger) -> Result<(), failure::Error> {
fn step_test_chrome(&mut self, step: &Step, log: &Logger) -> Result<(), Error> {
PBAR.step(step, "Running tests in Chrome...");
let chromedriver = self.chromedriver.as_ref().unwrap().display().to_string();
@ -378,19 +358,18 @@ impl Test {
Ok(())
}
fn step_get_geckodriver(&mut self, step: &Step, log: &Logger) -> Result<(), failure::Error> {
fn step_get_geckodriver(&mut self, step: &Step, _log: &Logger) -> Result<(), Error> {
PBAR.step(step, "Getting geckodriver...");
assert!(self.firefox && self.geckodriver.is_none());
self.geckodriver = Some(webdriver::get_or_install_geckodriver(
log,
&self.crate_path,
&self.cache,
self.mode,
)?);
Ok(())
}
fn step_test_firefox(&mut self, step: &Step, log: &Logger) -> Result<(), failure::Error> {
fn step_test_firefox(&mut self, step: &Step, log: &Logger) -> Result<(), Error> {
PBAR.step(step, "Running tests in Firefox...");
let geckodriver = self.geckodriver.as_ref().unwrap().display().to_string();
@ -421,15 +400,15 @@ impl Test {
Ok(())
}
fn step_get_safaridriver(&mut self, step: &Step, log: &Logger) -> Result<(), failure::Error> {
fn step_get_safaridriver(&mut self, step: &Step, _log: &Logger) -> Result<(), Error> {
PBAR.step(step, "Getting safaridriver...");
assert!(self.safari && self.safaridriver.is_none());
self.safaridriver = Some(webdriver::get_safaridriver(log, &self.crate_path)?);
self.safaridriver = Some(webdriver::get_safaridriver()?);
Ok(())
}
fn step_test_safari(&mut self, step: &Step, log: &Logger) -> Result<(), failure::Error> {
fn step_test_safari(&mut self, step: &Step, log: &Logger) -> Result<(), Error> {
PBAR.step(step, "Running tests in Safari...");
let safaridriver = self.safaridriver.as_ref().unwrap().display().to_string();

@ -4,19 +4,13 @@ use emoji;
use failure;
use progressbar::Step;
use std::fs;
use std::io;
use std::path::{Path, PathBuf};
use PBAR;
/// If an explicit path is given, then use it, otherwise assume the current
/// directory is the crate path.
pub fn set_crate_path(path: Option<PathBuf>) -> io::Result<PathBuf> {
let crate_path = match path {
Some(p) => p,
None => PathBuf::from("."),
};
crate_path.canonicalize()
pub fn set_crate_path(path: Option<PathBuf>) -> Result<PathBuf, failure::Error> {
Ok(path.unwrap_or(PathBuf::from(".")))
}
/// Construct our `pkg` directory in the crate.

@ -1,240 +0,0 @@
//! Code related to error handling for wasm-pack
use curl;
use serde_json;
use std::borrow::Cow;
use std::io;
use std::process::ExitStatus;
use toml;
use zip;
/// Errors that can potentially occur in `wasm-pack`.
#[derive(Debug, Fail)]
pub enum Error {
/// Maps any underlying I/O errors that are thrown to this variant
#[fail(display = "{}", _0)]
Io(#[cause] io::Error),
/// A JSON serialization or deserialization error.
#[fail(display = "{}", _0)]
SerdeJson(#[cause] serde_json::Error),
/// A TOML serialization or deserialization error.
#[fail(display = "{}", _0)]
SerdeToml(#[cause] toml::de::Error),
#[fail(display = "{}", _0)]
/// A curl error.
Curl(#[cause] curl::Error),
#[fail(display = "{}", _0)]
/// An error handling zip archives.
Zip(#[cause] zip::result::ZipError),
#[fail(display = "{}", _0)]
/// An error in parsing your rustc version.
RustcMissing {
/// Error message
message: String,
},
#[fail(display = "{}", _0)]
/// An error from having an unsupported rustc version.
RustcVersion {
/// Error message
message: String,
/// The minor version of the local rust
local_minor_version: String,
},
#[fail(display = "{}", _0)]
/// An error in parsing your wasm-pack version.
WasmPackMissing {
/// Error message
message: String,
},
#[fail(display = "{}", _0)]
/// An error from having an older wasm-pack version.
WasmPackVersion {
/// Error message
message: String,
/// Local version of wasm-pack
local_version: String,
/// Latest version of wasm-pack
latest_version: String,
},
/// An error invoking another CLI tool.
#[fail(
display = "Process exited with {}: {}.\n\nstdout:{}\n\nstderr:\n\n{}",
exit_status,
message,
stdout,
stderr
)]
Cli {
/// Error message.
message: String,
/// The underlying CLI's `stdout` output.
stdout: String,
/// The underlying CLI's `stderr` output.
stderr: String,
/// The exit status of the subprocess
exit_status: ExitStatus,
},
/// A crate configuration error.
#[fail(display = "{}", message)]
CrateConfig {
/// A message describing the configuration error.
message: String,
},
#[fail(display = "{}", message)]
/// Error when the 'pkg' directory is not found.
PkgNotFound {
/// Message describing the error.
message: String,
},
#[fail(display = "{}", message)]
/// An error related to an archive that we downloaded.
Archive {
/// Error message.
message: String,
},
#[fail(display = "{}", message)]
/// Error when some operation or feature is unsupported for the current
/// target or environment.
Unsupported {
/// Error message.
message: String,
},
#[fail(display = "{}", message)]
/// Error related to some HTTP request.
Http {
/// Error message.
message: String,
},
}
impl Error {
/// Construct a CLI error.
pub fn cli(message: &str, stdout: Cow<str>, stderr: Cow<str>, exit_status: ExitStatus) -> Self {
Error::Cli {
message: message.to_string(),
stdout: stdout.to_string(),
stderr: stderr.to_string(),
exit_status,
}
}
/// Construct a crate configuration error.
pub fn crate_config(message: &str) -> Self {
Error::CrateConfig {
message: message.to_string(),
}
}
/// Construct an archive error.
pub fn archive(message: &str) -> Self {
Error::Archive {
message: message.to_string(),
}
}
/// Construct an unsupported error.
pub fn unsupported(message: &str) -> Self {
Error::Unsupported {
message: message.to_string(),
}
}
/// Construct an http error.
pub fn http(message: &str) -> Self {
Error::Http {
message: message.to_string(),
}
}
/// Construct a rustc version error.
pub fn rustc_version_error(message: &str, local_version: &str) -> Self {
Error::RustcVersion {
message: message.to_string(),
local_minor_version: local_version.to_string(),
}
}
/// Get a string description of this error's type.
pub fn error_type(&self) -> String {
match self {
Error::Io(_) => "There was an I/O error. Details:\n\n",
Error::SerdeJson(_) => "There was an JSON error. Details:\n\n",
Error::SerdeToml(_) => "There was an TOML error. Details:\n\n",
Error::Zip(_) => "There was an error handling zip files. Details:\n\n",
Error::RustcMissing {
message: _,
} => "We can't figure out what your Rust version is- which means you might not have Rust installed. Please install Rust version 1.30.0 or higher.",
Error::RustcVersion {
message: _,
local_minor_version: _,
} => "Your rustc version is not supported. Please install version 1.30.0 or higher.",
Error::WasmPackMissing {
message: _,
} => "We can't figure out what your wasm-pack version is, make sure the installation path is correct.",
Error::WasmPackVersion {
message: _,
local_version: _,
latest_version: _,
} => "There's a newer version of wasm-pack available, the new version is: , you are using: ",
Error::Cli {
message: _,
stdout: _,
stderr: _,
exit_status: _,
} => "There was an error while calling another CLI tool. Details:\n\n",
Error::CrateConfig { message: _ } => {
"There was a crate configuration error. Details:\n\n"
}
Error::PkgNotFound {
message: _,
} => "Unable to find the 'pkg' directory at the path, set the path as the parent of the 'pkg' directory \n\n",
Error::Curl(_) => "There was an error making an HTTP request with curl. Details:\n\n",
Error::Archive {..} => "There was an error related to an archive file. Details:\n\n",
Error::Unsupported {..} => "There was an unsupported operation attempted. Details:\n\n",
Error::Http {..} => "There wasn an HTTP error. Details:\n\n",
}.to_string()
}
}
impl From<io::Error> for Error {
fn from(e: io::Error) -> Self {
Error::Io(e)
}
}
impl From<curl::Error> for Error {
fn from(e: curl::Error) -> Self {
Error::Curl(e)
}
}
impl From<serde_json::Error> for Error {
fn from(e: serde_json::Error) -> Self {
Error::SerdeJson(e)
}
}
impl From<zip::result::ZipError> for Error {
fn from(e: zip::result::ZipError) -> Self {
Error::Zip(e)
}
}
impl From<toml::de::Error> for Error {
fn from(e: toml::de::Error) -> Self {
Error::SerdeToml(e)
}
}

@ -5,20 +5,25 @@
extern crate cargo_metadata;
extern crate console;
extern crate curl;
extern crate dirs;
#[macro_use]
extern crate failure;
extern crate flate2;
extern crate hex;
extern crate indicatif;
#[macro_use]
extern crate lazy_static;
extern crate parking_lot;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate siphasher;
#[macro_use]
extern crate structopt;
#[macro_use]
extern crate slog;
extern crate chrono;
extern crate slog_async;
extern crate slog_term;
extern crate tar;
@ -32,7 +37,6 @@ pub mod build;
pub mod child;
pub mod command;
pub mod emoji;
pub mod error;
pub mod lockfile;
pub mod logger;
pub mod manifest;

@ -1,11 +1,11 @@
//! Reading Cargo.lock lock file.
use std::fs;
use std::path::{Path, PathBuf};
use std::path::PathBuf;
use cargo_metadata;
use console::style;
use error::Error;
use failure::{Error, ResultExt};
use manifest::CrateData;
use toml;
/// This struct represents the contents of `Cargo.lock`.
@ -23,10 +23,13 @@ struct Package {
impl Lockfile {
/// Read the `Cargo.lock` file for the crate at the given path.
pub fn new(crate_path: &Path) -> Result<Lockfile, failure::Error> {
let lock_path = get_lockfile_path(crate_path)?;
let lockfile = fs::read_to_string(lock_path)?;
toml::from_str(&lockfile).map_err(|err| Error::from(err).into())
pub fn new(crate_data: &CrateData) -> Result<Lockfile, Error> {
let lock_path = get_lockfile_path(crate_data)?;
let lockfile = fs::read_to_string(&lock_path)
.with_context(|_| format!("failed to read: {}", lock_path.display()))?;
let lockfile = toml::from_str(&lockfile)
.with_context(|_| format!("failed to parse: {}", lock_path.display()))?;
Ok(lockfile)
}
/// Get the version of `wasm-bindgen` dependency used in the `Cargo.lock`.
@ -36,15 +39,14 @@ impl Lockfile {
/// Like `wasm_bindgen_version`, except it returns an error instead of
/// `None`.
pub fn require_wasm_bindgen(&self) -> Result<&str, failure::Error> {
pub fn require_wasm_bindgen(&self) -> Result<&str, Error> {
self.wasm_bindgen_version().ok_or_else(|| {
let message = format!(
format_err!(
"Ensure that you have \"{}\" as a dependency in your Cargo.toml file:\n\
[dependencies]\n\
wasm-bindgen = \"0.2\"",
style("wasm-bindgen").bold().dim(),
);
Error::CrateConfig { message }.into()
)
})
}
@ -63,22 +65,12 @@ impl Lockfile {
/// 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.
fn get_lockfile_path(crate_path: &Path) -> Result<PathBuf, failure::Error> {
// Identify the crate's root directory, or return an error.
let manifest = crate_path.join("Cargo.toml");
let crate_root = cargo_metadata::metadata(Some(&manifest))
.map_err(|_| Error::CrateConfig {
message: String::from("Error while processing crate metadata"),
})?
.workspace_root;
fn get_lockfile_path(crate_data: &CrateData) -> Result<PathBuf, Error> {
// Check that a lock file can be found in the directory. Return an error
// if it cannot, otherwise return the path buffer.
let lockfile_path = Path::new(&crate_root).join("Cargo.lock");
let lockfile_path = crate_data.workspace_root().join("Cargo.lock");
if !lockfile_path.is_file() {
Err(Error::CrateConfig {
message: format!("Could not find lockfile at {:?}", lockfile_path),
}
.into())
bail!("Could not find lockfile at {:?}", lockfile_path)
} else {
Ok(lockfile_path)
}

@ -16,7 +16,7 @@ mod installer;
fn main() {
setup_panic!();
if let Err(e) = run() {
eprintln!("{}", e);
eprintln!("Error: {}", e);
for cause in e.iter_causes() {
eprintln!("Caused by: {}", cause);
}

@ -2,24 +2,34 @@
mod npm;
use std::collections::HashMap;
use std::fs::File;
use std::io::prelude::*;
use std::fs;
use std::path::Path;
use self::npm::{
repository::Repository, CommonJSPackage, ESModulesPackage, NoModulesPackage, NpmPackage,
};
use cargo_metadata::Metadata;
use chrono::offset;
use chrono::DateTime;
use command::build::BuildProfile;
use curl::easy;
use emoji;
use error::Error;
use failure;
use failure::{Error, ResultExt};
use progressbar::Step;
use serde::{self, Deserialize};
use serde_json;
use std::io::Write;
use toml;
use which;
use PBAR;
/// Store for metadata learned about a crate
pub struct CrateData {
data: Metadata,
current_idx: usize,
manifest: CargoManifest,
}
struct Collector(Vec<u8>);
impl easy::Handler for Collector {
@ -29,66 +39,86 @@ impl easy::Handler for Collector {
}
}
#[derive(Debug, Deserialize)]
#[derive(Deserialize)]
struct CargoManifest {
package: CargoPackage,
dependencies: Option<HashMap<String, CargoDependency>>,
#[serde(rename = "dev-dependencies")]
dev_dependencies: Option<HashMap<String, CargoDependency>>,
lib: Option<CargoLib>,
}
#[derive(Debug, Deserialize)]
#[derive(Deserialize)]
struct CargoPackage {
name: String,
authors: Vec<String>,
description: Option<String>,
version: String,
license: Option<String>,
repository: Option<String>,
#[serde(default)]
metadata: CargoMetadata,
}
impl CargoPackage {
fn check_optional_fields(&self) {
let mut messages = vec![];
if self.description.is_none() {
messages.push("description");
}
if self.repository.is_none() {
messages.push("repository");
}
if self.license.is_none() {
messages.push("license");
}
#[derive(Default, Deserialize)]
struct CargoMetadata {
#[serde(default, rename = "wasm-pack")]
wasm_pack: CargoWasmPack,
}
match messages.len() {
1 => PBAR.info(&format!("Optional field missing from Cargo.toml: '{}'. This is not necessary, but recommended", messages[0])),
2 => PBAR.info(&format!("Optional fields missing from Cargo.toml: '{}', '{}'. These are not necessary, but recommended", messages[0], messages[1])),
3 => PBAR.info(&format!("Optional fields missing from Cargo.toml: '{}', '{}', and '{}'. These are not necessary, but recommended", messages[0], messages[1], messages[2])),
_ => ()
};
}
#[derive(Default, Deserialize)]
struct CargoWasmPack {
#[serde(default)]
profile: CargoWasmPackProfiles,
}
#[derive(Debug, Deserialize)]
#[serde(untagged)]
enum CargoDependency {
Simple(String),
Detailed(DetailedCargoDependency),
#[derive(Deserialize)]
struct CargoWasmPackProfiles {
#[serde(
default = "CargoWasmPackProfile::default_dev",
deserialize_with = "CargoWasmPackProfile::deserialize_dev"
)]
dev: CargoWasmPackProfile,
#[serde(
default = "CargoWasmPackProfile::default_release",
deserialize_with = "CargoWasmPackProfile::deserialize_release"
)]
release: CargoWasmPackProfile,
#[serde(
default = "CargoWasmPackProfile::default_profiling",
deserialize_with = "CargoWasmPackProfile::deserialize_profiling"
)]
profiling: CargoWasmPackProfile,
}
#[derive(Debug, Deserialize)]
struct DetailedCargoDependency {
version: Option<String>,
impl Default for CargoWasmPackProfiles {
fn default() -> CargoWasmPackProfiles {
CargoWasmPackProfiles {
dev: CargoWasmPackProfile::default_dev(),
release: CargoWasmPackProfile::default_release(),
profiling: CargoWasmPackProfile::default_profiling(),
}
}
}
#[derive(Debug, Deserialize)]
struct CargoLib {
#[serde(rename = "crate-type")]
crate_type: Option<Vec<String>>,
/// This is where configuration goes for wasm-bindgen, wasm-opt, wasm-snip, or
/// anything else that wasm-pack runs.
#[derive(Default, Deserialize)]
pub struct CargoWasmPackProfile {
#[serde(default, rename = "wasm-bindgen")]
wasm_bindgen: CargoWasmPackProfileWasmBindgen,
}
/// Struct for crates.io api, currently checking wasm-pack latest version
#[derive(Default, Deserialize)]
struct CargoWasmPackProfileWasmBindgen {
#[serde(default, rename = "debug-js-glue")]
debug_js_glue: Option<bool>,
#[serde(default, rename = "demangle-name-section")]
demangle_name_section: Option<bool>,
#[serde(default, rename = "dwarf-debug-info")]
dwarf_debug_info: Option<bool>,
}
/// Struct for crate which is received from crates.io
#[derive(Deserialize, Debug)]
pub struct Crate {
#[serde(rename = "crate")]
@ -101,209 +131,464 @@ struct CrateInformation {
}
impl Crate {
/// Call to the crates.io api and return the latest version of `wasm-pack`
pub fn return_wasm_pack_latest_version() -> String {
let crt = Crate::check_wasm_pack_latest_version();
crt.crt.max_version
/// Returns latest wasm-pack version
pub fn return_wasm_pack_latest_version() -> Option<String> {
let current_time = chrono::offset::Local::now();
if let Some(contents) = Crate::return_wasm_pack_file() {
let (created, version) = Crate::return_stamp_file_values(&contents);
if current_time.signed_duration_since(created).num_hours() > 24 {
return Crate::return_api_call_result(current_time);
} else {
return Some(version);
}
} else {
return Crate::return_api_call_result(current_time);
}
}
fn check_wasm_pack_latest_version() -> Crate {
let mut easy = easy::Easy2::new(Collector(Vec::new()));
easy.get(true).unwrap();
easy.url("https://crates.io/api/v1/crates/wasm-pack")
fn return_api_call_result(current_time: DateTime<offset::Local>) -> Option<String> {
match Crate::call_for_wasm_pack_version() {
Some(version) => {
Crate::override_stamp_file(current_time, &version);
return Some(version);
}
None => return None,
}
}
fn override_stamp_file(current_time: DateTime<offset::Local>, version: &String) {
if let Ok(path) = which::which("wasm-pack") {
let file = fs::OpenOptions::new()
.read(true)
.write(true)
.append(true)
.create(true)
.open(path.with_extension("stamp"));
if let Ok(()) = file.as_ref().unwrap().set_len(0) {
if let Err(_) = write!(
file.unwrap(),
"created {:?}\nversion {}",
current_time,
version
) {}
}
}
}
fn return_wasm_pack_file() -> Option<String> {
if let Ok(path) = which::which("wasm-pack") {
if let Ok(file) = fs::read_to_string(path.with_extension("stamp")) {
return Some(file);
}
return None;
}
None
}
fn call_for_wasm_pack_version() -> Option<String> {
if let Ok(crt) = Crate::check_wasm_pack_latest_version() {
return Some(crt.crt.max_version);
}
None
}
fn return_stamp_file_values(file: &String) -> (DateTime<offset::FixedOffset>, String) {
let created = file
.lines()
.find(|line| line.starts_with("created"))
.unwrap()
.split_whitespace()
.nth(1)
.unwrap();
easy.perform().unwrap();
let last_updated = DateTime::parse_from_str(created, "%+").unwrap();
let version = file
.lines()
.find(|line| line.starts_with("version"))
.unwrap()
.split_whitespace()
.nth(1)
.unwrap()
.to_string();
(last_updated, version)
}
/// Call to the crates.io api and return the latest version of `wasm-pack`
fn check_wasm_pack_latest_version() -> Result<Crate, Error> {
let mut easy = easy::Easy2::new(Collector(Vec::new()));
easy.get(true)?;
easy.url("https://crates.io/api/v1/crates/wasm-pack")?;
easy.perform()?;
let contents = easy.get_ref();
let result = String::from_utf8_lossy(&contents.0);
Ok(serde_json::from_str(result.into_owned().as_str())?)
}
}
impl CargoWasmPackProfile {
fn default_dev() -> Self {
CargoWasmPackProfile {
wasm_bindgen: CargoWasmPackProfileWasmBindgen {
debug_js_glue: Some(true),
demangle_name_section: Some(true),
dwarf_debug_info: Some(false),
},
}
}
fn default_release() -> Self {
CargoWasmPackProfile {
wasm_bindgen: CargoWasmPackProfileWasmBindgen {
debug_js_glue: Some(false),
demangle_name_section: Some(true),
dwarf_debug_info: Some(false),
},
}
}
fn default_profiling() -> Self {
CargoWasmPackProfile {
wasm_bindgen: CargoWasmPackProfileWasmBindgen {
debug_js_glue: Some(false),
demangle_name_section: Some(true),
dwarf_debug_info: Some(false),
},
}
}
fn deserialize_dev<'de, D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let mut profile = <Option<Self>>::deserialize(deserializer)?.unwrap_or_default();
profile.update_with_defaults(Self::default_dev());
Ok(profile)
}
fn deserialize_release<'de, D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let mut profile = <Option<Self>>::deserialize(deserializer)?.unwrap_or_default();
profile.update_with_defaults(Self::default_release());
Ok(profile)
}
fn deserialize_profiling<'de, D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let mut profile = <Option<Self>>::deserialize(deserializer)?.unwrap_or_default();
profile.update_with_defaults(Self::default_profiling());
Ok(profile)
}
fn update_with_defaults(&mut self, defaults: Self) {
macro_rules! d {
( $( $path:ident ).* ) => {
self. $( $path ).* .get_or_insert(defaults. $( $path ).* .unwrap());
}
}
d!(wasm_bindgen.debug_js_glue);
d!(wasm_bindgen.demangle_name_section);
d!(wasm_bindgen.dwarf_debug_info);
}
/// Get this profile's configured `[wasm-bindgen.debug-js-glue]` value.
pub fn wasm_bindgen_debug_js_glue(&self) -> bool {
self.wasm_bindgen.debug_js_glue.unwrap()
}
serde_json::from_str(result.into_owned().as_str()).unwrap()
/// Get this profile's configured `[wasm-bindgen.demangle-name-section]` value.
pub fn wasm_bindgen_demangle_name_section(&self) -> bool {
self.wasm_bindgen.demangle_name_section.unwrap()
}
/// Get this profile's configured `[wasm-bindgen.dwarf-debug-info]` value.
pub fn wasm_bindgen_dwarf_debug_info(&self) -> bool {
self.wasm_bindgen.dwarf_debug_info.unwrap()
}
}
fn read_cargo_toml(path: &Path) -> Result<CargoManifest, failure::Error> {
let manifest_path = path.join("Cargo.toml");
if !manifest_path.is_file() {
return Err(Error::crate_config(&format!(
"Crate directory is missing a `Cargo.toml` file; is `{}` the wrong directory?",
path.display()
))
.into());
}
let mut cargo_file = File::open(manifest_path)?;
let mut cargo_contents = String::new();
cargo_file.read_to_string(&mut cargo_contents)?;
let manifest: CargoManifest = toml::from_str(&cargo_contents)?;
Ok(manifest)
struct NpmData {
name: String,
files: Vec<String>,
dts_file: Option<String>,
main: String,
}
impl CargoManifest {
fn into_commonjs(mut self, scope: &Option<String>, disable_dts: bool) -> NpmPackage {
let filename = self.package.name.replace("-", "_");
let wasm_file = format!("{}_bg.wasm", filename);
let js_file = format!("{}.js", filename);
let mut files = vec![wasm_file];
impl CrateData {
/// Reads all metadata for the crate whose manifest is inside the directory
/// specified by `path`.
pub fn new(crate_path: &Path) -> Result<CrateData, Error> {
let manifest_path = crate_path.join("Cargo.toml");
if !manifest_path.is_file() {
bail!(
"crate directory is missing a `Cargo.toml` file; is `{}` the \
wrong directory?",
crate_path.display()
)
}
let manifest = fs::read_to_string(&manifest_path)
.with_context(|_| format!("failed to read: {}", manifest_path.display()))?;
let manifest: CargoManifest = toml::from_str(&manifest)
.with_context(|_| format!("failed to parse manifest: {}", manifest_path.display()))?;
let data =
cargo_metadata::metadata(Some(&manifest_path)).map_err(error_chain_to_failure)?;
let current_idx = data
.packages
.iter()
.position(|pkg| pkg.name == manifest.package.name)
.ok_or_else(|| format_err!("failed to find package in metadata"))?;
return Ok(CrateData {
data,
manifest,
current_idx,
});
fn error_chain_to_failure(err: cargo_metadata::Error) -> Error {
let errors = err.iter().collect::<Vec<_>>();
let mut err: Error = match errors.last() {
Some(e) => format_err!("{}", e),
None => return format_err!("{}", err),
};
for e in errors[..errors.len() - 1].iter().rev() {
err = err.context(e.to_string()).into();
}
return err;
}
}
/// Get the configured profile.
pub fn configured_profile(&self, profile: BuildProfile) -> &CargoWasmPackProfile {
match profile {
BuildProfile::Dev => &self.manifest.package.metadata.wasm_pack.profile.dev,
BuildProfile::Profiling => &self.manifest.package.metadata.wasm_pack.profile.profiling,
BuildProfile::Release => &self.manifest.package.metadata.wasm_pack.profile.release,
}
}
let js_bg_file = format!("{}_bg.js", filename);
files.push(js_bg_file.to_string());
/// Check that the crate the given path is properly configured.
pub fn check_crate_config(&self, step: &Step) -> Result<(), Error> {
let msg = format!("{}Checking crate configuration...", emoji::WRENCH);
PBAR.step(&step, &msg);
self.check_crate_type()?;
Ok(())
}
if let Some(s) = scope {
self.package.name = format!("@{}/{}", s, self.package.name);
fn check_crate_type(&self) -> Result<(), Error> {
let pkg = &self.data.packages[self.current_idx];
let any_cdylib = pkg
.targets
.iter()
.filter(|target| target.kind.iter().any(|k| k == "cdylib"))
.any(|target| target.crate_types.iter().any(|s| s == "cdylib"));
if any_cdylib {
return Ok(());
}
bail!(
"crate-type must be cdylib to compile to wasm32-unknown-unknown. Add the following to your \
Cargo.toml file:\n\n\
[lib]\n\
crate-type = [\"cdylib\", \"rlib\"]"
)
}
let dts_file = if disable_dts == false {
let file = format!("{}.d.ts", filename);
files.push(file.to_string());
Some(file)
/// Get the crate name for the crate at the given path.
pub fn crate_name(&self) -> String {
let pkg = &self.data.packages[self.current_idx];
match pkg
.targets
.iter()
.find(|t| t.kind.iter().any(|k| k == "cdylib"))
{
Some(lib) => lib.name.replace("-", "_"),
None => pkg.name.replace("-", "_"),
}
}
/// Returns the path to this project's target directory where artifacts are
/// located after a cargo build.
pub fn target_directory(&self) -> &Path {
Path::new(&self.data.target_directory)
}
/// Returns the path to this project's root cargo workspace directory
pub fn workspace_root(&self) -> &Path {
Path::new(&self.data.workspace_root)
}
/// Generate a package.json file inside in `./pkg`.
pub fn write_package_json(
&self,
out_dir: &Path,
scope: &Option<String>,
disable_dts: bool,
target: &str,
step: &Step,
) -> Result<(), Error> {
let msg = format!("{}Writing a package.json...", emoji::MEMO);
PBAR.step(step, &msg);
let pkg_file_path = out_dir.join("package.json");
let npm_data = if target == "nodejs" {
self.to_commonjs(scope, disable_dts)
} else if target == "no-modules" {
self.to_nomodules(scope, disable_dts)
} else {
None
self.to_esmodules(scope, disable_dts)
};
&self.package.check_optional_fields();
NpmPackage::CommonJSPackage(CommonJSPackage {
name: self.package.name,
collaborators: self.package.authors,
description: self.package.description,
version: self.package.version,
license: self.package.license,
repository: self.package.repository.map(|repo_url| Repository {
ty: "git".to_string(),
url: repo_url,
}),
files: files,
main: js_file,
types: dts_file,
})
let npm_json = serde_json::to_string_pretty(&npm_data)?;
fs::write(&pkg_file_path, npm_json)
.with_context(|_| format!("failed to write: {}", pkg_file_path.display()))?;
Ok(())
}
fn into_esmodules(mut self, scope: &Option<String>, disable_dts: bool) -> NpmPackage {
let filename = self.package.name.replace("-", "_");
let wasm_file = format!("{}_bg.wasm", filename);
let js_file = format!("{}.js", filename);
let mut files = vec![wasm_file, js_file.clone()];
fn npm_data(
&self,
scope: &Option<String>,
include_commonjs_shim: bool,
disable_dts: bool,
) -> NpmData {
let crate_name = self.crate_name();
let wasm_file = format!("{}_bg.wasm", crate_name);
let js_file = format!("{}.js", crate_name);
let mut files = vec![wasm_file];
let dts_file = if disable_dts == false {
let file = format!("{}.d.ts", filename);
files.push(js_file.clone());
if include_commonjs_shim {
let js_bg_file = format!("{}_bg.js", crate_name);
files.push(js_bg_file.to_string());
}
let pkg = &self.data.packages[self.current_idx];
let npm_name = match scope {
Some(s) => format!("@{}/{}", s, pkg.name),
None => pkg.name.clone(),
};
let dts_file = if !disable_dts {
let file = format!("{}.d.ts", crate_name);
files.push(file.to_string());
Some(file)
} else {
None
};
if let Some(s) = scope {
self.package.name = format!("@{}/{}", s, self.package.name);
NpmData {
name: npm_name,
dts_file,
files,
main: js_file,
}
}
&self.package.check_optional_fields();
fn to_commonjs(&self, scope: &Option<String>, disable_dts: bool) -> NpmPackage {
let data = self.npm_data(scope, true, disable_dts);
let pkg = &self.data.packages[self.current_idx];
NpmPackage::ESModulesPackage(ESModulesPackage {
name: self.package.name,
collaborators: self.package.authors,
description: self.package.description,
version: self.package.version,
license: self.package.license,
repository: self.package.repository.map(|repo_url| Repository {
ty: "git".to_string(),
url: repo_url,
}),
files: files,
module: js_file,
types: dts_file,
side_effects: "false".to_string(),
self.check_optional_fields();
NpmPackage::CommonJSPackage(CommonJSPackage {
name: data.name,
collaborators: pkg.authors.clone(),
description: self.manifest.package.description.clone(),
version: pkg.version.clone(),
license: self.manifest.package.license.clone(),
repository: self
.manifest
.package
.repository
.clone()
.map(|repo_url| Repository {
ty: "git".to_string(),
url: repo_url,
}),
files: data.files,
main: data.main,
types: data.dts_file,
})
}
fn into_nomodules(mut self, scope: &Option<String>, disable_dts: bool) -> NpmPackage {
let filename = self.package.name.replace("-", "_");
let wasm_file = format!("{}_bg.wasm", filename);
let js_file = format!("{}.js", filename);
let mut files = vec![wasm_file, js_file.clone()];
fn to_esmodules(&self, scope: &Option<String>, disable_dts: bool) -> NpmPackage {
let data = self.npm_data(scope, false, disable_dts);
let pkg = &self.data.packages[self.current_idx];
let dts_file = if disable_dts == false {
let file = format!("{}.d.ts", filename);
files.push(file.to_string());
Some(file)
} else {
None
};
self.check_optional_fields();
if let Some(s) = scope {
self.package.name = format!("@{}/{}", s, self.package.name);
}
NpmPackage::ESModulesPackage(ESModulesPackage {
name: data.name,
collaborators: pkg.authors.clone(),
description: self.manifest.package.description.clone(),
version: pkg.version.clone(),
license: self.manifest.package.license.clone(),
repository: self
.manifest
.package
.repository
.clone()
.map(|repo_url| Repository {
ty: "git".to_string(),
url: repo_url,
}),
files: data.files,
module: data.main,
types: data.dts_file,
side_effects: "false".to_string(),
})
}
fn to_nomodules(&self, scope: &Option<String>, disable_dts: bool) -> NpmPackage {
let data = self.npm_data(scope, false, disable_dts);
let pkg = &self.data.packages[self.current_idx];
&self.package.check_optional_fields();
self.check_optional_fields();
NpmPackage::NoModulesPackage(NoModulesPackage {
name: self.package.name,
collaborators: self.package.authors,
description: self.package.description,
version: self.package.version,
license: self.package.license,
repository: self.package.repository.map(|repo_url| Repository {
ty: "git".to_string(),
url: repo_url,
}),
files: files,
browser: js_file,
types: dts_file,
name: data.name,
collaborators: pkg.authors.clone(),
description: self.manifest.package.description.clone(),
version: pkg.version.clone(),
license: self.manifest.package.license.clone(),
repository: self
.manifest
.package
.repository
.clone()
.map(|repo_url| Repository {
ty: "git".to_string(),
url: repo_url,
}),
files: data.files,
browser: data.main,
types: data.dts_file,
})
}
}
/// Generate a package.json file inside in `./pkg`.
pub fn write_package_json(
path: &Path,
out_dir: &Path,
scope: &Option<String>,
disable_dts: bool,
target: &str,
step: &Step,
) -> Result<(), failure::Error> {
let msg = format!("{}Writing a package.json...", emoji::MEMO);
PBAR.step(step, &msg);
let pkg_file_path = out_dir.join("package.json");
let mut pkg_file = File::create(pkg_file_path)?;
let crate_data = read_cargo_toml(path)?;
let npm_data = if target == "nodejs" {
crate_data.into_commonjs(scope, disable_dts)
} else if target == "no-modules" {
crate_data.into_nomodules(scope, disable_dts)
} else {
crate_data.into_esmodules(scope, disable_dts)
};
let npm_json = serde_json::to_string_pretty(&npm_data)?;
pkg_file.write_all(npm_json.as_bytes())?;
Ok(())
}
/// Get the crate name for the crate at the given path.
pub fn get_crate_name(path: &Path) -> Result<String, failure::Error> {
Ok(read_cargo_toml(path)?.package.name)
}
/// Check that the crate the given path is properly configured.
pub fn check_crate_config(path: &Path, step: &Step) -> Result<(), failure::Error> {
let msg = format!("{}Checking crate configuration...", emoji::WRENCH);
PBAR.step(&step, &msg);
check_crate_type(path)?;
Ok(())
}
fn check_optional_fields(&self) {
let mut messages = vec![];
if self.manifest.package.description.is_none() {
messages.push("description");
}
if self.manifest.package.repository.is_none() {
messages.push("repository");
}
if self.manifest.package.license.is_none() {
messages.push("license");
}
fn check_crate_type(path: &Path) -> Result<(), failure::Error> {
if read_cargo_toml(path)?.lib.map_or(false, |lib| {
lib.crate_type
.map_or(false, |types| types.iter().any(|s| s == "cdylib"))
}) {
return Ok(());
}
Err(Error::crate_config(
"crate-type must be cdylib to compile to wasm32-unknown-unknown. Add the following to your \
Cargo.toml file:\n\n\
[lib]\n\
crate-type = [\"cdylib\", \"rlib\"]"
).into())
match messages.len() {
1 => PBAR.info(&format!("Optional field missing from Cargo.toml: '{}'. This is not necessary, but recommended", messages[0])),
2 => PBAR.info(&format!("Optional fields missing from Cargo.toml: '{}', '{}'. These are not necessary, but recommended", messages[0], messages[1])),
3 => PBAR.info(&format!("Optional fields missing from Cargo.toml: '{}', '{}', and '{}'. These are not necessary, but recommended", messages[0], messages[1], messages[2])),
_ => ()
};
}
}

@ -22,12 +22,6 @@ where
K: AsRef<OsStr>,
V: AsRef<OsStr>,
{
use std::sync::Mutex;
lazy_static! {
static ref ONE_TEST_AT_A_TIME: Mutex<()> = Mutex::new(());
}
let _locked = ONE_TEST_AT_A_TIME.lock().unwrap();
let output = {
let mut cmd = Command::new("cargo");
cmd.envs(envs);

@ -1,40 +1,32 @@
//! Getting WebDriver client binaries.
use binaries::{
self, bin_path, install_binaries_from_targz_at_url, install_binaries_from_zip_at_url,
};
use binaries::Cache;
use command::build::BuildMode;
use error::Error;
use failure;
use slog::Logger;
use std::path::{Path, PathBuf};
use std::path::PathBuf;
use target;
/// Get the path to an existing `chromedriver`, or install it if no existing
/// binary is found.
pub fn get_or_install_chromedriver(
log: &Logger,
crate_path: &Path,
cache: &Cache,
mode: BuildMode,
) -> Result<PathBuf, failure::Error> {
match (mode, bin_path(log, crate_path, "chromedriver")) {
(_, Some(path)) => Ok(path),
(BuildMode::Normal, None) => install_chromedriver(crate_path),
(BuildMode::Force, None) => install_chromedriver(crate_path),
(BuildMode::Noinstall, None) => Err(Error::crate_config(
"No crate-local `chromedriver` binary found, and could not find a global \
`chromedriver` on the `$PATH`. Not installing `chromedriver` because of noinstall \
mode.",
)
.into()),
if let Ok(path) = which::which("chromedriver") {
return Ok(path);
}
let installation_allowed = match mode {
BuildMode::Noinstall => false,
_ => true,
};
install_chromedriver(cache, installation_allowed)
}
fn get_local_chromedriver_path(crate_path: &Path) -> PathBuf {
binaries::local_bin_path(crate_path, "chromedriver")
}
fn get_chromedriver_url() -> Result<String, Error> {
/// Download and install a pre-built `chromedriver` binary.
pub fn install_chromedriver(
cache: &Cache,
installation_allowed: bool,
) -> Result<PathBuf, failure::Error> {
let target = if target::LINUX && target::x86_64 {
"linux64"
} else if target::MACOS && target::x86_64 {
@ -42,46 +34,49 @@ fn get_chromedriver_url() -> Result<String, Error> {
} else if target::WINDOWS && target::x86 {
"win32"
} else {
return Err(Error::unsupported(
"geckodriver binaries are unavailable for this target",
));
bail!("geckodriver binaries are unavailable for this target")
};
Ok(format!(
let url = format!(
"https://chromedriver.storage.googleapis.com/2.41/chromedriver_{}.zip",
target
))
}
/// Download and install a pre-built `chromedriver` binary.
pub fn install_chromedriver(crate_path: &Path) -> Result<PathBuf, failure::Error> {
let url = get_chromedriver_url()?;
install_binaries_from_zip_at_url(crate_path, &url, Some("chromedriver"))?;
let chromedriver = get_local_chromedriver_path(crate_path);
assert!(chromedriver.is_file());
Ok(chromedriver)
);
match cache.download(
installation_allowed,
"chromedriver",
&["chromedriver"],
&url,
)? {
Some(dl) => Ok(dl.binary("chromedriver")),
None => bail!(
"No cached `chromedriver` binary found, and could not find a global \
`chromedriver` on the `$PATH`. Not installing `chromedriver` because of noinstall \
mode."
),
}
}
/// Get the path to an existing `geckodriver`, or install it if no existing
/// binary is found.
pub fn get_or_install_geckodriver(
log: &Logger,
crate_path: &Path,
cache: &Cache,
mode: BuildMode,
) -> Result<PathBuf, failure::Error> {
match (mode, bin_path(log, crate_path, "geckodriver")) {
(_, Some(path)) => Ok(path),
(BuildMode::Normal, None) => install_geckodriver(crate_path),
(BuildMode::Force, None) => install_geckodriver(crate_path),
(BuildMode::Noinstall, None) => Err(Error::crate_config(
"No crate-local `geckodriver` binary found, and could not find a global `geckodriver` \
on the `$PATH`. Not installing `geckodriver` because of noinstall mode.",
)
.into()),
if let Ok(path) = which::which("geckodriver") {
return Ok(path);
}
let installation_allowed = match mode {
BuildMode::Noinstall => false,
_ => true,
};
install_geckodriver(cache, installation_allowed)
}
fn get_geckodriver_url() -> Result<String, Error> {
/// Download and install a pre-built `geckodriver` binary.
pub fn install_geckodriver(
cache: &Cache,
installation_allowed: bool,
) -> Result<PathBuf, failure::Error> {
let (target, ext) = if target::LINUX && target::x86 {
("linux32", "tar.gz")
} else if target::LINUX && target::x86_64 {
@ -93,36 +88,21 @@ fn get_geckodriver_url() -> Result<String, Error> {
} else if target::WINDOWS && target::x86_64 {
("win64", "zip")
} else {
return Err(Error::unsupported(
"geckodriver binaries are unavailable for this target",
));
bail!("geckodriver binaries are unavailable for this target")
};
Ok(format!(
let url = format!(
"https://github.com/mozilla/geckodriver/releases/download/v0.21.0/geckodriver-v0.21.0-{}.{}",
target,
ext,
))
}
fn get_local_geckodriver_path(crate_path: &Path) -> PathBuf {
binaries::local_bin_path(crate_path, "geckodriver")
}
/// Download and install a pre-built `geckodriver` binary.
pub fn install_geckodriver(crate_path: &Path) -> Result<PathBuf, failure::Error> {
let url = get_geckodriver_url()?;
if url.ends_with("tar.gz") {
install_binaries_from_targz_at_url(crate_path, &url, Some("geckodriver"))?;
} else {
assert!(url.ends_with("zip"));
install_binaries_from_zip_at_url(crate_path, &url, Some("geckodriver"))?;
);
match cache.download(installation_allowed, "geckodriver", &["geckodriver"], &url)? {
Some(dl) => Ok(dl.binary("geckodriver")),
None => bail!(
"No cached `geckodriver` binary found, and could not find a global `geckodriver` \
on the `$PATH`. Not installing `geckodriver` because of noinstall mode."
),
}
let geckodriver = get_local_geckodriver_path(crate_path);
assert!(geckodriver.is_file());
Ok(geckodriver)
}
/// Get the path to an existing `safaridriver`.
@ -130,12 +110,9 @@ pub fn install_geckodriver(crate_path: &Path) -> Result<PathBuf, failure::Error>
/// We can't install `safaridriver` if an existing one is not found because
/// Apple does not provide pre-built binaries. However, `safaridriver` *should*
/// be present by default.
pub fn get_safaridriver(log: &Logger, crate_path: &Path) -> Result<PathBuf, Error> {
if let Some(p) = bin_path(log, crate_path, "safaridriver") {
Ok(p)
} else {
Err(Error::crate_config(
"could not find `safaridriver` on the `$PATH`",
))
pub fn get_safaridriver() -> Result<PathBuf, failure::Error> {
match which::which("safaridriver") {
Ok(p) => Ok(p),
Err(_) => bail!("could not find `safaridriver` on the `$PATH`"),
}
}

@ -1,4 +1,5 @@
use tempfile;
use wasm_pack::binaries::Cache;
use wasm_pack::bindgen;
#[test]
@ -8,23 +9,11 @@ use wasm_pack::bindgen;
all(windows, target_arch = "x86_64"),
))]
fn can_download_prebuilt_wasm_bindgen() {
use std::env;
let dir = tempfile::TempDir::new().unwrap();
bindgen::download_prebuilt_wasm_bindgen(dir.path(), "0.2.21").unwrap();
assert!(
dir.path()
.join("bin")
.join("wasm-bindgen")
.with_extension(env::consts::EXE_EXTENSION)
.is_file()
);
assert!(
dir.path()
.join("bin")
.join("wasm-bindgen-test-runner")
.with_extension(env::consts::EXE_EXTENSION)
.is_file()
);
let cache = Cache::at(dir.path());
let dl = bindgen::download_prebuilt_wasm_bindgen(&cache, "0.2.21", true).unwrap();
assert!(dl.binary("wasm-bindgen").is_file());
assert!(dl.binary("wasm-bindgen-test-runner").is_file())
}
#[test]
@ -36,9 +25,13 @@ fn can_download_prebuilt_wasm_bindgen() {
fn downloading_prebuilt_wasm_bindgen_handles_http_errors() {
let dir = tempfile::TempDir::new().unwrap();
let bad_version = "0.2.21-some-trailing-version-stuff-that-does-not-exist";
let result = bindgen::download_prebuilt_wasm_bindgen(dir.path(), bad_version);
let cache = Cache::at(dir.path());
let result = bindgen::download_prebuilt_wasm_bindgen(&cache, bad_version, true);
assert!(result.is_err());
let error_msg = result.unwrap_err().to_string();
assert!(error_msg.contains("404"));
assert!(error_msg.contains(bad_version));
let error = result.err().unwrap();
assert!(error.iter_chain().any(|e| e.to_string().contains("404")));
assert!(error
.iter_chain()
.any(|e| e.to_string().contains(bad_version)));
}

@ -1,6 +1,8 @@
use std::fs;
use std::path::Path;
use structopt::StructOpt;
use utils;
use wasm_pack::{command, logger, Cli};
use wasm_pack::Cli;
#[test]
fn build_in_non_crate_directory_doesnt_panic() {
@ -11,12 +13,218 @@ fn build_in_non_crate_directory_doesnt_panic() {
&fixture.path.display().to_string(),
])
.unwrap();
let logger = logger::new(&cli.cmd, cli.verbosity).unwrap();
let result = command::run_wasm_pack(cli.cmd, &logger);
let result = fixture.run(cli.cmd);
assert!(
result.is_err(),
"running wasm-pack in a non-crate directory should fail, but it should not panic"
);
let err_msg = result.unwrap_err().to_string();
assert!(err_msg.contains("missing a `Cargo.toml`"));
let err = result.unwrap_err();
assert!(err
.iter_chain()
.any(|e| e.to_string().contains("missing a `Cargo.toml`")));
}
#[test]
fn it_should_build_js_hello_world_example() {
let fixture = utils::fixture::js_hello_world();
fixture.install_local_wasm_bindgen();
let cli = Cli::from_iter_safe(vec![
"wasm-pack",
"build",
&fixture.path.display().to_string(),
])
.unwrap();
fixture.run(cli.cmd).unwrap();
}
#[test]
fn it_should_build_crates_in_a_workspace() {
let fixture = utils::fixture::Fixture::new();
fixture
.file(
"Cargo.toml",
r#"
[workspace]
members = ["blah"]
"#,
)
.file(
Path::new("blah").join("Cargo.toml"),
r#"
[package]
authors = ["The wasm-pack developers"]
description = "so awesome rust+wasm package"
license = "WTFPL"
name = "blah"
repository = "https://github.com/rustwasm/wasm-pack.git"
version = "0.1.0"
[lib]
crate-type = ["cdylib"]
[dependencies]
wasm-bindgen = "=0.2.21"
"#,
)
.file(
Path::new("blah").join("src").join("lib.rs"),
r#"
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn hello() -> u32 { 42 }
"#,
);
fixture.install_local_wasm_bindgen();
let cli = Cli::from_iter_safe(vec![
"wasm-pack",
"build",
&fixture.path.join("blah").display().to_string(),
])
.unwrap();
fixture.run(cli.cmd).unwrap();
}
#[test]
fn renamed_crate_name_works() {
let fixture = utils::fixture::Fixture::new();
fixture
.readme()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
authors = []
[lib]
crate-type = ["cdylib"]
name = 'bar'
[dependencies]
wasm-bindgen = "=0.2.21"
"#,
)
.file(
"src/lib.rs",
r#"
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn one() -> u32 { 1 }
"#,
);
fixture.install_local_wasm_bindgen();
let cli = Cli::from_iter_safe(vec![
"wasm-pack",
"build",
&fixture.path.display().to_string(),
])
.unwrap();
fixture.run(cli.cmd).unwrap();
}
#[test]
fn it_should_build_nested_project_with_transitive_dependencies() {
let fixture = utils::fixture::transitive_dependencies();
fixture.install_local_wasm_bindgen();
let cli = Cli::from_iter_safe(vec![
"wasm-pack",
"build",
&fixture.path.join("main").display().to_string(),
])
.unwrap();
fixture.run(cli.cmd).unwrap();
}
#[test]
fn build_different_profiles() {
let fixture = utils::fixture::js_hello_world();
fixture.install_local_wasm_bindgen();
for profile in ["--dev", "--debug", "--profiling", "--release"]
.iter()
.cloned()
{
let cli = Cli::from_iter_safe(vec![
"wasm-pack",
"build",
profile,
&fixture.path.display().to_string(),
])
.unwrap();
fixture.run(cli.cmd).unwrap();
}
}
#[test]
fn build_with_and_without_wasm_bindgen_debug() {
for debug in [true, false].iter().cloned() {
let fixture = utils::fixture::Fixture::new();
fixture
.readme()
.file(
"Cargo.toml",
format!(
r#"
[package]
authors = ["The wasm-pack developers"]
description = "so awesome rust+wasm package"
license = "WTFPL"
name = "whatever"
repository = "https://github.com/rustwasm/wasm-pack.git"
version = "0.1.0"
[lib]
crate-type = ["cdylib"]
[dependencies]
wasm-bindgen = "0.2"
[package.metadata.wasm-pack.profile.dev.wasm-bindgen]
debug-js-glue = {}
"#,
debug
),
)
.file(
"src/lib.rs",
r#"
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub struct MyThing {}
#[wasm_bindgen]
impl MyThing {
pub fn new() -> MyThing {
MyThing {}
}
pub fn take(self) {}
}
"#,
);
let cli = Cli::from_iter_safe(vec![
"wasm-pack",
"build",
"--dev",
&fixture.path.display().to_string(),
])
.unwrap();
fixture.run(cli.cmd).unwrap();
let contents = fs::read_to_string(fixture.path.join("pkg/whatever.js")).unwrap();
assert_eq!(
contents.contains("throw new Error('Attempt to use a moved value')"),
debug,
"Should only contain moved value assertions when debug assertions are enabled"
);
}
}

@ -1,11 +1,13 @@
use utils::fixture;
use wasm_pack::lockfile::Lockfile;
use wasm_pack::manifest::CrateData;
#[test]
fn it_gets_wasm_bindgen_version() {
let fixture = fixture::js_hello_world();
fixture.cargo_check();
let lock = Lockfile::new(&fixture.path).unwrap();
let data = CrateData::new(&fixture.path).unwrap();
let lock = Lockfile::new(&data).unwrap();
assert_eq!(lock.wasm_bindgen_version(), Some("0.2.21"),);
}
@ -13,7 +15,8 @@ fn it_gets_wasm_bindgen_version() {
fn it_gets_wasm_bindgen_test_version() {
let fixture = fixture::wbg_test_node();
fixture.cargo_check();
let lock = Lockfile::new(&fixture.path).unwrap();
let data = CrateData::new(&fixture.path).unwrap();
let lock = Lockfile::new(&data).unwrap();
assert_eq!(lock.wasm_bindgen_test_version(), Some("0.2.21"),);
}
@ -57,7 +60,8 @@ fn it_gets_wasm_bindgen_version_in_crate_inside_workspace() {
"#,
);
fixture.cargo_check();
let lock = Lockfile::new(&fixture.path.join("blah")).unwrap();
let data = CrateData::new(&fixture.path.join("blah")).unwrap();
let lock = Lockfile::new(&data).unwrap();
assert_eq!(lock.wasm_bindgen_version(), Some("0.2.21"),);
}
@ -124,6 +128,7 @@ fn it_gets_wasm_bindgen_version_from_dependencies() {
"#,
);
fixture.cargo_check();
let lock = Lockfile::new(&fixture.path.join("parent")).unwrap();
let data = CrateData::new(&fixture.path.join("parent")).unwrap();
let lock = Lockfile::new(&data).unwrap();
assert_eq!(lock.wasm_bindgen_version(), Some("0.2.21"),);
}

@ -1,5 +1,7 @@
extern crate failure;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
#[macro_use]

@ -2,24 +2,24 @@ use std::collections::HashSet;
use std::fs;
use std::path::PathBuf;
use structopt::StructOpt;
use utils::{self, fixture};
use wasm_pack::{self, manifest};
use wasm_pack::{self, manifest, Cli};
#[test]
fn it_gets_the_crate_name_default_path() {
let path = &PathBuf::from(".");
assert!(manifest::get_crate_name(path).is_ok());
assert_eq!(manifest::get_crate_name(path).unwrap(), "wasm-pack");
let crate_data = manifest::CrateData::new(&path).unwrap();
let name = crate_data.crate_name();
assert_eq!(name, "wasm_pack");
}
#[test]
fn it_gets_the_crate_name_provided_path() {
let fixture = fixture::js_hello_world();
assert!(manifest::get_crate_name(&fixture.path).is_ok());
assert_eq!(
manifest::get_crate_name(&fixture.path).unwrap(),
"js-hello-world"
);
let crate_data = manifest::CrateData::new(&fixture.path).unwrap();
assert_eq!(crate_data.crate_name(), "js_hello_world");
}
#[test]
@ -27,8 +27,9 @@ fn it_checks_has_cdylib_default_path() {
let fixture = fixture::no_cdylib();
// Ensure that there is a `Cargo.lock`.
fixture.cargo_check();
let crate_data = manifest::CrateData::new(&fixture.path).unwrap();
let step = wasm_pack::progressbar::Step::new(1);
assert!(manifest::check_crate_config(&fixture.path, &step).is_err());
assert!(crate_data.check_crate_config(&step).is_err());
}
#[test]
@ -36,15 +37,17 @@ fn it_checks_has_cdylib_provided_path() {
let fixture = fixture::js_hello_world();
// Ensure that there is a `Cargo.lock`.
fixture.cargo_check();
let crate_data = manifest::CrateData::new(&fixture.path).unwrap();
let step = wasm_pack::progressbar::Step::new(1);
assert!(manifest::check_crate_config(&fixture.path, &step).is_ok());
crate_data.check_crate_config(&step).unwrap();
}
#[test]
fn it_checks_has_cdylib_wrong_crate_type() {
let fixture = fixture::bad_cargo_toml();
let crate_data = manifest::CrateData::new(&fixture.path).unwrap();
let step = wasm_pack::progressbar::Step::new(1);
assert!(manifest::check_crate_config(&fixture.path, &step).is_err());
assert!(crate_data.check_crate_config(&step).is_err());
}
#[test]
@ -52,20 +55,24 @@ fn it_recognizes_a_map_during_depcheck() {
let fixture = fixture::serde_feature();
// Ensure that there is a `Cargo.lock`.
fixture.cargo_check();
let crate_data = manifest::CrateData::new(&fixture.path).unwrap();
let step = wasm_pack::progressbar::Step::new(1);
assert!(manifest::check_crate_config(&fixture.path, &step).is_ok());
crate_data.check_crate_config(&step).unwrap();
}
#[test]
fn it_creates_a_package_json_default_path() {
let fixture = fixture::js_hello_world();
let out_dir = fixture.path.join("pkg");
let crate_data = manifest::CrateData::new(&fixture.path).unwrap();
let step = wasm_pack::progressbar::Step::new(1);
wasm_pack::command::utils::create_pkg_dir(&out_dir, &step).unwrap();
assert!(manifest::write_package_json(&fixture.path, &out_dir, &None, false, "", &step).is_ok());
assert!(crate_data
.write_package_json(&out_dir, &None, false, "", &step)
.is_ok());
let package_json_path = &fixture.path.join("pkg").join("package.json");
assert!(fs::metadata(package_json_path).is_ok());
assert!(utils::manifest::read_package_json(&fixture.path, &out_dir).is_ok());
fs::metadata(package_json_path).unwrap();
utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();
let pkg = utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();
assert_eq!(pkg.name, "js-hello-world");
assert_eq!(pkg.repository.ty, "git");
@ -83,9 +90,9 @@ fn it_creates_a_package_json_default_path() {
"js_hello_world.d.ts",
"js_hello_world.js",
]
.iter()
.map(|&s| String::from(s))
.collect();
.iter()
.map(|&s| String::from(s))
.collect();
assert_eq!(actual_files, expected_files);
}
@ -93,11 +100,14 @@ fn it_creates_a_package_json_default_path() {
fn it_creates_a_package_json_provided_path() {
let fixture = fixture::js_hello_world();
let out_dir = fixture.path.join("pkg");
let crate_data = manifest::CrateData::new(&fixture.path).unwrap();
let step = wasm_pack::progressbar::Step::new(1);
wasm_pack::command::utils::create_pkg_dir(&out_dir, &step).unwrap();
assert!(manifest::write_package_json(&fixture.path, &out_dir, &None, false, "", &step).is_ok());
assert!(crate_data
.write_package_json(&out_dir, &None, false, "", &step)
.is_ok());
let package_json_path = &fixture.path.join("pkg").join("package.json");
assert!(fs::metadata(package_json_path).is_ok());
fs::metadata(package_json_path).unwrap();
utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();
let pkg = utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();
assert_eq!(pkg.name, "js-hello-world");
@ -109,9 +119,9 @@ fn it_creates_a_package_json_provided_path() {
"js_hello_world.d.ts",
"js_hello_world.js",
]
.iter()
.map(|&s| String::from(s))
.collect();
.iter()
.map(|&s| String::from(s))
.collect();
assert_eq!(actual_files, expected_files);
}
@ -119,22 +129,15 @@ fn it_creates_a_package_json_provided_path() {
fn it_creates_a_package_json_provided_path_with_scope() {
let fixture = fixture::js_hello_world();
let out_dir = fixture.path.join("pkg");
let crate_data = manifest::CrateData::new(&fixture.path).unwrap();
let step = wasm_pack::progressbar::Step::new(1);
wasm_pack::command::utils::create_pkg_dir(&out_dir, &step).unwrap();
assert!(
manifest::write_package_json(
&fixture.path,
&out_dir,
&Some("test".to_string()),
false,
"",
&step
)
.is_ok()
);
assert!(crate_data
.write_package_json(&out_dir, &Some("test".to_string()), false, "", &step)
.is_ok());
let package_json_path = &fixture.path.join("pkg").join("package.json");
assert!(fs::metadata(package_json_path).is_ok());
assert!(utils::manifest::read_package_json(&fixture.path, &out_dir).is_ok());
fs::metadata(package_json_path).unwrap();
utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();
let pkg = utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();
assert_eq!(pkg.name, "@test/js-hello-world");
assert_eq!(pkg.module, "js_hello_world.js");
@ -145,9 +148,9 @@ fn it_creates_a_package_json_provided_path_with_scope() {
"js_hello_world.d.ts",
"js_hello_world.js",
]
.iter()
.map(|&s| String::from(s))
.collect();
.iter()
.map(|&s| String::from(s))
.collect();
assert_eq!(actual_files, expected_files);
}
@ -155,14 +158,14 @@ fn it_creates_a_package_json_provided_path_with_scope() {
fn it_creates_a_pkg_json_with_correct_files_on_node() {
let fixture = fixture::js_hello_world();
let out_dir = fixture.path.join("pkg");
let crate_data = manifest::CrateData::new(&fixture.path).unwrap();
let step = wasm_pack::progressbar::Step::new(1);
wasm_pack::command::utils::create_pkg_dir(&out_dir, &step).unwrap();
assert!(
manifest::write_package_json(&fixture.path, &out_dir, &None, false, "nodejs", &step)
.is_ok()
);
assert!(crate_data
.write_package_json(&out_dir, &None, false, "nodejs", &step)
.is_ok());
let package_json_path = &out_dir.join("package.json");
assert!(fs::metadata(package_json_path).is_ok());
fs::metadata(package_json_path).unwrap();
utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();
let pkg = utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();
assert_eq!(pkg.name, "js-hello-world");
@ -179,10 +182,11 @@ fn it_creates_a_pkg_json_with_correct_files_on_node() {
"js_hello_world_bg.wasm",
"js_hello_world_bg.js",
"js_hello_world.d.ts",
"js_hello_world.js",
]
.iter()
.map(|&s| String::from(s))
.collect();
.iter()
.map(|&s| String::from(s))
.collect();
assert_eq!(actual_files, expected_files);
}
@ -190,14 +194,14 @@ fn it_creates_a_pkg_json_with_correct_files_on_node() {
fn it_creates_a_pkg_json_with_correct_files_on_nomodules() {
let fixture = fixture::js_hello_world();
let out_dir = fixture.path.join("pkg");
let crate_data = manifest::CrateData::new(&fixture.path).unwrap();
let step = wasm_pack::progressbar::Step::new(1);
wasm_pack::command::utils::create_pkg_dir(&out_dir, &step).unwrap();
assert!(
manifest::write_package_json(&fixture.path, &out_dir, &None, false, "no-modules", &step)
.is_ok()
);
assert!(crate_data
.write_package_json(&out_dir, &None, false, "no-modules", &step)
.is_ok());
let package_json_path = &out_dir.join("package.json");
assert!(fs::metadata(package_json_path).is_ok());
fs::metadata(package_json_path).unwrap();
utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();
let pkg = utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();
assert_eq!(pkg.name, "js-hello-world");
@ -215,9 +219,9 @@ fn it_creates_a_pkg_json_with_correct_files_on_nomodules() {
"js_hello_world.js",
"js_hello_world.d.ts",
]
.iter()
.map(|&s| String::from(s))
.collect();
.iter()
.map(|&s| String::from(s))
.collect();
assert_eq!(actual_files, expected_files);
}
@ -225,25 +229,31 @@ fn it_creates_a_pkg_json_with_correct_files_on_nomodules() {
fn it_creates_a_pkg_json_in_out_dir() {
let fixture = fixture::js_hello_world();
let out_dir = fixture.path.join("./custom/out");
let crate_data = manifest::CrateData::new(&fixture.path).unwrap();
let step = wasm_pack::progressbar::Step::new(1);
wasm_pack::command::utils::create_pkg_dir(&out_dir, &step).unwrap();
assert!(manifest::write_package_json(&fixture.path, &out_dir, &None, false, "", &step).is_ok());
assert!(crate_data
.write_package_json(&out_dir, &None, false, "", &step)
.is_ok());
let package_json_path = &fixture.path.join(&out_dir).join("package.json");
assert!(fs::metadata(package_json_path).is_ok());
assert!(utils::manifest::read_package_json(&fixture.path, &out_dir).is_ok());
fs::metadata(package_json_path).unwrap();
utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();
}
#[test]
fn it_creates_a_package_json_with_correct_keys_when_types_are_skipped() {
let fixture = fixture::js_hello_world();
let out_dir = fixture.path.join("pkg");
let crate_data = manifest::CrateData::new(&fixture.path).unwrap();
let step = wasm_pack::progressbar::Step::new(1);
wasm_pack::command::utils::create_pkg_dir(&out_dir, &step).unwrap();
assert!(manifest::write_package_json(&fixture.path, &out_dir, &None, true, "", &step).is_ok());
assert!(crate_data
.write_package_json(&out_dir, &None, true, "", &step)
.is_ok());
let package_json_path = &out_dir.join("package.json");
assert!(fs::metadata(package_json_path).is_ok());
assert!(utils::manifest::read_package_json(&fixture.path, &out_dir).is_ok());
fs::metadata(package_json_path).unwrap();
utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();
let pkg = utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();
assert_eq!(pkg.name, "js-hello-world");
assert_eq!(pkg.repository.ty, "git");
@ -264,8 +274,9 @@ fn it_creates_a_package_json_with_correct_keys_when_types_are_skipped() {
#[test]
fn it_errors_when_wasm_bindgen_is_not_declared() {
let fixture = fixture::bad_cargo_toml();
let crate_data = manifest::CrateData::new(&fixture.path).unwrap();
let step = wasm_pack::progressbar::Step::new(1);
assert!(manifest::check_crate_config(&fixture.path, &step).is_err());
assert!(crate_data.check_crate_config(&step).is_err());
}
#[test]
@ -273,6 +284,52 @@ fn it_does_not_error_when_wasm_bindgen_is_declared() {
let fixture = fixture::js_hello_world();
// Ensure that there is a `Cargo.lock`.
fixture.cargo_check();
let crate_data = manifest::CrateData::new(&fixture.path).unwrap();
let step = wasm_pack::progressbar::Step::new(1);
assert!(manifest::check_crate_config(&fixture.path, &step).is_ok());
crate_data.check_crate_config(&step).unwrap();
}
#[test]
fn configure_wasm_bindgen_debug_incorrectly_is_error() {
let fixture = utils::fixture::Fixture::new();
fixture
.readme()
.file(
"Cargo.toml",
r#"
[package]
authors = ["The wasm-pack developers"]
description = "so awesome rust+wasm package"
license = "WTFPL"
name = "whatever"
repository = "https://github.com/rustwasm/wasm-pack.git"
version = "0.1.0"
[lib]
crate-type = ["cdylib"]
[dependencies]
wasm-bindgen = "0.2"
[package.metadata.wasm-pack.profile.dev.wasm-bindgen]
debug-js-glue = "not a boolean"
"#,
)
.hello_world_src_lib();
let cli = Cli::from_iter_safe(vec![
"wasm-pack",
"build",
"--dev",
&fixture.path.display().to_string(),
])
.unwrap();
let result = fixture.run(cli.cmd);
assert!(result.is_err());
let err = result.unwrap_err();
assert!(err.iter_chain().any(|c| c
.to_string()
.contains("package.metadata.wasm-pack.profile.dev.wasm-bindgen.debug")));
}

@ -32,7 +32,7 @@ fn it_copies_a_readme_default_path() {
}
#[test]
fn it_creates_a_package_json_provided_path() {
fn it_copies_a_readme_provided_path() {
let fixture = fixture::js_hello_world();
let out_dir = fixture.path.join("pkg");
fs::create_dir(&out_dir).expect("should create pkg directory OK");

@ -1,10 +1,16 @@
use failure::Error;
use std::env;
use std::fs;
use tempfile;
use utils::fixture;
use wasm_pack::binaries;
use wasm_pack::command::{self, build, test, Command};
use wasm_pack::logger;
use wasm_pack::command::{build, test, Command};
fn assert_err<T>(result: Result<T, Error>, msg: &str) -> Error {
let error = result.err().expect("should have failed");
for e in error.iter_chain() {
println!("err: {}", e);
}
assert!(error.iter_chain().any(|e| e.to_string().contains(msg)));
error
}
#[test]
fn it_can_run_node_tests() {
@ -16,8 +22,7 @@ fn it_can_run_node_tests() {
mode: build::BuildMode::Noinstall,
..Default::default()
});
let logger = logger::new(&cmd, 3).unwrap();
command::run_wasm_pack(cmd, &logger).expect("should run test command OK");
fixture.run(cmd).unwrap();
}
#[test]
@ -30,8 +35,7 @@ fn it_can_run_tests_with_different_wbg_test_and_wbg_versions() {
mode: build::BuildMode::Noinstall,
..Default::default()
});
let logger = logger::new(&cmd, 3).unwrap();
command::run_wasm_pack(cmd, &logger).expect("should run test command OK");
fixture.run(cmd).unwrap();
}
#[test]
@ -81,8 +85,7 @@ fn it_can_run_browser_tests() {
..Default::default()
});
let logger = logger::new(&cmd, 3).unwrap();
command::run_wasm_pack(cmd, &logger).expect("should run test command OK");
fixture.run(cmd).unwrap();
}
#[test]
@ -95,10 +98,9 @@ fn it_can_run_failing_tests() {
mode: build::BuildMode::Noinstall,
..Default::default()
});
let logger = logger::new(&cmd, 3).unwrap();
assert!(
command::run_wasm_pack(cmd, &logger).is_err(),
"failing tests should return Err"
assert_err(
fixture.run(cmd),
"Running Wasm tests with wasm-bindgen-test failed",
);
}
@ -111,34 +113,37 @@ fn it_can_run_failing_tests() {
all(target_os = "windows", target_arch = "x86_64")
))]
fn it_can_find_a_webdriver_on_path() {
use std::process::Command;
let fixture = fixture::wbg_test_browser();
fixture.install_local_wasm_bindgen();
fixture.install_local_geckodriver();
let geckodriver_dir = tempfile::TempDir::new().unwrap();
let local_geckodriver = binaries::local_bin_path(&fixture.path, "geckodriver");
fs::copy(
&local_geckodriver,
geckodriver_dir
.path()
.join(local_geckodriver.file_name().unwrap()),
)
.unwrap();
fs::remove_file(&local_geckodriver).unwrap();
let local_geckodriver = fixture.install_local_geckodriver();
let local_wasm_bindgen = fixture.install_local_wasm_bindgen();
let mut paths: Vec<_> = env::split_paths(&env::var("PATH").unwrap()).collect();
paths.insert(0, geckodriver_dir.path().into());
env::set_var("PATH", env::join_paths(paths).unwrap());
paths.insert(0, local_geckodriver.parent().unwrap().to_path_buf());
paths.insert(0, local_wasm_bindgen.parent().unwrap().to_path_buf());
let path = env::join_paths(paths).unwrap();
let cmd = Command::Test(test::TestOptions {
path: Some(fixture.path.clone()),
firefox: true,
headless: true,
mode: build::BuildMode::Noinstall,
..Default::default()
});
let logger = logger::new(&cmd, 3).unwrap();
command::run_wasm_pack(cmd, &logger).expect("should run test command OK");
let _lock = fixture.lock();
let mut me = env::current_exe().unwrap();
me.pop();
me.pop();
me.push("wasm-pack");
let output = Command::new(&me)
.arg("test")
.arg("--firefox")
.arg("--headless")
.arg("--mode")
.arg("no-install")
.env("PATH", &path)
.arg(&fixture.path)
.output()
.unwrap();
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
println!("status: {}", output.status);
assert!(output.status.success());
}
#[test]
@ -152,11 +157,7 @@ fn it_requires_node_or_a_browser() {
// Note: not setting node or any browser to true here.
..Default::default()
});
let logger = logger::new(&cmd, 3).unwrap();
assert!(
command::run_wasm_pack(cmd, &logger).is_err(),
"need to enable node or browser testing"
);
assert_err(fixture.run(cmd), "Must specify at least one of");
}
#[test]
@ -171,11 +172,7 @@ fn the_headless_flag_requires_a_browser() {
headless: true,
..Default::default()
});
let logger = logger::new(&cmd, 3).unwrap();
assert!(
command::run_wasm_pack(cmd, &logger).is_err(),
"running headless tests in node doesn't make sense"
);
assert_err(fixture.run(cmd), "only applies to browser tests");
}
#[test]
@ -213,13 +210,7 @@ fn complains_about_missing_wasm_bindgen_test_dependency() {
mode: build::BuildMode::Noinstall,
..Default::default()
});
let logger = logger::new(&cmd, 3).unwrap();
let result = command::run_wasm_pack(cmd, &logger);
assert!(
result.is_err(),
"running tests without wasm-bindgen-test won't work"
);
let error = assert_err(fixture.run(cmd), "Ensure that you have");
// Test that the error message has two occurrences of "wasm-bindgen-test" in
// it. I am surprised to learn there is no `str` method to count
@ -244,10 +235,102 @@ fn complains_about_missing_wasm_bindgen_test_dependency() {
// the output to a text file, then the escape codes go away, so I can't
// figure out which exact escape codes are even used here.
let err_msg = result.unwrap_err().to_string();
let err_msg = error.to_string();
let first = err_msg.find("wasm-bindgen-test");
assert!(first.is_some());
let second = err_msg.rfind("wasm-bindgen-test");
assert!(second.is_some());
assert_ne!(first, second, "should have found two occurrences");
}
#[test]
fn renamed_crate_name_works() {
let fixture = fixture::Fixture::new();
fixture
.readme()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
authors = []
[lib]
crate-type = ["cdylib"]
name = 'bar'
[dependencies]
wasm-bindgen = "=0.2.21"
[dev-dependencies]
wasm-bindgen-test = "=0.2.21"
"#,
)
.file(
"src/lib.rs",
r#"
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn one() -> u32 { 1 }
"#,
);
fixture.install_local_wasm_bindgen();
let cmd = Command::Test(test::TestOptions {
path: Some(fixture.path.clone()),
node: true,
mode: build::BuildMode::Noinstall,
..Default::default()
});
fixture.run(cmd).unwrap();
}
#[test]
fn cdylib_not_required() {
let fixture = fixture::Fixture::new();
fixture
.readme()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
authors = []
[dependencies]
wasm-bindgen = "=0.2.21"
[dev-dependencies]
wasm-bindgen-test = "=0.2.21"
"#,
)
.file(
"src/lib.rs",
r#"
pub fn foo() -> u32 { 1 }
"#,
)
.file(
"tests/foo.rs",
r#"
extern crate wasm_bindgen_test;
use wasm_bindgen_test::*;
#[wasm_bindgen_test]
fn smoke() {
foo::foo();
}
"#,
);
fixture.install_local_wasm_bindgen();
let cmd = Command::Test(test::TestOptions {
path: Some(fixture.path.clone()),
node: true,
mode: build::BuildMode::Noinstall,
..Default::default()
});
fixture.run(cmd).unwrap();
}

@ -1,20 +1,14 @@
use super::logger::null_logger;
use std::env;
use std::fs;
use std::io;
use std::mem::ManuallyDrop;
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
use std::sync::{Once, ONCE_INIT};
use std::sync::{MutexGuard, Once, ONCE_INIT};
use std::thread;
use tempfile::TempDir;
use wasm_pack;
fn hard_link_or_copy<P1: AsRef<Path>, P2: AsRef<Path>>(from: P1, to: P2) -> io::Result<()> {
let from = from.as_ref();
let to = to.as_ref();
fs::hard_link(from, to).or_else(|_| fs::copy(from, to).map(|_| ()))
}
use wasm_pack::binaries::Cache;
/// A test fixture in a temporary directory.
pub struct Fixture {
@ -134,120 +128,63 @@ impl Fixture {
///
/// Takes care not to re-install for every fixture, but only the one time
/// for the whole test suite.
pub fn install_local_wasm_bindgen(&self) -> &Self {
pub fn install_local_wasm_bindgen(&self) -> PathBuf {
static INSTALL_WASM_BINDGEN: Once = ONCE_INIT;
let cache = self.cache();
let version = "0.2.21";
let log = &null_logger();
let download = || {
if let Ok(download) =
wasm_pack::bindgen::download_prebuilt_wasm_bindgen(&cache, version, true)
{
return Ok(download);
}
let tests = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests");
let shared_wasm_bindgen = wasm_pack::binaries::local_bin_path(&tests, "wasm-bindgen");
let shared_wasm_bindgen_test_runner =
wasm_pack::binaries::local_bin_path(&tests, "wasm-bindgen-test-runner");
wasm_pack::bindgen::cargo_install_wasm_bindgen(log, &cache, version, true)
};
// Only one thread can perform the actual download, and then afterwards
// everything will hit the cache so we can run the same path.
INSTALL_WASM_BINDGEN.call_once(|| {
if shared_wasm_bindgen.is_file() {
assert!(shared_wasm_bindgen_test_runner.is_file());
return;
}
const WASM_BINDGEN_VERSION: &str = "0.2.21";
wasm_pack::bindgen::download_prebuilt_wasm_bindgen(&tests, WASM_BINDGEN_VERSION)
.or_else(|_| {
wasm_pack::bindgen::cargo_install_wasm_bindgen(
&null_logger(),
&tests,
WASM_BINDGEN_VERSION,
)
})
.unwrap();
download().unwrap();
});
assert!(shared_wasm_bindgen.is_file());
assert!(shared_wasm_bindgen_test_runner.is_file());
wasm_pack::binaries::ensure_local_bin_dir(&self.path).unwrap();
hard_link_or_copy(
&shared_wasm_bindgen,
wasm_pack::binaries::local_bin_path(&self.path, "wasm-bindgen"),
)
.expect("could not copy `wasm-bindgen` to fixture directory");
hard_link_or_copy(
&shared_wasm_bindgen_test_runner,
wasm_pack::binaries::local_bin_path(&self.path, "wasm-bindgen-test-runner"),
)
.expect("could not copy `wasm-bindgen-test` to fixture directory");
self
download().unwrap().binary("wasm-bindgen")
}
/// Download `geckodriver` and return its path.
///
/// Takes care to ensure that only one `geckodriver` is downloaded for the whole
/// test suite.
pub fn install_local_geckodriver(&self) -> &Self {
pub fn install_local_geckodriver(&self) -> PathBuf {
static FETCH_GECKODRIVER: Once = ONCE_INIT;
let cache = self.cache();
let tests = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests");
wasm_pack::binaries::ensure_local_bin_dir(&tests)
.expect("could not create fixture's `bin` directory");
let geckodriver = wasm_pack::binaries::local_bin_path(&tests, "geckodriver");
// like above for synchronization
FETCH_GECKODRIVER.call_once(|| {
if geckodriver.is_file() {
return;
}
wasm_pack::test::webdriver::install_geckodriver(&tests).unwrap();
assert!(geckodriver.is_file());
wasm_pack::test::webdriver::install_geckodriver(&cache, true).unwrap();
});
wasm_pack::binaries::ensure_local_bin_dir(&self.path)
.expect("could not create fixture's `bin` directory");
hard_link_or_copy(
&geckodriver,
wasm_pack::binaries::local_bin_path(&self.path, "geckodriver"),
)
.expect("could not copy `geckodriver` to fixture directory");
self
wasm_pack::test::webdriver::install_geckodriver(&cache, true).unwrap()
}
/// Download `chromedriver` and return its path.
///
/// Takes care to ensure that only one `chromedriver` is downloaded for the whole
/// test suite.
pub fn install_local_chromedriver(&self) -> &Self {
pub fn install_local_chromedriver(&self) -> PathBuf {
static FETCH_CHROMEDRIVER: Once = ONCE_INIT;
let cache = self.cache();
let tests = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests");
wasm_pack::binaries::ensure_local_bin_dir(&tests)
.expect("could not create fixture's `bin` directory");
let chromedriver = wasm_pack::binaries::local_bin_path(&tests, "chromedriver");
// like above for synchronization
FETCH_CHROMEDRIVER.call_once(|| {
if chromedriver.is_file() {
return;
}
wasm_pack::test::webdriver::install_chromedriver(&tests).unwrap();
assert!(chromedriver.is_file());
wasm_pack::test::webdriver::install_chromedriver(&cache, true).unwrap();
});
wasm_pack::test::webdriver::install_chromedriver(&cache, true).unwrap()
}
wasm_pack::binaries::ensure_local_bin_dir(&self.path)
.expect("could not create fixture's `bin` directory");
hard_link_or_copy(
&chromedriver,
wasm_pack::binaries::local_bin_path(&self.path, "chromedriver"),
)
.expect("could not copy `chromedriver` to fixture directory");
self
pub fn cache(&self) -> Cache {
let target_dir = Path::new(env!("CARGO_MANIFEST_DIR")).join("target");
Cache::at(&target_dir.join("test_cache"))
}
/// The `step_install_wasm_bindgen` and `step_run_wasm_bindgen` steps only
@ -266,6 +203,32 @@ impl Fixture {
.unwrap();
self
}
pub fn run(&self, cmd: wasm_pack::command::Command) -> Result<(), failure::Error> {
let logger = wasm_pack::logger::new(&cmd, 3)?;
match cmd {
wasm_pack::command::Command::Test(cmd) => {
let _lock = self.lock();
let mut test = wasm_pack::command::test::Test::try_from_opts(cmd)?;
test.set_cache(self.cache());
test.run(&logger)
}
wasm_pack::command::Command::Build(cmd) => {
let mut build = wasm_pack::command::build::Build::try_from_opts(cmd)?;
build.set_cache(self.cache());
build.run(&logger)
}
_ => unreachable!(),
}
}
pub fn lock(&self) -> MutexGuard<'static, ()> {
use std::sync::Mutex;
lazy_static! {
static ref ONE_TEST_AT_A_TIME: Mutex<()> = Mutex::new(());
}
ONE_TEST_AT_A_TIME.lock().unwrap_or_else(|e| e.into_inner())
}
}
impl Drop for Fixture {
@ -314,7 +277,7 @@ pub fn no_cdylib() -> Fixture {
authors = ["The wasm-pack developers"]
description = "so awesome rust+wasm package"
license = "WTFPL"
name = "{}"
name = "foo"
repository = "https://github.com/rustwasm/wasm-pack.git"
version = "0.1.0"
@ -474,3 +437,156 @@ pub fn wbg_test_node() -> Fixture {
);
fixture
}
pub fn transitive_dependencies() -> Fixture {
fn project_main_fixture(fixture: &mut Fixture) {
fixture.file(PathBuf::from("main/README"), "# Main Fixture\n");
fixture.file(
PathBuf::from("main/Cargo.toml"),
r#"
[package]
authors = ["The wasm-pack developers"]
description = "so awesome rust+wasm package"
license = "WTFPL"
name = "main_project"
repository = "https://github.com/rustwasm/wasm-pack.git"
version = "0.1.0"
[lib]
crate-type = ["cdylib"]
[dependencies]
wasm-bindgen = "=0.2.21"
project_a = { path = "../project_a" }
project_b = { path = "../project_b" }
[dev-dependencies]
wasm-bindgen-test = "=0.2.21"
"#,
);
fixture.file(
PathBuf::from("main/src/lib.rs"),
r#"
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
// Import the `window.alert` function from the Web.
#[wasm_bindgen]
extern {
fn alert(s: &str);
}
// Export a `greet` function from Rust to JavaScript, that alerts a
// hello message.
#[wasm_bindgen]
pub fn greet(name: &str) {
alert(&format!("Hello, {}!", name));
}
"#,
);
}
fn project_a_fixture(fixture: &mut Fixture) {
fixture.file(
PathBuf::from("project_a/README"),
"# Project Alpha Fixture\n",
);
fixture.file(
PathBuf::from("project_a/Cargo.toml"),
r#"
[package]
authors = ["The wasm-pack developers"]
description = "so awesome rust+wasm package"
license = "WTFPL"
name = "project_a"
repository = "https://github.com/rustwasm/wasm-pack.git"
version = "0.1.0"
[lib]
crate-type = ["cdylib"]
[dependencies]
wasm-bindgen = "=0.2.21"
project_b = { path = "../project_b" }
[dev-dependencies]
wasm-bindgen-test = "=0.2.21"
"#,
);
fixture.file(
PathBuf::from("project_a/src/lib.rs"),
r#"
extern crate wasm_bindgen;
// extern crate project_b;
use wasm_bindgen::prelude::*;
// Import the `window.alert` function from the Web.
#[wasm_bindgen]
extern {
fn alert(s: &str);
}
// Export a `greet` function from Rust to JavaScript, that alerts a
// hello message.
#[wasm_bindgen]
pub fn greet(name: &str) {
alert(&format!("Hello, {}!", name));
}
"#,
);
}
fn project_b_fixture(fixture: &mut Fixture) {
fixture.file(
PathBuf::from("project_b/README"),
"# Project Beta Fixture\n",
);
fixture.file(
PathBuf::from("project_b/Cargo.toml"),
r#"
[package]
authors = ["The wasm-pack developers"]
description = "so awesome rust+wasm package"
license = "WTFPL"
name = "project_b"
repository = "https://github.com/rustwasm/wasm-pack.git"
version = "0.1.0"
[lib]
crate-type = ["cdylib"]
[dependencies]
wasm-bindgen = "=0.2.21"
[dev-dependencies]
wasm-bindgen-test = "=0.2.21"
"#,
);
fixture.file(
PathBuf::from("project_b/src/lib.rs"),
r#"
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
// Import the `window.alert` function from the Web.
#[wasm_bindgen]
extern {
fn alert(s: &str);
}
// Export a `greet` function from Rust to JavaScript, that alerts a
// hello message.
#[wasm_bindgen]
pub fn greet(name: &str) {
alert(&format!("Hello, {}!", name));
}
"#,
);
}
let mut fixture = Fixture::new();
project_b_fixture(&mut fixture);
project_a_fixture(&mut fixture);
project_main_fixture(&mut fixture);
fixture
}

@ -1,4 +1,5 @@
use utils::fixture;
use wasm_pack::binaries::Cache;
use wasm_pack::test::webdriver;
#[test]
@ -9,7 +10,8 @@ use wasm_pack::test::webdriver;
))]
fn can_install_chromedriver() {
let fixture = fixture::js_hello_world();
assert!(webdriver::install_chromedriver(&fixture.path).is_ok());
let cache = Cache::at(&fixture.path);
assert!(webdriver::install_chromedriver(&cache, true).is_ok());
}
#[test]
@ -22,5 +24,6 @@ fn can_install_chromedriver() {
))]
fn can_install_geckodriver() {
let fixture = fixture::js_hello_world();
assert!(webdriver::install_geckodriver(&fixture.path).is_ok());
let cache = Cache::at(&fixture.path);
assert!(webdriver::install_geckodriver(&cache, true).is_ok());
}

Loading…
Cancel
Save