1use clap::{Arg, Command};
7
8#[derive(Debug, Clone)]
10pub struct MainArgs {
11 pub debug: bool,
13 pub ssh_logging: bool,
15 pub ssh_args: Vec<String>,
17 pub profile: Option<String>,
19 pub is_non_interactive: bool,
21}
22
23pub fn main_args() -> MainArgs {
41 let matches = Command::new("csh")
42 .version("v0.5.1")
43 .author("@karsyboy")
44 .about("A Rust-based SSH client wrapper with syntax highlighting and logging capabilities")
45 .arg_required_else_help(true)
46 .propagate_version(true)
47 .arg(
48 Arg::new("debug")
49 .short('d')
50 .long("debug")
51 .help("Enable debug mode with detailed logging to ~/.csh/logs/csh.log")
52 .action(clap::ArgAction::SetTrue),
53 )
54 .arg(
55 Arg::new("log")
56 .short('l')
57 .long("log")
58 .help("Enable SSH session logging to ~/.csh/logs/ssh_sessions/")
59 .action(clap::ArgAction::SetTrue),
60 )
61 .arg(
62 Arg::new("profile")
63 .short('P')
64 .long("profile")
65 .help("Specify a configuration profile to use")
66 .num_args(1)
67 .required(false)
68 .default_value(""),
69 )
70 .arg(
71 Arg::new("ssh_args")
72 .help("SSH arguments to forward to the SSH command")
73 .num_args(1..)
74 .required(true),
75 )
76 .after_help(
77 r#"
78csh -d user@example.com # Debug mode enabled
79csh -l user@example.com # SSH logging enabled
80csh -l -P network user@firewall.example.com # Use 'network' config profile
81csh -l user@host -p 2222 -i ~/.ssh/custom_key # Both modes with SSH args
82csh user@host -G # Non-interactive command
83"#,
84 )
85 .get_matches();
86
87 let ssh_args: Vec<String> = matches.get_many::<String>("ssh_args").map(|vals| vals.cloned().collect()).unwrap_or_default();
89
90 let is_non_interactive = ssh_args.iter().any(|arg| matches!(arg.as_str(), "-G" | "-V" | "-O" | "-Q" | "-T"));
93
94 MainArgs {
95 debug: matches.get_flag("debug"),
96 ssh_logging: matches.get_flag("log"),
97 profile: matches.get_one::<String>("profile").cloned().filter(|s| !s.is_empty()),
98 ssh_args,
99 is_non_interactive,
100 }
101}