|
|
|
@ -1,25 +1,28 @@ |
|
|
|
|
//! Functionality related to installing prebuilt binaries and/or running cargo install.
|
|
|
|
|
|
|
|
|
|
use self::krate::Krate; |
|
|
|
|
use crate::child; |
|
|
|
|
use crate::emoji; |
|
|
|
|
use crate::install; |
|
|
|
|
use crate::PBAR; |
|
|
|
|
use anyhow::{anyhow, bail, Context, Result}; |
|
|
|
|
use binary_install::{Cache, Download}; |
|
|
|
|
use child; |
|
|
|
|
use emoji; |
|
|
|
|
use failure::{self, ResultExt}; |
|
|
|
|
use install; |
|
|
|
|
use log::debug; |
|
|
|
|
use log::{info, warn}; |
|
|
|
|
use std::env; |
|
|
|
|
use std::fs; |
|
|
|
|
use std::path::Path; |
|
|
|
|
use std::process::Command; |
|
|
|
|
use target; |
|
|
|
|
use which::which; |
|
|
|
|
use PBAR; |
|
|
|
|
|
|
|
|
|
mod arch; |
|
|
|
|
mod krate; |
|
|
|
|
mod mode; |
|
|
|
|
mod os; |
|
|
|
|
mod tool; |
|
|
|
|
pub use self::arch::Arch; |
|
|
|
|
pub use self::mode::InstallMode; |
|
|
|
|
pub use self::os::Os; |
|
|
|
|
pub use self::tool::Tool; |
|
|
|
|
|
|
|
|
|
/// Possible outcomes of attempting to find/install a tool
|
|
|
|
@ -33,7 +36,7 @@ pub enum Status { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Handles possible installs status and returns the download or a error message
|
|
|
|
|
pub fn get_tool_path(status: &Status, tool: Tool) -> Result<&Download, failure::Error> { |
|
|
|
|
pub fn get_tool_path(status: &Status, tool: Tool) -> Result<&Download> { |
|
|
|
|
match status { |
|
|
|
|
Status::Found(download) => Ok(download), |
|
|
|
|
Status::CannotInstall => bail!("Not able to find or install a local {}.", tool), |
|
|
|
@ -54,7 +57,7 @@ pub fn download_prebuilt_or_cargo_install( |
|
|
|
|
cache: &Cache, |
|
|
|
|
version: &str, |
|
|
|
|
install_permitted: bool, |
|
|
|
|
) -> Result<Status, failure::Error> { |
|
|
|
|
) -> Result<Status> { |
|
|
|
|
// If the tool is installed globally and it has the right version, use
|
|
|
|
|
// that. Assume that other tools are installed next to it.
|
|
|
|
|
//
|
|
|
|
@ -86,11 +89,7 @@ pub fn download_prebuilt_or_cargo_install( |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Check if the tool dependency is locally satisfied.
|
|
|
|
|
pub fn check_version( |
|
|
|
|
tool: &Tool, |
|
|
|
|
path: &Path, |
|
|
|
|
expected_version: &str, |
|
|
|
|
) -> Result<bool, failure::Error> { |
|
|
|
|
pub fn check_version(tool: &Tool, path: &Path, expected_version: &str) -> Result<bool> { |
|
|
|
|
let expected_version = if expected_version == "latest" { |
|
|
|
|
let krate = Krate::new(tool)?; |
|
|
|
|
krate.max_version |
|
|
|
@ -107,7 +106,7 @@ pub fn check_version( |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Fetches the version of a CLI tool
|
|
|
|
|
pub fn get_cli_version(tool: &Tool, path: &Path) -> Result<String, failure::Error> { |
|
|
|
|
pub fn get_cli_version(tool: &Tool, path: &Path) -> Result<String> { |
|
|
|
|
let mut cmd = Command::new(path); |
|
|
|
|
cmd.arg("--version"); |
|
|
|
|
let stdout = child::run_capture_stdout(cmd, tool)?; |
|
|
|
@ -124,7 +123,7 @@ pub fn download_prebuilt( |
|
|
|
|
cache: &Cache, |
|
|
|
|
version: &str, |
|
|
|
|
install_permitted: bool, |
|
|
|
|
) -> Result<Status, failure::Error> { |
|
|
|
|
) -> Result<Status> { |
|
|
|
|
let url = match prebuilt_url(tool, version) { |
|
|
|
|
Ok(url) => url, |
|
|
|
|
Err(e) => bail!( |
|
|
|
@ -149,7 +148,11 @@ pub fn download_prebuilt( |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
Tool::WasmOpt => { |
|
|
|
|
let binaries = &["wasm-opt"]; |
|
|
|
|
let binaries: &[&str] = match Os::get()? { |
|
|
|
|
Os::MacOS => &["bin/wasm-opt", "lib/libbinaryen.dylib"], |
|
|
|
|
Os::Linux => &["bin/wasm-opt"], |
|
|
|
|
Os::Windows => &["bin/wasm-opt.exe"], |
|
|
|
|
}; |
|
|
|
|
match cache.download(install_permitted, "wasm-opt", binaries, &url)? { |
|
|
|
|
Some(download) => Ok(Status::Found(download)), |
|
|
|
|
// TODO(ag_dubs): why is this different? i forget...
|
|
|
|
@ -161,33 +164,25 @@ pub fn download_prebuilt( |
|
|
|
|
|
|
|
|
|
/// Returns the URL of a precompiled version of wasm-bindgen, if we have one
|
|
|
|
|
/// available for our host platform.
|
|
|
|
|
fn prebuilt_url(tool: &Tool, version: &str) -> Result<String, failure::Error> { |
|
|
|
|
let target = if target::LINUX && target::x86_64 { |
|
|
|
|
match tool { |
|
|
|
|
Tool::WasmOpt => "x86-linux", |
|
|
|
|
_ => "x86_64-unknown-linux-musl", |
|
|
|
|
} |
|
|
|
|
} else if target::LINUX && target::x86 { |
|
|
|
|
match tool { |
|
|
|
|
Tool::WasmOpt => "x86-linux", |
|
|
|
|
_ => bail!("Unrecognized target!"), |
|
|
|
|
} |
|
|
|
|
} else if target::MACOS && (target::x86_64 || target::aarch64) { |
|
|
|
|
"x86_64-apple-darwin" |
|
|
|
|
} else if target::WINDOWS && target::x86_64 { |
|
|
|
|
match tool { |
|
|
|
|
Tool::WasmOpt => "x86-windows", |
|
|
|
|
_ => "x86_64-pc-windows-msvc", |
|
|
|
|
} |
|
|
|
|
} else if target::WINDOWS && target::x86 { |
|
|
|
|
match tool { |
|
|
|
|
Tool::WasmOpt => "x86-windows", |
|
|
|
|
_ => bail!("Unrecognized target!"), |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
bail!("Unrecognized target!") |
|
|
|
|
}; |
|
|
|
|
fn prebuilt_url(tool: &Tool, version: &str) -> Result<String> { |
|
|
|
|
let os = Os::get()?; |
|
|
|
|
let arch = Arch::get()?; |
|
|
|
|
prebuilt_url_for(tool, version, &arch, &os) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Get the download URL for some tool at some version, architecture and operating system
|
|
|
|
|
pub fn prebuilt_url_for(tool: &Tool, version: &str, arch: &Arch, os: &Os) -> Result<String> { |
|
|
|
|
let target = match (os, arch, tool) { |
|
|
|
|
(Os::Linux, Arch::X86_64, Tool::WasmOpt) => "x86_64-linux", |
|
|
|
|
(Os::Linux, Arch::X86_64, _) => "x86_64-unknown-linux-musl", |
|
|
|
|
(Os::MacOS, Arch::X86_64, Tool::WasmOpt) => "x86_64-macos", |
|
|
|
|
(Os::MacOS, Arch::X86_64, _) => "x86_64-apple-darwin", |
|
|
|
|
(Os::MacOS, Arch::AArch64, Tool::CargoGenerate) => "aarch64-apple-darwin", |
|
|
|
|
(Os::MacOS, Arch::AArch64, Tool::WasmOpt) => "arm64-macos", |
|
|
|
|
(Os::Windows, Arch::X86_64, Tool::WasmOpt) => "x86_64-windows", |
|
|
|
|
(Os::Windows, Arch::X86_64, _) => "x86_64-pc-windows-msvc", |
|
|
|
|
_ => bail!("Unrecognized target!"), |
|
|
|
|
}; |
|
|
|
|
match tool { |
|
|
|
|
Tool::WasmBindgen => { |
|
|
|
|
Ok(format!( |
|
|
|
@ -199,15 +194,14 @@ fn prebuilt_url(tool: &Tool, version: &str) -> Result<String, failure::Error> { |
|
|
|
|
Tool::CargoGenerate => { |
|
|
|
|
Ok(format!( |
|
|
|
|
"https://github.com/cargo-generate/cargo-generate/releases/download/v{0}/cargo-generate-v{0}-{1}.tar.gz", |
|
|
|
|
// Krate::new(&Tool::CargoGenerate)?.max_version,
|
|
|
|
|
"0.5.1", // latest released binary [#907](https://github.com/rustwasm/wasm-pack/issues/907)
|
|
|
|
|
"0.17.3", |
|
|
|
|
target |
|
|
|
|
)) |
|
|
|
|
}, |
|
|
|
|
Tool::WasmOpt => { |
|
|
|
|
Ok(format!( |
|
|
|
|
"https://github.com/WebAssembly/binaryen/releases/download/{vers}/binaryen-{vers}-{target}.tar.gz", |
|
|
|
|
vers = "version_108", |
|
|
|
|
vers = "version_111", |
|
|
|
|
target = target, |
|
|
|
|
)) |
|
|
|
|
} |
|
|
|
@ -221,7 +215,7 @@ pub fn cargo_install( |
|
|
|
|
cache: &Cache, |
|
|
|
|
version: &str, |
|
|
|
|
install_permitted: bool, |
|
|
|
|
) -> Result<Status, failure::Error> { |
|
|
|
|
) -> Result<Status> { |
|
|
|
|
debug!( |
|
|
|
|
"Attempting to use a `cargo install`ed version of `{}={}`", |
|
|
|
|
tool, version, |
|
|
|
@ -276,7 +270,7 @@ pub fn cargo_install( |
|
|
|
|
// just want them in `$root/*` directly (which matches how the tarballs are
|
|
|
|
|
// laid out, and where the rest of our code expects them to be). So we do a
|
|
|
|
|
// little renaming here.
|
|
|
|
|
let binaries: Result<Vec<&str>, failure::Error> = match tool { |
|
|
|
|
let binaries: Result<Vec<&str>> = match tool { |
|
|
|
|
Tool::WasmBindgen => Ok(vec!["wasm-bindgen", "wasm-bindgen-test-runner"]), |
|
|
|
|
Tool::CargoGenerate => Ok(vec!["cargo-generate"]), |
|
|
|
|
Tool::WasmOpt => bail!("Cannot install wasm-opt with cargo."), |
|
|
|
@ -288,8 +282,8 @@ pub fn cargo_install( |
|
|
|
|
.join(b) |
|
|
|
|
.with_extension(env::consts::EXE_EXTENSION); |
|
|
|
|
let to = tmp.join(from.file_name().unwrap()); |
|
|
|
|
fs::rename(&from, &to).with_context(|_| { |
|
|
|
|
format!( |
|
|
|
|
fs::rename(&from, &to).with_context(|| { |
|
|
|
|
anyhow!( |
|
|
|
|
"failed to move {} to {} for `cargo install`ed `{}`", |
|
|
|
|
from.display(), |
|
|
|
|
to.display(), |
|
|
|
|