feat: finalize target download and caching system

This commit is contained in:
Erica Marigold 2024-03-14 18:19:07 +05:30
parent b9b1ba7d03
commit a40d267d2b
No known key found for this signature in database
GPG key ID: 2768CC0C23D245D1
3 changed files with 86 additions and 24 deletions

44
Cargo.lock generated
View file

@ -137,6 +137,7 @@ dependencies = [
"brotli", "brotli",
"flate2", "flate2",
"futures-core", "futures-core",
"futures-io",
"memchr", "memchr",
"pin-project-lite", "pin-project-lite",
"tokio", "tokio",
@ -153,6 +154,21 @@ dependencies = [
"syn 2.0.48", "syn 2.0.48",
] ]
[[package]]
name = "async_zip"
version = "0.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "527207465fb6dcafbf661b0d4a51d0d2306c9d0c2975423079a6caa807930daf"
dependencies = [
"async-compression",
"crc32fast",
"futures-lite",
"pin-project",
"thiserror",
"tokio",
"tokio-util",
]
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.1.0" version = "1.1.0"
@ -692,6 +708,25 @@ version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
[[package]]
name = "futures-io"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
[[package]]
name = "futures-lite"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "445ba825b27408685aaecefd65178908c36c6e96aaf6d8599419d46e624192ba"
dependencies = [
"fastrand",
"futures-core",
"futures-io",
"parking",
"pin-project-lite",
]
[[package]] [[package]]
name = "futures-macro" name = "futures-macro"
version = "0.3.30" version = "0.3.30"
@ -1101,6 +1136,7 @@ dependencies = [
"anyhow", "anyhow",
"async-compression", "async-compression",
"async-trait", "async-trait",
"async_zip",
"chrono", "chrono",
"chrono_lc", "chrono_lc",
"clap", "clap",
@ -1138,6 +1174,7 @@ dependencies = [
"thiserror", "thiserror",
"tokio", "tokio",
"tokio-tungstenite", "tokio-tungstenite",
"tokio-util",
"toml", "toml",
"tracing", "tracing",
"tracing-subscriber", "tracing-subscriber",
@ -1347,6 +1384,12 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
[[package]]
name = "parking"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae"
[[package]] [[package]]
name = "parking_lot" name = "parking_lot"
version = "0.12.1" version = "0.12.1"
@ -2418,6 +2461,7 @@ checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15"
dependencies = [ dependencies = [
"bytes", "bytes",
"futures-core", "futures-core",
"futures-io",
"futures-sink", "futures-sink",
"pin-project-lite", "pin-project-lite",
"tokio", "tokio",

View file

@ -27,6 +27,8 @@ cli = [
"dep:include_dir", "dep:include_dir",
"dep:regex", "dep:regex",
"dep:rustyline", "dep:rustyline",
"dep:async_zip",
"dep:tokio-util",
] ]
roblox = [ roblox = [
"dep:glam", "dep:glam",
@ -137,3 +139,10 @@ rbx_dom_weak = { optional = true, version = "2.6.0" }
rbx_reflection = { optional = true, version = "4.4.0" } rbx_reflection = { optional = true, version = "4.4.0" }
rbx_reflection_database = { optional = true, version = "0.2.9" } rbx_reflection_database = { optional = true, version = "0.2.9" }
rbx_xml = { optional = true, version = "0.13.2" } rbx_xml = { optional = true, version = "0.13.2" }
### CROSS COMPILATION
async_zip = { optional = true, version = "0.0.16", features = [
"tokio",
"deflate",
] }
tokio-util = { optional = true, version = "0.7", features = ["io-util"] }

View file

@ -1,20 +1,22 @@
use std::{ use std::{
env::consts::EXE_EXTENSION, env::consts::EXE_EXTENSION,
io::Cursor,
path::{Path, PathBuf}, path::{Path, PathBuf},
process::ExitCode, process::ExitCode,
}; };
use anyhow::{bail, Context, Error, Result}; use anyhow::{bail, Context, Error, Result};
use async_compression::tokio::bufread::DeflateDecoder; use async_zip::base::read::seek::ZipFileReader;
use clap::Parser; use clap::Parser;
use console::style; use console::style;
use directories::BaseDirs; use directories::BaseDirs;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use thiserror::Error; use thiserror::Error;
use tokio::{ use tokio::{
fs, fs::{self, File},
io::{AsyncReadExt, AsyncWriteExt as _}, io::{AsyncReadExt, AsyncWriteExt},
}; };
use tokio_util::compat::{FuturesAsyncReadCompatExt, TokioAsyncReadCompatExt};
use crate::standalone::metadata::Metadata; use crate::standalone::metadata::Metadata;
@ -74,7 +76,7 @@ impl BuildCommand {
if let Err(other_err) = inner_err { if let Err(other_err) = inner_err {
bail!( bail!(
"Encountered an error while handling cross-compilation flags: {}", "Encountered an error while handling cross-compilation flags: {:#?}",
other_err other_err
); );
} }
@ -101,25 +103,29 @@ impl BuildCommand {
style("Write").blue().bold(), style("Write").blue().bold(),
style(output_path.display()).underlined() style(output_path.display()).underlined()
); );
write_executable_file_to(output_path, patched_bin).await?; write_file_to(output_path, patched_bin, 0o755).await?; // Read & execute for all, write for owner
Ok(ExitCode::SUCCESS) Ok(ExitCode::SUCCESS)
} }
} }
async fn write_executable_file_to(path: impl AsRef<Path>, bytes: impl AsRef<[u8]>) -> Result<()> { async fn write_file_to(
path: impl AsRef<Path>,
bytes: impl AsRef<[u8]>,
perms: u32,
) -> Result<File> {
let mut options = fs::OpenOptions::new(); let mut options = fs::OpenOptions::new();
options.write(true).create(true).truncate(true); options.write(true).read(true).create(true).truncate(true);
#[cfg(unix)] #[cfg(unix)]
{ {
options.mode(0o755); // Read & execute for all, write for owner options.mode(perms);
} }
let mut file = options.open(path).await?; let mut file = options.open(path).await?;
file.write_all(bytes.as_ref()).await?; file.write_all(bytes.as_ref()).await?;
Ok(()) Ok(file)
} }
/// Possible ways in which the discovery and/or download of a base binary's path can error /// Possible ways in which the discovery and/or download of a base binary's path can error
@ -222,26 +228,29 @@ async fn get_base_exe_path(
.into()); .into());
} }
let compressed_reader = resp let compressed_data = Cursor::new(
.bytes() resp.bytes()
.await .await
.map_err(BasePathDiscoveryError::IoError)?; .map_err(BasePathDiscoveryError::IoError)?
let mut decompressed_bytes = vec![]; .to_vec(),
);
// This errors, so idk what decoder to use let mut decoder = ZipFileReader::new(compressed_data.compat())
DeflateDecoder::new(compressed_reader.as_ref())
.read_to_end(&mut decompressed_bytes)
.await .await
.map_err(BasePathDiscoveryError::Decompression)?; .map_err(BasePathDiscoveryError::Decompression)?;
fs::OpenOptions::new() let mut decompressed = vec![];
.write(true)
.create(true) decoder
.truncate(true) .reader_without_entry(0)
.open(&path)
.await .await
.map_err(BasePathDiscoveryError::IoError)? .map_err(BasePathDiscoveryError::Decompression)?
.write_all(&decompressed_bytes) .compat()
.read_to_end(&mut decompressed)
.await
.map_err(BasePathDiscoveryError::Decompression)?;
write_file_to(&path, decompressed, 0o644)
.await .await
.map_err(BasePathDiscoveryError::IoError)?; .map_err(BasePathDiscoveryError::IoError)?;