mirror of
https://github.com/velopack/velopack.git
synced 2025-10-25 15:19:22 +00:00
Fix issue with = in command line parsing
This commit is contained in:
@@ -54,7 +54,10 @@ pub fn header_offset_and_length() -> (i64, i64) {
|
||||
|
||||
fn main() -> Result<()> {
|
||||
windows::mitigate::pre_main_sideload_mitigation();
|
||||
shared::cli_host::clap_run_main("Setup", main_inner)
|
||||
}
|
||||
|
||||
fn main_inner() -> Result<()> {
|
||||
#[rustfmt::skip]
|
||||
let mut arg_config = Command::new("Setup")
|
||||
.about(format!("Velopack Setup ({}) installs applications.\nhttps://github.com/velopack/velopack", env!("NGBV_VERSION")))
|
||||
@@ -69,38 +72,19 @@ fn main() -> Result<()> {
|
||||
.arg(arg!(-d --debug <FILE> "Debug mode, install from a nupkg file").required(false).value_parser(value_parser!(PathBuf)));
|
||||
}
|
||||
|
||||
if let Err(e) = run_inner(arg_config) {
|
||||
let error_string = format!("An error has occurred: {:?}", e);
|
||||
if let Ok(downcast) = e.downcast::<clap::Error>() {
|
||||
let output_string = downcast.to_string();
|
||||
match downcast.kind() {
|
||||
clap::error::ErrorKind::DisplayHelp => { println!("{output_string}"); return Ok(()); }
|
||||
clap::error::ErrorKind::DisplayHelpOnMissingArgumentOrSubcommand => { println!("{output_string}"); return Ok(()); }
|
||||
clap::error::ErrorKind::DisplayVersion => { println!("{output_string}"); return Ok(()); }
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
error!("{}", error_string);
|
||||
dialogs::show_error("Setup Error", None, &error_string);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run_inner(arg_config: Command) -> Result<()>
|
||||
{
|
||||
let matches = arg_config.try_get_matches()?;
|
||||
|
||||
let silent = matches.get_flag("silent");
|
||||
dialogs::set_silent(silent);
|
||||
|
||||
let verbose = matches.get_flag("verbose");
|
||||
let debug = matches.get_one::<PathBuf>("debug");
|
||||
let logfile = matches.get_one::<PathBuf>("log");
|
||||
logging::setup_logging("setup", logfile, true, verbose)?;
|
||||
|
||||
let debug = matches.get_one::<PathBuf>("debug");
|
||||
let install_to = matches.get_one::<PathBuf>("installto");
|
||||
let exe_args: Option<Vec<&str>> = matches.get_many::<String>("EXE_ARGS").map(|v| v.map(|f| f.as_str()).collect());
|
||||
|
||||
dialogs::set_silent(silent);
|
||||
logging::setup_logging("setup", logfile, true, verbose)?;
|
||||
|
||||
info!("Starting Velopack Setup ({})", env!("NGBV_VERSION"));
|
||||
info!(" Location: {:?}", env::current_exe()?);
|
||||
info!(" Silent: {}", silent);
|
||||
@@ -152,4 +136,3 @@ fn run_inner(arg_config: Command) -> Result<()>
|
||||
|
||||
bail!("Could not find embedded zip file. Please contact the application author.");
|
||||
}
|
||||
|
||||
|
||||
35
src/bins/src/shared/cli_host.rs
Normal file
35
src/bins/src/shared/cli_host.rs
Normal file
@@ -0,0 +1,35 @@
|
||||
pub fn clap_run_main(program_name: &str, main_inner: fn() -> anyhow::Result<()>) -> anyhow::Result<()> {
|
||||
if let Err(e) = main_inner() {
|
||||
let error_string = format!("An error has occurred: {:?}", e);
|
||||
match e.downcast::<clap::Error>() {
|
||||
Ok(downcast) => {
|
||||
let output_string = downcast.to_string();
|
||||
match downcast.kind() {
|
||||
clap::error::ErrorKind::DisplayHelp => {
|
||||
println!("{output_string}");
|
||||
return Ok(());
|
||||
}
|
||||
clap::error::ErrorKind::DisplayHelpOnMissingArgumentOrSubcommand => {
|
||||
println!("{output_string}");
|
||||
return Ok(());
|
||||
}
|
||||
clap::error::ErrorKind::DisplayVersion => {
|
||||
println!("{output_string}");
|
||||
return Ok(());
|
||||
}
|
||||
_ => {
|
||||
error!("{}", error_string);
|
||||
crate::dialogs::show_error(format!("{program_name} Error").as_str(), None, &error_string);
|
||||
return Err(anyhow::Error::from(downcast));
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
error!("{}", error_string);
|
||||
crate::dialogs::show_error(format!("{program_name} Error").as_str(), None, &error_string);
|
||||
return Err(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
pub mod runtime_arch;
|
||||
pub mod cli_host;
|
||||
|
||||
mod dialogs_const;
|
||||
mod dialogs_common;
|
||||
|
||||
@@ -45,8 +45,10 @@ fn main() -> ExitCode {
|
||||
match Process::new(update_exe).args(args).creation_flags(CREATE_NO_WINDOW).spawn() {
|
||||
Ok(res) => {
|
||||
let _ = unsafe { AllowSetForegroundWindow(res.id()) };
|
||||
info!("Successfully started Update.exe");
|
||||
ExitCode::SUCCESS
|
||||
}, Err(e) => {
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Stub failed to start Update.exe: {}", e);
|
||||
ExitCode::FAILURE
|
||||
}
|
||||
|
||||
@@ -7,8 +7,7 @@ extern crate log;
|
||||
use anyhow::{anyhow, bail, Result};
|
||||
use clap::{arg, value_parser, ArgMatches, Command};
|
||||
use std::{env, path::PathBuf};
|
||||
use velopack::locator;
|
||||
use velopack::locator::{auto_locate_app_manifest, LocationContext};
|
||||
use velopack::locator::{self, auto_locate_app_manifest, LocationContext};
|
||||
use velopack_bins::*;
|
||||
|
||||
#[rustfmt::skip]
|
||||
@@ -39,9 +38,6 @@ fn root_command() -> Command {
|
||||
.arg(arg!(--patch <FILE> "The Zstd patch to apply to the old file").required(true).value_parser(value_parser!(PathBuf)))
|
||||
.arg(arg!(--output <FILE> "The file to create with the patch applied").required(true).value_parser(value_parser!(PathBuf)))
|
||||
)
|
||||
.subcommand(Command::new("get-version")
|
||||
.about("Prints the current version of the application")
|
||||
)
|
||||
.arg(arg!(--verbose "Print debug messages to console / log").global(true))
|
||||
.arg(arg!(-s --silent "Don't show any prompts / dialogs").global(true))
|
||||
.arg(arg!(-l --log <PATH> "Override the default log file location").global(true).value_parser(value_parser!(PathBuf)))
|
||||
@@ -68,16 +64,18 @@ fn try_parse_command_line_matches(input_args: Vec<String>) -> Result<ArgMatches>
|
||||
// Also, replace `--processStartAndWait` with `--processStart --wait`
|
||||
let mut args = Vec::new();
|
||||
let mut preserve = false;
|
||||
let mut first = true;
|
||||
for arg in input_args {
|
||||
if preserve {
|
||||
if preserve || first {
|
||||
args.push(arg);
|
||||
first = false;
|
||||
} else if arg == "--" {
|
||||
args.push("--".to_string());
|
||||
preserve = true;
|
||||
} else if arg.eq_ignore_ascii_case("--processStartAndWait") {
|
||||
args.push("--processStart".to_string());
|
||||
args.push("--wait".to_string());
|
||||
} else if arg.starts_with("--processStartAndWait=") {
|
||||
} else if arg.to_ascii_lowercase().starts_with("--processstartandwait=") {
|
||||
let mut split_arg = arg.splitn(2, '=');
|
||||
split_arg.next(); // Skip the `--processStartAndWait` part
|
||||
args.push("--processStart".to_string());
|
||||
@@ -85,10 +83,13 @@ fn try_parse_command_line_matches(input_args: Vec<String>) -> Result<ArgMatches>
|
||||
if let Some(rest) = split_arg.next() {
|
||||
args.push(rest.to_string());
|
||||
}
|
||||
} else if arg.contains('=') {
|
||||
} else if arg.to_ascii_lowercase().starts_with("--processtart=") {
|
||||
let mut split_arg = arg.splitn(2, '=');
|
||||
args.push(split_arg.next().unwrap().to_string());
|
||||
args.push(split_arg.next().unwrap().to_string());
|
||||
split_arg.next(); // Skip the `--processStart` part
|
||||
args.push("--processStart".to_string());
|
||||
if let Some(rest) = split_arg.next() {
|
||||
args.push(rest.to_string());
|
||||
}
|
||||
} else {
|
||||
args.push(arg);
|
||||
}
|
||||
@@ -114,6 +115,10 @@ fn get_op_wait(matches: &ArgMatches) -> shared::OperationWait {
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
shared::cli_host::clap_run_main("Update", main_inner)
|
||||
}
|
||||
|
||||
fn main_inner() -> Result<()> {
|
||||
#[cfg(windows)]
|
||||
windows::mitigate::pre_main_sideload_mitigation();
|
||||
|
||||
@@ -122,13 +127,11 @@ fn main() -> Result<()> {
|
||||
#[cfg(unix)]
|
||||
let matches = root_command().try_get_matches()?;
|
||||
|
||||
let (subcommand, subcommand_matches) = matches.subcommand().ok_or_else(|| anyhow!("No subcommand was used. Try `--help` for more information."))?;
|
||||
let silent = get_flag_or_false(&matches, "silent");
|
||||
dialogs::set_silent(silent);
|
||||
|
||||
let verbose = get_flag_or_false(&matches, "verbose");
|
||||
let silent = get_flag_or_false(&matches, "silent");
|
||||
let log_file = matches.get_one("log");
|
||||
|
||||
dialogs::set_silent(silent);
|
||||
let desired_log_file = log_file.cloned().unwrap_or(locator::default_log_location(LocationContext::IAmUpdateExe));
|
||||
logging::setup_logging("update", Some(&desired_log_file), true, verbose)?;
|
||||
|
||||
@@ -145,6 +148,9 @@ fn main() -> Result<()> {
|
||||
info!(" Silent: {}", silent);
|
||||
info!(" Log File: {:?}", log_file);
|
||||
|
||||
let (subcommand, subcommand_matches) =
|
||||
matches.subcommand().ok_or_else(|| anyhow!("No known subcommand was used. Try `--help` for more information."))?;
|
||||
|
||||
let result = match subcommand {
|
||||
#[cfg(target_os = "windows")]
|
||||
"uninstall" => uninstall(subcommand_matches).map_err(|e| anyhow!("Uninstall error: {}", e)),
|
||||
@@ -163,16 +169,20 @@ fn main() -> Result<()> {
|
||||
}
|
||||
|
||||
fn patch(matches: &ArgMatches) -> Result<()> {
|
||||
let old_file = matches.get_one::<PathBuf>("old").unwrap();
|
||||
let patch_file = matches.get_one::<PathBuf>("patch").unwrap();
|
||||
let output_file = matches.get_one::<PathBuf>("output").unwrap();
|
||||
let old_file = matches.get_one::<PathBuf>("old");
|
||||
let patch_file = matches.get_one::<PathBuf>("patch");
|
||||
let output_file = matches.get_one::<PathBuf>("output");
|
||||
|
||||
info!("Command: Patch");
|
||||
info!(" Old File: {:?}", old_file);
|
||||
info!(" Patch File: {:?}", patch_file);
|
||||
info!(" Output File: {:?}", output_file);
|
||||
|
||||
velopack::delta::zstd_patch_single(old_file, patch_file, output_file)?;
|
||||
if old_file.is_none() || patch_file.is_none() || output_file.is_none() {
|
||||
bail!("Missing required arguments. Please provide --old, --patch, and --output.");
|
||||
}
|
||||
|
||||
velopack::delta::zstd_patch_single(old_file.unwrap(), patch_file.unwrap(), output_file.unwrap())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user