From a8e953ebf7144eb3366fecfe2e0b176cfb3e3464 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Tue, 28 Aug 2018 17:24:43 -0700 Subject: [PATCH] feature: Use pre-built `wasm-bindgen` CLIs from Github releases Implements downloading tarballs from `wasm-bindgen`'s GitHub releases page and using them if the current target has pre-built binaries. --- .travis.yml | 2 +- Cargo.lock | 150 +++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 7 ++ src/bindgen.rs | 144 +++++++++++++++++++++++++++++++++++++++-- src/command/build.rs | 3 +- src/error.rs | 59 +++++++++++++++++ src/lib.rs | 3 + tests/all/bindgen.rs | 34 ++++++++++ tests/all/main.rs | 1 + 9 files changed, 395 insertions(+), 8 deletions(-) create mode 100644 tests/all/bindgen.rs diff --git a/.travis.yml b/.travis.yml index 699a89d05..771cf1a56 100644 --- a/.travis.yml +++ b/.travis.yml @@ -57,7 +57,7 @@ matrix: - env: JOB=dist-linux TARGET=x86_64-unknown-linux-musl DEPLOY=1 rust: nightly before_script: rustup target add $TARGET - script: cargo build --release --target $TARGET --locked + script: cargo build --release --target $TARGET --locked --features vendored-openssl addons: apt: packages: diff --git a/Cargo.lock b/Cargo.lock index d919a7673..a5231acbe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -131,6 +131,35 @@ dependencies = [ "walkdir 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "curl" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "curl-sys 0.4.8 (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.35 (registry+https://github.com/rust-lang/crates.io-index)", + "schannel 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "socket2 0.3.7 (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.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.22 (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.20 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.35 (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.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "failure" version = "0.1.2" @@ -151,6 +180,25 @@ dependencies = [ "synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "filetime" +version = "0.2.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)", + "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.2" +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)", +] + [[package]] name = "fuchsia-zircon" version = "0.3.3" @@ -234,6 +282,17 @@ name = "libc" version = "0.2.43" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "libz-sys" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (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)", +] + [[package]] name = "lock_api" version = "0.1.3" @@ -251,6 +310,15 @@ dependencies = [ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "miniz-sys" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "num-integer" version = "0.1.39" @@ -264,6 +332,22 @@ name = "num-traits" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "openssl-probe" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "openssl-sys" +version = "0.9.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (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)", +] + [[package]] name = "os_type" version = "2.0.0" @@ -300,6 +384,11 @@ dependencies = [ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "pkg-config" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "proc-macro2" version = "0.4.13" @@ -394,6 +483,15 @@ name = "ryu" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "schannel" +version = "0.1.13" +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)", + "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "scopeguard" version = "0.3.3" @@ -459,6 +557,17 @@ dependencies = [ "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "socket2" +version = "0.3.7" +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)", + "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.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "stable_deref_trait" version = "1.1.1" @@ -514,6 +623,17 @@ name = "take_mut" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "tar" +version = "0.4.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "filetime 0.2.1 (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)", +] + [[package]] name = "tempdir" version = "0.3.7" @@ -641,6 +761,11 @@ dependencies = [ "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "vcpkg" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "vec_map" version = "0.8.1" @@ -671,7 +796,9 @@ version = "0.4.2" dependencies = [ "console 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "copy_dir 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "curl 0.4.14 (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)", "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)", @@ -683,6 +810,7 @@ dependencies = [ "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)", + "tar 0.4.16 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "which 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -734,6 +862,14 @@ dependencies = [ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "xattr" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", +] + [metadata] "checksum aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "68f56c7353e5a9547cbd76ed90f7bb5ffc3ba09d4ea9bd1d8c06c8b1142eeb5a" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" @@ -750,8 +886,12 @@ dependencies = [ "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "checksum console 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7649ca90478264b9686aac8d269fcb014f14c2bed7c79a7e51b9f6afd4d783eb" "checksum copy_dir 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6e4281031634644843bd2f5aa9c48cf98fc48d6b083bd90bb11becf10deaf8b0" +"checksum curl 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)" = "444c2f9e71458b34e75471ed8d756947a0bb920b8b8b9bfc56dfcc4fc6819a13" +"checksum curl-sys 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "981bd902fcd8b8b999cf71b81447e27d66c3493a7f62f1372866fd32986c0c82" "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 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 human-panic 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "21638c5955a6daf3ecc42cae702335fc37a72a4abcc6959ce457b31a7d43bbdd" @@ -762,14 +902,19 @@ dependencies = [ "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 libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d" +"checksum libz-sys 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)" = "f5f9aba969b3c45fe9c94bec65895868a9ceca9a600699f4054b75747a19c7c6" "checksum lock_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "949826a5ccf18c1b3a7c3d57692778d21768b79e46eb9dd07bfc4c2160036c54" "checksum memchr 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a3b4142ab8738a78c51896f704f83c11df047ff1bda9a92a661aa6361552d93d" +"checksum miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "609ce024854aeb19a0ef7567d348aaa5a746b32fb72e336df7fcc16869d7e2b4" "checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" "checksum num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe" +"checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" +"checksum openssl-sys 0.9.35 (registry+https://github.com/rust-lang/crates.io-index)" = "912f301a749394e1025d9dcddef6106ddee9252620e6d0a0e5f8d0681de9b129" "checksum os_type 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "081f0539f57611638feee0d72fe98ad0b685e99da117be6b254bd1dfd7421609" "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" "checksum parking_lot 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "69376b761943787ebd5cc85a5bc95958651a22609c5c1c2b65de21786baec72b" "checksum parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "4db1a8ccf734a7bce794cc19b3df06ed87ab2f3907036b693c68f56b4d4537fa" +"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" "checksum proc-macro2 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "ee5697238f0d893c7f0ecc59c0999f18d2af85e424de441178bcacc9f9e6cf67" "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" @@ -782,6 +927,7 @@ dependencies = [ "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 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 scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "checksum serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)" = "22d340507cea0b7e6632900a176101fea959c7065d93ba555072da90aaaafc87" "checksum serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)" = "234fc8b737737b148ccd625175fc6390f5e4dacfdaa543cb93a3430d984a9119" @@ -790,6 +936,7 @@ dependencies = [ "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.7 (registry+https://github.com/rust-lang/crates.io-index)" = "962a516af4d3a7c272cb3a1d50a8cc4e5b41802e4ad54cfb7bee8ba61d37d703" "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" @@ -797,6 +944,7 @@ dependencies = [ "checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741" "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.16 (registry+https://github.com/rust-lang/crates.io-index)" = "e8f41ca4a5689f06998f0247fcb60da6c760f1950cc9df2a10d71575ad0b062a" "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" "checksum tempfile 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c4b103c6d08d323b92ff42c8ce62abcd83ca8efa7fd5bf7927efefec75f58c76" "checksum term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e6b677dd1e8214ea1ef4297f85dbcbed8e8cdddb561040cc998ca2551c37561" @@ -813,6 +961,7 @@ dependencies = [ "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 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" "checksum version_check 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7716c242968ee87e5542f8021178248f267f295a5c4803beae8b8b7fd9bc6051" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" @@ -824,3 +973,4 @@ dependencies = [ "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum wincolor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eeb06499a3a4d44302791052df005d5232b927ed1a9658146d842165c4de7767" +"checksum xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c" diff --git a/Cargo.toml b/Cargo.toml index 9657eefc6..77eac9a88 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,10 +10,13 @@ categories = ["wasm"] [dependencies] console = "0.6.1" +curl = "0.4.13" failure = "0.1.2" +flate2 = "1.0.2" human-panic = "1.0.1" indicatif = "0.9.0" lazy_static = "1.1.0" +openssl = { version = '0.10.11', optional = true } parking_lot = "0.6" serde = "1.0.74" serde_derive = "1.0.74" @@ -22,9 +25,13 @@ slog = "2.3" slog-term = "2.4" slog-async = "2.3" structopt = "0.2" +tar = "0.4.16" toml = "0.4" which = "2.0.0" [dev-dependencies] copy_dir = "0.1.2" tempfile = "3" + +[features] +vendored-openssl = ['openssl/vendored'] diff --git a/src/bindgen.rs b/src/bindgen.rs index 55d2356d9..4166aa215 100644 --- a/src/bindgen.rs +++ b/src/bindgen.rs @@ -1,22 +1,35 @@ //! Functionality related to installing and running `wasm-bindgen`. +use curl; use emoji; use error::Error; +use failure; +use flate2; use progressbar::Step; +use slog::Logger; +use std::ffi; +use std::fs; use std::path::{Path, PathBuf}; use std::process::Command; +use tar; use which::which; use PBAR; -/// Install the `wasm-bindgen` CLI with `cargo install`. -pub fn cargo_install_wasm_bindgen( - path: &Path, +/// Install the `wasm-bindgen` CLI. +/// +/// Prefers an existing local install, if any exists. Then checks if there is a +/// global install on `$PATH` that fits the bill. Then attempts to download a +/// 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, version: &str, install_permitted: bool, step: &Step, + log: &Logger, ) -> Result<(), Error> { // If the `wasm-bindgen` dependency is already met, print a message and return. - if wasm_bindgen_path(path) + if wasm_bindgen_path(root_path) .map(|bindgen_path| wasm_bindgen_version_check(&bindgen_path, version)) .unwrap_or(false) { @@ -34,6 +47,115 @@ pub fn cargo_install_wasm_bindgen( 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(root_path, version) + }) +} + +fn curl(url: &str) -> Result, failure::Error> { + let mut data = Vec::new(); + + fn with_url_context(url: &str, r: Result) -> Result + where + Result: failure::ResultExt, + { + use failure::ResultExt; + r.with_context(|_| format!("when requesting {}", url)) + } + + let mut easy = curl::easy::Easy::new(); + with_url_context(url, easy.follow_location(true))?; + with_url_context(url, easy.url(url))?; + + { + 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())?; + } + + let code = with_url_context(url, easy.response_code())?; + if 200 <= code && code < 300 { + Ok(data) + } else { + Err(Error::http(&format!( + "received a bad HTTP status code ({}) when requesting {}", + code, url + )).into()) + } +} + +/// Download a tarball containing a pre-built `wasm-bindgen` binary. +pub fn download_prebuilt_wasm_bindgen(root_path: &Path, version: &str) -> Result<(), Error> { + let linux = cfg!(target_os = "linux"); + let macos = cfg!(target_os = "macos"); + let x86_64 = cfg!(target_arch = "x86_64"); + + let target = if linux && x86_64 { + "x86_64-unknown-linux-musl" + } else if macos && x86_64 { + "x86_64-apple-darwin" + } else { + return Err(Error::unsupported( + "there are no pre-built `wasm-bindgen` binaries for this target", + )); + }; + + let url = format!( + "https://github.com/rustwasm/wasm-bindgen/releases/download/{0}/wasm-bindgen-{0}-{1}.tar.gz", + version, + target + ); + + let tarball = curl(&url).map_err(|e| Error::http(&e.to_string()))?; + let mut archive = tar::Archive::new(flate2::read::GzDecoder::new(&tarball[..])); + + let bin = root_path.join("bin"); + fs::create_dir_all(&bin)?; + + let mut found_wasm_bindgen = false; + let mut found_test_runner = false; + + for entry in archive.entries()? { + let mut entry = entry?; + + let dest = match entry.path()?.file_stem() { + Some(f) if f == ffi::OsStr::new("wasm-bindgen") => { + found_wasm_bindgen = true; + bin.join(entry.path()?.file_name().unwrap()) + } + Some(f) if f == ffi::OsStr::new("wasm-bindgen-test-runner") => { + found_test_runner = true; + bin.join(entry.path()?.file_name().unwrap()) + } + _ => continue, + }; + + entry.unpack(dest)?; + } + + if found_wasm_bindgen && found_test_runner { + Ok(()) + } else { + Err(Error::archive( + "the wasm-bindgen tarball was missing expected executables", + )) + } +} + +/// Use `cargo install` to install the `wasm-bindgen` CLI to the given root +/// path. +pub fn cargo_install_wasm_bindgen(root_path: &Path, version: &str) -> Result<(), Error> { let output = Command::new("cargo") .arg("install") .arg("--force") @@ -41,7 +163,7 @@ pub fn cargo_install_wasm_bindgen( .arg("--version") .arg(version) .arg("--root") - .arg(path) + .arg(root_path) .output()?; if !output.status.success() { let message = "Installing wasm-bindgen failed".to_string(); @@ -51,6 +173,11 @@ pub fn cargo_install_wasm_bindgen( stderr: s.to_string(), }) } else { + if cfg!(target_os = "windows") { + assert!(root_path.join("bin").join("wasm-bindgen.exe").is_file()); + } else { + assert!(root_path.join("bin").join("wasm-bindgen").is_file()); + } Ok(()) } } @@ -67,6 +194,7 @@ pub fn wasm_bindgen_build( ) -> Result<(), 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" }; @@ -128,7 +256,11 @@ fn wasm_bindgen_path(crate_path: &Path) -> Option { let local_bindgen_path = |crate_path: &Path| -> Option { let mut p = crate_path.to_path_buf(); p.push("bin"); - p.push("wasm-bindgen"); + if cfg!(target_os = "windows") { + p.push("wasm-bindgen.exe"); + } else { + p.push("wasm-bindgen"); + } if p.is_file() { Some(p) } else { diff --git a/src/command/build.rs b/src/command/build.rs index ae26938b6..343d77221 100644 --- a/src/command/build.rs +++ b/src/command/build.rs @@ -226,11 +226,12 @@ impl Build { BuildMode::Normal => true, BuildMode::Noinstall => false, }; - bindgen::cargo_install_wasm_bindgen( + bindgen::install_wasm_bindgen( &self.crate_path, &bindgen_version, install_permitted, step, + log, )?; info!(&log, "Installing wasm-bindgen-cli was successful."); diff --git a/src/error.rs b/src/error.rs index 960cb135c..597211f53 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,4 +1,5 @@ //! Code related to error handling for wasm-pack +use curl; use serde_json; use std::borrow::Cow; use std::io; @@ -19,6 +20,10 @@ pub enum Error { #[fail(display = "{}", _0)] SerdeToml(#[cause] toml::de::Error), + #[fail(display = "{}", _0)] + /// A curl error. + Curl(#[cause] curl::Error), + /// An error invoking another CLI tool. #[fail(display = "{}. stderr:\n\n{}", message, stderr)] Cli { @@ -34,12 +39,35 @@ pub enum Error { /// 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 { @@ -58,6 +86,27 @@ impl Error { }) } + /// 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(), + } + } + /// Get a string description of this error's type. pub fn error_type(&self) -> String { match self { @@ -74,6 +123,10 @@ impl Error { 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() } } @@ -84,6 +137,12 @@ impl From for Error { } } +impl From for Error { + fn from(e: curl::Error) -> Self { + Error::Curl(e) + } +} + impl From for Error { fn from(e: serde_json::Error) -> Self { Error::SerdeJson(e) diff --git a/src/lib.rs b/src/lib.rs index 8f01d3669..5873494c9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,8 +3,10 @@ #![deny(missing_docs)] extern crate console; +extern crate curl; #[macro_use] extern crate failure; +extern crate flate2; extern crate indicatif; #[macro_use] extern crate lazy_static; @@ -18,6 +20,7 @@ extern crate structopt; extern crate slog; extern crate slog_async; extern crate slog_term; +extern crate tar; extern crate toml; extern crate which; diff --git a/tests/all/bindgen.rs b/tests/all/bindgen.rs new file mode 100644 index 000000000..add58382f --- /dev/null +++ b/tests/all/bindgen.rs @@ -0,0 +1,34 @@ +use tempfile; +use wasm_pack::bindgen; + +#[test] +#[cfg(any( + all(target_os = "linux", target_arch = "x86_64"), + all(target_os = "macos", target_arch = "x86_64") +))] +fn can_download_prebuilt_wasm_bindgen() { + let dir = tempfile::TempDir::new().unwrap(); + bindgen::download_prebuilt_wasm_bindgen(dir.path(), "0.2.19").unwrap(); + assert!(dir.path().join("bin").join("wasm-bindgen").is_file()); + assert!( + dir.path() + .join("bin") + .join("wasm-bindgen-test-runner") + .is_file() + ); +} + +#[test] +#[cfg(any( + all(target_os = "linux", target_arch = "x86_64"), + all(target_os = "macos", target_arch = "x86_64") +))] +fn downloading_prebuilt_wasm_bindgen_handles_http_errors() { + let dir = tempfile::TempDir::new().unwrap(); + let bad_version = "0.2.19-some-trailing-version-stuff-that-does-not-exist"; + let result = bindgen::download_prebuilt_wasm_bindgen(dir.path(), bad_version); + assert!(result.is_err()); + let error_msg = result.unwrap_err().to_string(); + assert!(error_msg.contains("404")); + assert!(error_msg.contains(bad_version)); +} diff --git a/tests/all/main.rs b/tests/all/main.rs index b4480b4c7..569989446 100644 --- a/tests/all/main.rs +++ b/tests/all/main.rs @@ -9,6 +9,7 @@ extern crate wasm_pack; #[macro_use] extern crate lazy_static; +mod bindgen; mod build; mod manifest; mod readme;