From 40ab630d974052c4fdb53635293640db6a043b3f Mon Sep 17 00:00:00 2001 From: Mackenzie Clark Date: Sun, 28 Oct 2018 22:23:50 -0700 Subject: [PATCH] fix canonicalize on windows Change to INFO when alerting users about missing fields in Cargo.toml Combine filed missing messages into one INFO line Fix bad formating Merge pull request #394 from mstallmo/master Change to INFO when alerting users about missing fields Cargo.toml child: Always print everything to our output Also don't buffer the child's stdout and stderr. error: Add stdout to the `Error::Cli` variant refactor: Return failure::Error instead of wasm_pack::error::Error refactor: Import self and use full module path for failure Use full module path for failure to be consistent since it's used like that in other modules. refactor: Return failure::Error instead of wasm_pack::error::Error chore: Run rustfmt chore: Run rustfmt Merge pull request #392 from fitzgen/child-process-and-output-management Child process and output management Merge pull request #401 from drager/return-failure-error Return `Result` instead of `Result` v0.5.1 Merge pull request #404 from rustwasm/0.5.1 v0.5.1 feat(website): bump vers Merge pull request #405 from rustwasm/website-update feat(website): bump vers test(command/build): add a test for build command useing local wasm-bindgen Fix typo in test function name for copying the README bugfix(bindgen-target-dir): use PathBuf to join the old code are hard coded path with "/", which may cause error on windows, thus changing to use PathBuf.join. fixing #414 change for cargo_metadata Merge branch 'master' into test-build-for-example Merge pull request #408 from huangjj27/test-build-for-example test(command/build): add a test for build command Merge pull request #412 from mstallmo/typo-fix Fix typo in test function name for copying the README Merge branch 'master' into fix-canonical-paths-on-windows this change is not related to this PR use absolutize remove unused use cargo fmt --- CHANGELOG.md | 66 ++++++++++++++ Cargo.lock | 138 +++++++++++++++++------------ Cargo.toml | 3 +- docs/index.html | 6 +- src/binaries.rs | 10 ++- src/bindgen.rs | 86 +++++++++--------- src/build.rs | 76 +++++++--------- src/child.rs | 177 +++++++++++++++++++++++++++++++++++++ src/command/build.rs | 38 ++++---- src/command/login.rs | 5 +- src/command/mod.rs | 9 +- src/command/pack.rs | 4 +- src/command/publish/mod.rs | 4 +- src/command/test.rs | 61 +++++++------ src/command/utils.rs | 12 +-- src/error.rs | 22 ++--- src/installer.rs | 6 +- src/lib.rs | 2 + src/lockfile.rs | 13 +-- src/logger.rs | 4 +- src/manifest/mod.rs | 40 +++++---- src/npm.rs | 64 ++++++-------- src/readme.rs | 4 +- src/test/mod.rs | 21 ++--- src/test/webdriver.rs | 21 +++-- tests/all/bindgen.rs | 26 +++--- tests/all/build.rs | 15 ++++ tests/all/main.rs | 2 + tests/all/manifest.rs | 63 ++++++------- tests/all/readme.rs | 2 +- tests/all/utils/fixture.rs | 10 ++- tests/all/utils/logger.rs | 6 ++ tests/all/utils/mod.rs | 1 + 33 files changed, 663 insertions(+), 354 deletions(-) create mode 100644 src/child.rs create mode 100644 tests/all/utils/logger.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index db92ba554..8b9394359 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,71 @@ # Changelog +## 🌄 0.5.1 + +- ### 🤕 Fixes + + - **Child Process and output management - [fitzgen], [issue/287] [pull/392]** + + Not exactly a "fix", but definitely a huge improvment in how child processes and their + output are handled by `wasm-pack`. Ever sat at a long prompt from `wasm-pack` and + wondered what was happening? No longer! Did `wasm-pack` eat your test output- no more! + + [issue/287]: https://github.com/rustwasm/wasm-pack/issues/287 + [pull/392]: https://github.com/rustwasm/wasm-pack/pull/392 + + - **Less scary missing field messages - [mstallmo], [issue/393] [pull/394]** + + After watching a livestream of someone using `wasm-pack`, [fitzgen] noted that folks + seemed pretty alarmed by the loud warning about missing optional manifest fields. + As a result, we are now downgrading those messages from WARN to INFO, and consolidating + them on a single line. + + [issue/393]: https://github.com/rustwasm/wasm-pack/issues/393 + [pull/394]: https://github.com/rustwasm/wasm-pack/pull/394 + + - **Add `exit_status` to CLI errors - [konstin], [issue/291] [pull/387]** + + We'd been hiding these- but we shouldn't have been! + + [konstin]: https://github.com/konstin + [issue/291]: https://github.com/rustwasm/wasm-pack/issues/291 + [pull/387]: https://github.com/rustwasm/wasm-pack/pull/387 + + - **Remove lingering forced nightly usage - [alexcrichton], [pull/383]** + + In 0.5.0 we removed all forced nightly usage as we depend on `~1.30` which is now + available on both nightly and beta channels! We had a bit of a race condition with + that PR and the `wasm-pack test` PR, and missed a few as a result! This removes all + lingering forced nightly, which only affected the `wasm-pack test` command. + + [pull/383]: https://github.com/rustwasm/wasm-pack/pull/383 + + - **Fix `wasm-bindgen-test` dependency error message - [fitzgen], [issue/377] [pull/378]** + + The error message about missing the `wasm-bindgen-test` dependency errantly stated + that the user was missing a `wasm-bindgen` dependency! We've fixed it to correctly + state the missing dependency now. + + [issue/377]: https://github.com/rustwasm/wasm-pack/issues/377 + [pull/378]: https://github.com/rustwasm/wasm-pack/pull/378 + + - **Fix prerequisites links in docs - [fitzgen], [pull/376]** + + [pull/376]: https://github.com/rustwasm/wasm-pack/pull/376 + +- ### 🛠️ Maintenance + + - **Leverage `failure::Error` consistently - [drager], [issue/280] [pull/401]** + + This PR finally makes it so that `wasm-pack` is handling errors in a consistent + way across the codebase. + + [drager]: https://github.com/drager + [issue/280]: https://github.com/rustwasm/wasm-pack/issues/280 + [pull/401]: https://github.com/rustwasm/wasm-pack/pull/401 + + + ## ☀️ 0.5.0 - ### ✨ Features diff --git a/Cargo.lock b/Cargo.lock index 9cf4cf602..3ed5c2344 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -92,7 +92,7 @@ dependencies = [ "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_json 1.0.30 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -159,7 +159,7 @@ dependencies = [ "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)", - "termios 0.3.0 (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)", ] @@ -174,22 +174,22 @@ dependencies = [ [[package]] name = "curl" -version = "0.4.17" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "curl-sys 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "curl-sys 0.4.13 (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)", - "schannel 0.1.13 (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)", ] [[package]] name = "curl-sys" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", @@ -223,7 +223,7 @@ name = "failure_derive" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", + "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)", @@ -241,7 +241,7 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", @@ -288,7 +288,7 @@ dependencies = [ "serde_derive 1.0.79 (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.6 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -359,7 +359,7 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -486,7 +486,7 @@ name = "parking_lot" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lock_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "lock_api 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -502,6 +502,22 @@ dependencies = [ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "path-absolutize" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "path-dedot 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "path-dedot" +version = "1.1.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)", +] + [[package]] name = "pkg-config" version = "0.3.14" @@ -514,7 +530,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "proc-macro2" -version = "0.4.19" +version = "0.4.20" 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)", @@ -525,7 +541,7 @@ name = "quote" version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -546,13 +562,21 @@ dependencies = [ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rand_core" -version = "0.2.1" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -636,7 +660,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "schannel" -version = "0.1.13" +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)", @@ -672,14 +696,14 @@ name = "serde_derive" version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", + "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.6 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_json" -version = "1.0.30" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -689,7 +713,7 @@ dependencies = [ [[package]] name = "slog" -version = "2.3.3" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -697,7 +721,7 @@ name = "slog-async" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "slog 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -709,7 +733,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "isatty 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "slog 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -745,21 +769,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "structopt" -version = "0.2.10" +version = "0.2.11" 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.10 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt-derive 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "structopt-derive" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", + "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)", + "syn 0.15.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -767,17 +791,17 @@ name = "syn" version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", + "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.6" +version = "0.15.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", + "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)", ] @@ -787,7 +811,7 @@ name = "synstructure" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", + "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)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -860,7 +884,7 @@ dependencies = [ [[package]] name = "termios" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", @@ -894,7 +918,7 @@ dependencies = [ [[package]] name = "toml" -version = "0.4.6" +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)", @@ -959,29 +983,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "wasm-pack" -version = "0.5.0" +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)", "console 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "curl 0.4.17 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", + "flate2 1.0.3 (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)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "path-absolutize 1.1.1 (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_json 1.0.30 (registry+https://github.com/rust-lang/crates.io-index)", - "slog 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.32 (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.10 (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)", "tempfile 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.4.6 (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)", "zip 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1046,7 +1071,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.2 (registry+https://github.com/rust-lang/crates.io-index)", + "flate2 1.0.3 (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)", @@ -1073,13 +1098,13 @@ dependencies = [ "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 crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb" -"checksum curl 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)" = "c8172e96ecfb1a2bfe3843d9d7154099a15130cf4a2f658259c7aa9cc2b5d4ff" -"checksum curl-sys 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "78800a6de442f65dab6ce26c6f369c14fc585686432bf4b77119d2d384216c31" +"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 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.2 (registry+https://github.com/rust-lang/crates.io-index)" = "37847f133aae7acf82bb9577ccd8bda241df836787642654286e79679826a54b" +"checksum flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4af030962d89d62aa52cd9492083b1cd9b2d1a77764878102a6c0f86b4d5444d" "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" @@ -1093,7 +1118,7 @@ dependencies = [ "checksum lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca488b89a5657b0a2ecd45b95609b3e848cf1755da332a0da46e2b2b1cb371a7" "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 lock_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "949826a5ccf18c1b3a7c3d57692778d21768b79e46eb9dd07bfc4c2160036c54" +"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" @@ -1109,13 +1134,16 @@ dependencies = [ "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 path-absolutize 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6bd20546730045b90f32bf46ecaf86a825c6fe1c912be34e0b5828d0829acec7" +"checksum path-dedot 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d6c852f9c1fd5acf5ce337fc80323cc8d5232fb3fa0976be41817da2d980b47" "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.19 (registry+https://github.com/rust-lang/crates.io-index)" = "ffe022fb8c8bd254524b0b3305906c1921fa37a84a644e29079a9e62200c3901" +"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 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.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2" +"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 regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384" @@ -1126,24 +1154,24 @@ dependencies = [ "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.13 (registry+https://github.com/rust-lang/crates.io-index)" = "dc1fabf2a7b6483a141426e1afd09ad543520a77ac49bd03c286e7696ccfd77f" +"checksum schannel 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "0e1a231dc10abf6749cfa5d7767f25888d484201accbd919b66ab5413c502d56" "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_json 1.0.30 (registry+https://github.com/rust-lang/crates.io-index)" = "7f60a296fed15c3edbbe9aa83b646531459e565c525b0ab628deb1a4b28e4180" -"checksum slog 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "09e4f1d0276ac7d448d98db16f0dab0220c24d4842d88ce4dad4b306fa234f1d" +"checksum serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "43344e7ce05d0d8280c5940cabb4964bea626aa58b1ec0e8c73fa2a8512a38ce" +"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" "checksum smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "153ffa32fd170e9944f7e0838edf824a754ec4c1fc64746fcc9fe1f8fa602e5d" "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.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d8e9ad6a11096cbecdcca0cc6aa403fdfdbaeda2fb3323a39c98e6a166a1e45a" -"checksum structopt-derive 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4cbce8ccdc62166bd594c14396a3242bf94c337a51dbfa9be1076dd74b3db2af" +"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.6 (registry+https://github.com/rust-lang/crates.io-index)" = "854b08a640fc8f54728fb95321e3ec485b365a97fe47609797c671addd1dde69" +"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 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" @@ -1152,11 +1180,11 @@ dependencies = [ "checksum term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e6b677dd1e8214ea1ef4297f85dbcbed8e8cdddb561040cc998ca2551c37561" "checksum termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "adc4587ead41bf016f11af03e55a624c06568b5a19db4e90fde573d805074f83" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" -"checksum termios 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "70226acdf12d182df757d9fb07c0257a1558ec48c8059f607d6b38145ce4e2fa" +"checksum termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72b620c5ea021d75a735c943269bb07d30c9b77d6ac6b236bc8b5c496ef05625" "checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" "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.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a0263c6c02c4db6c8f7681f9fd35e90de799ebd4cfdeab77a38f4ff6b3d8c0d9" +"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 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" diff --git a/Cargo.toml b/Cargo.toml index 3e2e13771..9cd9050d2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "wasm-pack" description = "pack up the wasm and publish it to npm!" -version = "0.5.0" +version = "0.5.1" authors = ["Ashley Williams "] repository = "https://github.com/ashleygwilliams/wasm-pack.git" license = "MIT/Apache-2.0" @@ -21,6 +21,7 @@ indicatif = "0.9.0" lazy_static = "1.1.0" openssl = { version = '0.10.11', optional = true } parking_lot = "0.6" +path-absolutize = "1.1.1" serde = "1.0.74" serde_derive = "1.0.74" serde_json = "1.0.26" diff --git a/docs/index.html b/docs/index.html index 8ec2cb65b..25906991a 100644 --- a/docs/index.html +++ b/docs/index.html @@ -42,9 +42,9 @@

wasm-pack

📦✨ your favorite rust -> wasm workflow tool!

- ✨ Install wasm-pack 0.5.0 ✨ -

24 Sep 2018 | - + ✨ Install wasm-pack 0.5.1 ✨ +

9 Oct 2018 | + Release Notes

diff --git a/src/binaries.rs b/src/binaries.rs index 82eacb70a..ba7a1ec26 100644 --- a/src/binaries.rs +++ b/src/binaries.rs @@ -138,7 +138,7 @@ pub fn install_binaries_from_targz_at_url<'a, I>( crate_path: &Path, url: &str, binaries: I, -) -> Result<(), Error> +) -> Result<(), failure::Error> where I: IntoIterator, { @@ -175,7 +175,8 @@ where .map(|s| s.to_string_lossy()) .collect::>() .join(", "), - ))) + )) + .into()) } } @@ -186,7 +187,7 @@ pub fn install_binaries_from_zip_at_url<'a, I>( crate_path: &Path, url: &str, binaries: I, -) -> Result<(), Error> +) -> Result<(), failure::Error> where I: IntoIterator, { @@ -226,7 +227,8 @@ where .map(|s| s.to_string_lossy()) .collect::>() .join(", "), - ))) + )) + .into()) } } diff --git a/src/bindgen.rs b/src/bindgen.rs index 715bcfa5c..296e4ab38 100644 --- a/src/bindgen.rs +++ b/src/bindgen.rs @@ -1,8 +1,11 @@ //! Functionality related to installing and running `wasm-bindgen`. use binaries::{self, bin_path, install_binaries_from_targz_at_url}; +use cargo_metadata; +use child; use emoji; use error::Error; +use failure::{self, ResultExt}; use progressbar::Step; use slog::Logger; use std::path::{Path, PathBuf}; @@ -22,7 +25,7 @@ pub fn install_wasm_bindgen( install_permitted: bool, step: &Step, log: &Logger, -) -> Result<(), Error> { +) -> 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)) @@ -37,7 +40,7 @@ pub fn install_wasm_bindgen( // permitted, return a configuration error. if !install_permitted { let msg = format!("wasm-bindgen v{} is not installed!", version); - return Error::crate_config(&msg); + return Err(Error::crate_config(&msg).into()); } let msg = format!("{}Installing wasm-bindgen...", emoji::DOWN_ARROW); @@ -48,12 +51,15 @@ pub fn install_wasm_bindgen( log, "could not download pre-built `wasm-bindgen`: {}. Falling back to `cargo install`.", e ); - cargo_install_wasm_bindgen(root_path, version) + cargo_install_wasm_bindgen(log, root_path, version) }) } /// Download a tarball containing a pre-built `wasm-bindgen` binary. -pub fn download_prebuilt_wasm_bindgen(root_path: &Path, version: &str) -> Result<(), Error> { +pub fn download_prebuilt_wasm_bindgen( + root_path: &Path, + version: &str, +) -> Result<(), failure::Error> { let target = if target::LINUX && target::x86_64 { "x86_64-unknown-linux-musl" } else if target::MACOS && target::x86_64 { @@ -63,7 +69,8 @@ pub fn download_prebuilt_wasm_bindgen(root_path: &Path, version: &str) -> Result } else { return Err(Error::unsupported( "there are no pre-built `wasm-bindgen` binaries for this target", - )); + ) + .into()); }; let url = format!( @@ -81,28 +88,23 @@ pub fn download_prebuilt_wasm_bindgen(root_path: &Path, version: &str) -> Result /// Use `cargo install` to install the `wasm-bindgen` CLI locally into the given /// crate. -pub fn cargo_install_wasm_bindgen(crate_path: &Path, version: &str) -> Result<(), Error> { - let output = Command::new("cargo") - .arg("install") +pub fn cargo_install_wasm_bindgen( + logger: &Logger, + crate_path: &Path, + version: &str, +) -> Result<(), failure::Error> { + let mut cmd = Command::new("cargo"); + cmd.arg("install") .arg("--force") .arg("wasm-bindgen-cli") .arg("--version") .arg(version) .arg("--root") - .arg(crate_path) - .output()?; - if !output.status.success() { - let message = "Installing wasm-bindgen failed".to_string(); - let s = String::from_utf8_lossy(&output.stderr); - Err(Error::Cli { - message, - stderr: s.to_string(), - exit_status: output.status, - }) - } else { - assert!(binaries::local_bin_path(crate_path, "wasm-bindgen").is_file()); - Ok(()) - } + .arg(crate_path); + + child::run(logger, cmd, "cargo install").context("Installing wasm-bindgen with cargo")?; + assert!(binaries::local_bin_path(crate_path, "wasm-bindgen").is_file()); + Ok(()) } /// Run the `wasm-bindgen` CLI to generate bindings for the current crate's @@ -116,7 +118,7 @@ pub fn wasm_bindgen_build( debug: bool, step: &Step, log: &Logger, -) -> Result<(), Error> { +) -> Result<(), failure::Error> { let msg = format!("{}Running WASM-bindgen...", emoji::RUNNER); PBAR.step(step, &msg); @@ -126,10 +128,17 @@ pub fn wasm_bindgen_build( 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 manifest = path.join("Cargo.toml"); + let target_path = cargo_metadata::metadata(Some(&manifest)) + .unwrap() + .target_directory; + let mut wasm_path = PathBuf::from(&target_path) + .join("wasm32-unknown-unknown") + .join(release_or_debug) + .join(binary_name); + wasm_path.set_extension("wasm"); + let wasm_path = wasm_path.display().to_string(); + let dts_arg = if disable_dts { "--no-typescript" } else { @@ -153,27 +162,20 @@ pub fn wasm_bindgen_build( cmd.arg("--debug"); } - let output = cmd.output()?; - if !output.status.success() { - let s = String::from_utf8_lossy(&output.stderr); - Error::cli("wasm-bindgen failed to execute properly", s, output.status) - } else { - Ok(()) - } + child::run(log, cmd, "wasm-bindgen").context("Running the wasm-bindgen CLI")?; + Ok(()) } else { - Error::crate_config("Could not find `wasm-bindgen`") + Err(Error::crate_config("Could not find `wasm-bindgen`").into()) } } /// Check if the `wasm-bindgen` dependency is locally satisfied. fn wasm_bindgen_version_check(bindgen_path: &PathBuf, dep_version: &str, log: &Logger) -> bool { - Command::new(bindgen_path) - .arg("--version") - .output() - .ok() - .filter(|output| output.status.success()) - .map(|output| { - String::from_utf8_lossy(&output.stdout) + let mut cmd = Command::new(bindgen_path); + cmd.arg("--version"); + child::run(log, cmd, "wasm-bindgen") + .map(|stdout| { + stdout .trim() .split_whitespace() .nth(1) diff --git a/src/build.rs b/src/build.rs index 928fc32ee..f539744c8 100644 --- a/src/build.rs +++ b/src/build.rs @@ -1,15 +1,18 @@ //! Building a Rust crate into a `.wasm` binary. +use child; use emoji; use error::Error; +use failure::ResultExt; use progressbar::Step; +use slog::Logger; use std::path::Path; use std::process::Command; 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 { +pub fn check_rustc_version(step: &Step) -> Result { let msg = format!("{}Checking `rustc` version...", emoji::CRAB); PBAR.step(step, &msg); let local_minor_version = rustc_minor_version(); @@ -22,14 +25,14 @@ pub fn check_rustc_version(step: &Step) -> Result { mv.to_string() ), local_minor_version: mv.to_string(), - }) + }.into()) } else { 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()), } } @@ -54,28 +57,23 @@ fn rustc_minor_version() -> Option { /// Ensure that `rustup` has the `wasm32-unknown-unknown` target installed for /// current toolchain -pub fn rustup_add_wasm_target(step: &Step) -> Result<(), Error> { +pub fn rustup_add_wasm_target(log: &Logger, step: &Step) -> Result<(), failure::Error> { let msg = format!("{}Adding WASM target...", emoji::TARGET); PBAR.step(step, &msg); - let output = Command::new("rustup") - .arg("target") - .arg("add") - .arg("wasm32-unknown-unknown") - .output()?; - if !output.status.success() { - let s = String::from_utf8_lossy(&output.stderr); - Error::cli( - "Adding the wasm32-unknown-unknown target failed", - s, - output.status, - ) - } else { - Ok(()) - } + let mut cmd = Command::new("rustup"); + cmd.arg("target").arg("add").arg("wasm32-unknown-unknown"); + child::run(log, cmd, "rustup") + .context("Adding the wasm32-unknown-unknown target with rustup")?; + Ok(()) } /// Run `cargo build` targetting `wasm32-unknown-unknown`. -pub fn cargo_build_wasm(path: &Path, debug: bool, step: &Step) -> Result<(), Error> { +pub fn cargo_build_wasm( + log: &Logger, + path: &Path, + debug: bool, + step: &Step, +) -> Result<(), failure::Error> { let msg = format!("{}Compiling to WASM...", emoji::CYCLONE); PBAR.step(step, &msg); let mut cmd = Command::new("cargo"); @@ -84,32 +82,22 @@ pub fn cargo_build_wasm(path: &Path, debug: bool, step: &Step) -> Result<(), Err cmd.arg("--release"); } cmd.arg("--target").arg("wasm32-unknown-unknown"); - let output = cmd.output()?; - - if !output.status.success() { - let s = String::from_utf8_lossy(&output.stderr); - Error::cli("Compilation of your program failed", s, output.status) - } else { - Ok(()) - } + child::run(log, cmd, "cargo build").context("Compiling your crate to WebAssembly")?; + Ok(()) } /// Run `cargo build --tests` targetting `wasm32-unknown-unknown`. -pub fn cargo_build_wasm_tests(path: &Path, debug: bool) -> Result<(), Error> { - let output = { - let mut cmd = Command::new("cargo"); - cmd.current_dir(path).arg("build").arg("--tests"); - if !debug { - cmd.arg("--release"); - } - cmd.arg("--target").arg("wasm32-unknown-unknown"); - cmd.output()? - }; - - if !output.status.success() { - let s = String::from_utf8_lossy(&output.stderr); - Error::cli("Compilation of your program failed", s, output.status) - } else { - Ok(()) +pub fn cargo_build_wasm_tests( + log: &Logger, + path: &Path, + debug: bool, +) -> Result<(), failure::Error> { + let mut cmd = Command::new("cargo"); + cmd.current_dir(path).arg("build").arg("--tests"); + if !debug { + cmd.arg("--release"); } + cmd.arg("--target").arg("wasm32-unknown-unknown"); + child::run(log, cmd, "cargo build").context("Compilation of your program failed")?; + Ok(()) } diff --git a/src/child.rs b/src/child.rs new file mode 100644 index 000000000..9b45d70fb --- /dev/null +++ b/src/child.rs @@ -0,0 +1,177 @@ +//! Utilties for managing child processes. +//! +//! 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 slog::Logger; +use std::{ + io::{self, Read}, + mem, process, string, + sync::mpsc, + thread, +}; +use PBAR; + +#[derive(Debug)] +enum OutputFragment { + Stdout(Vec), + Stderr(Vec), +} + +/// Read data from the give reader and send it as an `OutputFragment` over the +/// given sender. +fn read_and_send( + mut reader: R, + sender: mpsc::Sender, + mut map: F, +) -> io::Result<()> +where + R: Read, + F: FnMut(Vec) -> OutputFragment, +{ + let mut buf = vec![0; 1024]; + loop { + match reader.read(&mut buf) { + Err(e) => { + if e.kind() == io::ErrorKind::Interrupted { + continue; + } else { + return Err(e); + } + } + Ok(0) => return Ok(()), + Ok(n) => { + buf.truncate(n); + let buf = mem::replace(&mut buf, vec![0; 1024]); + sender.send(map(buf)).unwrap(); + } + } + } +} + +/// Accumulates output from a stream of output fragments and calls a callback on +/// each complete line as it is accumulating. +struct OutputAccumulator { + result: String, + in_progress: Vec, + on_each_line: F, +} + +impl OutputAccumulator +where + F: FnMut(&str), +{ + /// Construct a new output accumulator with the given `on_each_line` + /// callback. + fn new(on_each_line: F) -> OutputAccumulator { + OutputAccumulator { + result: String::new(), + in_progress: Vec::new(), + on_each_line, + } + } + + /// Add another fragment of output to the accumulation, calling the + /// `on_each_line` callback for any complete lines we accumulate. + fn push(&mut self, fragment: Vec) -> Result<(), string::FromUtf8Error> { + debug_assert!(!fragment.is_empty()); + self.in_progress.extend(fragment); + + if let Some((last_newline, _)) = self + .in_progress + .iter() + .cloned() + .enumerate() + .rev() + .find(|(_, ch)| *ch == b'\n') + { + let next_in_progress: Vec = self.in_progress[last_newline + 1..] + .iter() + .cloned() + .collect(); + let mut these_lines = mem::replace(&mut self.in_progress, next_in_progress); + these_lines.truncate(last_newline + 1); + let these_lines = String::from_utf8(these_lines)?; + for line in these_lines.lines() { + (self.on_each_line)(line); + } + self.result.push_str(&these_lines); + } + + Ok(()) + } + + /// Finish accumulation, run the `on_each_line` callback on the final line + /// (if any), and return the accumulated output. + fn finish(mut self) -> Result { + if !self.in_progress.is_empty() { + let last_line = String::from_utf8(self.in_progress)?; + (self.on_each_line)(&last_line); + self.result.push_str(&last_line); + } + Ok(self.result) + } +} + +/// Run the given command and return its stdout. +pub fn run( + logger: &Logger, + mut command: process::Command, + command_name: &str, +) -> Result { + info!(logger, "Running {:?}", command); + + let mut child = command + .stdout(process::Stdio::piped()) + .stderr(process::Stdio::piped()) + .spawn()?; + + let stdout = child.stdout.take().unwrap(); + let stderr = child.stderr.take().unwrap(); + + let (send, recv) = mpsc::channel(); + let stdout_send = send.clone(); + let stderr_send = send; + + // Because pipes have a fixed-size buffer, we need to keep reading stdout + // and stderr on a separate thread to avoid potential dead locks with + // waiting on the child process. + + let stdout_handle = + thread::spawn(move || read_and_send(stdout, stdout_send, OutputFragment::Stdout)); + let stderr_handle = + thread::spawn(move || read_and_send(stderr, stderr_send, OutputFragment::Stderr)); + + let mut stdout = OutputAccumulator::new(|line| { + info!(logger, "{} (stdout): {}", command_name, line); + PBAR.message(line) + }); + let mut stderr = OutputAccumulator::new(|line| { + info!(logger, "{} (stderr): {}", command_name, line); + PBAR.message(line) + }); + + for output in recv { + match output { + OutputFragment::Stdout(line) => stdout.push(line)?, + OutputFragment::Stderr(line) => stderr.push(line)?, + }; + } + + let stdout = stdout.finish()?; + let stderr = stderr.finish()?; + + // Join the threads reading the child's output to make sure the finish OK. + stdout_handle.join().unwrap()?; + stderr_handle.join().unwrap()?; + + let exit = child.wait()?; + 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()); + } +} diff --git a/src/command/build.rs b/src/command/build.rs index 9e81c653e..be1de7234 100644 --- a/src/command/build.rs +++ b/src/command/build.rs @@ -55,7 +55,7 @@ impl FromStr for BuildMode { "no-install" => Ok(BuildMode::Noinstall), "normal" => Ok(BuildMode::Normal), "force" => Ok(BuildMode::Force), - _ => Error::crate_config(&format!("Unknown build mode: {}", s)).map(|_| unreachable!()), + _ => Err(Error::crate_config(&format!("Unknown build mode: {}", s))), } } } @@ -94,11 +94,11 @@ pub struct BuildOptions { pub out_dir: String, } -type BuildStep = fn(&mut Build, &Step, &Logger) -> Result<(), Error>; +type BuildStep = fn(&mut Build, &Step, &Logger) -> Result<(), failure::Error>; impl Build { /// Construct a build command from the given options. - pub fn try_from_opts(build_opts: BuildOptions) -> Result { + pub fn try_from_opts(build_opts: BuildOptions) -> Result { let crate_path = set_crate_path(build_opts.path)?; let crate_name = manifest::get_crate_name(&crate_path)?; let out_dir = crate_path.join(PathBuf::from(build_opts.out_dir)); @@ -117,7 +117,7 @@ impl Build { } /// Execute this `Build` command. - pub fn run(&mut self, log: &Logger) -> Result<(), Error> { + pub fn run(&mut self, log: &Logger) -> Result<(), failure::Error> { let process_steps = Build::get_process_steps(&self.mode); let mut step_counter = Step::new(process_steps.len()); @@ -188,7 +188,11 @@ impl Build { } } - fn step_check_rustc_version(&mut self, step: &Step, log: &Logger) -> Result<(), Error> { + fn step_check_rustc_version( + &mut self, + step: &Step, + log: &Logger, + ) -> Result<(), failure::Error> { info!(&log, "Checking rustc version..."); let version = build::check_rustc_version(step)?; let msg = format!("rustc version is {}.", version); @@ -196,23 +200,23 @@ impl Build { Ok(()) } - fn step_check_crate_config(&mut self, step: &Step, log: &Logger) -> Result<(), Error> { + 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<(), Error> { + fn step_add_wasm_target(&mut self, step: &Step, log: &Logger) -> Result<(), failure::Error> { info!(&log, "Adding wasm-target..."); - build::rustup_add_wasm_target(step)?; + 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<(), Error> { + fn step_build_wasm(&mut self, step: &Step, log: &Logger) -> Result<(), failure::Error> { info!(&log, "Building wasm..."); - build::cargo_build_wasm(&self.crate_path, self.debug, step)?; + build::cargo_build_wasm(log, &self.crate_path, self.debug, step)?; info!( &log, @@ -226,14 +230,14 @@ impl Build { Ok(()) } - fn step_create_dir(&mut self, step: &Step, log: &Logger) -> Result<(), Error> { + fn step_create_dir(&mut self, step: &Step, log: &Logger) -> Result<(), failure::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<(), Error> { + fn step_create_json(&mut self, step: &Step, log: &Logger) -> Result<(), failure::Error> { info!(&log, "Writing a package.json..."); manifest::write_package_json( &self.crate_path, @@ -251,14 +255,18 @@ impl Build { Ok(()) } - fn step_copy_readme(&mut self, step: &Step, log: &Logger) -> Result<(), Error> { + fn step_copy_readme(&mut self, step: &Step, log: &Logger) -> Result<(), failure::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<(), Error> { + fn step_install_wasm_bindgen( + &mut self, + step: &Step, + log: &Logger, + ) -> Result<(), failure::Error> { info!(&log, "Identifying wasm-bindgen dependency..."); let lockfile = Lockfile::new(&self.crate_path)?; let bindgen_version = lockfile.require_wasm_bindgen()?; @@ -288,7 +296,7 @@ impl Build { Ok(()) } - fn step_run_wasm_bindgen(&mut self, step: &Step, log: &Logger) -> Result<(), Error> { + fn step_run_wasm_bindgen(&mut self, step: &Step, log: &Logger) -> Result<(), failure::Error> { info!(&log, "Building the wasm bindings..."); bindgen::wasm_bindgen_build( &self.crate_path, diff --git a/src/command/login.rs b/src/command/login.rs index f537cdc0c..a660cb9e3 100644 --- a/src/command/login.rs +++ b/src/command/login.rs @@ -1,4 +1,3 @@ -use error::Error; use npm; use slog::Logger; use std::result; @@ -10,7 +9,7 @@ pub fn login( always_auth: bool, auth_type: Option, log: &Logger, -) -> result::Result<(), Error> { +) -> result::Result<(), failure::Error> { let registry = registry.unwrap_or(npm::DEFAULT_NPM_REGISTRY.to_string()); info!(&log, "Logging in to npm..."); @@ -23,7 +22,7 @@ pub fn login( &auth_type ); info!(&log, "npm info located in the npm debug log"); - npm::npm_login(®istry, &scope, always_auth, &auth_type)?; + npm::npm_login(log, ®istry, &scope, always_auth, &auth_type)?; info!(&log, "Logged you in!"); PBAR.message(&format!("👋 logged you in!")); diff --git a/src/command/mod.rs b/src/command/mod.rs index 248ab7c85..ee418da4c 100644 --- a/src/command/mod.rs +++ b/src/command/mod.rs @@ -84,7 +84,7 @@ pub enum Command { } /// Run a command with the given logger! -pub fn run_wasm_pack(command: Command, log: &Logger) -> result::Result<(), Error> { +pub fn run_wasm_pack(command: Command, log: &Logger) -> result::Result<(), failure::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 status = match command { @@ -129,7 +129,12 @@ pub fn run_wasm_pack(command: Command, log: &Logger) -> result::Result<(), Error Ok(_) => {} Err(ref e) => { error!(&log, "{}", e); - PBAR.error(e.error_type()); + for c in e.iter_chain() { + if let Some(e) = c.downcast_ref::() { + PBAR.error(e.error_type()); + break; + } + } } } diff --git a/src/command/pack.rs b/src/command/pack.rs index 5390b5790..f4820fc6b 100644 --- a/src/command/pack.rs +++ b/src/command/pack.rs @@ -8,7 +8,7 @@ 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, log: &Logger) -> result::Result<(), Error> { +pub fn pack(path: Option, log: &Logger) -> result::Result<(), failure::Error> { let crate_path = set_crate_path(path)?; info!(&log, "Packing up the npm package..."); @@ -18,7 +18,7 @@ pub fn pack(path: Option, log: &Logger) -> result::Result<(), Error> { &crate_path, &crate_path ), })?; - npm::npm_pack(&pkg_directory.to_string_lossy())?; + npm::npm_pack(log, &pkg_directory.to_string_lossy())?; info!( &log, "Your package is located at {:#?}", diff --git a/src/command/publish/mod.rs b/src/command/publish/mod.rs index 0b69b0037..8e1acb69f 100644 --- a/src/command/publish/mod.rs +++ b/src/command/publish/mod.rs @@ -16,7 +16,7 @@ pub fn publish( path: Option, access: Option, log: &Logger, -) -> result::Result<(), Error> { +) -> result::Result<(), failure::Error> { let crate_path = set_crate_path(path)?; info!(&log, "Publishing the npm package..."); @@ -28,7 +28,7 @@ pub fn publish( ), })?; - npm::npm_publish(&pkg_directory.to_string_lossy(), access)?; + npm::npm_publish(log, &pkg_directory.to_string_lossy(), access)?; info!(&log, "Published your package!"); PBAR.message("💥 published your package!"); diff --git a/src/command/test.rs b/src/command/test.rs index 1bf2e97ba..507bd1887 100644 --- a/src/command/test.rs +++ b/src/command/test.rs @@ -94,11 +94,11 @@ pub struct Test { test_runner_path: Option, } -type TestStep = fn(&mut Test, &Step, &Logger) -> Result<(), Error>; +type TestStep = fn(&mut Test, &Step, &Logger) -> Result<(), failure::Error>; impl Test { /// Construct a test command from the given options. - pub fn try_from_opts(test_opts: TestOptions) -> Result { + pub fn try_from_opts(test_opts: TestOptions) -> Result { let TestOptions { path, node, @@ -124,18 +124,18 @@ impl Test { let any_browser = chrome || firefox || safari; if !node && !any_browser { - return Error::crate_config( + return Err(Error::crate_config( "Must specify at least one of `--node`, `--chrome`, `--firefox`, or `--safari`", ) - .map(|_| unreachable!()); + .into()); } if headless && !any_browser { - return Error::crate_config( + return Err(Error::crate_config( "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.", ) - .map(|_| unreachable!()); + .into()); } Ok(Test { @@ -155,7 +155,7 @@ impl Test { } /// Execute this test command. - pub fn run(mut self, log: &Logger) -> Result<(), Error> { + pub fn run(mut self, log: &Logger) -> Result<(), failure::Error> { let process_steps = self.get_process_steps(); let mut step_counter = Step::new(process_steps.len()); @@ -227,40 +227,48 @@ impl Test { } } - fn step_check_rustc_version(&mut self, step: &Step, log: &Logger) -> Result<(), Error> { + fn step_check_rustc_version( + &mut self, + step: &Step, + log: &Logger, + ) -> Result<(), failure::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<(), Error> { + 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<(), Error> { + fn step_add_wasm_target(&mut self, step: &Step, log: &Logger) -> Result<(), failure::Error> { info!(&log, "Adding wasm-target..."); - build::rustup_add_wasm_target(step)?; + 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<(), Error> { + fn step_build_tests(&mut self, step: &Step, log: &Logger) -> Result<(), failure::Error> { info!(log, "Compiling tests to wasm..."); let msg = format!("{}Compiling tests to WASM...", emoji::CYCLONE); PBAR.step(step, &msg); - build::cargo_build_wasm_tests(&self.crate_path, !self.release)?; + build::cargo_build_wasm_tests(log, &self.crate_path, !self.release)?; info!(log, "Finished compiling tests to wasm."); Ok(()) } - fn step_install_wasm_bindgen(&mut self, step: &Step, log: &Logger) -> Result<(), Error> { + fn step_install_wasm_bindgen( + &mut self, + step: &Step, + log: &Logger, + ) -> Result<(), failure::Error> { info!(&log, "Identifying wasm-bindgen dependency..."); let lockfile = Lockfile::new(&self.crate_path)?; let bindgen_version = lockfile.require_wasm_bindgen()?; @@ -277,7 +285,7 @@ impl Test { wasm-bindgen-test = \"0.2\"", style("wasm-bindgen-test").bold().dim(), ); - return Err(Error::CrateConfig { message }); + return Err(Error::CrateConfig { message }.into()); } let install_permitted = match self.mode { @@ -310,7 +318,7 @@ impl Test { Ok(()) } - fn step_test_node(&mut self, step: &Step, log: &Logger) -> Result<(), Error> { + fn step_test_node(&mut self, step: &Step, log: &Logger) -> Result<(), failure::Error> { assert!(self.node); info!(log, "Running tests in node..."); PBAR.step(step, "Running tests in node..."); @@ -327,7 +335,7 @@ impl Test { Ok(()) } - fn step_get_chromedriver(&mut self, step: &Step, log: &Logger) -> Result<(), Error> { + fn step_get_chromedriver(&mut self, step: &Step, log: &Logger) -> Result<(), failure::Error> { PBAR.step(step, "Getting chromedriver..."); assert!(self.chrome && self.chromedriver.is_none()); @@ -339,7 +347,7 @@ impl Test { Ok(()) } - fn step_test_chrome(&mut self, step: &Step, log: &Logger) -> Result<(), Error> { + fn step_test_chrome(&mut self, step: &Step, log: &Logger) -> Result<(), failure::Error> { PBAR.step(step, "Running tests in Chrome..."); let chromedriver = self.chromedriver.as_ref().unwrap().display().to_string(); @@ -366,10 +374,11 @@ impl Test { envs.push(("NO_HEADLESS", "1")); } - test::cargo_test_wasm(&self.crate_path, self.release, log, envs) + test::cargo_test_wasm(&self.crate_path, self.release, log, envs)?; + Ok(()) } - fn step_get_geckodriver(&mut self, step: &Step, log: &Logger) -> Result<(), Error> { + fn step_get_geckodriver(&mut self, step: &Step, log: &Logger) -> Result<(), failure::Error> { PBAR.step(step, "Getting geckodriver..."); assert!(self.firefox && self.geckodriver.is_none()); @@ -381,7 +390,7 @@ impl Test { Ok(()) } - fn step_test_firefox(&mut self, step: &Step, log: &Logger) -> Result<(), Error> { + fn step_test_firefox(&mut self, step: &Step, log: &Logger) -> Result<(), failure::Error> { PBAR.step(step, "Running tests in Firefox..."); let geckodriver = self.geckodriver.as_ref().unwrap().display().to_string(); @@ -408,10 +417,11 @@ impl Test { envs.push(("NO_HEADLESS", "1")); } - test::cargo_test_wasm(&self.crate_path, self.release, log, envs) + test::cargo_test_wasm(&self.crate_path, self.release, log, envs)?; + Ok(()) } - fn step_get_safaridriver(&mut self, step: &Step, log: &Logger) -> Result<(), Error> { + fn step_get_safaridriver(&mut self, step: &Step, log: &Logger) -> Result<(), failure::Error> { PBAR.step(step, "Getting safaridriver..."); assert!(self.safari && self.safaridriver.is_none()); @@ -419,7 +429,7 @@ impl Test { Ok(()) } - fn step_test_safari(&mut self, step: &Step, log: &Logger) -> Result<(), Error> { + fn step_test_safari(&mut self, step: &Step, log: &Logger) -> Result<(), failure::Error> { PBAR.step(step, "Running tests in Safari..."); let safaridriver = self.safaridriver.as_ref().unwrap().display().to_string(); @@ -446,6 +456,7 @@ impl Test { envs.push(("NO_HEADLESS", "1")); } - test::cargo_test_wasm(&self.crate_path, self.release, log, envs) + test::cargo_test_wasm(&self.crate_path, self.release, log, envs)?; + Ok(()) } } diff --git a/src/command/utils.rs b/src/command/utils.rs index 07db00cdf..8879b878e 100644 --- a/src/command/utils.rs +++ b/src/command/utils.rs @@ -1,26 +1,26 @@ //! Utility functions for commands. use emoji; -use error::Error; +use failure; +use path_absolutize::*; 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) -> io::Result { +pub fn set_crate_path(path: Option) -> Result { let crate_path = match path { Some(p) => p, None => PathBuf::from("."), }; - - crate_path.canonicalize() + let absolute_crate_path = crate_path.absolutize()?; + Ok(absolute_crate_path) } /// Construct our `pkg` directory in the crate. -pub fn create_pkg_dir(out_dir: &Path, step: &Step) -> Result<(), Error> { +pub fn create_pkg_dir(out_dir: &Path, step: &Step) -> Result<(), failure::Error> { let msg = format!("{}Creating a pkg directory...", emoji::FOLDER); PBAR.step(step, &msg); fs::create_dir_all(&out_dir)?; diff --git a/src/error.rs b/src/error.rs index 5b65d00e0..75c43b309 100644 --- a/src/error.rs +++ b/src/error.rs @@ -48,14 +48,14 @@ pub enum Error { /// An error invoking another CLI tool. #[fail( - display = "Process exited with {}: {}. stderr:\n\n{}", - exit_status, - message, - stderr + 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 @@ -101,19 +101,20 @@ pub enum Error { impl Error { /// Construct a CLI error. - pub fn cli(message: &str, stderr: Cow, exit_status: ExitStatus) -> Result<(), Self> { - Err(Error::Cli { + pub fn cli(message: &str, stdout: Cow, stderr: Cow, 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) -> Result<(), Self> { - Err(Error::CrateConfig { + pub fn crate_config(message: &str) -> Self { + Error::CrateConfig { message: message.to_string(), - }) + } } /// Construct an archive error. @@ -161,6 +162,7 @@ impl Error { } => "Your rustc version is not supported. Please install version 1.30.0 or higher.", Error::Cli { message: _, + stdout: _, stderr: _, exit_status: _, } => "There was an error while calling another CLI tool. Details:\n\n", diff --git a/src/installer.rs b/src/installer.rs index 8d1f779a9..b2e42ad20 100644 --- a/src/installer.rs +++ b/src/installer.rs @@ -23,7 +23,7 @@ use std::path::Path; use std::process; use atty; -use failure::{Error, ResultExt}; +use failure::{self, ResultExt}; use which; pub fn install() -> ! { @@ -47,7 +47,7 @@ pub fn install() -> ! { process::exit(0); } -fn do_install() -> Result<(), Error> { +fn do_install() -> Result<(), failure::Error> { // Find `rustup.exe` in PATH, we'll be using its installation directory as // our installation directory. let rustup = match which::which("rustup") { @@ -85,7 +85,7 @@ fn do_install() -> Result<(), Error> { Ok(()) } -fn confirm_can_overwrite(dst: &Path) -> Result<(), Error> { +fn confirm_can_overwrite(dst: &Path) -> Result<(), failure::Error> { // If the `-f` argument was passed, we can always overwrite everything. if env::args().any(|arg| arg == "-f") { return Ok(()); diff --git a/src/lib.rs b/src/lib.rs index bb3f2b1c6..830b6c405 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,6 +12,7 @@ extern crate indicatif; #[macro_use] extern crate lazy_static; extern crate parking_lot; +extern crate path_absolutize; #[macro_use] extern crate serde_derive; extern crate serde_json; @@ -29,6 +30,7 @@ extern crate zip; pub mod binaries; pub mod bindgen; pub mod build; +pub mod child; pub mod command; pub mod emoji; pub mod error; diff --git a/src/lockfile.rs b/src/lockfile.rs index e016802f3..1b2cb81ac 100644 --- a/src/lockfile.rs +++ b/src/lockfile.rs @@ -23,10 +23,10 @@ struct Package { impl Lockfile { /// Read the `Cargo.lock` file for the crate at the given path. - pub fn new(crate_path: &Path) -> Result { + pub fn new(crate_path: &Path) -> Result { let lock_path = get_lockfile_path(crate_path)?; let lockfile = fs::read_to_string(lock_path)?; - toml::from_str(&lockfile).map_err(Error::from) + toml::from_str(&lockfile).map_err(|err| Error::from(err).into()) } /// Get the version of `wasm-bindgen` dependency used in the `Cargo.lock`. @@ -36,7 +36,7 @@ impl Lockfile { /// Like `wasm_bindgen_version`, except it returns an error instead of /// `None`. - pub fn require_wasm_bindgen(&self) -> Result<&str, Error> { + pub fn require_wasm_bindgen(&self) -> Result<&str, failure::Error> { self.wasm_bindgen_version().ok_or_else(|| { let message = format!( "Ensure that you have \"{}\" as a dependency in your Cargo.toml file:\n\ @@ -44,7 +44,7 @@ impl Lockfile { wasm-bindgen = \"0.2\"", style("wasm-bindgen").bold().dim(), ); - Error::CrateConfig { message } + Error::CrateConfig { message }.into() }) } @@ -63,7 +63,7 @@ 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 { +fn get_lockfile_path(crate_path: &Path) -> Result { // 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)) @@ -77,7 +77,8 @@ fn get_lockfile_path(crate_path: &Path) -> Result { if !lockfile_path.is_file() { Err(Error::CrateConfig { message: format!("Could not find lockfile at {:?}", lockfile_path), - }) + } + .into()) } else { Ok(lockfile_path) } diff --git a/src/logger.rs b/src/logger.rs index 543e60386..f8f6cc4cb 100644 --- a/src/logger.rs +++ b/src/logger.rs @@ -1,7 +1,7 @@ //! Logging facilities for `wasm-pack`. use command::Command; -use error::Error; +use failure; use slog::{Drain, Level, Logger}; use slog_async::Async; use slog_term::{FullFormat, PlainDecorator}; @@ -9,7 +9,7 @@ use std::fs::OpenOptions; use std::path::PathBuf; /// Create the logger for wasm-pack that will output any info warning or errors we encounter -pub fn new(cmd: &Command, verbosity: u8) -> Result { +pub fn new(cmd: &Command, verbosity: u8) -> Result { let log_path = log_file_path(&cmd); let file = OpenOptions::new() .create(true) diff --git a/src/manifest/mod.rs b/src/manifest/mod.rs index 4b559db09..f253b15d5 100644 --- a/src/manifest/mod.rs +++ b/src/manifest/mod.rs @@ -12,6 +12,7 @@ use self::npm::{ }; use emoji; use error::Error; +use failure; use progressbar::Step; use serde_json; use toml; @@ -38,22 +39,23 @@ struct CargoPackage { impl CargoPackage { fn check_optional_fields(&self) { - let warn_fmt = |field| { - format!( - "Field '{}' is missing from Cargo.toml. It is not necessary, but recommended", - field - ) - }; - + let mut messages = vec![]; if self.description.is_none() { - PBAR.warn(&warn_fmt("description")); + messages.push("description"); } if self.repository.is_none() { - PBAR.warn(&warn_fmt("repository")); + messages.push("repository"); } if self.license.is_none() { - PBAR.warn(&warn_fmt("license")); + messages.push("license"); } + + 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])), + _ => () + }; } } @@ -75,14 +77,14 @@ struct CargoLib { crate_type: Option>, } -fn read_cargo_toml(path: &Path) -> Result { +fn read_cargo_toml(path: &Path) -> Result { let manifest_path = path.join("Cargo.toml"); if !manifest_path.is_file() { - return Error::crate_config(&format!( + return Err(Error::crate_config(&format!( "Crate directory is missing a `Cargo.toml` file; is `{}` the wrong directory?", path.display() )) - .map(|_| unreachable!()); + .into()); } let mut cargo_file = File::open(manifest_path)?; let mut cargo_contents = String::new(); @@ -214,7 +216,7 @@ pub fn write_package_json( disable_dts: bool, target: &str, step: &Step, -) -> Result<(), Error> { +) -> Result<(), failure::Error> { let msg = format!("{}Writing a package.json...", emoji::MEMO); PBAR.step(step, &msg); @@ -235,29 +237,29 @@ pub fn write_package_json( } /// Get the crate name for the crate at the given path. -pub fn get_crate_name(path: &Path) -> Result { +pub fn get_crate_name(path: &Path) -> Result { 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<(), Error> { +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_crate_type(path: &Path) -> Result<(), Error> { +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(()); } - Error::crate_config( + 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()) } diff --git a/src/npm.rs b/src/npm.rs index d17fccbcd..76fe84171 100644 --- a/src/npm.rs +++ b/src/npm.rs @@ -1,56 +1,51 @@ //! Functionality related to publishing to npm. +use child; use command::publish::access::Access; -use error::Error; +use failure::{self, ResultExt}; +use slog::Logger; use std::process::{Command, Stdio}; /// The default npm registry used when we aren't working with a custom registry. pub const DEFAULT_NPM_REGISTRY: &'static str = "https://registry.npmjs.org/"; /// Run the `npm pack` command. -pub fn npm_pack(path: &str) -> Result<(), Error> { - let output = Command::new("npm").current_dir(path).arg("pack").output()?; - if !output.status.success() { - let s = String::from_utf8_lossy(&output.stderr); - Error::cli("Packaging up your code failed", s, output.status) - } else { - Ok(()) - } +pub fn npm_pack(log: &Logger, path: &str) -> Result<(), failure::Error> { + let mut cmd = Command::new("npm"); + cmd.current_dir(path).arg("pack"); + child::run(log, cmd, "npm pack").context("Packaging up your code failed")?; + Ok(()) } /// Run the `npm publish` command. -pub fn npm_publish(path: &str, access: Option) -> Result<(), Error> { - let output = match access { - Some(a) => Command::new("npm") +pub fn npm_publish(log: &Logger, path: &str, access: Option) -> Result<(), failure::Error> { + let mut cmd = Command::new("npm"); + match access { + Some(a) => cmd .current_dir(path) .arg("publish") .arg(&format!("{}", a.to_string())) .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .output()?, - None => Command::new("npm") + .stdout(Stdio::inherit()), + None => cmd .current_dir(path) .arg("publish") .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .output()?, + .stdout(Stdio::inherit()), }; - if !output.status.success() { - let s = String::from_utf8_lossy(&output.stderr); - Error::cli("Publishing to npm failed", s, output.status) - } else { - Ok(()) - } + child::run(log, cmd, "npm publish").context("Publishing to npm failed")?; + Ok(()) } /// Run the `npm login` command. pub fn npm_login( + log: &Logger, registry: &String, scope: &Option, always_auth: bool, auth_type: &Option, -) -> Result<(), Error> { +) -> Result<(), failure::Error> { let mut args = String::new(); args.push_str(&format!("--registry={}", registry)); @@ -67,21 +62,12 @@ pub fn npm_login( args.push_str(&format!(" --auth_type={}", auth_type)); } - let output = Command::new("npm") - .arg("login") + let mut cmd = Command::new("npm"); + cmd.arg("login") .arg(args) .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .output()?; - - if !output.status.success() { - let s = String::from_utf8_lossy(&output.stderr); - Error::cli( - &format!("Login to registry {} failed", registry), - s, - output.status, - ) - } else { - Ok(()) - } + .stdout(Stdio::inherit()); + child::run(log, cmd, "npm login") + .with_context(|_| format!("Login to registry {} failed", registry))?; + Ok(()) } diff --git a/src/readme.rs b/src/readme.rs index 2c34a2e65..83a4b10c8 100644 --- a/src/readme.rs +++ b/src/readme.rs @@ -1,6 +1,6 @@ //! Generating `README` files for the packaged wasm. -use error::Error; +use failure; use std::fs; use std::path::Path; @@ -9,7 +9,7 @@ use progressbar::Step; use PBAR; /// Copy the crate's README into the `pkg` directory. -pub fn copy_from_crate(path: &Path, out_dir: &Path, step: &Step) -> Result<(), Error> { +pub fn copy_from_crate(path: &Path, out_dir: &Path, step: &Step) -> Result<(), failure::Error> { assert!( fs::metadata(path).ok().map_or(false, |m| m.is_dir()), "crate directory should exist" diff --git a/src/test/mod.rs b/src/test/mod.rs index f30100fd9..db683ff6e 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -2,7 +2,8 @@ pub mod webdriver; -use error::Error; +use child; +use failure::{self, ResultExt}; use slog::Logger; use std::ffi::OsStr; use std::path::Path; @@ -15,7 +16,7 @@ pub fn cargo_test_wasm( release: bool, log: &Logger, envs: I, -) -> Result<(), Error> +) -> Result<(), failure::Error> where I: IntoIterator, K: AsRef, @@ -35,17 +36,13 @@ where cmd.arg("--release"); } cmd.arg("--target").arg("wasm32-unknown-unknown"); - cmd.output()? + child::run(log, cmd, "cargo test") + .context("Running Wasm tests with wasm-bindgen-test failed")? }; - if !output.status.success() { - let s = String::from_utf8_lossy(&output.stderr); - Error::cli("Running wasm tests failed", s, output.status) - } else { - for line in String::from_utf8_lossy(&output.stdout).lines() { - info!(log, "test output: {}", line); - println!("{}", line); - } - Ok(()) + for line in output.lines() { + info!(log, "test output: {}", line); + println!("{}", line); } + Ok(()) } diff --git a/src/test/webdriver.rs b/src/test/webdriver.rs index ad83e3c35..cac6d3941 100644 --- a/src/test/webdriver.rs +++ b/src/test/webdriver.rs @@ -5,6 +5,7 @@ use binaries::{ }; use command::build::BuildMode; use error::Error; +use failure; use slog::Logger; use std::path::{Path, PathBuf}; use target; @@ -15,17 +16,17 @@ pub fn get_or_install_chromedriver( log: &Logger, crate_path: &Path, mode: BuildMode, -) -> Result { +) -> Result { 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) => Error::crate_config( + (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.", ) - .map(|_| unreachable!()), + .into()), } } @@ -53,7 +54,7 @@ fn get_chromedriver_url() -> Result { } /// Download and install a pre-built `chromedriver` binary. -pub fn install_chromedriver(crate_path: &Path) -> Result { +pub fn install_chromedriver(crate_path: &Path) -> Result { let url = get_chromedriver_url()?; install_binaries_from_zip_at_url(crate_path, &url, Some("chromedriver"))?; let chromedriver = get_local_chromedriver_path(crate_path); @@ -67,16 +68,16 @@ pub fn get_or_install_geckodriver( log: &Logger, crate_path: &Path, mode: BuildMode, -) -> Result { +) -> Result { 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) => Error::crate_config( + (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.", ) - .map(|_| unreachable!()), + .into()), } } @@ -109,7 +110,7 @@ fn get_local_geckodriver_path(crate_path: &Path) -> PathBuf { } /// Download and install a pre-built `geckodriver` binary. -pub fn install_geckodriver(crate_path: &Path) -> Result { +pub fn install_geckodriver(crate_path: &Path) -> Result { let url = get_geckodriver_url()?; if url.ends_with("tar.gz") { @@ -133,6 +134,8 @@ pub fn get_safaridriver(log: &Logger, crate_path: &Path) -> Result, P2: AsRef>(from: P1, to: P2) -> io::Result<()> { let from = from.as_ref(); @@ -151,7 +151,11 @@ impl Fixture { 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(&tests, WASM_BINDGEN_VERSION) + wasm_pack::bindgen::cargo_install_wasm_bindgen( + &null_logger(), + &tests, + WASM_BINDGEN_VERSION, + ) }) .unwrap(); }); diff --git a/tests/all/utils/logger.rs b/tests/all/utils/logger.rs new file mode 100644 index 000000000..46cc0d7e4 --- /dev/null +++ b/tests/all/utils/logger.rs @@ -0,0 +1,6 @@ +use slog::Logger; + +// Create a logger that ignores log messages for testing. +pub fn null_logger() -> Logger { + Logger::root(slog::Discard, o!()) +} diff --git a/tests/all/utils/mod.rs b/tests/all/utils/mod.rs index 8b4244fa1..655b80d81 100644 --- a/tests/all/utils/mod.rs +++ b/tests/all/utils/mod.rs @@ -1,3 +1,4 @@ pub mod file; pub mod fixture; +pub mod logger; pub mod manifest;