carch_cli/
args.rs

1use crate::commands;
2use carch_core::error::{CarchError, Result};
3use carch_core::version;
4use clap::builder::styling::{AnsiColor, Style};
5use clap::{ArgAction, Parser, Subcommand};
6use env_logger::{Builder, Target};
7use log::info;
8use std::env;
9use std::fs::{self, OpenOptions};
10use std::path::PathBuf;
11
12fn styles() -> clap::builder::Styles {
13    clap::builder::Styles::styled()
14        .header(Style::new().fg_color(Some(AnsiColor::Green.into())).bold())
15        .usage(Style::new().fg_color(Some(AnsiColor::Green.into())).bold())
16        .literal(Style::new().fg_color(Some(AnsiColor::Cyan.into())))
17        .placeholder(Style::new().fg_color(Some(AnsiColor::Cyan.into())))
18}
19
20#[derive(Parser)]
21#[command(author, about, long_about = None, styles = styles())]
22pub struct Cli {
23    #[command(subcommand)]
24    pub command:          Option<Commands>,
25    #[arg(
26        short = 'l',
27        long,
28        global = true,
29        help = "Enable logging, output is on ~/.config/carch/carch.log"
30    )]
31    pub log:              bool,
32    #[arg(short = 'v', long = "version", action = ArgAction::Version, help = "Print version information")]
33    #[arg(short = 'v', long = "version", action = ArgAction::SetTrue, help = "Print version information")]
34    version:              bool,
35    #[arg(short = 'c', long, global = true, help = "Set theme to Catppuccin Mocha")]
36    pub catppuccin_mocha: bool,
37    #[arg(short = 'd', long, global = true, help = "Set theme to Dracula")]
38    pub dracula:          bool,
39    #[arg(short = 'g', long, global = true, help = "Set theme to Gruvbox")]
40    pub gruvbox:          bool,
41    #[arg(short = 'n', long, global = true, help = "Set theme to Nord")]
42    pub nord:             bool,
43    #[arg(short = 'r', long, global = true, help = "Set theme to Rosé Pine")]
44    pub rose_pine:        bool,
45}
46
47#[derive(Subcommand)]
48pub enum Commands {
49    #[command(about = "Check for updates")]
50    CheckUpdate,
51    #[command(about = "Update the application")]
52    Update,
53    #[command(about = "Uninstall the application")]
54    Uninstall,
55}
56
57#[derive(Clone, Default)]
58pub struct Settings {
59    pub log_mode:     bool,
60    pub theme:        String,
61    pub theme_locked: bool,
62}
63
64pub fn parse_args() -> Result<()> {
65    let cli = Cli::parse();
66
67    if cli.version {
68        println!("{}", version::get_current_version());
69        return Ok(());
70    }
71
72    let mut settings = Settings { ..Default::default() };
73
74    if cli.log {
75        settings.log_mode = true;
76        let home_dir = env::var("HOME").map_err(|_| CarchError::HomeDirNotFound)?;
77        let log_dir = PathBuf::from(home_dir).join(".config/carch");
78        fs::create_dir_all(&log_dir)?;
79        let log_file = log_dir.join("carch.log");
80
81        let file = OpenOptions::new().create(true).append(true).open(log_file)?;
82
83        Builder::new()
84            .target(Target::Pipe(Box::new(file)))
85            .filter(None, log::LevelFilter::Info)
86            .init();
87        info!("Carch TUI started");
88    }
89
90    settings.theme = if cli.catppuccin_mocha {
91        "catppuccin-mocha"
92    } else if cli.dracula {
93        "dracula"
94    } else if cli.gruvbox {
95        "gruvbox"
96    } else if cli.nord {
97        "nord"
98    } else if cli.rose_pine {
99        "rose-pine"
100    } else {
101        "catppuccin-mocha"
102    }
103    .to_string();
104
105    settings.theme_locked =
106        cli.catppuccin_mocha || cli.dracula || cli.gruvbox || cli.nord || cli.rose_pine;
107
108    match cli.command {
109        Some(Commands::CheckUpdate) => {
110            info!("Checking for updates");
111            commands::check_for_updates()
112        }
113        Some(Commands::Update) => {
114            info!("Running update process");
115            commands::update()
116        }
117        Some(Commands::Uninstall) => {
118            info!("Running uninstall process");
119            commands::uninstall()
120        }
121        None => crate::run_tui(settings),
122    }
123}