feat: refactor code for managing args

better command line help usage
This commit is contained in:
Cyrix126 2024-06-15 13:59:14 +02:00
parent 7cd6a99215
commit 5686d9e953
8 changed files with 187 additions and 150 deletions

41
Cargo.lock generated
View file

@ -997,6 +997,46 @@ dependencies = [
"inout", "inout",
] ]
[[package]]
name = "clap"
version = "4.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_derive"
version = "4.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn 2.0.65",
]
[[package]]
name = "clap_lex"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70"
[[package]] [[package]]
name = "clipboard-win" name = "clipboard-win"
version = "5.3.1" version = "5.3.1"
@ -2150,6 +2190,7 @@ dependencies = [
"bytes", "bytes",
"cfg-if", "cfg-if",
"chrono", "chrono",
"clap",
"derive_more", "derive_more",
"dirs", "dirs",
"eframe", "eframe",

View file

@ -29,6 +29,7 @@ bundle = []
distro = [] distro = []
[dependencies] [dependencies]
clap = {version="4.5", features=["cargo", "derive"]}
anyhow = "1.0.86" anyhow = "1.0.86"
benri = "0.1.12" benri = "0.1.12"
bytes = "1.6.0" bytes = "1.6.0"

View file

@ -1,3 +1,5 @@
use crate::cli::parse_args;
use crate::cli::Cli;
use crate::components::gupax::FileWindow; use crate::components::gupax::FileWindow;
use crate::components::node::Ping; use crate::components::node::Ping;
use crate::components::node::RemoteNode; use crate::components::node::RemoteNode;
@ -27,7 +29,6 @@ use crate::inits::init_text_styles;
use crate::miscs::cmp_f64; use crate::miscs::cmp_f64;
use crate::miscs::get_exe; use crate::miscs::get_exe;
use crate::miscs::get_exe_dir; use crate::miscs::get_exe_dir;
use crate::miscs::parse_args;
use crate::utils::constants::VISUALS; use crate::utils::constants::VISUALS;
use crate::utils::macros::arc_mut; use crate::utils::macros::arc_mut;
use crate::utils::macros::lock; use crate::utils::macros::lock;
@ -170,7 +171,7 @@ impl App {
#[cold] #[cold]
#[inline(never)] #[inline(never)]
pub fn new(now: Instant) -> Self { pub fn new(now: Instant, args: Cli) -> Self {
info!("Initializing App Struct..."); info!("Initializing App Struct...");
info!("App Init | P2Pool & XMRig processes..."); info!("App Init | P2Pool & XMRig processes...");
let p2pool = arc_mut!(Process::new( let p2pool = arc_mut!(Process::new(
@ -336,7 +337,7 @@ impl App {
// It's not safe to [--reset] if any of the previous variables // It's not safe to [--reset] if any of the previous variables
// are unset (null path), so make sure we just abort if the [panic] String contains something. // are unset (null path), so make sure we just abort if the [panic] String contains something.
info!("App Init | Applying argument state..."); info!("App Init | Applying argument state...");
let mut app = parse_args(app, panic); let mut app = parse_args(app, args, panic);
use crate::disk::errors::TomlError::*; use crate::disk::errors::TomlError::*;
// Read disk state // Read disk state

133
src/cli.rs Normal file
View file

@ -0,0 +1,133 @@
use std::process::exit;
use clap::crate_authors;
use clap::crate_description;
use clap::crate_name;
use clap::crate_version;
use clap::Parser;
use clap::Subcommand;
use log::debug;
use log::info;
use log::warn;
use crate::app::App;
use crate::miscs::print_disk_file;
use crate::miscs::print_gupax_p2pool_api;
use crate::resets::reset;
use crate::resets::reset_gupax_p2pool_api;
use crate::resets::reset_nodes;
use crate::resets::reset_pools;
use crate::resets::reset_state;
#[derive(Parser)]
#[command(name = crate_name!())]
#[command(author = crate_authors!())]
#[command(version = crate_version!())]
#[command(about = crate_description!(), long_about = None)]
#[command(next_line_help = true)]
#[group(required = false, multiple = false)]
pub struct Cli {
#[command(subcommand)]
pub info: Option<GupaxxData>,
}
#[derive(Subcommand)]
pub enum GupaxxData {
#[command(about = "Print Gupaxx state")]
State,
#[command(about = "Print the manual node list")]
Nodes,
#[command(about = "Print the P2Pool payout log, payout count, and total XMR mined")]
Payouts,
#[command(about = "Reset all Gupaxxstate (your settings)")]
ResetState,
#[command(about = "Reset the manual node list in the [P2Pool] tab")]
ResetNodes,
#[command(about = "Reset the manual pool list in the [XMRig] tab")]
ResetPools,
#[command(about = "Reset the permanent P2Pool stats that appear in the [Status] tab")]
ResetPayouts,
#[command(about = "Reset all Gupaxx state (your settings)")]
ResetAll,
#[command(
about = "Disable all auto-startup settings for this instance (auto-update, auto-ping, etc)",
name = "no-startup"
)]
Nostartup,
}
// #[cold]
// #[inline(never)]
pub fn parse_args<S: Into<String>>(mut app: App, args: Cli, panic: S) -> App {
info!("Parsing CLI arguments...");
// Abort on panic
let panic = panic.into();
if !panic.is_empty() {
warn!("[Gupax error] {}", panic);
exit(1);
}
if let Some(arg) = args.info {
match arg {
GupaxxData::State => {
debug!("Printing state...");
print_disk_file(&app.state_path);
exit(0);
}
GupaxxData::Nodes => {
debug!("Printing node list...");
print_disk_file(&app.node_path);
exit(0);
}
GupaxxData::Payouts => {
debug!("Printing payouts...\n");
print_gupax_p2pool_api(&app.gupax_p2pool_api);
exit(0);
}
GupaxxData::ResetState => {
if let Ok(()) = reset_state(&app.state_path) {
println!("\nState reset ... OK");
exit(0);
} else {
eprintln!("\nState reset ... FAIL");
exit(1)
}
}
GupaxxData::ResetNodes => {
if let Ok(()) = reset_nodes(&app.node_path) {
println!("\nNode reset ... OK");
exit(0)
} else {
eprintln!("\nNode reset ... FAIL");
exit(1)
}
}
GupaxxData::ResetPools => {
if let Ok(()) = reset_pools(&app.pool_path) {
println!("\nPool reset ... OK");
exit(0)
} else {
eprintln!("\nPool reset ... FAIL");
exit(1)
}
}
GupaxxData::ResetPayouts => {
if let Ok(()) = reset_gupax_p2pool_api(&app.gupax_p2pool_api_path) {
println!("\nGupaxP2poolApi reset ... OK");
exit(0)
} else {
eprintln!("\nGupaxP2poolApi reset ... FAIL");
exit(1)
}
}
GupaxxData::ResetAll => reset(
&app.os_data_path,
&app.state_path,
&app.node_path,
&app.pool_path,
&app.gupax_p2pool_api_path,
),
GupaxxData::Nostartup => app.no_startup = true,
}
}
app
}

View file

@ -26,6 +26,7 @@ compile_error!("gupax is only compatible with 64-bit CPUs");
compile_error!("gupax is only built for windows/macos/linux"); compile_error!("gupax is only built for windows/macos/linux");
use crate::app::App; use crate::app::App;
use crate::cli::Cli;
//---------------------------------------------------------------------------------------------------- Imports //---------------------------------------------------------------------------------------------------- Imports
use crate::constants::*; use crate::constants::*;
use crate::inits::init_auto; use crate::inits::init_auto;
@ -33,12 +34,14 @@ use crate::inits::init_logger;
use crate::inits::init_options; use crate::inits::init_options;
use crate::miscs::clean_dir; use crate::miscs::clean_dir;
use crate::utils::*; use crate::utils::*;
use clap::Parser;
use egui::Vec2; use egui::Vec2;
use log::info; use log::info;
use log::warn; use log::warn;
use std::time::Instant; use std::time::Instant;
mod app; mod app;
mod cli;
mod components; mod components;
mod disk; mod disk;
mod helper; mod helper;
@ -52,6 +55,7 @@ extern crate sudo as sudo_check;
//---------------------------------------------------------------------------------------------------- Main [App] frame //---------------------------------------------------------------------------------------------------- Main [App] frame
fn main() { fn main() {
let args = Cli::parse();
let now = Instant::now(); let now = Instant::now();
// Set custom panic hook. // Set custom panic hook.
@ -59,7 +63,7 @@ fn main() {
// Init logger. // Init logger.
init_logger(now); init_logger(now);
let mut app = App::new(now); let mut app = App::new(now, args);
init_auto(&mut app); init_auto(&mut app);
// Init GUI stuff. // Init GUI stuff.

View file

@ -1,111 +1,4 @@
//---------------------------------------------------------------------------------------------------- Misc functions //---------------------------------------------------------------------------------------------------- Misc functions
#[cold]
#[inline(never)]
pub fn parse_args<S: Into<String>>(mut app: App, panic: S) -> App {
info!("Parsing CLI arguments...");
let mut args: Vec<String> = env::args().collect();
if args.len() == 1 {
info!("No args ... OK");
return app;
} else {
args.remove(0);
info!("Args ... {:?}", args);
}
// [help/version], exit early
for arg in &args {
match arg.as_str() {
"--help" => {
println!("{}", ARG_HELP);
exit(0);
}
"--version" => {
println!("Gupaxx {} [OS: {}, Commit: {}]\nThis Gupax was originally bundled with:\n - P2Pool {}\n - XMRig {}\n\n{}", GUPAX_VERSION, OS_NAME, &COMMIT[..40], P2POOL_VERSION, XMRIG_VERSION, ARG_COPYRIGHT);
exit(0);
}
"--ferris" => {
println!("{}", FERRIS_ANSI);
exit(0);
}
_ => (),
}
}
// Abort on panic
let panic = panic.into();
if !panic.is_empty() {
info!("[Gupax error] {}", panic);
exit(1);
}
// Everything else
for arg in args {
match arg.as_str() {
"--state" => {
info!("Printing state...");
print_disk_file(&app.state_path);
}
"--nodes" => {
info!("Printing node list...");
print_disk_file(&app.node_path);
}
"--payouts" => {
info!("Printing payouts...\n");
print_gupax_p2pool_api(&app.gupax_p2pool_api);
}
"--reset-state" => {
if let Ok(()) = reset_state(&app.state_path) {
println!("\nState reset ... OK");
exit(0);
} else {
eprintln!("\nState reset ... FAIL");
exit(1)
}
}
"--reset-nodes" => {
if let Ok(()) = reset_nodes(&app.node_path) {
println!("\nNode reset ... OK");
exit(0)
} else {
eprintln!("\nNode reset ... FAIL");
exit(1)
}
}
"--reset-pools" => {
if let Ok(()) = reset_pools(&app.pool_path) {
println!("\nPool reset ... OK");
exit(0)
} else {
eprintln!("\nPool reset ... FAIL");
exit(1)
}
}
"--reset-payouts" => {
if let Ok(()) = reset_gupax_p2pool_api(&app.gupax_p2pool_api_path) {
println!("\nGupaxP2poolApi reset ... OK");
exit(0)
} else {
eprintln!("\nGupaxP2poolApi reset ... FAIL");
exit(1)
}
}
"--reset-all" => reset(
&app.os_data_path,
&app.state_path,
&app.node_path,
&app.pool_path,
&app.gupax_p2pool_api_path,
),
"--no-startup" => app.no_startup = true,
_ => {
eprintln!(
"\n[Gupax error] Invalid option: [{}]\nFor help, use: [--help]",
arg
);
exit(1);
}
}
}
app
}
// Get absolute [Gupax] binary path // Get absolute [Gupax] binary path
#[cold] #[cold]
@ -167,7 +60,7 @@ pub fn clean_dir() -> Result<(), anyhow::Error> {
// Print disk files to console // Print disk files to console
#[cold] #[cold]
#[inline(never)] #[inline(never)]
fn print_disk_file(path: &PathBuf) { pub fn print_disk_file(path: &PathBuf) {
match std::fs::read_to_string(path) { match std::fs::read_to_string(path) {
Ok(string) => { Ok(string) => {
print!("{}", string); print!("{}", string);
@ -240,21 +133,14 @@ use log::error;
use log::warn; use log::warn;
use regex::Regex; use regex::Regex;
use std::path::PathBuf; use std::path::PathBuf;
use std::process::exit;
use std::sync::Arc; use std::sync::Arc;
use std::sync::Mutex; use std::sync::Mutex;
use std::{env, process::exit};
use log::info; use log::info;
//---------------------------------------------------------------------------------------------------- Use //---------------------------------------------------------------------------------------------------- Use
use crate::{ use crate::constants::*;
app::App,
constants::*,
utils::{
ferris::FERRIS_ANSI,
resets::{reset, reset_gupax_p2pool_api, reset_nodes, reset_pools, reset_state},
},
};
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
#[cold] #[cold]

View file

@ -440,28 +440,6 @@ pub const XVB_ROUND_DONOR_VIP_MIN_HR: u32 = 10000;
pub const XVB_ROUND_DONOR_WHALE_MIN_HR: u32 = 100000; pub const XVB_ROUND_DONOR_WHALE_MIN_HR: u32 = 100000;
pub const XVB_ROUND_DONOR_MEGA_MIN_HR: u32 = 1000000; pub const XVB_ROUND_DONOR_MEGA_MIN_HR: u32 = 1000000;
// CLI argument messages
pub const ARG_HELP: &str = r#"USAGE: ./gupaxx [--flag]
--help Print this help message
--version Print version and build info
--state Print Gupaxxstate
--nodes Print the manual node list
--payouts Print the P2Pool payout log, payout count, and total XMR mined
--no-startup Disable all auto-startup settings for this instance (auto-update, auto-ping, etc)
--reset-state Reset all Gupaxxstate (your settings)
--reset-nodes Reset the manual node list in the [P2Pool] tab
--reset-pools Reset the manual pool list in the [XMRig] tab
--reset-payouts Reset the permanent P2Pool stats that appear in the [Status] tab
--reset-all Reset the state, manual node list, manual pool list, and P2Pool stats
To view more detailed console debug information, start Gupaxxwith
the environment variable [RUST_LOG] set to a log level like so:
RUST_LOG=(trace|debug|info|warn|error) ./gupaxx"#;
pub const ARG_COPYRIGHT: &str = r#"Gupaxxis licensed under GPLv3.
For more information, see link below:
<https://github.com/Cyrix126/gupaxx>"#;
// Unknown Data, replace HumanNumlber::unknown() // Unknown Data, replace HumanNumlber::unknown()
pub const UNKNOWN_DATA: &str = "???"; pub const UNKNOWN_DATA: &str = "???";
// Time PPLNS WINDOW in seconds // Time PPLNS WINDOW in seconds

File diff suppressed because one or more lines are too long