resource_merger
A small, practical Rust library and CLI for merging Minecraft resource packs (folders, zip files, or remote zip URLs) into a single merged resource pack. The merge is ordered: later packs overwrite earlier ones by default.
Key features
- Accept inputs as directories, zip files on disk, in-memory zip bytes, or HTTP/HTTPS URLs
- CLI with handy flags (overwrite policy, dry-run, config file, write-as-dir)
- Library API: in-memory merge, file output, and (placeholder) directory output
- Config file support: sorted list of paths/URLs to merge in order
Install / add to Cargo.toml
[]
= { = "../ResourceMerger" }
Library usage (examples)
- Simple merge to bytes:
use ;
use PathBuf;
let packs = vec!;
let merged = merge_packs_to_bytes?; // Vec<u8> with a zip archive
- Merge and write to a file with options:
use ;
use PathBuf;
let opts = default;
let packs = vec!;
merge_packs_to_file_with_options?;
- Merge a folder containing multiple packs (useful for a
resourcepacks/directory):
use merge_all_packs_in_folder;
use Path;
let bytes = merge_all_packs_in_folder?;
- Read a config file (one URL/path per line) and use it:
use read_config_file;
let packs = read_config_file?; // Vec<PackInput>
Overwrite policies
LastWins(default): later packs overwrite earlier ones.FirstWins: first occurrence wins; later duplicates ignored.ErrorIfConflict: error on duplicate paths.SkipIfExists: skip writing if file already exists.
CLI usage
Build the binary with cargo build --release or run via cargo run --bin merge -- ....
Examples:
- Merge into a zip (last wins):
- Merge into a directory (streaming / safer for large packs):
- Use a config file (entries are processed first, then positional args):
Flags (CLI)
--out <PATH>: output path (zip or directory)--dir: write the merged output as a directory instead of a zip--config <PATH>: read inputs (URLs or file paths) from a newline-separated config file--overwrite <last|first|error|skip>: overwrite policy (defaultlast)--dry-run: scan and validate inputs, but don't write output--buffer-size <BYTES>: buffer size for streaming copies (default 32768)--atomic/--no-atomic: write atomically when possible (default true)--preserve-timestamps: preserve timestamps when extracting (optional)
Config file format
- Plain text file; one entry per line. Lines starting with
#are comments. - Each entry can be an absolute or relative filesystem path, or an
http:///https://URL. - Entries are processed in file order. Example
packs.txt:
# base packs
https://example.com/base_pack.zip
./mods/some_pack.zip
# overlay packs
./local_overlays/overlay_folder
Security notes
- The library must sanitize zip paths to avoid zip-slip (entries attempting to write outside the destination). Avoid passing untrusted zips to extraction without validation.
- Remote URLs are downloaded and treated as zip archives. Consider size limits and validating the response before extraction.
Publishing notes
- The crate exposes a typed
MergeErrorandMergeOptionsfor predictable consumption by other crates. - Add CI to run tests and
cargo fmt/clippybefore publishing.
License
This project is licensed under MIT. See the LICENSE file for details.