Skip to content

Conversation

Else00
Copy link

@Else00 Else00 commented Aug 24, 2025

Closes #859

This PR addresses several CLI user experience issues related to discovering supported formats by introducing a central format registry and a new list-formats subcommand. The previous approach had inconsistent, out-of-date, and context-unaware hints for formats.

The Problem

As detailed in issue #859, there were three core problems:

  1. No straightforward way to list supported formats from the CLI.
  2. Hints for the --format flag did not distinguish between compression and decompression capabilities.
  3. The hardcoded hint lists were out of date with the actual supported formats.

These issues stemmed from the lack of a single source of truth for format information.

The Solution

This PR implements the suggestions from the issue by making format information a central, authoritative part of the application.

  1. Central Format Registry (src/formats.rs)
    A new module, src/formats.rs, now acts as the single source of truth. It defines every supported format, its extensions and aliases, its role (archive vs. compressor), and its capabilities (compress/decompress). This eliminates hardcoded lists and prevents future drift between documentation, hints, and application logic.

  2. New list-formats Subcommand
    A new subcommand ouch list-formats (with aliases formats and support) has been added. It prints a detailed, beautifully formatted table of all supported formats and their capabilities, generated directly from the new registry.

  3. Smarter, Context-Aware Hints
    Error messages are now much more helpful. The logic distinguishes between two types of errors:

    • Missing Format: If a format is missing entirely (e.g., ouch compress file output), the hint is highly specific to the command being run, showing only the formats that support compression.
    • Invalid Format: If an invalid format is passed via --format (e.g., ouch decompress file --format asd), the tool assumes the user might be confused about general capabilities, so it provides broader guidance by showing two separate, clearly labeled lists for all supported compression and decompression formats.
  4. Code Refactoring
    The extension.rs and error.rs modules have been refactored to consume information from the new formats.rs registry, ensuring consistency across the entire application.

Benefits of the New list-formats Command

The new ouch list-formats command provides a comprehensive and easy-to-understand overview of all supported formats, empowering users to understand and use ouch more effectively.

  • Clarifies Format Roles: The ROLE column immediately teaches the user the crucial difference between an archive (a container for multiple files, like tar or zip) and a compressor (an algorithm that works on a single stream of data). This helps users understand why they need tar to compress a directory.

  • Shows Explicit Capabilities: The COMPRESS and DECOMPRESS columns remove all guesswork. Users can see at a glance that, for example, ouch can decompress .rar files but cannot create them, or that .lzma decompression is supported but compression is not.

  • Demystifies Shorthands: The separate shorthands table clearly shows how convenient aliases like tgz expand to their full tar.gz equivalent, distinguishing them from single-format extensions.

New CLI Output

Here are some examples of the new and improved output.

1. The list-formats command output:
Note: The layout is responsive. The capabilities and shorthands tables will appear side-by-side on wide terminals, or stacked vertically on narrow ones.

ROLE column:
  • archive — holds multiple files in one container (e.g., tar, zip, 7z)
  • compressor — compresses a single stream; use with 'tar' for directories                         Shorthand chains (left → expands to right).
                                                                                                    These are filename shortcuts only.
COMPRESS / DECOMPRESS columns show what this tool supports for each format.                         Example: 'tgz' expands to 'tar.gz'.

┌────────┬─────────────┬─────────────┬──────────┬────────────┬─────────────────────────────────┐    ┌───────────┬────────────┐
│ FORMAT ┆ LONG NAME   ┆ ROLE        ┆ COMPRESS ┆ DECOMPRESS ┆ NOTES                           │    │ SHORTHAND ┆ EXPANDS TO │
╞════════╪═════════════╪═════════════╪══════════╪════════════╪═════════════════════════════════╡    ╞═══════════╪════════════╡
│ tar    ┆ Tar         ┆ archive     ┆    yes   ┆     yes    ┆                                 │    │ tgz       ┆ tar.gz     │
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤    ├╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ zip    ┆ ZIP         ┆ archive     ┆    yes   ┆     yes    ┆ cannot be streamed when chained │    │ tbz       ┆ tar.bz2    │
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤    ├╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ rar    ┆ RAR         ┆ archive     ┆    no    ┆     yes    ┆                                 │    │ tbz2      ┆ tar.bz2    │
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤    ├╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ 7z     ┆ 7-Zip       ┆ archive     ┆    yes   ┆     yes    ┆ cannot be streamed when chained │    │ tbz3      ┆ tar.bz3    │
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤    ├╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ gz     ┆ Gzip        ┆ compressor  ┆    yes   ┆     yes    ┆                                 │    │ tlz4      ┆ tar.lz4    │
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤    ├╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ bz2/bz ┆ Bzip2       ┆ compressor  ┆    yes   ┆     yes    ┆                                 │    │ txz       ┆ tar.xz     │
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤    ├╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ bz3    ┆ Bzip3       ┆ compressor  ┆    yes   ┆     yes    ┆                                 │    │ tlzma     ┆ tar.lzma   │
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤    ├╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ xz     ┆ XZ (LZMA2)  ┆ compressor  ┆    yes   ┆     yes    ┆                                 │    │ tlz       ┆ tar.lz     │
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤    ├╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ lzma   ┆ LZMA (v1)   ┆ compressor  ┆    no    ┆     yes    ┆                                 │    │ tsz       ┆ tar.sz     │
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤    ├╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ lz     ┆ Lzip        ┆ compressor  ┆    no    ┆     yes    ┆                                 │    │ tzst      ┆ tar.zst    │
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤    └───────────┴────────────┘
│ lz4    ┆ LZ4         ┆ compressor  ┆    yes   ┆     yes    ┆                                 │
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ sz     ┆ Snappy (sz) ┆ compressor  ┆    yes   ┆     yes    ┆                                 │
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ zst    ┆ Zstandard   ┆ compressor  ┆    yes   ┆     yes    ┆                                 │
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ br     ┆ Brotli      ┆ compressor  ┆    yes   ┆     yes    ┆                                 │
└────────┴─────────────┴─────────────┴──────────┴────────────┴─────────────────────────────────┘

2. Context-aware hint for a missing compression format:

[ERROR] Cannot compress to 'output'.
 - You shall supply the compression format

hint: Try adding supported extensions (see --help):
hint:   ouch compress <FILES>... output.tar.gz
hint:   ouch compress <FILES>... output.zip
hint:
hint: Alternatively, you can overwrite this option by using the '--format' flag:
hint:   ouch compress <FILES>... output --format tar.gz
hint: Supported extensions for compression are: tar, zip, 7z, gz, bz2, bz3, xz, lz4, sz, zst, br
hint: Supported aliases are: tgz, tbz, tbz2, tbz3, tlz4, txz, tlzma, tlz, tsz, tzst
hint: For detailed capabilities and notes, run: ouch list-formats

3. General hint for an invalid format provided via flag:

[ERROR] Failed to parse `--format asd`
 - Unsupported extension 'asd'

hint: Supported extensions for compression are: tar, zip, 7z, gz, bz2, bz3, xz, lz4, sz, zst, br
hint: Supported extensions for decompression are: tar, zip, rar, 7z, gz, bz2, bz3, xz, lzma, lz, lz4, sz, zst, br
hint: Supported aliases are: tgz, tbz, tbz2, tbz3, tlz4, txz, tlzma, tlz, tsz, tzst
hint: For detailed capabilities and notes, run: ouch list-formats
hint:
hint: Examples:
hint:   --format tar
hint:   --format gz
hint:   --format tar.gz

@Else00 Else00 marked this pull request as draft August 24, 2025 17:51
…m to prevent false ZIP matches and build errors
@Else00 Else00 marked this pull request as ready for review August 24, 2025 18:44
@Else00 Else00 changed the title feat(cli): Add list-formats command and central format registry feat: Add list-formats command and central format registry Aug 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

CLI UX: hard to list supported formats; no compression/decompression distinction; CLI hint list out of date
1 participant