{"id":51625058,"url":"https://github.com/open-southeners/rcomp","last_synced_at":"2026-07-13T00:02:46.100Z","repository":{"id":364315573,"uuid":"1266777796","full_name":"open-southeners/rcomp","owner":"open-southeners","description":"Multi format CLI and GUI compression utility","archived":false,"fork":false,"pushed_at":"2026-06-12T14:46:24.000Z","size":251,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-12T15:24:17.736Z","etag":null,"topics":["cli-tool","compression-tool","file-compression"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/open-southeners.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-12T00:13:39.000Z","updated_at":"2026-06-12T14:47:45.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/open-southeners/rcomp","commit_stats":null,"previous_names":["open-southeners/rcomp"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/open-southeners/rcomp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/open-southeners%2Frcomp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/open-southeners%2Frcomp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/open-southeners%2Frcomp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/open-southeners%2Frcomp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/open-southeners","download_url":"https://codeload.github.com/open-southeners/rcomp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/open-southeners%2Frcomp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35405750,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-12T02:00:06.386Z","response_time":87,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli-tool","compression-tool","file-compression"],"created_at":"2026-07-13T00:02:45.391Z","updated_at":"2026-07-13T00:02:46.094Z","avatar_url":"https://github.com/open-southeners.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# rcomp\n\nOne tool for the most popular compression and archive formats.\n\n**`rcomp-core`** is a reusable Rust library (the product). **`rcomp`** is the\ncommand-line tool, and **Rcomp** is the Tauri desktop app.\n\n## Install\n\nHomebrew is the preferred installation method. Packages are published through\nthe Open Southeners tap at\n[open-southeners/homebrew-tap](https://github.com/open-southeners/homebrew-tap):\n\n```\nbrew tap open-southeners/tap\nbrew install rcomp                    # CLI\nbrew install --cask rcomp-desktop     # desktop app\n```\n\nIf you only want the CLI and already have Rust installed, you can also install\nfrom crates.io:\n\n```\ncargo install rcomp\n```\n\n`rcomp` and `rcomp-core` are published to crates.io automatically when a GitHub\nrelease is tagged. See [RELEASING.md](RELEASING.md) for the release runbook.\n\n## Usage\n\n```\nrcomp /path/to/folder compressed.bz2     # picks bzip2 from the extension, tars the folder transparently\nrcomp big.iso big.iso.zst --edge         # max zstd compression\nrcomp archive.7z                         # detects 7z by magic bytes, extracts to cwd\nrcomp archive.7z ~/restored              # ...or into an explicit destination folder\nrcomp ls archive.zip                     # list entries without extracting\nrcomp weird-file -a bzip2                # force an algorithm explicitly\n```\n\n### Subcommands\n\n```\nrcomp \u003cINPUT\u003e [OUTPUT] [OPTIONS]    # compress or extract (inferred from arguments)\nrcomp ls \u003cARCHIVE\u003e                  # list entries without extracting\nrcomp completions \u003cSHELL\u003e           # print shell completion script to stdout\nrcomp man                           # print a troff man page to stdout\n```\n\n### Options\n\n```\n  -a, --algo \u003cALGO\u003e      Force algorithm/format (bzip2, zstd, 7z, tar.xz, ...)\n      --fast             Fastest compression\n      --best             Balanced (default)\n      --edge             Maximum compression ratio, hardware expensive\n  -c, --compress         Force compress mode (for re-compressing a .gz, etc.)\n  -x, --extract          Force extract mode\n      --unwrap           Extract entries directly into the destination\n                         (skip the auto-wrap folder)\n      --checksum         Write a sha256sum-format sidecar \u003cOUTPUT\u003e.sha256\n                         and show the digest in the summary (compress only;\n                         on extraction a sidecar is auto-verified when found)\n      --all              Ignore .gitignore rules: include every file in the\n                         input folder, .git included (compress only)\n      --exclude \u003cGLOB\u003e   Exclude paths matching a gitignore-style glob,\n                         relative to the input folder; repeatable; works\n                         with or without --all (compress only)\n  -y, --yes              Auto-accept all confirmation prompts\n  -f, --force            Overwrite existing output\n  -q, --quiet            No progress output\n```\n\n### Inference rules\n\nCompress vs. extract is inferred from the arguments in this order:\n\n1. `--compress` or `--extract` given — obey.\n2. `OUTPUT` given with a recognizable compression/archive extension — compress.\n3. `INPUT` is a readable file recognized as compressed/archive via magic bytes —\n   extract. `OUTPUT`, when given, is the destination directory (created if\n   missing).\n4. Otherwise — error listing both interpretations and the flag to pick one.\n\n### Silent-tar folder rule\n\nWhen the output format is a codec (e.g. `.bz2`) and the input is a folder,\nrcomp automatically wraps the folder in a tar stream first. The output file\nkeeps the exact name you gave (`out.bz2` contains tar-then-bzip2 data).\nrcomp warns you about this and asks for confirmation before proceeding.\nPass `-y` to auto-accept.\n\n### Extraction auto-wrap\n\nWhen an archive contains multiple loose top-level entries, rcomp wraps them in\na new folder named after the archive stem (`photos.tar.gz` extracts into\n`./photos/`). A single top-level folder, a single file, or a bare codec stream\nextracts directly without extra nesting. `--unwrap` forces direct extraction\nregardless.\n\n### Checksums\n\nPass `--checksum` when compressing to compute a SHA-256 digest of the output\nand write a sidecar file next to it:\n\n```\nrcomp folder/ archive.tar.gz --checksum\n```\n\nThe sidecar is named `\u003coutput\u003e.sha256` (e.g. `archive.tar.gz.sha256`).  Its\nformat is compatible with `sha256sum -c`:\n\n```\n# content-sha256: 3b4c2a1d...e8f9        ← only for codec/tar outputs\na1b2c3d4...f0  archive.tar.gz\n```\n\nThe `# content-sha256:` comment line is present for formats that have a single\npre-compression byte stream (codec-only, tar, and tar+codec combinations).  It\nis absent for zip and 7z, which compress entries individually.\n\n**Artifact digest** — SHA-256 of the compressed file written to disk (transport\nintegrity).\n\n**Content digest** — SHA-256 of the pre-compression stream:\n\n- codec-only, file input: digest of the raw input file bytes\n- tar + codec: digest of the uncompressed tar byte stream\n- plain tar: same bytes as the artifact digest (both are always equal)\n- zip / 7z: not produced (`None`)\n\nThe content digest is brotli's only integrity check — see [Limitations](#limitations).\n\nThe artifact digest is also printed to stdout after the summary line:\n\n```\narchive.tar.gz  1.2 MiB → 380 KiB (31.7%)  in 0.4s\nsha256: a1b2c3d4...f0\n```\n\n`-q` suppresses all stdout output but still writes the sidecar file.\n\n**Verifying manually:**\n\n```\nsha256sum -c archive.tar.gz.sha256\n```\n\n`sha256sum` verifies the artifact line and ignores the `#` comment.\n\n**Auto-verify on extraction:**\n\nWhen extracting an archive that has a sibling `\u003carchive\u003e.sha256` file, rcomp\nreads and verifies both digests automatically — no flag is needed:\n\n```\nrcomp archive.tar.gz                  # sidecar found → verifies before unpacking\n```\n\nThe artifact digest is checked before any files are written to the destination.\nThe content digest is checked during extraction as the stream is read.  A\nmismatch on either causes an error (exit 1) with a clear message; no output\nfiles are left behind when the artifact check fails.\n\nIf the sidecar is present but cannot be parsed, extraction fails (exit 1) —\na present sidecar is treated as a promise.  If no sidecar exists, extraction\nproceeds exactly as before with no verification.\n\n`--checksum` on an extract operation is a usage error (exit 2).\n\n### .gitignore awareness\n\nWhen compressing a folder, rcomp follows `.gitignore` rules by default.  Full\ngit semantics are applied: the origin folder's own `.gitignore` and any nested\n`.gitignore` files in subdirectories are honoured.  The `.git` directory itself\nis always excluded.  Hidden dotfiles (e.g. `.editorconfig`, `.gitignore`) are\nincluded — only ignore rules and `.git` exclude things.\n\nA folder with no `.gitignore` anywhere is archived identically to before.\n\n**`--all`** disables all `.gitignore` filtering.  Every file is included,\nincluding the `.git` directory:\n\n```\nrcomp folder/ archive.tar.gz --all\n```\n\n**`--exclude \u003cGLOB\u003e`** excludes paths matching a gitignore-style glob, matched\nrelative to the input folder.  The flag may be repeated and works with or\nwithout `--all`:\n\n```\nrcomp folder/ archive.tar.gz --exclude 'target/' --exclude '*.log'\nrcomp folder/ archive.tar.gz --all --exclude 'target/'\n```\n\nAn invalid glob is a usage error (exit 2).\n\nWhen any paths are excluded, rcomp prints a note to stderr naming which sources\nwere active:\n\n```\nexcluded 47 paths via .gitignore (use --all to include)\nexcluded 12 paths via --exclude\nexcluded 59 paths via .gitignore and --exclude\n```\n\nThis note goes to stderr and is suppressed by `-q`, like other non-error output.\n\n**Reproducibility:** rcomp deliberately does not consult parent-directory\n`.gitignore` files, the global gitignore (`~/.config/git/ignore`), or\n`.git/info/exclude`.  Archives are reproducible from the folder alone,\nindependent of machine-local git configuration.\n\n`--all` and `--exclude` on an extract operation are usage errors (exit 2).\n\n### Exit codes\n\n| Code | Meaning |\n|------|---------|\n| 0 | Success |\n| 1 | Operation error (I/O, already-exists, unsupported format, cancelled, ...) |\n| 2 | Usage/ambiguity error (bad `--algo` value, inference ambiguity) |\n\nCtrl-C cancels cleanly: partial output is removed and rcomp exits 1.\n\n## Supported formats\n\n### Codecs (single-stream)\n\n| Codec | Extension | Notes |\n|-------|-----------|-------|\n| gzip | `.gz` | |\n| bzip2 | `.bz2` | |\n| xz | `.xz` | |\n| zstd | `.zst` | |\n| lz4 | `.lz4` | |\n| brotli | `.br` | No magic bytes — see Limitations |\n\n### Archives\n\n| Format | Extension | Notes |\n|--------|-----------|-------|\n| tar | `.tar`, `.tar.*`, `.tgz`, `.tbz2`, `.txz`, ... | |\n| zip | `.zip` | |\n| 7z | `.7z` | |\n| rar | `.rar` | Extract-only — see License note |\n\ntar can be combined with any codec: `.tar.gz`, `.tar.bz2`, `.tar.xz`,\n`.tar.zst`, `.tar.lz4`, `.tar.br`.\n\n## Compression levels\n\nThe three levels describe the **output ratio**, never the hardware cost.\n`--edge` turns on every ratio-improving feature a codec offers.\nCodec-native multithreading (zstd workers, xz threads) is used at every\nlevel because it does not change the compressed result.\n\n| Codec | `--fast` | `--best` (default) | `--edge` |\n|-------|----------|--------------------|----------|\n| gzip | 1 | 6 | 9 |\n| bzip2 | 1 | 6 | 9 |\n| xz | 1 | 6 | 9 + extreme |\n| zstd | 1 | 3 | 22 + long-distance matching |\n| brotli | 2 | 6 | 11 + large window |\n| lz4 | 1 | 6 | 12 (HC) |\n| zip (deflate) | 1 | 6 | 9 |\n| 7z (LZMA2) | 1 | 5 | 9 |\n\n## Limitations\n\n- **7z: no unix permissions or symlinks.** The `sevenz-rust2` crate does not\n  expose unix mode bits or symlink entries. Executable scripts come back as\n  `0644`, and symlinks are stored as regular files (dereferenced). This is an\n  upstream crate limitation.\n\n- **Brotli: no magic bytes, no internal checksum.** Brotli-compressed files\n  cannot be detected by content alone — an extensionless `.br` file requires\n  `--algo brotli`.  Brotli has no framing checksum, so a corrupted stream can\n  decode \"successfully\" into wrong bytes rather than returning an error.  Use\n  `--checksum` when compressing brotli outputs; the content digest in the\n  resulting sidecar is the only integrity protection available for `.br` files.\n\n- **Zip extraction progress has no percentage.** The zip format is\n  random-access, so rcomp reports entry count and bytes written rather than\n  a percentage of the input file consumed.\n\n- **Ctrl-C and multithreaded xz.** Ctrl-C cancels cleanly for all formats,\n  but with the multithreaded xz encoder the interrupt may only take effect\n  once encoding finishes its queued blocks (input is already queued to worker\n  threads before the cancel signal is checked).\n\n## rar license note\n\nThe default `rar` cargo feature links the freeware `unrar` library, which is\n**not OSI-approved**. If your project requires only OSI-approved dependencies,\nbuild without it:\n\n```\ncargo install rcomp --no-default-features\n```\n\nRAR extraction will not be available in that build. All other formats are\nunaffected.\n\n## License\n\nLicensed under either of:\n\n- [MIT License](LICENSE-MIT)\n- [Apache License, Version 2.0](LICENSE-APACHE)\n\nat your option.\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in this project by you shall be dual-licensed as above, without\nany additional terms or conditions.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopen-southeners%2Frcomp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopen-southeners%2Frcomp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopen-southeners%2Frcomp/lists"}