refactor(tool): Небольшой рефакторинг CLI

This commit is contained in:
gasaichandesu
2026-05-30 14:39:33 +04:00
parent 583da559b4
commit df143b0bf1
7 changed files with 194 additions and 101 deletions
+19 -96
View File
@@ -1,118 +1,41 @@
use clap::Parser;
mod commands;
use clap::{Parser, Subcommand};
use log::{error, info};
use std::error::Error;
use std::fs;
use std::path::{Path, PathBuf};
use walkdir::WalkDir;
use wow_mpq::compression::flags;
use wow_mpq::{ArchiveBuilder, FormatVersion, ListfileOption};
#[derive(Parser, Debug)]
struct Args {
input_dir: PathBuf,
destination_dir: PathBuf,
struct Cli {
#[command(subcommand)]
command: Commands,
}
fn main() {
#[derive(Subcommand, Debug)]
enum Commands {
BuildMpq(commands::build_mpq::BuildMpqCommand),
}
#[tokio::main]
async fn main() {
env_logger::builder()
.filter_level(log::LevelFilter::Debug)
.format_target(false)
.format_timestamp(None)
.init();
let args = Args::parse();
let args = Cli::parse();
if let Err(err) = run(args) {
if let Err(err) = run(args).await {
error!("{}", err);
std::process::exit(1);
}
}
fn run(args: Args) -> Result<(), Box<dyn Error>> {
async fn run(args: Cli) -> Result<(), Box<dyn Error>> {
info!("Starting tool...");
let data_dir = args.input_dir.join("Data");
if !data_dir.exists() {
return Err(format!("Data directory not found at {}", data_dir.display()).into());
}
info!("Found Data directory at {}", data_dir.display());
for entry in fs::read_dir(&data_dir)? {
let entry = entry?;
let path = entry.path();
if !path.is_dir() {
continue;
}
let dir_name = entry.file_name().to_string_lossy().to_string();
if dir_name.starts_with("ruRU") {
for sub_entry in fs::read_dir(&path)? {
let sub_entry = sub_entry?;
let sub_path = sub_entry.path();
let sub_name = sub_entry.file_name().to_string_lossy().to_string();
let destination = args
.destination_dir
.join("Data")
.join(&dir_name)
.join(&sub_name);
let _ = build_mpq(&sub_path, &destination);
}
continue;
}
let destination = args.destination_dir.join("Data").join(&dir_name);
let _ = build_mpq(&path, &destination)?;
}
Ok(())
}
fn build_mpq(input_dir: &Path, destination: &Path) -> Result<(), Box<dyn Error>> {
info!(
"Packing MPQ from {} to {}",
input_dir.display(),
destination.display()
);
let mut destination = destination.to_path_buf();
destination.set_extension("MPQ");
if let Some(parent) = destination.parent() {
fs::create_dir_all(parent)?;
}
let mut builder = ArchiveBuilder::new()
.version(FormatVersion::V2)
.block_size(7)
.default_compression(flags::ZLIB)
.listfile_option(ListfileOption::Generate);
let base = input_dir.canonicalize()?;
for entry in WalkDir::new(&base)
.into_iter()
.filter_map(|e| e.ok())
.filter(|e| e.file_type().is_file())
{
let absolute_path = entry.path().canonicalize()?;
let relative_path = absolute_path.strip_prefix(&base)?;
builder = builder.add_file(&absolute_path, &relative_path.to_string_lossy().to_string());
}
let _ = builder.build(&destination);
info!("Successfully packed {}", destination.display());
Ok(())
return match args.command {
Commands::BuildMpq(args) => commands::build_mpq::execute(args),
};
}