commit
740b8b896e
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,142 @@ |
|||||||
|
use binary_install::Cache; |
||||||
|
use std::path::Path; |
||||||
|
use utils; |
||||||
|
|
||||||
|
#[test] |
||||||
|
fn it_returns_none_if_install_is_not_permitted() { |
||||||
|
let binary_name = "wasm-pack"; |
||||||
|
let binaries = vec![binary_name]; |
||||||
|
|
||||||
|
let dir = tempfile::TempDir::new().unwrap(); |
||||||
|
let cache = Cache::at(dir.path()); |
||||||
|
|
||||||
|
let dl = cache.download( |
||||||
|
false, |
||||||
|
binary_name, |
||||||
|
&binaries, |
||||||
|
&format!("{}/{}.tar.gz", "", binary_name), |
||||||
|
); |
||||||
|
|
||||||
|
assert!(dl.is_ok()); |
||||||
|
assert!(dl.unwrap().is_none()) |
||||||
|
} |
||||||
|
|
||||||
|
#[test] |
||||||
|
fn it_downloads_tarball() { |
||||||
|
let binary_name = "wasm-pack"; |
||||||
|
let binaries = vec![binary_name]; |
||||||
|
|
||||||
|
// Create a temporary tarball.
|
||||||
|
let tarball = utils::create_tarball(binary_name).ok(); |
||||||
|
|
||||||
|
// Spin up a local TcpListener.
|
||||||
|
let server_port = utils::start_server(tarball, None).recv().unwrap(); |
||||||
|
|
||||||
|
let url = format!("http://{}:{}", utils::TEST_SERVER_HOST, server_port); |
||||||
|
|
||||||
|
let dir = tempfile::TempDir::new().unwrap(); |
||||||
|
let cache = Cache::at(dir.path()); |
||||||
|
|
||||||
|
let dl = cache.download( |
||||||
|
true, |
||||||
|
binary_name, |
||||||
|
&binaries, |
||||||
|
&format!("{}/{}.tar.gz", &url, binary_name), |
||||||
|
); |
||||||
|
|
||||||
|
assert!(dl.is_ok()); |
||||||
|
assert!(dl.unwrap().is_some()) |
||||||
|
} |
||||||
|
|
||||||
|
#[test] |
||||||
|
fn it_returns_error_when_it_failed_to_download() { |
||||||
|
let server_port = 7881; |
||||||
|
let url = format!("http://{}:{}", utils::TEST_SERVER_HOST, server_port); |
||||||
|
let binary_name = "wasm-pack"; |
||||||
|
let binaries = vec![binary_name]; |
||||||
|
|
||||||
|
let dir = tempfile::TempDir::new().unwrap(); |
||||||
|
let cache = Cache::at(dir.path()); |
||||||
|
let full_url = &format!("{}/{}.tar.gz", &url, binary_name); |
||||||
|
|
||||||
|
let dl = cache.download(true, binary_name, &binaries, full_url); |
||||||
|
|
||||||
|
assert!(dl.is_err()); |
||||||
|
assert_eq!( |
||||||
|
&format!("failed to download from {}", full_url), |
||||||
|
&format!("{}", dl.unwrap_err()) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
#[test] |
||||||
|
fn it_returns_error_when_it_failed_to_extract_tarball() { |
||||||
|
let binary_name = "wasm-pack"; |
||||||
|
let binaries = vec![binary_name]; |
||||||
|
|
||||||
|
let dir = tempfile::TempDir::new().unwrap(); |
||||||
|
let cache = Cache::at(dir.path()); |
||||||
|
|
||||||
|
// Spin up a local TcpListener.
|
||||||
|
let server_port = utils::start_server(None, None).recv().unwrap(); |
||||||
|
|
||||||
|
let url = format!("http://{}:{}", utils::TEST_SERVER_HOST, server_port); |
||||||
|
let full_url = &format!("{}/{}.tar.gz", &url, binary_name); |
||||||
|
|
||||||
|
let dl = cache.download(true, binary_name, &binaries, full_url); |
||||||
|
|
||||||
|
assert!(dl.is_err()); |
||||||
|
assert_eq!( |
||||||
|
&format!("failed to extract tarball from {}", full_url), |
||||||
|
&format!("{}", dl.unwrap_err()) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
#[test] |
||||||
|
fn it_returns_error_when_it_failed_to_extract_zip() { |
||||||
|
let binary_name = "wasm-pack"; |
||||||
|
let binaries = vec![binary_name]; |
||||||
|
|
||||||
|
let dir = tempfile::TempDir::new().unwrap(); |
||||||
|
let cache = Cache::at(dir.path()); |
||||||
|
|
||||||
|
// Spin up a local TcpListener.
|
||||||
|
let server_port = utils::start_server(None, None).recv().unwrap(); |
||||||
|
|
||||||
|
let url = format!("http://{}:{}", utils::TEST_SERVER_HOST, server_port); |
||||||
|
let full_url = &format!("{}/{}.zip", &url, binary_name); |
||||||
|
|
||||||
|
let dl = cache.download(true, binary_name, &binaries, full_url); |
||||||
|
|
||||||
|
assert!(dl.is_err()); |
||||||
|
assert_eq!( |
||||||
|
&format!("failed to extract zip from {}", full_url), |
||||||
|
&format!("{}", dl.unwrap_err()) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
#[test] |
||||||
|
#[should_panic(expected = "don't know how to extract http://localhost:7884/wasm-pack.bin")] |
||||||
|
fn it_panics_if_not_tarball_or_zip() { |
||||||
|
let server_port = 7884; |
||||||
|
let binary_name = "wasm-pack"; |
||||||
|
let binaries = vec![binary_name]; |
||||||
|
|
||||||
|
let dir = tempfile::TempDir::new().unwrap(); |
||||||
|
let cache = Cache::at(dir.path()); |
||||||
|
|
||||||
|
// Spin up a local TcpListener.
|
||||||
|
utils::start_server(None, Some(server_port)).recv().unwrap(); |
||||||
|
|
||||||
|
let url = format!("http://{}:{}", utils::TEST_SERVER_HOST, server_port); |
||||||
|
let full_url = &format!("{}/{}.bin", &url, binary_name); |
||||||
|
|
||||||
|
let _ = cache.download(true, binary_name, &binaries, full_url); |
||||||
|
} |
||||||
|
|
||||||
|
#[test] |
||||||
|
fn it_joins_path_with_destination() { |
||||||
|
let dir = tempfile::TempDir::new().unwrap(); |
||||||
|
let cache = Cache::at(dir.path()); |
||||||
|
|
||||||
|
assert_eq!(dir.path().join("hello"), cache.join(Path::new("hello"))); |
||||||
|
} |
@ -0,0 +1,125 @@ |
|||||||
|
use binary_install::Download; |
||||||
|
use std::fs::OpenOptions; |
||||||
|
|
||||||
|
#[test] |
||||||
|
#[cfg(unix)] |
||||||
|
fn it_returns_binary_name_for_unix() { |
||||||
|
use std::os::unix::fs::OpenOptionsExt; |
||||||
|
|
||||||
|
let binary_name = "wasm-pack"; |
||||||
|
|
||||||
|
let dir = tempfile::TempDir::new().unwrap(); |
||||||
|
let download = Download::at(dir.path()); |
||||||
|
|
||||||
|
let full_path = dir.path().join(binary_name); |
||||||
|
|
||||||
|
let mut options = OpenOptions::new(); |
||||||
|
options.create(true); |
||||||
|
options.write(true); |
||||||
|
|
||||||
|
// Make the "binary" an executable.
|
||||||
|
options.mode(0o755); |
||||||
|
|
||||||
|
options.open(&full_path).unwrap(); |
||||||
|
|
||||||
|
let binary = download.binary(binary_name); |
||||||
|
|
||||||
|
assert!(binary.is_ok()); |
||||||
|
assert_eq!(full_path, binary.unwrap()); |
||||||
|
} |
||||||
|
|
||||||
|
#[test] |
||||||
|
#[cfg(not(windows))] |
||||||
|
fn it_bails_if_not_file_for_unix() { |
||||||
|
let binary_name = "wasm-pack"; |
||||||
|
|
||||||
|
let dir = tempfile::TempDir::new().unwrap(); |
||||||
|
let download = Download::at(dir.path()); |
||||||
|
|
||||||
|
let full_path = dir.path().join(binary_name); |
||||||
|
|
||||||
|
let mut options = OpenOptions::new(); |
||||||
|
options.create(true); |
||||||
|
options.write(true); |
||||||
|
|
||||||
|
let binary = download.binary(binary_name); |
||||||
|
|
||||||
|
assert!(binary.is_err()); |
||||||
|
assert_eq!( |
||||||
|
format!("{} binary does not exist", full_path.to_str().unwrap()), |
||||||
|
binary.unwrap_err().to_string() |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
#[test] |
||||||
|
#[cfg(windows)] |
||||||
|
fn it_bails_if_not_file_for_windows() { |
||||||
|
let binary_name = "wasm-pack.exe"; |
||||||
|
|
||||||
|
let dir = tempfile::TempDir::new().unwrap(); |
||||||
|
let download = Download::at(dir.path()); |
||||||
|
|
||||||
|
let full_path = dir.path().join(binary_name); |
||||||
|
|
||||||
|
let mut options = OpenOptions::new(); |
||||||
|
options.create(true); |
||||||
|
options.write(true); |
||||||
|
|
||||||
|
let binary = download.binary(binary_name); |
||||||
|
|
||||||
|
assert!(binary.is_err()); |
||||||
|
assert_eq!( |
||||||
|
format!("{} binary does not exist", full_path.to_str().unwrap()), |
||||||
|
binary.unwrap_err().to_string() |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
#[test] |
||||||
|
#[cfg(not(windows))] |
||||||
|
fn it_bails_if_not_executable_for_unix() { |
||||||
|
let binary_name = "wasm-pack"; |
||||||
|
|
||||||
|
let dir = tempfile::TempDir::new().unwrap(); |
||||||
|
let download = Download::at(dir.path()); |
||||||
|
|
||||||
|
let full_path = dir.path().join(binary_name); |
||||||
|
|
||||||
|
let mut options = OpenOptions::new(); |
||||||
|
options.create(true); |
||||||
|
options.write(true); |
||||||
|
|
||||||
|
options.open(&full_path).unwrap(); |
||||||
|
|
||||||
|
let binary = download.binary(binary_name); |
||||||
|
|
||||||
|
assert!(binary.is_err()); |
||||||
|
assert_eq!( |
||||||
|
format!("{} is not executable", full_path.to_str().unwrap()), |
||||||
|
binary.unwrap_err().to_string() |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
#[test] |
||||||
|
#[cfg(windows)] |
||||||
|
fn it_bails_if_not_executable_for_windows() { |
||||||
|
let binary_name = "wasm-pack.exe"; |
||||||
|
|
||||||
|
let dir = tempfile::TempDir::new().unwrap(); |
||||||
|
let download = Download::at(dir.path()); |
||||||
|
|
||||||
|
let full_path = dir.path().join(binary_name); |
||||||
|
|
||||||
|
let mut options = OpenOptions::new(); |
||||||
|
options.create(true); |
||||||
|
options.write(true); |
||||||
|
|
||||||
|
options.open(&full_path).unwrap(); |
||||||
|
|
||||||
|
let binary = download.binary(binary_name); |
||||||
|
|
||||||
|
assert!(binary.is_err()); |
||||||
|
assert_eq!( |
||||||
|
format!("{} is not executable", full_path.to_str().unwrap()), |
||||||
|
binary.unwrap_err().to_string() |
||||||
|
); |
||||||
|
} |
@ -0,0 +1,7 @@ |
|||||||
|
extern crate binary_install; |
||||||
|
extern crate flate2; |
||||||
|
extern crate tar; |
||||||
|
|
||||||
|
mod cache; |
||||||
|
mod download; |
||||||
|
mod utils; |
@ -0,0 +1,79 @@ |
|||||||
|
use flate2::write::GzEncoder; |
||||||
|
use flate2::Compression; |
||||||
|
use std::fs::{File, OpenOptions}; |
||||||
|
use std::io::{self, Read, Write}; |
||||||
|
use std::net::TcpListener; |
||||||
|
use std::sync::mpsc::{channel, Receiver}; |
||||||
|
use std::thread; |
||||||
|
|
||||||
|
pub const TEST_SERVER_HOST: &'static str = "localhost"; |
||||||
|
|
||||||
|
pub fn start_server(tarball: Option<Vec<u8>>, server_port: Option<u16>) -> Receiver<u16> { |
||||||
|
let (sender, receiver) = channel(); |
||||||
|
|
||||||
|
thread::spawn(move || { |
||||||
|
TcpListener::bind(format!( |
||||||
|
"{}:{}", |
||||||
|
TEST_SERVER_HOST, |
||||||
|
server_port.unwrap_or_else(|| 0) |
||||||
|
)) |
||||||
|
.map(|listener| { |
||||||
|
sender.send(listener.local_addr().unwrap().port()).unwrap(); |
||||||
|
|
||||||
|
for stream in listener.incoming() { |
||||||
|
let mut stream = stream.unwrap(); |
||||||
|
|
||||||
|
let mut buffer = [0; 512]; |
||||||
|
|
||||||
|
stream.read(&mut buffer).unwrap(); |
||||||
|
|
||||||
|
let response = "HTTP/1.1 200 OK\r\n\r\n"; |
||||||
|
|
||||||
|
stream.write(response.as_bytes()).unwrap(); |
||||||
|
|
||||||
|
match tarball.to_owned() { |
||||||
|
Some(tar) => { |
||||||
|
stream.write(tar.as_ref()).unwrap(); |
||||||
|
} |
||||||
|
None => {} |
||||||
|
} |
||||||
|
|
||||||
|
stream.flush().unwrap(); |
||||||
|
} |
||||||
|
}) |
||||||
|
.unwrap(); |
||||||
|
}); |
||||||
|
|
||||||
|
receiver |
||||||
|
} |
||||||
|
|
||||||
|
pub fn create_tarball(binary_name: &str) -> Result<Vec<u8>, io::Error> { |
||||||
|
let temp_dir = tempfile::TempDir::new().unwrap(); |
||||||
|
let full_path = temp_dir.path().join(binary_name.to_owned() + ".tar.gz"); |
||||||
|
|
||||||
|
let tar = OpenOptions::new() |
||||||
|
.create(true) |
||||||
|
.read(true) |
||||||
|
.write(true) |
||||||
|
.open(&full_path)?; |
||||||
|
|
||||||
|
let mut file = OpenOptions::new() |
||||||
|
.create(true) |
||||||
|
.read(true) |
||||||
|
.write(true) |
||||||
|
.open(temp_dir.path().join(binary_name))?; |
||||||
|
|
||||||
|
let mut encoder = GzEncoder::new(tar, Compression::default()); |
||||||
|
{ |
||||||
|
let mut archive = tar::Builder::new(&mut encoder); |
||||||
|
archive.append_file(binary_name, &mut file)?; |
||||||
|
} |
||||||
|
|
||||||
|
let mut contents = vec![]; |
||||||
|
|
||||||
|
encoder.finish()?; |
||||||
|
|
||||||
|
File::open(temp_dir.path().join(&full_path))?.read_to_end(&mut contents)?; |
||||||
|
|
||||||
|
Ok(contents) |
||||||
|
} |
@ -0,0 +1 @@ |
|||||||
|
too-many-arguments-threshold = 8 |
@ -0,0 +1,44 @@ |
|||||||
|
<style> |
||||||
|
header.warning { |
||||||
|
background-color: rgb(242, 222, 222); |
||||||
|
border-bottom-color: rgb(238, 211, 215); |
||||||
|
border-bottom-left-radius: 4px; |
||||||
|
border-bottom-right-radius: 4px; |
||||||
|
border-bottom-style: solid; |
||||||
|
border-bottom-width: 0.666667px; |
||||||
|
border-image-outset: 0 0 0 0; |
||||||
|
border-image-repeat: stretch stretch; |
||||||
|
border-image-slice: 100% 100% 100% 100%; |
||||||
|
border-image-source: none; |
||||||
|
border-image-width: 1 1 1 1; |
||||||
|
border-left-color: rgb(238, 211, 215); |
||||||
|
border-left-style: solid; |
||||||
|
border-left-width: 0.666667px; |
||||||
|
border-right-color: rgb(238, 211, 215); |
||||||
|
border-right-style: solid; |
||||||
|
border-right-width: 0.666667px; |
||||||
|
border-top-color: rgb(238, 211, 215); |
||||||
|
border-top-left-radius: 4px; |
||||||
|
border-top-right-radius: 4px; |
||||||
|
border-top-style: solid; |
||||||
|
border-top-width: 0.666667px; |
||||||
|
color: rgb(185, 74, 72); |
||||||
|
margin-bottom: 0px; |
||||||
|
margin-left: 0px; |
||||||
|
margin-right: 0px; |
||||||
|
margin-top: 30px; |
||||||
|
padding-bottom: 8px; |
||||||
|
padding-left: 14px; |
||||||
|
padding-right: 35px; |
||||||
|
padding-top: 8px; |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
</style> |
||||||
|
<header class='warning'> |
||||||
|
This is the <strong>unpublished</strong> documentation of |
||||||
|
<code>wasm-pack</code>, the published documentation is available |
||||||
|
<a href="https://rustwasm.github.io/docs/wasm-pack/"> |
||||||
|
on the main Rust and WebAssembly documentation site |
||||||
|
</a>. Features documented here may not be available in released versions of |
||||||
|
<code>wasm-pack</code>. |
||||||
|
</header> |
@ -0,0 +1,54 @@ |
|||||||
|
# wee_alloc |
||||||
|
|
||||||
|
1. [What is `wee_alloc`?](#what-is-wee_alloc) |
||||||
|
2. [Enabling `wee_alloc`](#enabling-wee_alloc) |
||||||
|
3. [Rust nightly](#rust-nightly) |
||||||
|
|
||||||
|
## What is `wee_alloc`? |
||||||
|
|
||||||
|
Reducing the size of compiled WebAssembly code is important, since it is often transmitted over the Internet or placed on embedded devices. |
||||||
|
|
||||||
|
> `wee_alloc` is a tiny allocator designed for WebAssembly that has a (pre-compression) code-size footprint of only a single kilobyte. |
||||||
|
|
||||||
|
[An analysis](http://fitzgeraldnick.com/2018/02/09/wee-alloc.html) suggests that over half of the bare minimum WebAssembly memory footprint is required by Rust's default memory allocator. Yet, WebAssembly code often does not require a sophisticated allocator, since it often just requests a couple of large initial allocations. |
||||||
|
|
||||||
|
`wee_alloc` trades off size for speed. Although it has a tiny code-size footprint, it is relatively slow if additional allocations are needed. |
||||||
|
|
||||||
|
For even more details, see the [`wee_alloc` repository](https://github.com/rustwasm/wee_alloc). |
||||||
|
|
||||||
|
## Enabling `wee_alloc` |
||||||
|
|
||||||
|
In `lib.rs`, we have the configuration for `wee_alloc` inside a `cfg_if!` macro: |
||||||
|
|
||||||
|
```rust |
||||||
|
cfg_if! { |
||||||
|
if #[cfg(feature = "wee_alloc")] { |
||||||
|
extern crate wee_alloc; |
||||||
|
#[global_allocator] |
||||||
|
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT; |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
This code block is intended to initialize `wee_alloc` as the global memory allocator, but only if the `wee_alloc` feature is enabled in `Cargo.toml`. |
||||||
|
|
||||||
|
To do so we need to append `"wee_alloc"` to the `default` vector in `Cargo.toml`. Then, the `cfg_if!` block is replaced with the contents of the `if` block, shown above. |
||||||
|
|
||||||
|
```toml |
||||||
|
[features] |
||||||
|
default = ["console_error_panic_hook", "wee_alloc"] |
||||||
|
``` |
||||||
|
|
||||||
|
## Rust nightly |
||||||
|
|
||||||
|
`wee_alloc` currently relies on features only available in Rust nightly. As such it requires you to use the nightly toolchain for compilation. If you have [Rustup](https://rustup.rs/) set up, you can install the nightly toolchain as follows: |
||||||
|
|
||||||
|
``` |
||||||
|
rustup toolchain add nightly |
||||||
|
``` |
||||||
|
|
||||||
|
To use `wasm-pack` with Rust nightly run: |
||||||
|
|
||||||
|
``` |
||||||
|
rustup run nightly wasm-pack build |
||||||
|
``` |
Loading…
Reference in new issue