feat: Make bzip3 optout (#814)

Co-authored-by: João Marcos <marcospb19@hotmail.com>
This commit is contained in:
Amyspark 2025-05-03 20:43:59 -03:00 committed by GitHub
parent 1ff1932e3d
commit 07967927dd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 59 additions and 21 deletions

View File

@ -25,7 +25,7 @@ on:
type: boolean type: boolean
required: true required: true
artifact_upload_mode: artifact_upload_mode:
description: "Control which artifacts to upload: 'none' for no uploads, 'with_default_features' to upload only artifacts with default features (use_zlib+use_zstd_thin+unrar), or 'all' to upload all feature combinations." description: "Control which artifacts to upload: 'none' for no uploads, 'with_default_features' to upload only artifacts with default features (use_zlib+use_zstd_thin+unrar+bzip3), or 'all' to upload all feature combinations."
type: string type: string
required: true required: true
@ -37,7 +37,8 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
feature-unrar: ${{ inputs.matrix_all_combinations && fromJSON('[true, false]') || fromJSON('[false]')}} feature-unrar: ${{ inputs.matrix_all_combinations && fromJSON('[true, false]') || fromJSON('[true]')}}
feature-bzip3: ${{ inputs.matrix_all_combinations && fromJSON('[true, false]') || fromJSON('[true]')}}
feature-use-zlib: ${{ inputs.matrix_all_combinations && fromJSON('[true, false]') || fromJSON('[false]')}} feature-use-zlib: ${{ inputs.matrix_all_combinations && fromJSON('[true, false]') || fromJSON('[false]')}}
feature-use-zstd-thin: ${{ inputs.matrix_all_combinations && fromJSON('[true, false]') || fromJSON('[false]')}} feature-use-zstd-thin: ${{ inputs.matrix_all_combinations && fromJSON('[true, false]') || fromJSON('[false]')}}
target: target:
@ -76,12 +77,14 @@ jobs:
- target: armv7-unknown-linux-musleabihf - target: armv7-unknown-linux-musleabihf
use-cross: true use-cross: true
# features (unless `matrix_all_combinations` is true, we only run these on linux-gnu) # features (unless `matrix_all_combinations` is true, we only run these on linux-gnu)
- feature-unrar: true - feature-unrar: false
target: x86_64-unknown-linux-gnu target: x86_64-unknown-linux-gnu
- feature-use-zlib: true - feature-use-zlib: true
target: x86_64-unknown-linux-gnu target: x86_64-unknown-linux-gnu
- feature-use-zstd-thin: true - feature-use-zstd-thin: true
target: x86_64-unknown-linux-gnu target: x86_64-unknown-linux-gnu
- feature-bzip3: false
target: x86_64-unknown-linux-gnu
steps: steps:
- name: Checkout - name: Checkout
@ -105,6 +108,7 @@ jobs:
if [[ "${{ matrix.feature-unrar }}" == true ]]; then FEATURES+=(unrar); fi if [[ "${{ matrix.feature-unrar }}" == true ]]; then FEATURES+=(unrar); fi
if [[ "${{ matrix.feature-use-zlib }}" == true ]]; then FEATURES+=(use_zlib); fi if [[ "${{ matrix.feature-use-zlib }}" == true ]]; then FEATURES+=(use_zlib); fi
if [[ "${{ matrix.feature-use-zstd-thin }}" == true ]]; then FEATURES+=(use_zstd_thin); fi if [[ "${{ matrix.feature-use-zstd-thin }}" == true ]]; then FEATURES+=(use_zstd_thin); fi
if [[ "${{ matrix.feature-bzip3 }}" == true ]]; then FEATURES+=(bzip3); fi
# Output plus-separated list for artifact names # Output plus-separated list for artifact names
IFS='+' IFS='+'
echo "FEATURES_PLUS=${FEATURES[*]}" >> $GITHUB_OUTPUT echo "FEATURES_PLUS=${FEATURES[*]}" >> $GITHUB_OUTPUT
@ -127,7 +131,7 @@ jobs:
- uses: Swatinem/rust-cache@v2 - uses: Swatinem/rust-cache@v2
with: with:
key: "${{ matrix.target }}-${{ matrix.feature-unrar }}-${{ matrix.feature-use-zlib }}-${{ matrix.feature-use-zstd-thin }}" key: "${{ matrix.target }}-${{ matrix.feature-unrar }}-${{ matrix.feature-use-zlib }}-${{ matrix.feature-use-zstd-thin }}-${{ matrix.feature-bzip3 }}"
- name: Test on stable - name: Test on stable
# there's no way to run tests for ARM64 Windows for now # there's no way to run tests for ARM64 Windows for now
@ -146,7 +150,7 @@ jobs:
if: | if: |
${{ inputs.artifact_upload_mode != 'none' && ${{ inputs.artifact_upload_mode != 'none' &&
(inputs.artifact_upload_mode == 'all' || (inputs.artifact_upload_mode == 'all' ||
(matrix.feature-unrar && matrix.feature-use-zlib && matrix.feature-use-zstd-thin)) }} (matrix.feature-unrar && matrix.feature-use-zlib && matrix.feature-use-zstd-thin && matrix.feature-bzip3)) }}
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: ouch-${{ matrix.target }}${{ steps.concat-features.outputs.FEATURES_PLUS != '' && format('-{0}', steps.concat-features.outputs.FEATURES_PLUS) || '' }} name: ouch-${{ matrix.target }}${{ steps.concat-features.outputs.FEATURES_PLUS != '' && format('-{0}', steps.concat-features.outputs.FEATURES_PLUS) || '' }}

View File

@ -29,6 +29,8 @@ Categories Used:
### Bug Fixes ### Bug Fixes
### Tweaks ### Tweaks
- Make `.bz3` opt-out [\#814](https://github.com/ouch-org/ouch/pull/814) ([amyspark](https://github.com/amyspark))
## [0.6.1](https://github.com/ouch-org/ouch/compare/0.6.0...0.6.1) ## [0.6.1](https://github.com/ouch-org/ouch/compare/0.6.0...0.6.1)
- Fix .zip crash when file mode isn't present [\#804](https://github.com/ouch-org/ouch/pull/804) ([marcospb19](https://github.com/marcospb19)) - Fix .zip crash when file mode isn't present [\#804](https://github.com/ouch-org/ouch/pull/804) ([marcospb19](https://github.com/marcospb19))

View File

@ -19,7 +19,7 @@ brotli = "7.0.0"
bstr = { version = "1.10.0", default-features = false, features = ["std"] } bstr = { version = "1.10.0", default-features = false, features = ["std"] }
bytesize = "1.3.0" bytesize = "1.3.0"
bzip2 = "0.4.4" bzip2 = "0.4.4"
bzip3 = { version = "0.9.0", features = ["bundled"] } bzip3 = { version = "0.9.0", features = ["bundled"] , optional = true }
clap = { version = "4.5.20", features = ["derive", "env"] } clap = { version = "4.5.20", features = ["derive", "env"] }
filetime_creation = "0.2" filetime_creation = "0.2"
flate2 = { version = "1.0.30", default-features = false } flate2 = { version = "1.0.30", default-features = false }
@ -70,7 +70,7 @@ regex = "1.10.4"
test-strategy = "0.4.0" test-strategy = "0.4.0"
[features] [features]
default = ["unrar", "use_zlib", "use_zstd_thin"] default = ["unrar", "use_zlib", "use_zstd_thin", "bzip3"]
use_zlib = ["flate2/zlib", "gzp/deflate_zlib", "zip/deflate-zlib"] use_zlib = ["flate2/zlib", "gzp/deflate_zlib", "zip/deflate-zlib"]
use_zstd_thin = ["zstd/thin"] use_zstd_thin = ["zstd/thin"]
allow_piped_choice = [] allow_piped_choice = []

View File

@ -21,7 +21,7 @@ PLATFORMS=(
"x86_64-unknown-linux-musl" "x86_64-unknown-linux-musl"
) )
# TODO: remove allow_piped_choice later # TODO: remove allow_piped_choice later
DEFAULT_FEATURES="allow_piped_choice+unrar+use_zlib+use_zstd_thin" DEFAULT_FEATURES="allow_piped_choice+unrar+use_zlib+use_zstd_thin+bzip3"
for platform in "${PLATFORMS[@]}"; do for platform in "${PLATFORMS[@]}"; do
path="ouch-${platform}" path="ouch-${platform}"

View File

@ -0,0 +1,7 @@
use crate::Error;
pub fn no_support() -> Error {
Error::UnsupportedFormat {
reason: "BZip3 support is disabled for this build, possibly due to missing bindgen-cli dependency.".into(),
}
}

View File

@ -1,5 +1,7 @@
//! Archive compression algorithms //! Archive compression algorithms
#[cfg(not(feature = "bzip3"))]
pub mod bzip3_stub;
#[cfg(feature = "unrar")] #[cfg(feature = "unrar")]
pub mod rar; pub mod rar;
#[cfg(not(feature = "unrar"))] #[cfg(not(feature = "unrar"))]

View File

@ -57,10 +57,16 @@ pub fn compress_files(
encoder, encoder,
level.map_or_else(Default::default, |l| bzip2::Compression::new((l as u32).clamp(1, 9))), level.map_or_else(Default::default, |l| bzip2::Compression::new((l as u32).clamp(1, 9))),
)), )),
Bzip3 => Box::new( Bzip3 => {
// Use block size of 16 MiB #[cfg(not(feature = "bzip3"))]
bzip3::write::Bz3Encoder::new(encoder, 16 * 2_usize.pow(20))?, return Err(archive::bzip3_stub::no_support());
),
#[cfg(feature = "bzip3")]
Box::new(
// Use block size of 16 MiB
bzip3::write::Bz3Encoder::new(encoder, 16 * 2_usize.pow(20))?,
)
}
Lz4 => Box::new(lz4_flex::frame::FrameEncoder::new(encoder).auto_finish()), Lz4 => Box::new(lz4_flex::frame::FrameEncoder::new(encoder).auto_finish()),
Lzma => Box::new(xz2::write::XzEncoder::new( Lzma => Box::new(xz2::write::XzEncoder::new(
encoder, encoder,

View File

@ -6,6 +6,8 @@ use std::{
use fs_err as fs; use fs_err as fs;
#[cfg(not(feature = "bzip3"))]
use crate::archive;
use crate::{ use crate::{
commands::{warn_user_about_loading_sevenz_in_memory, warn_user_about_loading_zip_in_memory}, commands::{warn_user_about_loading_sevenz_in_memory, warn_user_about_loading_zip_in_memory},
extension::{ extension::{
@ -118,7 +120,13 @@ pub fn decompress_file(options: DecompressOptions) -> crate::Result<()> {
let decoder: Box<dyn Read> = match format { let decoder: Box<dyn Read> = match format {
Gzip => Box::new(flate2::read::GzDecoder::new(decoder)), Gzip => Box::new(flate2::read::GzDecoder::new(decoder)),
Bzip => Box::new(bzip2::read::BzDecoder::new(decoder)), Bzip => Box::new(bzip2::read::BzDecoder::new(decoder)),
Bzip3 => Box::new(bzip3::read::Bz3Decoder::new(decoder)?), Bzip3 => {
#[cfg(not(feature = "bzip3"))]
return Err(archive::bzip3_stub::no_support());
#[cfg(feature = "bzip3")]
Box::new(bzip3::read::Bz3Decoder::new(decoder)?)
}
Lz4 => Box::new(lz4_flex::frame::FrameDecoder::new(decoder)), Lz4 => Box::new(lz4_flex::frame::FrameDecoder::new(decoder)),
Lzma => Box::new(xz2::read::XzDecoder::new(decoder)), Lzma => Box::new(xz2::read::XzDecoder::new(decoder)),
Snappy => Box::new(snap::read::FrameDecoder::new(decoder)), Snappy => Box::new(snap::read::FrameDecoder::new(decoder)),

View File

@ -6,7 +6,7 @@ use std::{
use fs_err as fs; use fs_err as fs;
use crate::{ use crate::{
archive::sevenz, archive,
commands::warn_user_about_loading_zip_in_memory, commands::warn_user_about_loading_zip_in_memory,
extension::CompressionFormat::{self, *}, extension::CompressionFormat::{self, *},
list::{self, FileInArchive, ListOptions}, list::{self, FileInArchive, ListOptions},
@ -50,7 +50,13 @@ pub fn list_archive_contents(
let decoder: Box<dyn Read + Send> = match format { let decoder: Box<dyn Read + Send> = match format {
Gzip => Box::new(flate2::read::GzDecoder::new(decoder)), Gzip => Box::new(flate2::read::GzDecoder::new(decoder)),
Bzip => Box::new(bzip2::read::BzDecoder::new(decoder)), Bzip => Box::new(bzip2::read::BzDecoder::new(decoder)),
Bzip3 => Box::new(bzip3::read::Bz3Decoder::new(decoder).unwrap()), Bzip3 => {
#[cfg(not(feature = "bzip3"))]
return Err(archive::bzip3_stub::no_support());
#[cfg(feature = "bzip3")]
Box::new(bzip3::read::Bz3Decoder::new(decoder).unwrap())
}
Lz4 => Box::new(lz4_flex::frame::FrameDecoder::new(decoder)), Lz4 => Box::new(lz4_flex::frame::FrameDecoder::new(decoder)),
Lzma => Box::new(xz2::read::XzDecoder::new(decoder)), Lzma => Box::new(xz2::read::XzDecoder::new(decoder)),
Snappy => Box::new(snap::read::FrameDecoder::new(decoder)), Snappy => Box::new(snap::read::FrameDecoder::new(decoder)),
@ -111,7 +117,7 @@ pub fn list_archive_contents(
} }
} }
Box::new(sevenz::list_archive(archive_path, password)?) Box::new(archive::sevenz::list_archive(archive_path, password)?)
} }
Gzip | Bzip | Bzip3 | Lz4 | Lzma | Snappy | Zstd | Brotli => { Gzip | Bzip | Bzip3 | Lz4 | Lzma | Snappy | Zstd | Brotli => {
panic!("Not an archive! This should never happen, if it does, something is wrong with `CompressionFormat::is_archive()`. Please report this error!"); panic!("Not an archive! This should never happen, if it does, something is wrong with `CompressionFormat::is_archive()`. Please report this error!");

View File

@ -200,6 +200,7 @@ impl From<std::io::Error> for Error {
} }
} }
#[cfg(feature = "bzip3")]
impl From<bzip3::Error> for Error { impl From<bzip3::Error> for Error {
fn from(err: bzip3::Error) -> Self { fn from(err: bzip3::Error) -> Self {
use bzip3::Error as Bz3Error; use bzip3::Error as Bz3Error;

View File

@ -286,7 +286,7 @@ mod tests {
#[test] #[test]
/// Test extension parsing for input/output files /// Test extension parsing for input/output files
fn test_separate_known_extensions_from_name() { fn test_separate_known_extensions_from_name() {
let _handler = spawn_logger_thread(); spawn_logger_thread();
assert_eq!( assert_eq!(
separate_known_extensions_from_name("file".as_ref()), separate_known_extensions_from_name("file".as_ref()),
("file".as_ref(), vec![]) ("file".as_ref(), vec![])

View File

@ -133,7 +133,7 @@ pub fn try_infer_extension(path: &Path) -> Option<Extension> {
buf.starts_with(&[0x42, 0x5A, 0x68]) buf.starts_with(&[0x42, 0x5A, 0x68])
} }
fn is_bz3(buf: &[u8]) -> bool { fn is_bz3(buf: &[u8]) -> bool {
buf.starts_with(bzip3::MAGIC_NUMBER) buf.starts_with(b"BZ3v1")
} }
fn is_xz(buf: &[u8]) -> bool { fn is_xz(buf: &[u8]) -> bool {
buf.starts_with(&[0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00]) buf.starts_with(&[0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00])

View File

@ -25,6 +25,7 @@ enum DirectoryExtension {
Tar, Tar,
Tbz, Tbz,
Tbz2, Tbz2,
#[cfg(feature = "bzip3")]
Tbz3, Tbz3,
Tgz, Tgz,
Tlz4, Tlz4,
@ -41,6 +42,7 @@ enum DirectoryExtension {
enum FileExtension { enum FileExtension {
Bz, Bz,
Bz2, Bz2,
#[cfg(feature = "bzip3")]
Bz3, Bz3,
Gz, Gz,
Lz4, Lz4,
@ -59,9 +61,9 @@ enum Extension {
} }
/// Converts a list of extension structs to string /// Converts a list of extension structs to string
fn merge_extensions(ext: impl ToString, exts: &Vec<FileExtension>) -> String { fn merge_extensions(ext: impl ToString, exts: &[FileExtension]) -> String {
once(ext.to_string()) once(ext.to_string())
.chain(exts.into_iter().map(|x| x.to_string())) .chain(exts.iter().map(|x| x.to_string()))
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(".") .join(".")
} }
@ -89,6 +91,7 @@ fn create_random_files(dir: impl Into<PathBuf>, depth: u8, rng: &mut SmallRng) {
} }
/// Create n random files on directory dir /// Create n random files on directory dir
#[cfg_attr(not(feature = "allow_piped_choice"), allow(dead_code))]
fn create_n_random_files(n: usize, dir: impl Into<PathBuf>, rng: &mut SmallRng) { fn create_n_random_files(n: usize, dir: impl Into<PathBuf>, rng: &mut SmallRng) {
let dir: &PathBuf = &dir.into(); let dir: &PathBuf = &dir.into();

View File

@ -2,7 +2,6 @@
/// ///
/// See CONTRIBUTING.md for a brief guide on how to use [`insta`] for these tests. /// See CONTRIBUTING.md for a brief guide on how to use [`insta`] for these tests.
/// [`insta`]: https://docs.rs/insta /// [`insta`]: https://docs.rs/insta
#[macro_use] #[macro_use]
mod utils; mod utils;