ouch

repository·main·Indexed 25 days ago

https://github.com/ouch-org/ouch

A fast, easy-to-use command-line utility for compressing and decompressing files and directories. Ouch (Obvious Unified Compression Helper) provides a single interface for various archive formats, including .tar, .zip, .7z, .gz, .xz, .lzma, .lz, .bz, .lz4, .rar, and .br. It supports chained extensions (e.g., .tar.gz.xz.zst), parallel compression for specific formats, and features subcommands for compressing, decompressing, and listing archive contents.

Tokens
5.2K
Snippets
13
Records
35
Agent score
87%

What's inside ouch

  1. Draft a new release using the draft script

    main

    Use the scripts/draft-new-release.py script to prepare a release-candidate tag and trigger the GitHub Actions release workflow.

    Prerequisites

    Before running the script, ensure the following requirements are met:

    • You are on the main branch.
    • Your local main branch matches origin/main.
    • You have no staged or unstaged tracked changes (untracked files are ignored).
    • Rust and Cargo are installed and available in your environment.

    Execution

    Run the script providing the new version in MAJOR.MINOR.PATCH format.

    Automated Actions

    The script performs the following steps:

    1. Updates CHANGELOG.md by pointing Unreleased to the new version, adding fresh sections, and creating a comparison section.
    2. Prompts for a review of CHANGELOG.md (enter y to proceed).
    3. Updates the package version in Cargo.toml.
    4. Runs cargo test --profile fast and updates Cargo.lock.
    5. Commits CHANGELOG.md, Cargo.toml, and Cargo.lock with the message "bump version NEW_VERSION".
    6. Creates a release candidate tag (e.g., NEW_VERSION-rc1).
    7. Pushes the new tags.
    8. Prints the GitHub Actions URL.
    scripts/draft-new-release.py 0.8.0
  2. List archive contents with `ouch list`

    main

    Use the list subcommand (aliases l or ls) to view the contents of an archive without extracting it.

    Usage

    • Standard list: ouch list <archive_file>
    • Tree view: Use the --tree flag to display contents in a hierarchical tree format.

    Examples

    # List contents of a zip file
    ouch list archive.zip
    
    # List contents in tree format
    ouch list source-code.zip --tree
    ouch list source-code.zip --tree
  3. Install Ouch

    main

    You can install ouch using various package managers or by compiling from source.

    Common Installation Methods

    • Arch Linux: pacman -S ouch
    • macOS (Homebrew): brew install ouch
    • Windows (Scoop): scoop install ouch
    • Rust (crates.io): cargo install ouch (Note: Ubuntu users may need to install clang first).

    Release Bundles

    Download binaries from the GitHub releases page. Release binaries are signed with Sigstore.

  4. Finalize a release after running the draft script

    main

    Once the draft script has completed, follow these steps to finalize the release:

    1. Monitor Workflow: Go to GitHub Actions and wait for the release workflow triggered by the RC tag to complete.
    2. Review Draft: Go to GitHub Releases and open the drafted release associated with the RC tag. You can continue polishing release notes or the changelog here.
    3. Publish to Crates.io: Run cargo publish to publish the version.
    4. Push Version Bump: The script creates a commit for the version bump but does not push it. Manually run git push to push the commit to main.
    5. Finalize on GitHub:
      • Edit the release in GitHub.
      • Change the status from a pre-release to the final release.
      • Verify the title, body, and assets are correct.
      • Click Release.
  5. Compress files with `ouch compress`

    main

    Use the compress subcommand (alias c) to create archives. Pass the input files first, followed by the output file at the end. ouch determines the compression format(s) to use based on the extension of the output file.

    Usage

    ouch compress <input_file1> <input_file2> ... <output_file>

    Examples

    # Compress two files into a zip archive
    ouch compress one.txt two.txt archive.zip
    
    # Chain multiple compression formats (e.g., lz4 and zstd)
    ouch compress file.txt file.txt.lz4.zst
    ouch compress one.txt two.txt archive.zip
  6. Decompress files with `ouch decompress`

    main

    Use the decompress subcommand (alias d) to extract files. ouch automatically detects the format based on the file extension.

    Usage

    • Single file: ouch decompress <file>
    • Multiple files: ouch decompress <file1> <file2> ...
    • Redirect to directory: Use the -d or --dir flag to specify a target directory for the extracted contents.

    Examples

    # Decompress a single zip file
    ouch decompress a.zip
    
    # Decompress multiple files
    ouch decompress a.zip b.tar.gz c.tar
    
    # Decompress into a specific folder
    ouch decompress summer_vacation.zip --dir pictures
    ouch decompress summer_vacation.zip --dir pictures
  7. Supported compression formats

    main

    Ouch supports a wide variety of formats. It can also handle chained extensions (e.g., .tar.gz.xz.zst). If a filename has no extension, ouch will attempt to infer the format via file signatures and prompt for confirmation.

    Supported Formats

    • .tar (Aliases: tgz, tbz, tbz2, tlz4, txz, tlzma, tsz, tzst, tlz, cbt)
    • .zip (Aliases: cbz, epub)
    • .7z (Alias: cb7)
    • .gz (Alias: sz)
    • .xz
    • .lzma
    • .lz
    • .bz, .bz2, .bz3
    • .lz4
    • .rar (Alias: cbr) — Note: Due to licensing, only decompression and listing are supported for RAR. To exclude RAR support from your build, disable the unrar feature.
    • .br

    Format Capabilities

    • Streaming: .zip, .7z, .gz, .sz, and .zst do not support streaming due to format limitations.
    • Parallelism: .gz, .sz, and .zst support parallel compression.
  8. Prepare decompression targets with `prepare_decompress_target`

    main

    The prepare_decompress_target function resolves where files should be written before the decompression sandbox is applied. It handles path conflicts and determines whether to create a new directory or extract files directly.

    It returns a PreparedTarget which can be Target { dir, file_name } or Cancelled if the user opts out of a conflict resolution.

    pub fn prepare_decompress_target(
        formats: &[Extension],
        output_dir: &Path,
        output_file_path: &Path,
        output_dir_was_explicit: bool,
        here: bool,
        question_policy: QuestionPolicy,
        claimed_targets: &mut HashSet<PathBuf>,
    ) -> Result<PreparedTarget>
  9. List archive contents with list_files()

    main

    The list_files function prints the contents of an archive to standard output. It accepts the archive path, an iterator of FileInArchive results, and ListOptions.

    Arguments:

    • archive: A reference to the Path of the archive file.
    • files: An iterator where each item is a Result<FileInArchive>.
    • list_options: A ListOptions instance defining the output format (tree vs flat, quiet mode).
    pub fn list_files(
        archive: &Path,
        files: impl IntoIterator<Item = Result<FileInArchive>>,
        list_options: ListOptions,
    ) -> Result<()> {
        // ...
    }
  10. Extract extensions from a file path

    main

    To determine the compression formats applied to a file based on its name, use extensions_from_path or separate_known_extensions_from_name.

    • extensions_from_path(path: &Path) -> Result<Vec<Extension>>: Returns only the list of detected extensions.
    • separate_known_extensions_from_name(path: &Path) -> Result<(&Path, Vec<Extension>)>: Returns the path with the extensions stripped off and the list of detected extensions.

    Validation Rule: Ouch enforces that archive extensions (like .tar or .zip) must appear at the start of the extension chain. For example, file.tar.gz is valid, but file.gz.tar is invalid and will return an error.

  11. Handle errors using the Error enum

    main
    The Error enum captures all possible errors generated by ouch. It includes specialized variants for different compression formats (LZ4, Zip, Sevenzip) and common I/O issues like NotFound, PermissionDenied, and AlreadyExists. You can also use Error::Custom to wrap a FinalError for unique error reporting.
  12. Check for RAR or BZip3 support availability

    main

    Depending on how ouch was compiled, certain formats might be unavailable. You can generate specific error variants to communicate this to the user:

    • Error::rar_no_support(): Returns an UnsupportedFormat error indicating RAR support is disabled (often due to licensing).
    • Error::bzip3_no_support(): Returns an UnsupportedFormat error indicating BZip3 support is disabled (often due to missing dependencies).