From d54ea11af8b3a3e2fcc03aad97bae56d48823794 Mon Sep 17 00:00:00 2001 From: hdhoang Date: Fri, 10 Jan 2025 14:04:34 +0700 Subject: [PATCH] archive: switch to deko AnyDecoder and support tar.xz --- Cargo.lock | 47 ++++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 2 +- src/sync/archive.rs | 31 ++++++++++++++++++------------ 3 files changed, 66 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1dce524..a8c7f80 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -182,6 +182,16 @@ version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +[[package]] +name = "deko" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79090f96b34402b7ebe46979a49f3d1ee291912bc6afecf875643a4da03948ca" +dependencies = [ + "flate2", + "xz", +] + [[package]] name = "derive_arbitrary" version = "1.4.1" @@ -532,6 +542,17 @@ version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +[[package]] +name = "lzma-sys" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + [[package]] name = "memchr" version = "2.7.4" @@ -571,6 +592,12 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "pkg-config" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" + [[package]] name = "portable-atomic" version = "1.10.0" @@ -953,8 +980,8 @@ dependencies = [ "clap", "clap_complete", "console", + "deko", "dirs", - "flate2", "indicatif", "serde", "shellexpand", @@ -1311,6 +1338,24 @@ dependencies = [ "rustix", ] +[[package]] +name = "xz" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c887690ff2a2e233e8e49633461521f98ec57fbff9d59a884c9a4f04ec1da34" +dependencies = [ + "xz2", +] + +[[package]] +name = "xz2" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2" +dependencies = [ + "lzma-sys", +] + [[package]] name = "yoke" version = "0.7.5" diff --git a/Cargo.toml b/Cargo.toml index e64e960..bce4c34 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,9 +27,9 @@ zip = { version = "2.2.2", default-features = false, features = ["deflate"] } clap_complete = "4.5.42" console = "0.15.10" dirs = "5.0.1" -flate2 = "1.0" indicatif = "0.17.9" shellexpand = "3.1.0" tar = "0.4.43" tempdir = "0.3.7" toml = "0.8.19" +deko = { version = "0", default-features = false, features = ["flate2", "xz"] } diff --git a/src/sync/archive.rs b/src/sync/archive.rs index aec6ec0..79bd2f8 100644 --- a/src/sync/archive.rs +++ b/src/sync/archive.rs @@ -1,6 +1,7 @@ -use flate2::read::GzDecoder; +use deko::AnyDecoder; use std::fmt::{Display, Formatter}; use std::fs::File; +use std::io::BufReader; use std::path::{Path, PathBuf}; use crate::model::asset_name::mk_exe_name; @@ -18,7 +19,7 @@ enum ArchiveType<'a> { AppImage(&'a str), Exe(&'a str), Zip(&'a str), - TarGz(&'a str), + TarBall(&'a str), } pub enum UnpackError { @@ -89,7 +90,7 @@ impl<'a> Archive<'a> { tmp_dir, exe_name, tag, - archive_type: ArchiveType::TarGz(prefix), + archive_type: ArchiveType::TarBall(prefix), } .into() } @@ -103,14 +104,19 @@ impl<'a> Archive<'a> { } .into() } - _ => { - asset_name.strip_suffix(".tar.gz").map(|tar_gz_dir| Archive { - archive_path, - tmp_dir, - exe_name, + Some((prefix, "xz"|"gz")) => { + return Archive { + archive_path, + tmp_dir, + exe_name, tag, - archive_type: ArchiveType::TarGz(tar_gz_dir), - }) + archive_type: ArchiveType::TarBall(prefix.trim_end_matches(".tar")), + } + .into() + } + _ => { + dbg!("unsupported asset format {asset_name}"); + return None } } } @@ -125,7 +131,7 @@ impl<'a> Archive<'a> { ArchiveType::Exe(exe_file) => Ok(self.tmp_dir.join(exe_file)), // unpack .tar.gz archive - ArchiveType::TarGz(asset_name) => { + ArchiveType::TarBall(asset_name) => { unpack_tar(self.archive_path, self.tmp_dir).map_err(UnpackError::IOError)?; find_path_to_exe(self.archive_path, self.tmp_dir, self.exe_name, asset_name, self.tag) } @@ -145,7 +151,7 @@ fn unpack_tar( ) -> Result<(), std::io::Error> { // unpack tar_path to tmp_dir let tar_file = File::open(tar_path)?; - let tar_decoder = GzDecoder::new(tar_file); + let tar_decoder = AnyDecoder::new(BufReader::new(tar_file)); let mut archive = tar::Archive::new(tar_decoder); archive.unpack(tmp_dir) } @@ -199,6 +205,7 @@ fn exe_paths( vec![ asset_name.into(), + asset_name.trim_end_matches(".tar.xz").into(), asset_name.trim_end_matches(".tar.gz").into(), asset_name.trim_end_matches(".tgz").into(), asset_name.trim_end_matches(".zip").into(),