mirror of
https://github.com/cargo-bins/cargo-binstall.git
synced 2025-06-15 15:16:37 +00:00
feat: use in memory extration
This commit is contained in:
parent
2d68a74637
commit
e5502cb80b
10 changed files with 244 additions and 337 deletions
173
Cargo.lock
generated
173
Cargo.lock
generated
|
@ -138,22 +138,13 @@ dependencies = [
|
|||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "camino"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f3132262930b0522068049f5870a856ab8affc80c70d08b6ecb785771a6fc23"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cargo-binstall"
|
||||
version = "0.7.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"cargo_metadata",
|
||||
"bytes",
|
||||
"cargo_toml",
|
||||
"crates-index",
|
||||
"crates_io_api",
|
||||
|
@ -169,7 +160,6 @@ dependencies = [
|
|||
"strum",
|
||||
"strum_macros",
|
||||
"tar",
|
||||
"tempdir",
|
||||
"tinytemplate",
|
||||
"tokio",
|
||||
"url",
|
||||
|
@ -177,28 +167,6 @@ dependencies = [
|
|||
"zip",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cargo-platform"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cbdb825da8a5df079a43676dbe042702f1707b1109f713a01420fbb4cc71fa27"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cargo_metadata"
|
||||
version = "0.14.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa"
|
||||
dependencies = [
|
||||
"camino",
|
||||
"cargo-platform",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cargo_toml"
|
||||
version = "0.11.5"
|
||||
|
@ -475,12 +443,6 @@ dependencies = [
|
|||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-cprng"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.21"
|
||||
|
@ -593,9 +555,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "git2"
|
||||
version = "0.14.2"
|
||||
version = "0.14.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3826a6e0e2215d7a41c2bfc7c9244123969273f3476b939a226aac0ab56e9e3c"
|
||||
checksum = "5e77a14ffc6ba4ad5188d6cf428894c4fcfda725326b37558f35bb677e712cec"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"libc",
|
||||
|
@ -818,15 +780,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.124"
|
||||
version = "0.2.125"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21a41fed9d98f27ab1c6d161da622a4fa35e8a54a8adc24bbf3ddd0ef70b0e50"
|
||||
checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b"
|
||||
|
||||
[[package]]
|
||||
name = "libgit2-sys"
|
||||
version = "0.13.2+1.4.2"
|
||||
version = "0.13.3+1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a42de9a51a5c12e00fc0e4ca6bc2ea43582fc6418488e8f615e905d886f258b"
|
||||
checksum = "c24d36c3ac9b9996a2418d6bf428cc0bc5d1a814a84303fc60986088c5ed60de"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
|
@ -900,9 +862,9 @@ checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
|
|||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.4.1"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
|
@ -962,9 +924,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.44"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
|
||||
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
|
@ -1041,9 +1003,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.9.2"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "995f667a6c822200b0433ac218e05582f0e2efa1b922a3fd2fbaadc5f87bab37"
|
||||
checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
|
@ -1059,7 +1021,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "1d791538a6dcc1e7cb7fe6f6b58aca40e7f79403c45b2bc274008b5e647af1d8"
|
||||
dependencies = [
|
||||
"base64ct",
|
||||
"rand_core 0.6.3",
|
||||
"rand_core",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
|
@ -1141,34 +1103,6 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
|
||||
dependencies = [
|
||||
"fuchsia-cprng",
|
||||
"libc",
|
||||
"rand_core 0.3.1",
|
||||
"rdrand",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
||||
dependencies = [
|
||||
"rand_core 0.4.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.3"
|
||||
|
@ -1199,15 +1133,6 @@ dependencies = [
|
|||
"num_cpus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rdrand"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.13"
|
||||
|
@ -1245,15 +1170,6 @@ version = "0.6.25"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
||||
|
||||
[[package]]
|
||||
name = "remove_dir_all"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.11.10"
|
||||
|
@ -1367,24 +1283,21 @@ name = "semver"
|
|||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d65bd28f48be7196d222d95b9243287f48d27aca604e08497513019ff0502cc4"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.136"
|
||||
version = "1.0.137"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789"
|
||||
checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.136"
|
||||
version = "1.0.137"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9"
|
||||
checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -1393,9 +1306,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.79"
|
||||
version = "1.0.80"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95"
|
||||
checksum = "f972498cf015f7c0746cac89ebe1d6ef10c293b94175a243a2d9442c163d9944"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
|
@ -1559,9 +1472,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.91"
|
||||
version = "1.0.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d"
|
||||
checksum = "7ff7c592601f11445996a06f8ad0c27f094a58857c2f89e97974ab9235b92c52"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -1579,16 +1492,6 @@ dependencies = [
|
|||
"xattr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempdir"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
|
||||
dependencies = [
|
||||
"rand",
|
||||
"remove_dir_all",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.1.3"
|
||||
|
@ -1609,18 +1512,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.30"
|
||||
version = "1.0.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417"
|
||||
checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.30"
|
||||
version = "1.0.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"
|
||||
checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -2004,9 +1907,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
|||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.34.0"
|
||||
version = "0.36.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5acdd78cb4ba54c0045ac14f62d8f94a03d10047904ae2a40afa1e99d8f70825"
|
||||
checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
|
||||
dependencies = [
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
|
@ -2017,33 +1920,33 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.34.0"
|
||||
version = "0.36.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d"
|
||||
checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.34.0"
|
||||
version = "0.36.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed"
|
||||
checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.34.0"
|
||||
version = "0.36.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956"
|
||||
checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.34.0"
|
||||
version = "0.36.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4"
|
||||
checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.34.0"
|
||||
version = "0.36.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9"
|
||||
checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
|
||||
|
||||
[[package]]
|
||||
name = "winreg"
|
||||
|
|
|
@ -21,7 +21,7 @@ pkg-fmt = "zip"
|
|||
[dependencies]
|
||||
anyhow = "1.0.57"
|
||||
async-trait = "0.1.52"
|
||||
cargo_metadata = "0.14.2"
|
||||
bytes = "1.1.0"
|
||||
cargo_toml = "0.11.4"
|
||||
crates-index = "0.18.7"
|
||||
crates_io_api = { version = "0.8.0", default-features = false, features = ["rustls"] }
|
||||
|
@ -36,7 +36,6 @@ structopt = "0.3.26"
|
|||
strum = "0.24.0"
|
||||
strum_macros = "0.24.0"
|
||||
tar = "0.4.38"
|
||||
tempdir = "0.3.7"
|
||||
tinytemplate = "1.2.1"
|
||||
tokio = { version = "1.18.0", features = [ "full" ] }
|
||||
url = "2.2.2"
|
||||
|
|
62
src/bins.rs
62
src/bins.rs
|
@ -1,14 +1,18 @@
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::{
|
||||
fs::File,
|
||||
io::Write,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use cargo_toml::Product;
|
||||
use log::debug;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::{PkgFmt, PkgMeta, Template};
|
||||
use crate::{extract_file, PkgFmt, PkgMeta, Template};
|
||||
|
||||
pub struct BinFile {
|
||||
pub base_name: String,
|
||||
pub source: PathBuf,
|
||||
pub source: Option<PathBuf>,
|
||||
pub dest: PathBuf,
|
||||
pub link: PathBuf,
|
||||
}
|
||||
|
@ -35,19 +39,21 @@ impl BinFile {
|
|||
|
||||
// Generate install paths
|
||||
// Source path is the download dir + the generated binary path
|
||||
let source_file_path = ctx.render(&data.meta.bin_dir)?;
|
||||
let source = if data.meta.pkg_fmt == PkgFmt::Bin {
|
||||
data.bin_path.clone()
|
||||
None
|
||||
} else {
|
||||
data.bin_path.join(&source_file_path)
|
||||
Some(PathBuf::from(ctx.render(&data.meta.bin_dir)?))
|
||||
};
|
||||
|
||||
// Destination path is the install dir + base-name-version{.extension}
|
||||
let dest_file_path = ctx.render("{ bin }-v{ version }{ binary-ext }")?;
|
||||
let dest = data.install_path.join(dest_file_path);
|
||||
let dest = data
|
||||
.install_path
|
||||
.join(ctx.render("{ bin }-v{ version }{ binary-ext }")?);
|
||||
|
||||
// Link at install dir + base-name{.extension}
|
||||
let link = data.install_path.join(&ctx.render("{ bin }{ binary-ext }")?);
|
||||
let link = data
|
||||
.install_path
|
||||
.join(&ctx.render("{ bin }{ binary-ext }")?);
|
||||
|
||||
Ok(Self {
|
||||
base_name,
|
||||
|
@ -58,12 +64,7 @@ impl BinFile {
|
|||
}
|
||||
|
||||
pub fn preview_bin(&self) -> String {
|
||||
format!(
|
||||
"{} ({} -> {})",
|
||||
self.base_name,
|
||||
self.source.file_name().unwrap().to_string_lossy(),
|
||||
self.dest.display()
|
||||
)
|
||||
format!("{} ({})", self.base_name, self.dest.display())
|
||||
}
|
||||
|
||||
pub fn preview_link(&self) -> String {
|
||||
|
@ -75,14 +76,28 @@ impl BinFile {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn install_bin(&self) -> Result<(), anyhow::Error> {
|
||||
// TODO: check if file already exists
|
||||
debug!(
|
||||
"Copy file from '{}' to '{}'",
|
||||
self.source.display(),
|
||||
self.dest.display()
|
||||
);
|
||||
std::fs::copy(&self.source, &self.dest)?;
|
||||
pub fn is_binary_already_installed(&self) -> bool {
|
||||
self.dest.exists()
|
||||
}
|
||||
|
||||
pub fn install_bin(&self, data: &bytes::Bytes, pkg_fmt: PkgFmt) -> Result<(), anyhow::Error> {
|
||||
debug!("Writing file to '{}'", self.dest.display());
|
||||
|
||||
// Extract files
|
||||
let bin_file = if pkg_fmt != PkgFmt::Bin {
|
||||
extract_file(data, pkg_fmt, self.source.as_ref().unwrap().to_path_buf())?
|
||||
} else {
|
||||
data.to_vec()
|
||||
};
|
||||
|
||||
if let Some(parent_dir) = self.dest.parent() {
|
||||
std::fs::create_dir_all(parent_dir)?;
|
||||
}
|
||||
|
||||
// Will truncate existing file
|
||||
let mut file = File::create(&self.dest)?;
|
||||
file.write_all(&bin_file)?;
|
||||
file.flush().unwrap();
|
||||
|
||||
#[cfg(target_family = "unix")]
|
||||
{
|
||||
|
@ -135,7 +150,6 @@ pub struct Data {
|
|||
pub version: String,
|
||||
pub repo: Option<String>,
|
||||
pub meta: PkgMeta,
|
||||
pub bin_path: PathBuf,
|
||||
pub install_path: PathBuf,
|
||||
}
|
||||
|
||||
|
|
|
@ -2,13 +2,16 @@ use std::path::{Path, PathBuf};
|
|||
use std::time::Duration;
|
||||
|
||||
use anyhow::{anyhow, Context};
|
||||
use cargo_toml::Manifest;
|
||||
use log::debug;
|
||||
use semver::{Version, VersionReq};
|
||||
|
||||
use crates_io_api::AsyncClient;
|
||||
|
||||
use crate::helpers::*;
|
||||
use crate::Meta;
|
||||
use crate::PkgFmt;
|
||||
use std::str::FromStr;
|
||||
|
||||
fn find_version<'a, V: Iterator<Item = &'a str>>(
|
||||
requirement: &str,
|
||||
|
@ -21,7 +24,7 @@ fn find_version<'a, V: Iterator<Item = &'a str>>(
|
|||
let mut filtered: Vec<_> = version_iter
|
||||
.filter(|v| {
|
||||
// Remove leading `v` for git tags
|
||||
let ver_str = match v.strip_prefix("s") {
|
||||
let ver_str = match v.strip_prefix('s') {
|
||||
Some(v) => v,
|
||||
None => v,
|
||||
};
|
||||
|
@ -60,11 +63,10 @@ fn find_version<'a, V: Iterator<Item = &'a str>>(
|
|||
}
|
||||
|
||||
/// Fetch a crate by name and version from crates.io
|
||||
pub async fn fetch_crate_cratesio(
|
||||
pub async fn fetch_manifest_cratesio(
|
||||
name: &str,
|
||||
version_req: &str,
|
||||
temp_dir: &Path,
|
||||
) -> Result<PathBuf, anyhow::Error> {
|
||||
) -> Result<Manifest<Meta>, anyhow::Error> {
|
||||
// Fetch / update index
|
||||
debug!("Updating crates.io index");
|
||||
let mut index = crates_index::Index::new_cargo_default()?;
|
||||
|
@ -119,21 +121,23 @@ pub async fn fetch_crate_cratesio(
|
|||
debug!("Found information for crate version: '{}'", version.num);
|
||||
|
||||
// Download crate to temporary dir (crates.io or git?)
|
||||
let crate_url = format!("https://crates.io/{}", version.dl_path);
|
||||
let tgz_path = temp_dir.join(format!("{}.tgz", name));
|
||||
let crate_url = format!("https://crates.io{}", version.dl_path);
|
||||
|
||||
debug!("Fetching crate from: {}", crate_url);
|
||||
|
||||
// Download crate
|
||||
download(&crate_url, &tgz_path).await?;
|
||||
let crate_data = download(&crate_url).await?;
|
||||
|
||||
// Decompress downloaded tgz
|
||||
debug!("Decompressing crate archive");
|
||||
extract(&tgz_path, PkgFmt::Tgz, &temp_dir)?;
|
||||
let crate_path = temp_dir.join(format!("{}-{}", name, version_name));
|
||||
let raw_manifest = extract_file(
|
||||
&crate_data,
|
||||
PkgFmt::Tgz,
|
||||
PathBuf::from_str(&format!("{}-{}/Cargo.toml", name, version_name)).unwrap(),
|
||||
)?;
|
||||
|
||||
// Return crate directory
|
||||
Ok(crate_path)
|
||||
Ok(Manifest::<Meta>::from_slice_with_metadata(&raw_manifest)?)
|
||||
}
|
||||
|
||||
/// Fetch a crate by name and version from github
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
use std::path::Path;
|
||||
|
||||
pub use gh_crate_meta::*;
|
||||
pub use log::debug;
|
||||
pub use quickinstall::*;
|
||||
|
@ -17,7 +15,7 @@ pub trait Fetcher {
|
|||
Self: Sized;
|
||||
|
||||
/// Fetch a package
|
||||
async fn fetch(&self, dst: &Path) -> Result<(), anyhow::Error>;
|
||||
async fn fetch(&self) -> Result<bytes::Bytes, anyhow::Error>;
|
||||
|
||||
/// Check if a package is available for download
|
||||
async fn check(&self) -> Result<bool, anyhow::Error>;
|
||||
|
@ -54,15 +52,18 @@ impl MultiFetcher {
|
|||
|
||||
pub async fn first_available(&self) -> Option<&dyn Fetcher> {
|
||||
for fetcher in &self.fetchers {
|
||||
if fetcher.check().await.unwrap_or_else(|err| {
|
||||
match fetcher.check().await {
|
||||
Ok(true) => {
|
||||
return Some(&**fetcher);
|
||||
}
|
||||
Ok(false) => {}
|
||||
Err(err) => {
|
||||
debug!(
|
||||
"Error while checking fetcher {}: {}",
|
||||
fetcher.source_name(),
|
||||
err
|
||||
);
|
||||
false
|
||||
}) {
|
||||
return Some(&**fetcher);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
use std::path::Path;
|
||||
|
||||
use log::{debug, info};
|
||||
use reqwest::Method;
|
||||
use serde::Serialize;
|
||||
|
@ -16,7 +14,7 @@ impl GhCrateMeta {
|
|||
fn url(&self) -> Result<Url, anyhow::Error> {
|
||||
let ctx = Context::from_data(&self.data);
|
||||
debug!("Using context: {:?}", ctx);
|
||||
Ok(ctx.render_url(&self.data.meta.pkg_url)?)
|
||||
ctx.render_url(&self.data.meta.pkg_url)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,10 +30,10 @@ impl super::Fetcher for GhCrateMeta {
|
|||
remote_exists(url.as_str(), Method::HEAD).await
|
||||
}
|
||||
|
||||
async fn fetch(&self, dst: &Path) -> Result<(), anyhow::Error> {
|
||||
async fn fetch(&self) -> Result<bytes::Bytes, anyhow::Error> {
|
||||
let url = self.url()?;
|
||||
info!("Downloading package from: '{url}'");
|
||||
download(url.as_str(), dst).await
|
||||
download(url.as_str()).await
|
||||
}
|
||||
|
||||
fn pkg_fmt(&self) -> PkgFmt {
|
||||
|
@ -171,8 +169,11 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn different_url() {
|
||||
let mut meta = PkgMeta::default();
|
||||
meta.pkg_url = "{ repo }/releases/download/v{ version }/sx128x-util-{ target }-v{ version }.{ archive-format }".to_string();
|
||||
let meta = PkgMeta {
|
||||
pkg_url: "{ repo }/releases/download/v{ version }/sx128x-util-{ target }-v{ version }.{ archive-format }".to_string(),
|
||||
..PkgMeta::default()
|
||||
};
|
||||
|
||||
let data = Data {
|
||||
name: "radio-sx128x".to_string(),
|
||||
target: "x86_64-unknown-linux-gnu".to_string(),
|
||||
|
@ -190,8 +191,11 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn deprecated_format() {
|
||||
let mut meta = PkgMeta::default();
|
||||
meta.pkg_url = "{ repo }/releases/download/v{ version }/sx128x-util-{ target }-v{ version }.{ format }".to_string();
|
||||
let meta = PkgMeta {
|
||||
pkg_url: "{ repo }/releases/download/v{ version }/sx128x-util-{ target }-v{ version }.{ format }".to_string(),
|
||||
..PkgMeta::default()
|
||||
};
|
||||
|
||||
let data = Data {
|
||||
name: "radio-sx128x".to_string(),
|
||||
target: "x86_64-unknown-linux-gnu".to_string(),
|
||||
|
@ -209,11 +213,13 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn different_ext() {
|
||||
let mut meta = PkgMeta::default();
|
||||
meta.pkg_url =
|
||||
let meta = PkgMeta {
|
||||
pkg_url:
|
||||
"{ repo }/releases/download/v{ version }/{ name }-v{ version }-{ target }.tar.xz"
|
||||
.to_string();
|
||||
meta.pkg_fmt = PkgFmt::Txz;
|
||||
.to_string(),
|
||||
pkg_fmt: PkgFmt::Txz,
|
||||
..PkgMeta::default()
|
||||
};
|
||||
let data = Data {
|
||||
name: "cargo-watch".to_string(),
|
||||
target: "aarch64-apple-darwin".to_string(),
|
||||
|
@ -231,9 +237,12 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn no_archive() {
|
||||
let mut meta = PkgMeta::default();
|
||||
meta.pkg_url = "{ repo }/releases/download/v{ version }/{ name }-v{ version }-{ target }{ binary-ext }".to_string();
|
||||
meta.pkg_fmt = PkgFmt::Bin;
|
||||
let meta = PkgMeta{
|
||||
pkg_fmt: PkgFmt::Bin,
|
||||
pkg_url: "{ repo }/releases/download/v{ version }/{ name }-v{ version }-{ target }{ binary-ext }".to_string(),
|
||||
..PkgMeta::default()
|
||||
};
|
||||
|
||||
let data = Data {
|
||||
name: "cargo-watch".to_string(),
|
||||
target: "aarch64-pc-windows-msvc".to_string(),
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
use std::path::Path;
|
||||
|
||||
use log::info;
|
||||
use reqwest::Method;
|
||||
|
||||
|
@ -32,10 +30,10 @@ impl super::Fetcher for QuickInstall {
|
|||
remote_exists(&url, Method::HEAD).await
|
||||
}
|
||||
|
||||
async fn fetch(&self, dst: &Path) -> Result<(), anyhow::Error> {
|
||||
async fn fetch(&self) -> Result<bytes::Bytes, anyhow::Error> {
|
||||
let url = self.package_url();
|
||||
info!("Downloading package from: '{url}'");
|
||||
download(&url, &dst).await
|
||||
download(&url).await
|
||||
}
|
||||
|
||||
fn pkg_fmt(&self) -> PkgFmt {
|
||||
|
|
131
src/helpers.rs
131
src/helpers.rs
|
@ -1,10 +1,14 @@
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::{
|
||||
io::Cursor,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use log::{debug, error, info};
|
||||
|
||||
use cargo_toml::Manifest;
|
||||
use flate2::read::GzDecoder;
|
||||
use serde::Serialize;
|
||||
use std::io::Read;
|
||||
use tar::Archive;
|
||||
use tinytemplate::TinyTemplate;
|
||||
use xz2::read::XzDecoder;
|
||||
|
@ -15,10 +19,20 @@ use crate::Meta;
|
|||
use super::PkgFmt;
|
||||
|
||||
/// Load binstall metadata from the crate `Cargo.toml` at the provided path
|
||||
pub fn load_manifest_path<P: AsRef<Path>>(
|
||||
manifest_path: P,
|
||||
) -> Result<Manifest<Meta>, anyhow::Error> {
|
||||
debug!("Reading manifest: {}", manifest_path.as_ref().display());
|
||||
pub fn load_manifest_path(mut manifest_path: PathBuf) -> Result<Manifest<Meta>, anyhow::Error> {
|
||||
debug!("Reading manifest: {}", manifest_path.display());
|
||||
|
||||
if manifest_path.is_dir() {
|
||||
manifest_path = manifest_path.join("Cargo.toml");
|
||||
}
|
||||
|
||||
if !manifest_path.exists() {
|
||||
error!(
|
||||
"Manifest at '{:?}' could not be found",
|
||||
manifest_path.display()
|
||||
);
|
||||
return Err(anyhow::anyhow!("Manifest could not be found"));
|
||||
}
|
||||
|
||||
// Load and parse manifest (this checks file system for binary output names)
|
||||
let manifest = Manifest::<Meta>::from_path_with_metadata(manifest_path)?;
|
||||
|
@ -33,7 +47,7 @@ pub async fn remote_exists(url: &str, method: reqwest::Method) -> Result<bool, a
|
|||
}
|
||||
|
||||
/// Download a file from the provided URL to the provided path
|
||||
pub async fn download<P: AsRef<Path>>(url: &str, path: P) -> Result<(), anyhow::Error> {
|
||||
pub async fn download(url: &str) -> Result<bytes::Bytes, anyhow::Error> {
|
||||
debug!("Downloading from: '{}'", url);
|
||||
|
||||
let resp = reqwest::get(url).await?;
|
||||
|
@ -43,90 +57,89 @@ pub async fn download<P: AsRef<Path>>(url: &str, path: P) -> Result<(), anyhow::
|
|||
return Err(anyhow::anyhow!(resp.status()));
|
||||
}
|
||||
|
||||
let bytes = resp.bytes().await?;
|
||||
Ok(resp.bytes().await?)
|
||||
}
|
||||
|
||||
let path = path.as_ref();
|
||||
debug!("Download OK, writing to file: '{}'", path.display());
|
||||
// Extracts a file at path from tar archive to byte vector
|
||||
fn extract_file_from_tar_archive<T: std::io::Read>(
|
||||
tar_archive: &mut Archive<T>,
|
||||
path: PathBuf,
|
||||
) -> Result<Vec<u8>, anyhow::Error> {
|
||||
let mut file = tar_archive
|
||||
.entries()?
|
||||
.find(|e| {
|
||||
if let Ok(value) = e.as_ref() {
|
||||
if let Ok(file_path) = value.path() {
|
||||
file_path == path
|
||||
} else {
|
||||
false
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
.unwrap()?;
|
||||
|
||||
std::fs::create_dir_all(path.parent().unwrap())?;
|
||||
std::fs::write(&path, bytes)?;
|
||||
let mut buffer = Vec::with_capacity(file.size() as usize);
|
||||
|
||||
Ok(())
|
||||
file.read_to_end(&mut buffer)?;
|
||||
|
||||
Ok(buffer)
|
||||
}
|
||||
|
||||
/// Extract files from the specified source onto the specified path
|
||||
pub fn extract<S: AsRef<Path>, P: AsRef<Path>>(
|
||||
source: S,
|
||||
pub fn extract_file(
|
||||
source: &bytes::Bytes,
|
||||
fmt: PkgFmt,
|
||||
path: P,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
file: PathBuf,
|
||||
) -> Result<Vec<u8>, anyhow::Error> {
|
||||
match fmt {
|
||||
PkgFmt::Tar => {
|
||||
// Extract to install dir
|
||||
debug!(
|
||||
"Extracting from tar archive '{:?}' to `{:?}`",
|
||||
source.as_ref(),
|
||||
path.as_ref()
|
||||
);
|
||||
debug!("Extracting from tar archive '{:?}'", source.as_ref(),);
|
||||
|
||||
let dat = std::fs::File::open(source)?;
|
||||
let mut tar = Archive::new(dat);
|
||||
let mut tar = Archive::new(&source[..]);
|
||||
|
||||
tar.unpack(path)?;
|
||||
extract_file_from_tar_archive(&mut tar, file)
|
||||
}
|
||||
PkgFmt::Tgz => {
|
||||
// Extract to install dir
|
||||
debug!(
|
||||
"Decompressing from tgz archive '{:?}' to `{:?}`",
|
||||
source.as_ref(),
|
||||
path.as_ref()
|
||||
);
|
||||
debug!("Decompressing from tgz archive '{:?}'", source.as_ref());
|
||||
|
||||
let dat = std::fs::File::open(source)?;
|
||||
let tar = GzDecoder::new(dat);
|
||||
let tar = GzDecoder::new(&source[..]);
|
||||
let mut tgz = Archive::new(tar);
|
||||
|
||||
tgz.unpack(path)?;
|
||||
extract_file_from_tar_archive(&mut tgz, file)
|
||||
}
|
||||
PkgFmt::Txz => {
|
||||
// Extract to install dir
|
||||
debug!(
|
||||
"Decompressing from txz archive '{:?}' to `{:?}`",
|
||||
source.as_ref(),
|
||||
path.as_ref()
|
||||
);
|
||||
debug!("Decompressing from txz archive '{:?}'", source.as_ref());
|
||||
|
||||
let dat = std::fs::File::open(source)?;
|
||||
let tar = XzDecoder::new(dat);
|
||||
let tar = XzDecoder::new(&source[..]);
|
||||
let mut txz = Archive::new(tar);
|
||||
|
||||
txz.unpack(path)?;
|
||||
extract_file_from_tar_archive(&mut txz, file)
|
||||
}
|
||||
PkgFmt::Zip => {
|
||||
// Extract to install dir
|
||||
debug!(
|
||||
"Decompressing from zip archive '{:?}' to `{:?}`",
|
||||
source.as_ref(),
|
||||
path.as_ref()
|
||||
);
|
||||
debug!("Decompressing from zip archive '{:?}'", source.as_ref());
|
||||
|
||||
let dat = std::fs::File::open(source)?;
|
||||
let mut zip = ZipArchive::new(dat)?;
|
||||
let mut zip = ZipArchive::new(Cursor::new(&source[..]))?;
|
||||
|
||||
zip.extract(path)?;
|
||||
let mut file = zip.by_name(file.to_str().unwrap())?;
|
||||
|
||||
let mut buffer = Vec::with_capacity(file.size() as usize);
|
||||
|
||||
file.read_to_end(&mut buffer)?;
|
||||
|
||||
Ok(buffer)
|
||||
}
|
||||
PkgFmt::Bin => {
|
||||
debug!(
|
||||
"Copying binary '{:?}' to `{:?}`",
|
||||
source.as_ref(),
|
||||
path.as_ref()
|
||||
);
|
||||
debug!("Copying binary '{:?}'", source.as_ref());
|
||||
// Copy to install dir
|
||||
std::fs::copy(source, path)?;
|
||||
Ok(source.to_vec())
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Fetch install path from environment
|
||||
|
@ -162,7 +175,7 @@ pub fn get_install_path<P: AsRef<Path>>(install_path: Option<P>) -> Option<PathB
|
|||
// Local executable dir if no cargo is found
|
||||
if let Some(d) = dirs::executable_dir() {
|
||||
debug!("Fallback to {}", d.display());
|
||||
return Some(d.into());
|
||||
return Some(d);
|
||||
}
|
||||
|
||||
None
|
||||
|
@ -192,7 +205,7 @@ pub trait Template: Serialize {
|
|||
let mut tt = TinyTemplate::new();
|
||||
|
||||
// Add template to instance
|
||||
tt.add_template("path", &template)?;
|
||||
tt.add_template("path", template)?;
|
||||
|
||||
// Render output
|
||||
Ok(tt.render("path", self)?)
|
||||
|
|
22
src/lib.rs
22
src/lib.rs
|
@ -13,14 +13,14 @@ pub mod bins;
|
|||
pub mod fetchers;
|
||||
|
||||
/// Compiled target triple, used as default for binary fetching
|
||||
pub const TARGET: &'static str = env!("TARGET");
|
||||
pub const TARGET: &str = env!("TARGET");
|
||||
|
||||
/// Default package path template (may be overridden in package Cargo.toml)
|
||||
pub const DEFAULT_PKG_URL: &'static str =
|
||||
pub const DEFAULT_PKG_URL: &str =
|
||||
"{ repo }/releases/download/v{ version }/{ name }-{ target }-v{ version }.{ archive-format }";
|
||||
|
||||
/// Default binary name template (may be overridden in package Cargo.toml)
|
||||
pub const DEFAULT_BIN_DIR: &'static str = "{ name }-{ target }-v{ version }/{ bin }{ binary-ext }";
|
||||
pub const DEFAULT_BIN_DIR: &str = "{ name }-{ target }-v{ version }/{ bin }{ binary-ext }";
|
||||
|
||||
/// Binary format enumeration
|
||||
#[derive(
|
||||
|
@ -108,7 +108,7 @@ impl PkgMeta {
|
|||
/// Target specific overrides for binary installation
|
||||
///
|
||||
/// Exposed via `[package.metadata.TARGET]` in `Cargo.toml`
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Default)]
|
||||
#[serde(rename_all = "kebab-case", default)]
|
||||
pub struct PkgOverride {
|
||||
/// URL template override for package downloads
|
||||
|
@ -121,16 +121,6 @@ pub struct PkgOverride {
|
|||
pub bin_dir: Option<String>,
|
||||
}
|
||||
|
||||
impl Default for PkgOverride {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
pkg_url: None,
|
||||
pkg_fmt: None,
|
||||
bin_dir: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub struct BinMeta {
|
||||
|
@ -157,9 +147,9 @@ mod test {
|
|||
let mut manifest_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
|
||||
manifest_dir.push_str("/Cargo.toml");
|
||||
|
||||
let manifest = load_manifest_path(&manifest_dir).expect("Error parsing metadata");
|
||||
let manifest = load_manifest_path(manifest_dir.into()).expect("Error parsing metadata");
|
||||
let package = manifest.package.unwrap();
|
||||
let meta = package.metadata.map(|m| m.binstall).flatten().unwrap();
|
||||
let meta = package.metadata.and_then(|m| m.binstall).unwrap();
|
||||
|
||||
assert_eq!(&package.name, "cargo-binstall");
|
||||
|
||||
|
|
84
src/main.rs
84
src/main.rs
|
@ -4,7 +4,6 @@ use cargo_toml::{Package, Product};
|
|||
use log::{debug, error, info, warn, LevelFilter};
|
||||
use simplelog::{ColorChoice, ConfigBuilder, TermLogger, TerminalMode};
|
||||
use structopt::StructOpt;
|
||||
use tempdir::TempDir;
|
||||
use tokio::process::Command;
|
||||
|
||||
use cargo_binstall::{
|
||||
|
@ -46,10 +45,6 @@ struct Options {
|
|||
#[structopt(long)]
|
||||
no_confirm: bool,
|
||||
|
||||
/// Do not cleanup temporary files on success
|
||||
#[structopt(long)]
|
||||
no_cleanup: bool,
|
||||
|
||||
/// Override manifest source.
|
||||
/// This skips searching crates.io for a manifest and uses
|
||||
/// the specified path directly, useful for debugging and
|
||||
|
@ -88,21 +83,17 @@ async fn main() -> Result<(), anyhow::Error> {
|
|||
)
|
||||
.unwrap();
|
||||
|
||||
// Create a temporary directory for downloads etc.
|
||||
let temp_dir = TempDir::new("cargo-binstall")?;
|
||||
|
||||
info!("Installing package: '{}'", opts.name);
|
||||
|
||||
debug!("Reading manifest");
|
||||
// Fetch crate via crates.io, git, or use a local manifest path
|
||||
// TODO: work out which of these to do based on `opts.name`
|
||||
// TODO: support git-based fetches (whole repo name rather than just crate name)
|
||||
let manifest_path = match opts.manifest_path.clone() {
|
||||
Some(p) => p,
|
||||
None => fetch_crate_cratesio(&opts.name, &opts.version, temp_dir.path()).await?,
|
||||
let manifest = match opts.manifest_path.clone() {
|
||||
Some(p) => load_manifest_path(p)?,
|
||||
None => fetch_manifest_cratesio(&opts.name, &opts.version).await?,
|
||||
};
|
||||
|
||||
debug!("Reading manifest: {}", manifest_path.display());
|
||||
let manifest = load_manifest_path(manifest_path.join("Cargo.toml"))?;
|
||||
let package = manifest.package.unwrap();
|
||||
|
||||
let is_plain_version = semver::Version::from_str(&opts.version).is_ok();
|
||||
|
@ -122,9 +113,8 @@ async fn main() -> Result<(), anyhow::Error> {
|
|||
package
|
||||
.metadata
|
||||
.as_ref()
|
||||
.map(|m| m.binstall.clone())
|
||||
.flatten()
|
||||
.unwrap_or(PkgMeta::default()),
|
||||
.and_then(|m| m.binstall.clone())
|
||||
.unwrap_or_default(),
|
||||
manifest.bin,
|
||||
);
|
||||
|
||||
|
@ -142,12 +132,6 @@ async fn main() -> Result<(), anyhow::Error> {
|
|||
})?;
|
||||
debug!("Using install path: {}", install_path.display());
|
||||
|
||||
// Compute temporary directory for downloads
|
||||
let pkg_path = temp_dir
|
||||
.path()
|
||||
.join(format!("pkg-{}.{}", opts.name, meta.pkg_fmt));
|
||||
debug!("Using temporary download path: {}", pkg_path.display());
|
||||
|
||||
let fetcher_data = Data {
|
||||
name: package.name.clone(),
|
||||
target: opts.target.clone(),
|
||||
|
@ -163,17 +147,7 @@ async fn main() -> Result<(), anyhow::Error> {
|
|||
|
||||
match fetchers.first_available().await {
|
||||
Some(fetcher) => {
|
||||
install_from_package(
|
||||
binaries,
|
||||
fetcher,
|
||||
install_path,
|
||||
meta,
|
||||
opts,
|
||||
package,
|
||||
pkg_path,
|
||||
temp_dir,
|
||||
)
|
||||
.await
|
||||
install_from_package(binaries, fetcher, install_path, meta, opts, package).await
|
||||
}
|
||||
None => install_from_source(opts, package).await,
|
||||
}
|
||||
|
@ -186,8 +160,6 @@ async fn install_from_package(
|
|||
mut meta: PkgMeta,
|
||||
opts: Options,
|
||||
package: Package<Meta>,
|
||||
pkg_path: PathBuf,
|
||||
temp_dir: TempDir,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
// Prompt user for third-party source
|
||||
if fetcher.is_third_party() {
|
||||
|
@ -212,11 +184,12 @@ async fn install_from_package(
|
|||
}
|
||||
|
||||
// Download package
|
||||
if opts.dry_run {
|
||||
let binary = if opts.dry_run {
|
||||
info!("Dry run, not downloading package");
|
||||
None
|
||||
} else {
|
||||
fetcher.fetch(&pkg_path).await?;
|
||||
}
|
||||
Some(fetcher.fetch().await?)
|
||||
};
|
||||
|
||||
#[cfg(incomplete)]
|
||||
{
|
||||
|
@ -242,25 +215,12 @@ async fn install_from_package(
|
|||
}
|
||||
}
|
||||
|
||||
let bin_path = temp_dir.path().join(format!("bin-{}", opts.name));
|
||||
debug!("Using temporary binary path: {}", bin_path.display());
|
||||
|
||||
if !opts.dry_run {
|
||||
// Extract files
|
||||
extract(&pkg_path, fetcher.pkg_fmt(), &bin_path)?;
|
||||
|
||||
// Bypass cleanup if disabled
|
||||
if opts.no_cleanup {
|
||||
let _ = temp_dir.into_path();
|
||||
}
|
||||
|
||||
if binaries.is_empty() {
|
||||
if !opts.dry_run && binaries.is_empty() {
|
||||
error!("No binaries specified (or inferred from file system)");
|
||||
return Err(anyhow::anyhow!(
|
||||
"No binaries specified (or inferred from file system)"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// List files to be installed
|
||||
// based on those found via Cargo.toml
|
||||
|
@ -270,7 +230,6 @@ async fn install_from_package(
|
|||
version: package.version.clone(),
|
||||
repo: package.repository.clone(),
|
||||
meta,
|
||||
bin_path,
|
||||
install_path,
|
||||
};
|
||||
|
||||
|
@ -304,7 +263,24 @@ async fn install_from_package(
|
|||
|
||||
info!("Installing binaries...");
|
||||
for file in &bin_files {
|
||||
file.install_bin()?;
|
||||
if file.is_binary_already_installed() {
|
||||
if opts.no_confirm {
|
||||
warn!(
|
||||
"The binary at {} does already exist, going to overwrite it",
|
||||
file.dest.display()
|
||||
);
|
||||
} else {
|
||||
warn!(
|
||||
"The binary at {} does already exist, would you like to overwrite it?",
|
||||
file.dest.display()
|
||||
);
|
||||
if !confirm()? {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
file.install_bin(binary.as_ref().unwrap(), fetcher.pkg_fmt())?;
|
||||
}
|
||||
|
||||
// Generate symlinks
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue