resource_merger 0.1.2

Merge multiple Minecraft resource packs (directories or zip files/bytes) into a single zip where later packs overwrite earlier ones.
Documentation

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

[dependencies]
resource_merger = { path = "../ResourceMerger" }

Library usage (examples)

  • Simple merge to bytes:
use resource_merger::{merge_packs_to_bytes, PackInput};
use std::path::PathBuf;

let packs = vec![
    PackInput::Dir(PathBuf::from("./pack_base")),
    PackInput::ZipFile(PathBuf::from("./overlay.zip")),
];
let merged = merge_packs_to_bytes(&packs)?; // Vec<u8> with a zip archive
  • Merge and write to a file with options:
use resource_merger::{merge_packs_to_file_with_options, PackInput, MergeOptions};
use std::path::PathBuf;

let opts = MergeOptions::default();
let packs = vec![PackInput::Dir(PathBuf::from("./pack_base"))];
merge_packs_to_file_with_options(&packs, PathBuf::from("merged.zip"), &opts)?;
  • Merge a folder containing multiple packs (useful for a resourcepacks/ directory):
use resource_merger::merge_all_packs_in_folder;
use std::path::Path;

let bytes = merge_all_packs_in_folder(Path::new("./resourcepacks"))?;
  • Read a config file (one URL/path per line) and use it:
use resource_merger::read_config_file;
let packs = read_config_file(Path::new("packs.txt"))?; // 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):
resource-merger --out merged.zip packA packB packC
  • Merge into a directory (streaming / safer for large packs):
resource-merger --dir --out merged_folder packA packB
  • Use a config file (entries are processed first, then positional args):
resource-merger --config packs.txt --out merged.zip

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 (default last)
  • --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 MergeError and MergeOptions for predictable consumption by other crates.
  • Add CI to run tests and cargo fmt / clippy before publishing.

License

This project is licensed under MIT. See the LICENSE file for details.