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}