Merge remote-tracking branch 'origin/main' into feat/flag-disable-smart-unpack

This commit is contained in:
Talison Fabio 2025-04-28 07:58:29 -03:00
commit 1882ad8efb
20 changed files with 366 additions and 200 deletions

View File

@ -14,4 +14,4 @@ jobs:
uses: ./.github/workflows/build-artifacts-and-run-tests.yml
with:
matrix_all_combinations: true
upload_artifacts: false
artifact_upload_mode: none

View File

@ -10,20 +10,23 @@ on:
type: boolean
required: true
default: true
upload_artifacts:
description: "if built artifacts should be uploaded"
type: boolean
artifact_upload_mode:
description: "Control what artifacts to upload: 'none' for no uploads, 'with_default_features' to upload artifacts with default features (for releases), or 'all' for all feature combinations."
type: choice
options:
- none
- with_default_features
- all
required: true
default: true
workflow_call:
inputs:
matrix_all_combinations:
description: "if matrix should have all combinations of targets and features"
type: boolean
required: true
upload_artifacts:
description: "if built artifacts should be uploaded"
type: boolean
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."
type: string
required: true
jobs:
@ -99,15 +102,19 @@ jobs:
shell: bash
run: |
FEATURES=(allow_piped_choice)
if [[ "${{ matrix.feature-unrar }}" == true ]]; then FEATURES+=(unrar); 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-unrar }}" == true ]]; then FEATURES+=(unrar); fi
# Output plus-separated list for artifact names
IFS='+'
echo "FEATURES_PLUS=${FEATURES[*]}" >> $GITHUB_OUTPUT
# Output comma-separated list for cargo flags
IFS=','
echo "FEATURES=${FEATURES[*]}" >> $GITHUB_OUTPUT
echo "FEATURES_COMMA=${FEATURES[*]}" >> $GITHUB_OUTPUT
- name: Set up extra cargo flags
env:
FEATURES: ${{steps.concat-features.outputs.FEATURES}}
FEATURES: ${{steps.concat-features.outputs.FEATURES_COMMA}}
shell: bash
run: |
FLAGS="--no-default-features"
@ -120,7 +127,7 @@ jobs:
- uses: Swatinem/rust-cache@v2
with:
key: "${{ matrix.target }}-${{ matrix.feature-unrar }}-${{ matrix.feature-use-zstd-thin }}-${{ matrix.feature-unrar }}"
key: "${{ matrix.target }}-${{ matrix.feature-unrar }}-${{ matrix.feature-use-zlib }}-${{ matrix.feature-use-zstd-thin }}"
- name: Test on stable
# there's no way to run tests for ARM64 Windows for now
@ -129,18 +136,21 @@ jobs:
${{ env.CARGO }} +stable test --profile fast --target ${{ matrix.target }} $EXTRA_CARGO_FLAGS
- name: Build release artifacts (binary and completions)
if: ${{ inputs.upload_artifacts }}
if: ${{ inputs.artifact_upload_mode != 'none' }}
run: |
${{ env.CARGO }} +stable build --release --target ${{ matrix.target }} $EXTRA_CARGO_FLAGS
env:
OUCH_ARTIFACTS_FOLDER: artifacts
OUCH_ARTIFACTS_FOLDER: man-page-and-completions-artifacts
- name: Upload release artifacts
if: ${{ inputs.upload_artifacts }}
if: |
${{ inputs.artifact_upload_mode != 'none' &&
(inputs.artifact_upload_mode == 'all' ||
(matrix.feature-unrar && matrix.feature-use-zlib && matrix.feature-use-zstd-thin)) }}
uses: actions/upload-artifact@v4
with:
name: ouch-${{ matrix.target }}-${{ steps.concat-features.outputs.FEATURES }}
name: ouch-${{ matrix.target }}${{ steps.concat-features.outputs.FEATURES_PLUS != '' && format('-{0}', steps.concat-features.outputs.FEATURES_PLUS) || '' }}
path: |
target/${{ matrix.target }}/release/ouch
target/${{ matrix.target }}/release/ouch.exe
artifacts/
man-page-and-completions-artifacts/

View File

@ -3,14 +3,14 @@ name: Automatic trigger draft release
on:
push:
tags:
- "[0-9]+.[0-9]+.[0-9]+"
- "[0-9]+.[0-9]+.[0-9]+-rc[0-9]+"
jobs:
call-workflow-build-artifacts-and-run-tests:
uses: ./.github/workflows/build-artifacts-and-run-tests.yml
with:
matrix_all_combinations: true
upload_artifacts: true
artifact_upload_mode: with_default_features
automated-draft-release:
runs-on: ubuntu-latest
@ -21,9 +21,10 @@ jobs:
uses: actions/checkout@v4
- name: Download artifacts
uses: dawidd6/action-download-artifact@v6
uses: actions/download-artifact@v4
with:
path: artifacts
path: downloaded_artifacts
pattern: ouch-*
- name: Package release assets
run: scripts/package-release-assets.sh
@ -32,4 +33,4 @@ jobs:
uses: softprops/action-gh-release@v2
with:
draft: true
files: release/ouch-*
files: output_assets/ouch-*

View File

@ -1,32 +0,0 @@
name: Manual trigger draft release
on:
workflow_dispatch:
inputs:
run_id:
description: Run id of the action run to pull artifacts from
required: true
jobs:
create-draft-release-from-manual-trigger:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Download artifacts
uses: dawidd6/action-download-artifact@v6
with:
path: artifacts
workflow: build-artifacts-and-run-tests.yml
run_id: ${{ github.event.inputs.run_id }}
- name: Package release assets
run: scripts/package-release-assets.sh
- name: Create release
uses: softprops/action-gh-release@v2
with:
draft: true
name: manual release ${{ github.event.inputs.run_id }}
files: release/ouch-*

View File

@ -32,4 +32,4 @@ jobs:
uses: ./.github/workflows/build-artifacts-and-run-tests.yml
with:
matrix_all_combinations: false
upload_artifacts: false
artifact_upload_mode: none

View File

@ -18,7 +18,18 @@ Categories Used:
**Bullet points in chronological order by PR**
## [Unreleased](https://github.com/ouch-org/ouch/compare/0.5.1...HEAD)
## [Unreleased](https://github.com/ouch-org/ouch/compare/0.6.1...HEAD)
### New Features
### Improvements
### Bug Fixes
### Tweaks
## [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))
## [0.6.0](https://github.com/ouch-org/ouch/compare/0.5.1...0.6.0)
### New Features
@ -37,7 +48,9 @@ Categories Used:
- CI refactor [\#578](https://github.com/ouch-org/ouch/pull/578) ([cyqsimon](https://github.com/cyqsimon))
- Use a prefix `tmp-ouch-` for temporary decompression path name to avoid conflicts [\#725](https://github.com/ouch-org/ouch/pull/725) ([valoq](https://github.com/valoq)) & [\#788](https://github.com/ouch-org/ouch/pull/788) ([talis-fb](https://github.com/talis-fb))
- Ignore `.git/` when `-g/--gitignore` is set [\#507](https://github.com/ouch-org/ouch/pull/507) ([talis-fb](https://github.com/talis-fb))
- Run clippy for tests too [\#738](https://github.com/ouch-org/ouch/pull/738) ([marcospb19](https://github.com/marcospb19))
- Sevenz-rust is unmaintained, switch to sevenz-rust2 [\#796](https://github.com/ouch-org/ouch/pull/796) ([tommady](https://github.com/tommady))
### Improvements
@ -46,6 +59,7 @@ Categories Used:
- Make `--format` more forgiving with the formatting of the provided format [\#519](https://github.com/ouch-org/ouch/pull/519) ([marcospb19](https://github.com/marcospb19))
- Use buffered writer for list output [\#764](https://github.com/ouch-org/ouch/pull/764) ([killercup](https://github.com/killercup))
- Disable smart unpack when `--dir` flag is provided in decompress command [\#782](https://github.com/ouch-org/ouch/pull/782) ([talis-fb](https://github.com/talis-fb))
- Align file sizes at left for each extracted file to make output clearer [\#792](https://github.com/ouch-org/ouch/pull/792) ([talis-fb](https://github.com/talis-fb))
## [0.5.1](https://github.com/ouch-org/ouch/compare/0.5.0...0.5.1)

191
Cargo.lock generated
View File

@ -154,30 +154,15 @@ dependencies = [
"which",
]
[[package]]
name = "bit-set"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0481a0e032742109b1133a095184ee93d88f3dc9e0d28a5d033dc77a073f44f"
dependencies = [
"bit-vec 0.7.0",
]
[[package]]
name = "bit-set"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3"
dependencies = [
"bit-vec 0.8.0",
"bit-vec",
]
[[package]]
name = "bit-vec"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2c54ff287cfc0a34f38a6b832ea1bd8e448a330b3e40a50859e6488bee07f22"
[[package]]
name = "bit-vec"
version = "0.8.0"
@ -481,21 +466,6 @@ dependencies = [
"libc",
]
[[package]]
name = "crc"
version = "3.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636"
dependencies = [
"crc-catalog",
]
[[package]]
name = "crc-catalog"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5"
[[package]]
name = "crc32fast"
version = "1.4.2"
@ -542,9 +512,9 @@ dependencies = [
[[package]]
name = "deranged"
version = "0.3.11"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e"
dependencies = [
"powerfmt",
]
@ -848,6 +818,30 @@ version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "jiff"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5ad87c89110f55e4cd4dc2893a9790820206729eaf221555f742d540b0724a0"
dependencies = [
"jiff-static",
"log",
"portable-atomic",
"portable-atomic-util",
"serde",
]
[[package]]
name = "jiff-static"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d076d5b64a7e2fe6f0743f02c43ca4a6725c0f904203bfe276a5b3e793103605"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.98",
]
[[package]]
name = "jobserver"
version = "0.1.32"
@ -968,10 +962,10 @@ dependencies = [
]
[[package]]
name = "lzma-rust"
version = "0.1.7"
name = "lzma-rust2"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5baab2bbbd7d75a144d671e9ff79270e903957d92fb7386fd39034c709bd2661"
checksum = "561d131e2d9b07641ac55bc35de5ae4ac3e783fdeebd3c4c1dd3b6a7b920051a"
dependencies = [
"byteorder",
]
@ -1029,11 +1023,13 @@ dependencies = [
[[package]]
name = "nt-time"
version = "0.8.1"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2de419e64947cd8830e66beb584acc3fb42ed411d103e3c794dda355d1b374b5"
checksum = "f5e71108c089b161344bacb1227dd2124fee63ed1792fdd8308e6689197c2754"
dependencies = [
"chrono",
"jiff",
"rand 0.9.0",
"time",
]
@ -1070,7 +1066,7 @@ checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e"
[[package]]
name = "ouch"
version = "0.5.1"
version = "0.6.1"
dependencies = [
"assert_cmd",
"atty",
@ -1097,11 +1093,11 @@ dependencies = [
"once_cell",
"parse-display",
"proptest",
"rand",
"rand 0.8.5",
"rayon",
"regex",
"same-file",
"sevenz-rust",
"sevenz-rust2",
"snap",
"tar",
"tempfile",
@ -1145,7 +1141,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700"
dependencies = [
"base64ct",
"rand_core",
"rand_core 0.6.4",
"subtle",
]
@ -1193,6 +1189,21 @@ version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
[[package]]
name = "portable-atomic"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e"
[[package]]
name = "portable-atomic-util"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507"
dependencies = [
"portable-atomic",
]
[[package]]
name = "powerfmt"
version = "0.2.0"
@ -1205,7 +1216,7 @@ version = "0.2.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
dependencies = [
"zerocopy",
"zerocopy 0.7.35",
]
[[package]]
@ -1250,13 +1261,13 @@ version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14cae93065090804185d3b75f0bf93b8eeda30c7a9b4a33d3bdb3988d6229e50"
dependencies = [
"bit-set 0.8.0",
"bit-vec 0.8.0",
"bit-set",
"bit-vec",
"bitflags 2.8.0",
"lazy_static",
"num-traits",
"rand",
"rand_chacha",
"rand 0.8.5",
"rand_chacha 0.3.1",
"rand_xorshift",
"regex-syntax",
"rusty-fork",
@ -1286,8 +1297,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
"rand_chacha 0.3.1",
"rand_core 0.6.4",
]
[[package]]
name = "rand"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
dependencies = [
"rand_chacha 0.9.0",
"rand_core 0.9.3",
"zerocopy 0.8.24",
]
[[package]]
@ -1297,7 +1319,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
"rand_core 0.6.4",
]
[[package]]
name = "rand_chacha"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
dependencies = [
"ppv-lite86",
"rand_core 0.9.3",
]
[[package]]
@ -1309,13 +1341,22 @@ dependencies = [
"getrandom 0.2.15",
]
[[package]]
name = "rand_core"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
dependencies = [
"getrandom 0.3.1",
]
[[package]]
name = "rand_xorshift"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f"
dependencies = [
"rand_core",
"rand_core 0.6.4",
]
[[package]]
@ -1455,21 +1496,21 @@ dependencies = [
]
[[package]]
name = "sevenz-rust"
version = "0.6.1"
name = "sevenz-rust2"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26482cf1ecce4540dc782fc70019eba89ffc4d87b3717eb5ec524b5db6fdefef"
checksum = "dd27d0f7d5e54cab609728bf243f870469dcc845b052285e7e47ef097c04ec6a"
dependencies = [
"aes",
"bit-set 0.6.0",
"bit-set",
"byteorder",
"cbc",
"crc",
"crc32fast",
"filetime_creation",
"getrandom 0.3.1",
"js-sys",
"lzma-rust",
"lzma-rust2",
"nt-time",
"rand",
"sha2",
"wasm-bindgen",
]
@ -1651,9 +1692,9 @@ dependencies = [
[[package]]
name = "time"
version = "0.3.37"
version = "0.3.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21"
checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40"
dependencies = [
"deranged",
"num-conv",
@ -1665,15 +1706,15 @@ dependencies = [
[[package]]
name = "time-core"
version = "0.1.2"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c"
[[package]]
name = "time-macros"
version = "0.2.19"
version = "0.2.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de"
checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49"
dependencies = [
"num-conv",
"time-core",
@ -2013,7 +2054,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
dependencies = [
"byteorder",
"zerocopy-derive",
"zerocopy-derive 0.7.35",
]
[[package]]
name = "zerocopy"
version = "0.8.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879"
dependencies = [
"zerocopy-derive 0.8.24",
]
[[package]]
@ -2027,6 +2077,17 @@ dependencies = [
"syn 2.0.98",
]
[[package]]
name = "zerocopy-derive"
version = "0.8.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.98",
]
[[package]]
name = "zip"
version = "0.6.6"

View File

@ -1,8 +1,8 @@
[package]
name = "ouch"
version = "0.5.1"
version = "0.6.1"
authors = [
"João M. Bezerra <marcospb19@hotmail.com>",
"João Marcos <marcospb19@hotmail.com>",
"Vinícius Rodrigues Miguel <vrmiguel99@gmail.com>",
]
edition = "2021"
@ -35,7 +35,7 @@ num_cpus = "1.16.0"
once_cell = "1.20.2"
rayon = "1.10.0"
same-file = "1.0.6"
sevenz-rust = { version = "0.6.1", features = ["compress", "aes256"] }
sevenz-rust2 = { version = "0.13.1", features = ["compress", "aes256"] }
snap = "1.1.1"
tar = "0.4.42"
tempfile = "3.10.1"
@ -70,7 +70,7 @@ regex = "1.10.4"
test-strategy = "0.4.0"
[features]
default = ["use_zlib", "use_zstd_thin", "unrar"]
default = ["unrar", "use_zlib", "use_zstd_thin"]
use_zlib = ["flate2/zlib", "gzp/deflate_zlib", "zip/deflate-zlib"]
use_zstd_thin = ["zstd/thin"]
allow_piped_choice = []

View File

@ -5,18 +5,12 @@
/// Set `OUCH_ARTIFACTS_FOLDER` to the name of the destination folder:
///
/// ```sh
/// OUCH_ARTIFACTS_FOLDER=my-folder cargo build
/// OUCH_ARTIFACTS_FOLDER=man-page-and-completions-artifacts cargo build
/// ```
///
/// All completion files will be generated inside of the folder "my-folder".
/// All completion files will be generated inside of the folder "man-page-and-completions-artifacts".
///
/// If the folder does not exist, it will be created.
///
/// We recommend you naming this folder "artifacts" for the sake of consistency.
///
/// ```sh
/// OUCH_ARTIFACTS_FOLDER=artifacts cargo build
/// ```
use std::{
env,
fs::{create_dir_all, File},

View File

@ -1,28 +1,60 @@
#!/usr/bin/env bash
set -e
mkdir release
cd artifacts
mkdir output_assets
echo "created folder 'output_assets/'"
ls -lA -w 1
cd downloaded_artifacts
echo "entered 'downloaded_artifacts/'"
ls -lA -w 1
for dir in ouch-*; do
cp -r "$dir/artifacts" "$dir/completions"
mkdir "$dir/man"
mv "$dir"/completions/*.1 "$dir/man"
PLATFORMS=(
"aarch64-pc-windows-msvc"
"aarch64-unknown-linux-gnu"
"aarch64-unknown-linux-musl"
"armv7-unknown-linux-gnueabihf"
"armv7-unknown-linux-musleabihf"
"x86_64-apple-darwin"
"x86_64-pc-windows-gnu"
"x86_64-pc-windows-msvc"
"x86_64-unknown-linux-gnu"
"x86_64-unknown-linux-musl"
)
# TODO: remove allow_piped_choice later
DEFAULT_FEATURES="allow_piped_choice+unrar+use_zlib+use_zstd_thin"
cp ../{README.md,LICENSE,CHANGELOG.md} "$dir"
rm -r "$dir/artifacts"
for platform in "${PLATFORMS[@]}"; do
path="ouch-${platform}"
echo "Processing $path"
if [[ "$dir" = *.exe ]]; then
target=${dir%.exe}
mv "$dir/target/${target/ouch-/}/release/ouch.exe" "$dir"
rm -r "$dir/target"
mv "$dir" "$target"
zip -r "../release/$target.zip" "$target"
if [ ! -d "${path}-${DEFAULT_FEATURES}" ]; then
echo "ERROR: Could not find artifact directory for $platform with default features ($path)"
exit 1
fi
mv "${path}-${DEFAULT_FEATURES}" "$path" # remove the annoying suffix
cp ../{README.md,LICENSE,CHANGELOG.md} "$path"
mkdir -p "$path/man"
mkdir -p "$path/completions"
mv "$path"/man-page-and-completions-artifacts/*.1 "$path/man"
mv "$path"/man-page-and-completions-artifacts/* "$path/completions"
rm -r "$path/man-page-and-completions-artifacts"
if [[ "$platform" == *"-windows-"* ]]; then
mv "$path/target/$platform/release/ouch.exe" "$path"
rm -rf "$path/target"
zip -r "../output_assets/${path}.zip" "$path"
echo "Created output_assets/${path}.zip"
else
mv "$dir/target/${dir/ouch-/}/release/ouch" "$dir"
rm -r "$dir/target"
chmod +x "$dir/ouch"
tar czf "../release/$dir.tar.gz" "$dir"
mv "$path/target/$platform/release/ouch" "$path"
rm -rf "$path/target"
chmod +x "$path/ouch"
tar czf "../output_assets/${path}.tar.gz" "$path"
echo "Created output_assets/${path}.tar.gz"
fi
done
echo "Done."

View File

@ -7,7 +7,7 @@ use unrar::Archive;
use crate::{
error::{Error, Result},
list::FileInArchive,
utils::logger::info,
utils::{logger::info, Bytes},
};
/// Unpacks the archive given by `archive_path` into the folder given by `output_folder`.
@ -33,9 +33,9 @@ pub fn unpack_archive(
archive = if entry.is_file() {
if !quiet {
info(format!(
"{} extracted. ({})",
"extracted ({}) {}",
Bytes::new(entry.unpacked_size),
entry.filename.display(),
entry.unpacked_size
));
}
unpacked += 1;

View File

@ -9,7 +9,7 @@ use std::{
use bstr::ByteSlice;
use fs_err as fs;
use same_file::Handle;
use sevenz_rust::SevenZArchiveEntry;
use sevenz_rust2::SevenZArchiveEntry;
use crate::{
error::{Error, FinalError, Result},
@ -31,7 +31,7 @@ pub fn compress_sevenz<W>(
where
W: Write + Seek,
{
let mut writer = sevenz_rust::SevenZWriter::new(writer)?;
let mut writer = sevenz_rust2::SevenZWriter::new(writer)?;
let output_handle = Handle::from_path(output_path);
for filename in files {
@ -81,7 +81,7 @@ where
.detail(format!("File at '{path:?}' has a non-UTF-8 name"))
})?;
let entry = sevenz_rust::SevenZArchiveEntry::from_path(path, entry_name.to_owned());
let entry = sevenz_rust2::SevenZArchiveEntry::from_path(path, entry_name.to_owned());
let entry_data = if metadata.is_dir() {
None
} else {
@ -127,9 +127,9 @@ where
} else {
if !quiet {
info(format!(
"{:?} extracted. ({})",
"extracted ({}) {:?}",
Bytes::new(entry.size()),
file_path.display(),
Bytes::new(entry.size())
));
}
@ -156,15 +156,15 @@ where
};
match password {
Some(password) => sevenz_rust::decompress_with_extract_fn_and_password(
Some(password) => sevenz_rust2::decompress_with_extract_fn_and_password(
reader,
output_path,
sevenz_rust::Password::from(password.to_str().map_err(|err| Error::InvalidPassword {
sevenz_rust2::Password::from(password.to_str().map_err(|err| Error::InvalidPassword {
reason: err.to_string(),
})?),
entry_extract_fn,
)?,
None => sevenz_rust::decompress_with_extract_fn(reader, output_path, entry_extract_fn)?,
None => sevenz_rust2::decompress_with_extract_fn(reader, output_path, entry_extract_fn)?,
}
Ok(count)
@ -197,14 +197,14 @@ pub fn list_archive(
})
}
};
sevenz_rust::decompress_with_extract_fn_and_password(
sevenz_rust2::decompress_with_extract_fn_and_password(
reader,
".",
sevenz_rust::Password::from(password),
sevenz_rust2::Password::from(password),
entry_extract_fn,
)?;
}
None => sevenz_rust::decompress_with_extract_fn(reader, ".", entry_extract_fn)?,
None => sevenz_rust2::decompress_with_extract_fn(reader, ".", entry_extract_fn)?,
}
Ok(files.into_iter())

View File

@ -56,9 +56,9 @@ pub fn unpack_archive(reader: Box<dyn Read>, output_folder: &Path, quiet: bool)
// and so on
if !quiet {
info(format!(
"{:?} extracted. ({})",
utils::strip_cur_dir(&output_folder.join(file.path()?)),
"extracted ({}) {:?}",
Bytes::new(file.size()),
utils::strip_cur_dir(&output_folder.join(file.path()?)),
));
files_unpacked += 1;

View File

@ -79,16 +79,14 @@ where
// same reason is in _is_dir: long, often not needed text
if !quiet {
info(format!(
"{:?} extracted. ({})",
"extracted ({}) {:?}",
Bytes::new(file.size()),
file_path.display(),
Bytes::new(file.size())
));
}
let mode = file.unix_mode().ok_or_else(|| {
std::io::Error::new(std::io::ErrorKind::InvalidData, "Cannot extract file's mode")
})?;
let is_symlink = (mode & 0o170000) == 0o120000;
let mode = file.unix_mode();
let is_symlink = mode.is_some_and(|mode| mode & 0o170000 == 0o120000);
if is_symlink {
let mut target = String::new();

View File

@ -235,8 +235,8 @@ impl From<unrar::error::UnrarError> for Error {
}
}
impl From<sevenz_rust::Error> for Error {
fn from(err: sevenz_rust::Error) -> Self {
impl From<sevenz_rust2::Error> for Error {
fn from(err: sevenz_rust2::Error) -> Self {
Self::SevenzipError {
reason: err.to_string(),
}

View File

@ -69,11 +69,18 @@ impl FileVisibilityPolicy {
/// Walks through a directory using [`ignore::Walk`]
pub fn build_walker(&self, path: impl AsRef<Path>) -> ignore::Walk {
ignore::WalkBuilder::new(path)
let mut builder = ignore::WalkBuilder::new(path);
builder
.git_exclude(self.read_git_exclude)
.git_ignore(self.read_git_ignore)
.ignore(self.read_ignore)
.hidden(self.read_hidden)
.build()
.hidden(self.read_hidden);
if self.read_git_ignore {
builder.filter_entry(|p| p.path().file_name().is_some_and(|name| name != ".git"));
}
builder.build()
}
}

View File

@ -105,11 +105,11 @@ impl Bytes {
impl std::fmt::Display for Bytes {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let &Self(num) = self;
let num = self.0;
debug_assert!(num >= 0.0);
if num < 1_f64 {
return write!(f, "{} B", num);
return write!(f, "{:>6.2} B", num);
}
let delimiter = 1000_f64;
@ -117,9 +117,9 @@ impl std::fmt::Display for Bytes {
write!(
f,
"{:.2} {}B",
"{:>6.2} {:>2}B",
num / delimiter.powi(exponent),
Bytes::UNIT_PREFIXES[exponent as usize]
Bytes::UNIT_PREFIXES[exponent as usize],
)
}
}
@ -138,33 +138,33 @@ mod tests {
let mb = kb * 1000;
let gb = mb * 1000;
assert_eq!("0 B", format_bytes(0)); // This is weird
assert_eq!("1.00 B", format_bytes(b));
assert_eq!("999.00 B", format_bytes(b * 999));
assert_eq!("12.00 MiB", format_bytes(mb * 12));
assert_eq!(" 0.00 B", format_bytes(0)); // This is weird
assert_eq!(" 1.00 B", format_bytes(b));
assert_eq!("999.00 B", format_bytes(b * 999));
assert_eq!(" 12.00 MiB", format_bytes(mb * 12));
assert_eq!("123.00 MiB", format_bytes(mb * 123));
assert_eq!("5.50 MiB", format_bytes(mb * 5 + kb * 500));
assert_eq!("7.54 GiB", format_bytes(gb * 7 + 540 * mb));
assert_eq!("1.20 TiB", format_bytes(gb * 1200));
assert_eq!(" 5.50 MiB", format_bytes(mb * 5 + kb * 500));
assert_eq!(" 7.54 GiB", format_bytes(gb * 7 + 540 * mb));
assert_eq!(" 1.20 TiB", format_bytes(gb * 1200));
// bytes
assert_eq!("234.00 B", format_bytes(234));
assert_eq!("999.00 B", format_bytes(999));
assert_eq!("234.00 B", format_bytes(234));
assert_eq!("999.00 B", format_bytes(999));
// kilobytes
assert_eq!("2.23 kiB", format_bytes(2234));
assert_eq!("62.50 kiB", format_bytes(62500));
assert_eq!(" 2.23 kiB", format_bytes(2234));
assert_eq!(" 62.50 kiB", format_bytes(62500));
assert_eq!("329.99 kiB", format_bytes(329990));
// megabytes
assert_eq!("2.75 MiB", format_bytes(2750000));
assert_eq!("55.00 MiB", format_bytes(55000000));
assert_eq!(" 2.75 MiB", format_bytes(2750000));
assert_eq!(" 55.00 MiB", format_bytes(55000000));
assert_eq!("987.65 MiB", format_bytes(987654321));
// gigabytes
assert_eq!("5.28 GiB", format_bytes(5280000000));
assert_eq!("95.20 GiB", format_bytes(95200000000));
assert_eq!(" 5.28 GiB", format_bytes(5280000000));
assert_eq!(" 95.20 GiB", format_bytes(95200000000));
assert_eq!("302.00 GiB", format_bytes(302000000000));
assert_eq!("302.99 GiB", format_bytes(302990000000));
// Weird aproximation cases:
assert_eq!("999.90 GiB", format_bytes(999900000000));
assert_eq!("1.00 TiB", format_bytes(999990000000));
assert_eq!(" 1.00 TiB", format_bytes(999990000000));
}
}

View File

@ -753,3 +753,48 @@ fn symlink_pack_and_unpack(
assert!(!f.file_type().unwrap().is_symlink())
}
}
#[test]
fn no_git_folder_after_decompression_with_gitignore_flag_active() {
use std::process::Command;
let dir = tempdir().unwrap();
let dir_path = dir.path();
let before = dir_path.join("before");
let decompressed = dir_path.join("decompressed");
// Create directory and a dummy file
fs::create_dir(&before).unwrap();
fs::write(before.join("hello.txt"), b"Hello, world!").unwrap();
// Run `git init` inside it
Command::new("git")
.arg("init")
.current_dir(&before)
.output()
.expect("failed to run git init");
assert!(before.join(".git").exists(), ".git folder should exist after git init");
// Compress it
let archive = dir_path.join("archive.zip");
ouch!("c", &before, &archive, "--gitignore");
// Decompress it
ouch!("d", &archive, "-d", &decompressed);
// Find the subdirectory inside decompressed (e.g., "before")
let decompressed_subdir = fs::read_dir(&decompressed)
.unwrap()
.find_map(Result::ok)
.map(|entry| entry.path())
.expect("Expected one directory inside decompressed");
// Assert that the decompressed folder does not include `.git/`
assert!(
!decompressed_subdir.join(".git").exists(),
".git folder should not exist after decompression"
);
}

View File

@ -0,0 +1,13 @@
---
source: tests/ui.rs
expression: stdout_lines
---
{
"",
"[INFO] Files unpacked: 4",
"[INFO] Successfully decompressed archive in <TMP_DIR>/outputs",
"[INFO] extracted ( 0.00 B) \"outputs/inputs\"",
"[INFO] extracted ( 0.00 B) \"outputs/inputs/input\"",
"[INFO] extracted ( 0.00 B) \"outputs/inputs/input2\"",
"[INFO] extracted ( 0.00 B) \"outputs/inputs/input3\"",
}

View File

@ -6,7 +6,7 @@
#[macro_use]
mod utils;
use std::{ffi::OsStr, io, path::Path, process::Output};
use std::{collections::BTreeSet, ffi::OsStr, io, path::Path, process::Output};
use insta::assert_snapshot as ui;
use regex::Regex;
@ -142,6 +142,29 @@ fn ui_test_ok_decompress() {
ui!(run_ouch("ouch decompress output.zst", dir));
}
#[cfg(target_os = "linux")]
#[test]
fn ui_test_ok_decompress_multiple_files() {
let (_dropper, dir) = testdir().unwrap();
let inputs_dir = dir.join("inputs");
std::fs::create_dir(&inputs_dir).unwrap();
let outputs_dir = dir.join("outputs");
std::fs::create_dir(&outputs_dir).unwrap();
// prepare
create_files_in(&inputs_dir, &["input", "input2", "input3"]);
let compress_command = format!("ouch compress {} output.tar.zst", inputs_dir.to_str().unwrap());
run_ouch(&compress_command, dir);
let decompress_command = format!("ouch decompress output.tar.zst --dir {}", outputs_dir.to_str().unwrap());
let stdout = run_ouch(&decompress_command, dir);
let stdout_lines = stdout.split('\n').collect::<BTreeSet<_>>();
insta::assert_debug_snapshot!(stdout_lines);
}
#[test]
fn ui_test_usage_help_flag() {
insta::with_settings!({filters => vec![