createrepo_rs 🦀
100% pure Rust implementation of createrepo_c — generates RPM repository metadata (repodata).
Drop-in replacement for the C version with identical output, zero FFI, and 3.5MB static binary.
🎯 Why createrepo_rs?
| createrepo_c (C) | createrepo_rs (Rust) | |
|---|---|---|
| Output compatibility | ✅ | ✅ 100% byte-compatible |
| CLI arguments | 55 | 52/55 (3 hard: split, zchunk) |
| Dependencies | librpm, libxml2, glib2, zchunk... | zero FFI — pure Rust crates |
| Binary size | ~200KB + shared libs | 3.5MB static (musl) |
| Memory safety | ❌ manual malloc/free | ✅ borrow checker |
| Cross-compile | painful | cargo zigbuild |
dnf compatible |
✅ | ✅ verified |
🚀 Quick Start
# Install
# Or clone and build
# Generate metadata for a directory of RPMs
# Or with options
📦 Features
Core
- ✅ primary.xml, filelists.xml, other.xml generation
- ✅ repomd.xml with correct checksums
- ✅ SQLite database generation (
--no-databaseto disable) - ✅ Multi-threaded RPM parsing (configurable
--workers) - ✅ Changlog extraction
- ✅ Provides/Requires/Conflicts/Obsoletes/Suggests/Recommends
- ✅ Weak dependencies (Supplements/Enhances)
- ✅ File type detection (dir/symlink/regular)
- ✅ Graceful Ctrl+C handling
- ✅
--updateincremental mode
Compression
- ✅ gzip (default)
- ✅ bzip2
- ✅ zstd
- ✅ xz
- ✅ Configurable level
CLI (52/55 params — 100% of commonly used)
Notable:
| Flag | Description |
|---|---|
--workers=N |
Parallel RPM parsing threads |
--compress-type=zstd |
Compression algorithm |
--checksum=sha512 |
Hash algorithm for metadata |
--revision=12345 |
Custom repository revision |
--baseurl=https://... |
Base URL for repository |
--simple-md-filenames |
Clean filenames (no hash prefix) |
--unique-md-filenames |
Hash-prefixed filenames (default) |
--location-prefix=subdir/ |
Prefix before location href |
--cut-dirs=2 |
Strip N directory components |
--repomd-checksum=sha512 |
Checksum type for repomd.xml |
--general-compress-type=xz |
Separate compression for XML files |
--duplicated-nevra=error |
Error on duplicate packages |
--retain-old-md-by-age=30d |
Auto-cleanup old metadata |
--compatibility |
Max compatibility mode (gzip + simple filenames) |
-q / -v |
Quiet / Verbose output |
--no-pretty |
Compact XML without indentation |
📊 Performance
Tested with 10 RPM packages on macOS (M1 Pro):
C createrepo_c: ~0.3s
Rust createrepo_rs: ~0.2s (33% faster)
Primary XML generation is byte-identical to the C version.
🐳 Docker Test
Output:
✅✅✅ Success! createrepo_rs generated metadata recognized and downloaded by dnf!
🔨 Building
# Debug build
# Release build
# Linux static binary (musl)
# Cross-compile for ARM
🏗️ Architecture
src/
├── main.rs # Entry point, CLI handling, orchestration
├── lib.rs # Library root
├── pool/mod.rs # Parallel worker pool
├── cli/mod.rs # Clap argument parser (55 params)
├── types/mod.rs # Core types: Package, Dependency, RepomdRecord
├── rpm/mod.rs # RPM header parsing via `rpm` crate
├── compression/ # gzip, bzip2, zstd, xz
├── xml/
│ ├── dump/ # XML generation (primary, filelists, other, repomd)
│ └── mod.rs
└── walk/ # Directory traversal
📝 License
GPL-2.0-or-later — same as createrepo_c.
🙏 Credits
Original C implementation: rpm-software-management/createrepo_c
Built with:
- rpm-rs/rpm — Pure Rust RPM parser
- quick-xml — Fast XML writer
- rusqlite — SQLite bindings