diff --git a/Cargo.lock b/Cargo.lock index da102f3..86d583e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -137,7 +137,7 @@ checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn", ] [[package]] @@ -407,7 +407,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.85", + "syn", ] [[package]] @@ -547,7 +547,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "syn 2.0.85", + "syn", ] [[package]] @@ -558,7 +558,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.85", + "syn", ] [[package]] @@ -636,7 +636,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.85", + "syn", ] [[package]] @@ -670,19 +670,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "env_logger" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" -dependencies = [ - "humantime", - "is-terminal", - "log", - "regex", - "termcolor", -] - [[package]] name = "equivalent" version = "1.0.1" @@ -843,7 +830,7 @@ checksum = "53010ccb100b96a67bc32c0175f0ed1426b31b655d562898e57325f81c023ac0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn", ] [[package]] @@ -874,12 +861,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" -[[package]] -name = "hermit-abi" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" - [[package]] name = "hex" version = "0.4.3" @@ -895,12 +876,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - [[package]] name = "iana-time-zone" version = "0.1.60" @@ -1025,18 +1000,7 @@ checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", -] - -[[package]] -name = "is-terminal" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" -dependencies = [ - "hermit-abi", - "libc", - "windows-sys 0.52.0", + "syn", ] [[package]] @@ -1163,28 +1127,6 @@ version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" -[[package]] -name = "logging_timer" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5669c09dbcb4a0b5f6de8364154495574238e18d6736bbdaa7726307f3268471" -dependencies = [ - "log", - "logging_timer_proc_macros", -] - -[[package]] -name = "logging_timer_proc_macros" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27906ca51651609191eeb2d1fdc6b52b8024789ec188b07aad88b6dfbe392fbe" -dependencies = [ - "log", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "loop9" version = "0.1.5" @@ -1293,7 +1235,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn", ] [[package]] @@ -1388,7 +1330,7 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.85", + "syn", ] [[package]] @@ -1447,16 +1389,6 @@ dependencies = [ "yansi", ] -[[package]] -name = "pretty_env_logger" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "865724d4dbe39d9f3dd3b52b88d859d66bcb2d6a0acfd5ea68a65fb66d4bdc1c" -dependencies = [ - "env_logger", - "log", -] - [[package]] name = "proc-macro2" version = "1.0.86" @@ -1474,7 +1406,7 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn", "version_check", "yansi", ] @@ -1495,7 +1427,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8021cf59c8ec9c432cfc2526ac6b8aa508ecaf29cd415f271b8406c1b851c3fd" dependencies = [ "quote", - "syn 2.0.85", + "syn", ] [[package]] @@ -1764,7 +1696,7 @@ checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn", ] [[package]] @@ -1788,7 +1720,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn", ] [[package]] @@ -1857,17 +1789,6 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - [[package]] name = "syn" version = "2.0.85" @@ -1925,15 +1846,6 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "termcolor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] - [[package]] name = "testdir" version = "0.9.3" @@ -1966,7 +1878,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn", ] [[package]] @@ -2118,9 +2030,9 @@ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "vpin" -version = "0.17.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7a6c05d80b75a8a0438c63331e18b5ddb7aaa0afd9d52fbd17d9113654a5244" +checksum = "bed695c6db91526006ddcf116c347ee47e878de4574e936b6fdf912f86e7aba2" dependencies = [ "byteorder", "bytes", @@ -2159,13 +2071,8 @@ dependencies = [ "indicatif", "is_executable", "jojodiff", - "log", - "logging_timer", "pinmame-nvram", "pretty_assertions", - "pretty_env_logger", - "quick-xml", - "rand", "regex", "rust-ini", "serde", @@ -2222,7 +2129,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.85", + "syn", "wasm-bindgen-shared", ] @@ -2244,7 +2151,7 @@ checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2540,7 +2447,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index d388b5e..4263385 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,10 +25,6 @@ dialoguer = { version = "0.11.0", features = ["fuzzy-select"] } dirs = "5.0.1" git-version = "0.3.9" indicatif = "0.17.9" -log = "0.4.22" -logging_timer = "1.1.1" -pretty_env_logger = "0.5.0" -quick-xml = { version = "0.37.1", features = ["serialize"] } serde = { version = "1.0.216", features = ["derive"] } serde_json = { version = "1.0.133", features = ["preserve_order"] } shellexpand = "3.1.0" @@ -38,7 +34,7 @@ figment = { version = "0.10", features = ["toml", "env"] } toml = "0.8.19" is_executable = "1.0.4" regex = { version = "1.11.1", features = [] } -vpin = { version = "0.17.0" } +vpin = { version = "0.17.1" } rust-ini = "0.21.1" edit = "0.1.5" jojodiff = "0.1.2" @@ -46,7 +42,6 @@ pinmame-nvram = "0.3.3" [dev-dependencies] pretty_assertions = "1.4.1" -rand = "0.8.5" testdir = "0.9.3" [profile.test] diff --git a/src/frontend.rs b/src/frontend.rs index 23c4dfe..60a0f83 100644 --- a/src/frontend.rs +++ b/src/frontend.rs @@ -274,7 +274,7 @@ fn table_menu( let result = if path.exists() { open_editor(&path, Some(config)) } else { - extractvbs(selected_path, false, None) + extractvbs(selected_path, None, false) .and_then(|_| open_editor(&path, Some(config))) }; match result { @@ -287,7 +287,7 @@ fn table_menu( } } } - Some(TableOption::ExtractVBS) => match extractvbs(selected_path, false, None) { + Some(TableOption::ExtractVBS) => match extractvbs(selected_path, None, false) { Ok(ExtractResult::Extracted(path)) => { prompt(format!("VBS extracted to {}", path.to_string_lossy())); } @@ -310,7 +310,7 @@ fn table_menu( } }, Some(TableOption::PatchVBS) => { - let vbs_path = match extractvbs(selected_path, false, Some("vbs")) { + let vbs_path = match extractvbs(selected_path, None, false) { Ok(ExtractResult::Existed(path)) => path, Ok(ExtractResult::Extracted(path)) => path, Err(err) => { @@ -340,7 +340,8 @@ fn table_menu( } } Some(TableOption::UnifyLineEndings) => { - let vbs_path = match extractvbs(selected_path, false, Some("vbs")) { + let vbs_path = vbs_path_for(selected_path); + let vbs_path = match extractvbs(selected_path, Some(vbs_path), false) { Ok(ExtractResult::Existed(path)) => path, Ok(ExtractResult::Extracted(path)) => path, Err(err) => { @@ -366,7 +367,8 @@ fn table_menu( } } Some(TableOption::CreateVBSPatch) => { - let original_path = match extractvbs(selected_path, true, Some("vbs.original")) { + let vbs_path = selected_path.with_extension("vbs.original"); + let original_path = match extractvbs(selected_path, Some(vbs_path), true) { Ok(ExtractResult::Existed(path)) => path, Ok(ExtractResult::Extracted(path)) => path, Err(err) => { diff --git a/src/lib.rs b/src/lib.rs index cb53072..d5b0502 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,6 +2,7 @@ use crate::config::{ResolvedConfig, SetupConfigResult}; use crate::indexer::{IndexError, Progress}; use crate::patcher::patch_vbs_file; use base64::Engine; +use clap::builder::Str; use clap::{arg, Arg, ArgMatches, Command}; use colored::Colorize; use console::Emoji; @@ -340,39 +341,20 @@ fn handle_command(matches: ArgMatches) -> io::Result { println!("{}", code)?; Ok(ExitCode::SUCCESS) } - Some((CMD_SCRIPT_EXTRACT, sub_matches)) => { - let path = sub_matches - .get_one::("VPXPATH") - .map(|s| s.as_str()) - .unwrap_or_default(); - - let expanded_path = expand_path_exists(path)?; - match extractvbs(&expanded_path, false, None) { - Ok(ExtractResult::Existed(vbs_path)) => { - let warning = - format!("EXISTED {}", vbs_path.display()).truecolor(255, 125, 0); - println!("{}", warning)?; - Ok(ExitCode::SUCCESS) - } - Ok(ExtractResult::Extracted(vbs_path)) => { - println!("CREATED {}", vbs_path.display())?; - Ok(ExitCode::SUCCESS) - } - Err(e) => { - let warning = format!("Error extracting vbs: {}", e).red(); - eprintln!("{}", warning)?; - Ok(ExitCode::FAILURE) - } - } - } + Some((CMD_SCRIPT_EXTRACT, sub_matches)) => handle_extractvbs(sub_matches), Some((CMD_SCRIPT_IMPORT, sub_matches)) => { let path = sub_matches .get_one::("VPXPATH") .map(|s| s.as_str()) .unwrap_or_default(); + let vbs_path_opt = sub_matches.get_one::("VBSPATH").map(|s| { + let path = s.as_str(); + expand_path(path) + }); + let expanded_path = expand_path_exists(path)?; - match importvbs(&expanded_path, None) { + match importvbs(&expanded_path, vbs_path_opt) { Ok(vbs_path) => { println!("IMPORTED {}", vbs_path.display())?; Ok(ExitCode::SUCCESS) @@ -398,7 +380,7 @@ fn handle_command(matches: ArgMatches) -> io::Result { if vbs_path.exists() { open_or_fail(&vbs_path, config) } else { - extractvbs(&expanded_vpx_path, false, None)?; + extractvbs(&expanded_vpx_path, None, false)?; open_or_fail(&vbs_path, config) } } @@ -420,7 +402,7 @@ fn handle_command(matches: ArgMatches) -> io::Result { .unwrap_or_default(); let expanded_path = expand_path_exists(path)?; - let vbs_path = match extractvbs(&expanded_path, false, None) { + let vbs_path = match extractvbs(&expanded_path, None, false) { Ok(ExtractResult::Existed(vbs_path)) => { let warning = format!("EXISTED {}", vbs_path.display()).truecolor(255, 125, 0); @@ -538,32 +520,7 @@ fn handle_command(matches: ArgMatches) -> io::Result { } } } - Some((CMD_EXTRACT_VBS, sub_matches)) => { - let overwrite = sub_matches.get_flag("OVERWRITE"); - let paths: Vec<&str> = sub_matches - .get_many::("VPXPATH") - .unwrap_or_default() - .map(|v| v.as_str()) - .collect::>(); - for path in paths { - let expanded_path = expand_path_exists(path)?; - match extractvbs(&expanded_path, overwrite, None) { - Ok(ExtractResult::Existed(vbs_path)) => { - let warning = - format!("EXISTED {}", vbs_path.display()).truecolor(255, 125, 0); - println!("{}", warning)?; - } - Ok(ExtractResult::Extracted(vbs_path)) => { - println!("CREATED {}", vbs_path.display())?; - } - Err(e) => { - let warning = format!("Error extracting vbs: {}", e).red(); - eprintln!("{}", warning)?; - } - } - } - Ok(ExitCode::SUCCESS) - } + Some((CMD_EXTRACT_VBS, sub_matches)) => handle_extractvbs(sub_matches), Some((CMD_IMPORT_VBS, sub_matches)) => { let path: &str = sub_matches.get_one::("VPXPATH").unwrap().as_str(); let expanded_path = expand_path_exists(path)?; @@ -793,6 +750,42 @@ fn handle_command(matches: ArgMatches) -> io::Result { } } +fn handle_extractvbs(sub_matches: &ArgMatches) -> io::Result { + let overwrite = sub_matches.get_flag("OVERWRITE"); + let vpx_path = sub_matches.get_one::("VPXPATH").map(expand_path); + let vbs_path = sub_matches.get_one::("VBSPATH").map(expand_path); + let directory = sub_matches.get_one::("DIRECTORY").map(expand_path); + let expanded_vpx_path = path_exists(vpx_path.expect("should be checked by clap"))?; + if vbs_path.is_some() && directory.is_some() { + return fail("Conflicting VBSPATH and DIRECTORY options, only one can be used"); + } + + let vbs_path_opt = vbs_path.or_else(|| { + directory.map(|dir| { + let mut path = dir; + path.push(expanded_vpx_path.file_stem().unwrap()); + path.set_extension("vbs"); + path + }) + }); + + match extractvbs(&expanded_vpx_path, vbs_path_opt, overwrite) { + Ok(ExtractResult::Existed(vbs_path)) => { + let warning = format!("EXISTED {}", vbs_path.display()).truecolor(255, 125, 0); + println!("{}", warning)?; + } + Ok(ExtractResult::Extracted(vbs_path)) => { + println!("CREATED {}", vbs_path.display())?; + } + Err(e) => { + let warning = format!("Error extracting vbs: {}", e).red(); + eprintln!("{}", warning)?; + } + } + + Ok(ExitCode::SUCCESS) +} + fn build_command() -> Command { // to allow for non-static strings in clap // I had to enable the "string" module @@ -907,12 +900,7 @@ fn build_command() -> Command { ), ) .subcommand( - Command::new(CMD_SCRIPT_EXTRACT) - .about("Extract the table vpx script") - .arg( - arg!( "The path to the vpx file") - .required(true), - ), + extract_command(CMD_SCRIPT_EXTRACT), ) .subcommand( Command::new(CMD_SCRIPT_IMPORT) @@ -920,6 +908,10 @@ fn build_command() -> Command { .arg( arg!( "The path to the vpx file") .required(true), + ) + .arg( + arg!([VBSPATH] "The optional path to the vbs file to import. Defaults to the vpx file path with the extension changed to .vbs.") + .required(false), ), ) .subcommand( @@ -972,21 +964,7 @@ fn build_command() -> Command { ), ) .subcommand( - Command::new(CMD_EXTRACT_VBS) - .about("Extracts the vbs from a vpx file next to it") - .arg( - Arg::new("OVERWRITE") - .short('o') - .long("overwrite") - .num_args(0) - .default_value("false") - .help("(Default: false) Will overwrite existing .vbs files if true, will skip the table file if false."), - ) - .arg( - arg!( "The path(s) to the vpx file(s)") - .required(true) - .num_args(1..), - ), + extract_command(CMD_EXTRACT_VBS), ) .subcommand( Command::new(CMD_IMPORT_VBS) @@ -1103,6 +1081,35 @@ fn build_command() -> Command { ) } +fn extract_command(name: impl Into) -> Command { + Command::new(name) + .about("Extracts the vbs from a vpx file, by default next to it") + .arg( + Arg::new("OVERWRITE") + .short('o') + .long("overwrite") + .num_args(0) + .default_value("false") + .help("(Default: false) Will overwrite existing .vbs file if set."), + ) + .arg( + arg!( "The path to the vpx file") + .required(true), + ) + .arg( + arg!([VBSPATH] "The optional path to the vbs file to write. Defaults to the vpx file path with the extension changed to .vbs.") + .required(false), + ) + .arg( + Arg::new("DIRECTORY") + .short('d') + .long("dir") + .num_args(1) + .required(false) + .help("The directory to extract the vbs file to. Only if no VBSPATH is provided"), + ) +} + fn open_or_fail(vbs_path: &Path, config: Option<&ResolvedConfig>) -> io::Result { match open_editor(vbs_path, config) { Ok(_) => Ok(ExitCode::SUCCESS), @@ -1119,8 +1126,8 @@ fn fail_with_error(message: impl Display, err: impl Error) -> io::Result>(message: M) -> io::Result { - let warning = message.as_ref().red(); - eprintln!("{}", warning)?; + let error = "error:".red(); + eprintln!("{} {}", error, message.as_ref())?; Ok(ExitCode::FAILURE) } @@ -1276,26 +1283,34 @@ fn os_independent_file_name(file_path: String) -> Option { file_path.rsplit(['/', '\\']).next().map(|f| f.to_string()) } -fn expand_path(path: &str) -> PathBuf { - shellexpand::tilde(path).to_string().into() +fn expand_path>(path: S) -> PathBuf { + shellexpand::tilde(path.as_ref()).to_string().into() } -fn expand_path_exists(path: &str) -> io::Result { +fn expand_path_exists>(path: S) -> io::Result { // TODO expand all instead of only tilde? - let expanded_path = shellexpand::tilde(path); + let expanded_path = shellexpand::tilde(path.as_ref()); + path_exists(PathBuf::from(expanded_path.to_string())) +} + +fn path_exists>(expanded_path: P) -> io::Result { match metadata(expanded_path.as_ref()) { Ok(md) => { if !md.is_file() && !md.is_dir() && md.is_symlink() { Err(io::Error::new( io::ErrorKind::InvalidInput, - format!("{} is not a file", expanded_path), + format!("{} is not a file", expanded_path.as_ref().display()), )) } else { - Ok(PathBuf::from(expanded_path.to_string())) + Ok(expanded_path.as_ref().to_path_buf()) } } Err(msg) => { - let warning = format!("Failed to read metadata for {}: {}", expanded_path, msg); + let warning = format!( + "Failed to read metadata for {}: {}", + expanded_path.as_ref().display(), + msg + ); Err(io::Error::new(io::ErrorKind::InvalidInput, warning)) } }