diff --git a/Cargo.toml b/Cargo.toml index 3b2d430..f0826b7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ edition = "2021" [dependencies] anyhow = "1.0.71" +bzip2 = "0.4.4" clap = { version = "4.2.5", features = ["derive"] } directories = "5.0.0" flate2 = "1.0.26" diff --git a/build.rs b/build.rs index af253ec..ae74075 100644 --- a/build.rs +++ b/build.rs @@ -10,7 +10,7 @@ use rand::distributions::{Alphanumeric, DistString}; use regex::Regex; const DEFAULT_PYTHON_VERSION: &str = "3.11"; -const KNOWN_DISTRIBUTION_FORMATS: &[&str] = &["tar|gzip", "tar|zstd", "zip"]; +const KNOWN_DISTRIBUTION_FORMATS: &[&str] = &["tar|bzip2", "tar|gzip", "tar|zstd", "zip"]; // Python version in the form MAJOR.MINOR // Target OS https://doc.rust-lang.org/reference/conditional-compilation.html#target_os @@ -442,6 +442,8 @@ fn set_distribution_format(distribution_source: &String) { } else { panic!("\n\nUnknown distribution format: {distribution_format}\n\n"); } + } else if distribution_source.ends_with(".tar.bz2") || distribution_source.ends_with(".bz2") { + set_runtime_variable(variable, "tar|bzip2"); } else if distribution_source.ends_with(".tar.gz") || distribution_source.ends_with(".tgz") { set_runtime_variable(variable, "tar|gzip"); } else if distribution_source.ends_with(".tar.zst") diff --git a/docs/changelog.md b/docs/changelog.md index 5cda52e..9ac2295 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -8,6 +8,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## Unreleased +***Added:*** + +- Add support for distributions with `bzip2` compression + ***Fixed:*** - Properly handle cases where temporary files are on different filesystems diff --git a/docs/config.md b/docs/config.md index 10dcd75..a8823ee 100644 --- a/docs/config.md +++ b/docs/config.md @@ -80,6 +80,7 @@ The following formats are supported for the `PYAPP_DISTRIBUTION_FORMAT` option, | Format | Extensions | Description | | --- | --- | --- | +| `tar|bzip2` | | A [tar file](https://en.wikipedia.org/wiki/Tar_(computing)) with [bzip2 compression](https://en.wikipedia.org/wiki/Bzip2) | | `tar|gzip` | | A [tar file](https://en.wikipedia.org/wiki/Tar_(computing)) with [gzip compression](https://en.wikipedia.org/wiki/Gzip) | | `tar|zstd` | | A [tar file](https://en.wikipedia.org/wiki/Tar_(computing)) with [Zstandard compression](https://en.wikipedia.org/wiki/Zstd) | | `zip` | | A [ZIP file](https://en.wikipedia.org/wiki/ZIP_(file_format)) with [DEFLATE compression](https://en.wikipedia.org/wiki/Deflate) | diff --git a/src/compression.rs b/src/compression.rs index 44536a8..066e396 100644 --- a/src/compression.rs +++ b/src/compression.rs @@ -7,6 +7,7 @@ use crate::terminal; pub fn unpack(format: String, archive: &PathBuf, destination: &PathBuf) -> Result<()> { match format.as_ref() { + "tar|bzip2" => unpack_tar_bzip2(archive, destination)?, "tar|gzip" => unpack_tar_gzip(archive, destination)?, "tar|zstd" => unpack_tar_zstd(archive, destination)?, "zip" => unpack_zip(archive, destination)?, @@ -16,6 +17,18 @@ pub fn unpack(format: String, archive: &PathBuf, destination: &PathBuf) -> Resul Ok(()) } +fn unpack_tar_bzip2(path: &PathBuf, destination: &PathBuf) -> Result<()> { + let bz = bzip2::read::BzDecoder::new(File::open(path)?); + let mut archive = tar::Archive::new(bz); + + let spinner = terminal::spinner("Unpacking distribution (tar|bzip2)".to_string()); + let result = archive.unpack(destination); + spinner.finish_and_clear(); + result?; + + Ok(()) +} + fn unpack_tar_gzip(path: &PathBuf, destination: &PathBuf) -> Result<()> { let gz = flate2::read::GzDecoder::new(File::open(path)?); let mut archive = tar::Archive::new(gz);