From 63c0ef1e8529336b0160145b7532de56f58b6228 Mon Sep 17 00:00:00 2001 From: Ottatop Date: Sat, 2 Mar 2024 01:23:31 -0600 Subject: [PATCH] Start on a better CLI --- Cargo.lock | 213 +++++++++++++++++++++++++++++++++ Cargo.toml | 41 ++++--- build.rs | 2 +- src/cli.rs | 317 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/config.rs | 5 +- src/main.rs | 42 ++----- 6 files changed, 570 insertions(+), 50 deletions(-) create mode 100644 src/cli.rs diff --git a/Cargo.lock b/Cargo.lock index 65cc27f..376d576 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -66,6 +66,21 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "anstream" version = "0.6.11" @@ -397,6 +412,20 @@ dependencies = [ "num-traits", ] +[[package]] +name = "chrono" +version = "0.4.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets 0.52.0", +] + [[package]] name = "clap" version = "4.5.1" @@ -437,6 +466,19 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +[[package]] +name = "cliclack" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be29210ca32b96e4f67fe9a520d2eeacc078d94ff4027100dc6b7262fdfec5c4" +dependencies = [ + "console", + "indicatif", + "once_cell", + "textwrap", + "zeroize", +] + [[package]] name = "color_quant" version = "1.1.0" @@ -468,6 +510,19 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "console" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "unicode-width", + "windows-sys 0.52.0", +] + [[package]] name = "const_format" version = "0.2.32" @@ -528,6 +583,19 @@ dependencies = [ "libc", ] +[[package]] +name = "crossbeam" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-epoch", + "crossbeam-queue", + "crossbeam-utils", +] + [[package]] name = "crossbeam-channel" version = "0.5.11" @@ -556,6 +624,15 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "crossbeam-queue" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.19" @@ -577,6 +654,17 @@ dependencies = [ "powerfmt", ] +[[package]] +name = "dircpy" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29259db751c34980bfc44100875890c507f585323453b91936960ab1104272ca" +dependencies = [ + "jwalk", + "log", + "walkdir", +] + [[package]] name = "dirs" version = "5.0.1" @@ -670,6 +758,12 @@ version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + [[package]] name = "encoding_rs" version = "0.8.33" @@ -1013,6 +1107,29 @@ dependencies = [ "tokio-io-timeout", ] +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "icrate" version = "0.0.4" @@ -1056,6 +1173,19 @@ dependencies = [ "hashbrown 0.14.3", ] +[[package]] +name = "indicatif" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3" +dependencies = [ + "console", + "instant", + "number_prefix", + "portable-atomic", + "unicode-width", +] + [[package]] name = "input" version = "0.9.0" @@ -1075,6 +1205,15 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd4f5b4d1c00331c5245163aacfe5f20be75b564c7112d45893d4ae038119eb0" +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + [[package]] name = "io-lifetimes" version = "1.0.11" @@ -1147,6 +1286,16 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "jwalk" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2735847566356cd2179a2a38264839308f7079fa96e6bd5a42d740460e003c56" +dependencies = [ + "crossbeam", + "rayon", +] + [[package]] name = "khronos_api" version = "3.1.0" @@ -1451,6 +1600,12 @@ dependencies = [ "syn", ] +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + [[package]] name = "objc-sys" version = "0.3.2" @@ -1586,7 +1741,10 @@ version = "0.0.1" dependencies = [ "anyhow", "bitflags 2.4.2", + "chrono", "clap", + "cliclack", + "dircpy", "image", "nix", "pinnacle-api-defs", @@ -1667,6 +1825,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "portable-atomic" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" + [[package]] name = "powerfmt" version = "0.2.0" @@ -2050,6 +2214,12 @@ version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +[[package]] +name = "smawk" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" + [[package]] name = "smithay" version = "0.3.0" @@ -2212,6 +2382,17 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "textwrap" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" +dependencies = [ + "smawk", + "unicode-linebreak", + "unicode-width", +] + [[package]] name = "thiserror" version = "1.0.57" @@ -2565,12 +2746,24 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "unicode-linebreak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" + [[package]] name = "unicode-segmentation" version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +[[package]] +name = "unicode-width" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + [[package]] name = "unicode-xid" version = "0.2.4" @@ -3271,3 +3464,23 @@ dependencies = [ "quote", "syn", ] + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.toml b/Cargo.toml index 35042a0..6d6babf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,20 +7,21 @@ edition = "2021" repository = "https://github.com/pinnacle-comp/pinnacle/" [workspace.dependencies] +# Tokio tokio = { version = "1.36.0", features = ["macros", "rt-multi-thread"]} tokio-stream = { version = "0.1.14", features = ["net"] } - +# gRPC prost = "0.12.3" tonic = "0.11.0" tonic-reflection = "0.11.0" tonic-build = "0.11.0" - +# API definitions pinnacle-api-defs = { path = "./pinnacle-api-defs" } - +# Misc. xkbcommon = "0.7.0" xdg = "2.5.2" -################################################################################# +########################################################################yo😎########### [package] name = "pinnacle" @@ -34,38 +35,42 @@ repository.workspace = true keywords = ["wayland", "compositor", "smithay", "lua"] [dependencies] +# Smithay smithay = { git = "https://github.com/Smithay/smithay", rev = "418190e", default-features = false, features = ["desktop", "wayland_frontend"] } smithay-drm-extras = { git = "https://github.com/Smithay/smithay", rev = "418190e" } - +# Tracing tracing = "0.1.40" tracing-subscriber = { version = "0.3.18", features = ["env-filter", "registry"] } tracing-appender = "0.2.3" - +# Errors anyhow = { version = "1.0.79", features = ["backtrace"] } thiserror = "1.0.57" - +# xcursor stuff xcursor = { version = "0.3.5" } image = { version = "0.24.8", default-features = false } - +# gRPC +prost = { workspace = true } +tonic = { workspace = true } +tonic-reflection = { workspace = true } +# Tokio +tokio = { workspace = true, features = ["process", "io-util", "signal"] } +tokio-stream = { workspace = true } +# CLI +clap = { version = "4.5.1", features = ["derive"] } +cliclack = "0.1.13" +# Misc. +bitflags = "2.4.2" serde = { version = "1.0.196", features = ["derive"] } toml = "0.8.10" shellexpand = "3.1.0" -clap = { version = "4.5.1", features = ["derive"] } x11rb = { version = "0.13.0", default-features = false, features = ["composite"] } xkbcommon = { workspace = true } xdg = { workspace = true } sysinfo = "0.30.5" nix = { version = "0.27.1", features = ["user", "resource"] } - -prost = { workspace = true } -tonic = { workspace = true } -tonic-reflection = { workspace = true } - -tokio = { workspace = true, features = ["process", "io-util", "signal"] } -tokio-stream = { workspace = true } - -bitflags = "2.4.2" pinnacle-api-defs = { workspace = true } +dircpy = "0.3.16" +chrono = "0.4.34" [build-dependencies] xdg = { workspace = true } diff --git a/build.rs b/build.rs index b1c16ca..ceacd6f 100644 --- a/build.rs +++ b/build.rs @@ -5,7 +5,7 @@ fn main() { let xdg = xdg::BaseDirectories::with_prefix("pinnacle").unwrap(); let proto_dir = xdg.place_data_file("protobuf").unwrap(); - let default_config_dir = xdg.place_data_file("default_config").unwrap(); + let default_config_dir = xdg.place_data_file("default_config").unwrap().join("lua"); let remove_protos = format!("rm -r {proto_dir:?}"); let copy_protos = format!("cp -r ./api/protocol {proto_dir:?}"); diff --git a/src/cli.rs b/src/cli.rs new file mode 100644 index 0000000..aa0bbf0 --- /dev/null +++ b/src/cli.rs @@ -0,0 +1,317 @@ +use std::{ + cell::RefCell, + ffi::OsString, + marker::PhantomData, + path::{Path, PathBuf}, + rc::Rc, +}; + +use clap::{error::ErrorKind, CommandFactory, Parser, ValueHint}; +use cliclack::Validate; + +/// Valid backends that Pinnacle can run. +#[derive(clap::ValueEnum, Debug, Clone, Copy)] +pub enum Backend { + /// Run Pinnacle in a window in your graphical environment + Winit, + /// Run Pinnacle from a tty + Udev, +} + +/// The main CLI struct. +#[derive(clap::Parser, Debug)] +#[command(author, version, about, long_about = None)] +pub struct Cli { + /// Start Pinnacle with the config at this directory + #[arg(short, long, value_name("DIR"), value_hint(ValueHint::DirPath))] + pub config_dir: Option, + + /// Run Pinnacle with the specified backend + /// + /// This is usually not necessary, but if your environment variables are mucked up + /// then this can be used to choose a backend. + #[arg(short, long)] + pub backend: Option, + + /// Force Pinnacle to run with the provided backend + #[arg(long, requires = "backend")] + pub force: bool, + + /// Allow running Pinnacle as root (this is NOT recommended) + #[arg(long)] + pub allow_root: bool, + + /// Start Pinnacle without a config + /// + /// This is meant to be used for debugging. + /// Additionally, Pinnacle will not load the + /// default config if a manually spawned one + /// crashes or exits. + #[arg(long)] + pub no_config: bool, + + /// Cli subcommands + #[command(subcommand)] + pub subcommand: Option, +} + +impl Cli { + pub fn parse_and_prompt() -> Self { + let args = Cli::parse(); + + match &args.subcommand { + Some(CliSubcommand::Config(ConfigSubcommand::Gen(config_gen))) => { + generate_config(config_gen.clone()).unwrap(); + } + None => (), + } + + args + } +} + +/// Cli subcommands. +#[derive(clap::Subcommand, Debug)] +pub enum CliSubcommand { + /// Commands dealing with configuration + #[command(subcommand)] + Config(ConfigSubcommand), +} + +/// Config subcommands +#[derive(clap::Subcommand, Debug)] +pub enum ConfigSubcommand { + /// Generate a config + /// + /// If not all flags are provided, this will launch an + /// interactive prompt. + Gen(ConfigGen), +} + +/// Config arguments. +#[derive(clap::Args, Debug, Clone)] +pub struct ConfigGen { + /// Generate a config in a specific language + #[arg(short, long)] + pub lang: Option, + /// Generate a config at this directory + #[arg(short, long, value_hint(ValueHint::DirPath))] + pub dir: Option, +} + +/// Possible languages for configuration. +#[derive(clap::ValueEnum, Debug, Clone, Copy, PartialEq, Eq)] +pub enum Lang { + /// Generate a Lua config + Lua, + /// Generate a Rust config + Rust, +} + +impl std::fmt::Display for Lang { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{self:?}") + } +} + +////////////////////////////////////////////////////////////////////// + +/// Show the interactive prompt for config generation. +pub fn generate_config(args: ConfigGen) -> anyhow::Result<()> { + cliclack::intro("Config generation")?; + + let mut skip_confirmation = true; + + let lang = match args.lang { + Some(lang) => { + cliclack::log::success(format!("Select a language:\n{lang} (from -l/--lang)"))?; + lang + } + None => { + skip_confirmation = false; + cliclack::select("Select a language:") + .items(&[(Lang::Lua, "Lua", ""), (Lang::Rust, "Rust", "")]) + .interact()? + } + }; + + let dir = match args.dir { + Some(dir) => { + cliclack::log::success(format!( + "Choose a directory to place the config in:\n{} (from -d/--dir)", + dir.display() + ))?; + dir + } + None => { + skip_confirmation = false; + let mut wants_to_create_dir: Option = None; + let mut wants_to_create = false; + + let dir: String = cliclack::input("Choose a directory to place the config in:") + // Now this is a grade A bastardization of what this function is supposed to do + .validate_interactively(DirValidator::new(move |s: &String| { + let dir = shellexpand::full(s) + .map_err(|err| format!("Directory expansion failed: {err}"))?; + let mut dir = PathBuf::from(dir.to_string()); + + if dir.is_relative() { + let mut new_dir = std::env::current_dir().map_err(|err| { + format!("Failed to get the current dir to resolve relative path: {err}") + })?; + new_dir.push(dir); + dir = new_dir; + } + + match dir.try_exists() { + Ok(exists) => { + if exists { + if !dir.is_dir() { + Err(format!( + "`{}` exists but is not a directory", + dir.display() + )) + } else { + wants_to_create_dir = None; + Ok(()) + } + } else if wants_to_create_dir.as_ref() == Some(&dir) { + if wants_to_create { + Ok(()) + } else { + wants_to_create = true; + Err(format!( + "`{}` doesn't exist. Press ENTER again to create it.", + dir.display() + )) + } + } else { + wants_to_create = false; + wants_to_create_dir = Some(dir.clone()); + Err(format!( + "`{}` doesn't exist. Press ENTER twice to create it.", + dir.display() + )) + } + } + Err(err) => Err(format!( + "Failed to check if `{}` exists: {err}", + dir.display() + )), + } + })) + .interact()?; + + let dir = shellexpand::full(&dir)?; + let mut dir = PathBuf::from(dir.to_string()); + + if dir.is_relative() { + let mut new_dir = std::env::current_dir()?; + new_dir.push(dir); + dir = new_dir; + } + + dir + } + }; + + if skip_confirmation { + cliclack::log::info("Final confirmation: skipping because all flags were present")?; + } else { + let confirm_creation = cliclack::confirm(format!( + "Final confirmation: create a {} config inside `{}`?", + lang, + dir.display() + )) + .initial_value(false) + .interact()?; + + if !confirm_creation { + cliclack::outro_cancel("Config generation cancelled.")?; + anyhow::bail!("cancelled"); + } else { + cliclack::log::info("HERE")?; + } + } + + // Generate the config + + let xdg_base_dirs = xdg::BaseDirectories::with_prefix("pinnacle")?; + let mut default_config_dir = xdg_base_dirs.get_data_file("default_config"); + match lang { + Lang::Lua => { + cliclack::log::info("HERE 2")?; + default_config_dir.push("lua"); + // %F = %Y-%m-%d or year-month-day in ISO 8601 + let now = format!("{}", chrono::Local::now().format("%F.%T")); + let mut backed_up_files: Vec<(String, String)> = Vec::new(); + for file in std::fs::read_dir(&default_config_dir)? { + let file = file?; + let name = file.file_name(); + let target_file = dir.join(&name); + if let Ok(true) = target_file.try_exists() { + let backup_name = format!("{}.{now}.bak", name.to_string_lossy()); + backed_up_files.push((name.to_string_lossy().to_string(), backup_name)); + } + } + cliclack::log::info("HERE 3")?; + + if !backed_up_files.is_empty() { + cliclack::log::info("HERE 4")?; + let prompt = backed_up_files + .iter() + .map(|(src, dst)| format!("{src} -> {dst}")) + .collect::>() + .join("\n"); + cliclack::note("The following files will be renamed:", prompt)?; + let r#continue = cliclack::confirm("Continue?").interact()?; + + if !r#continue { + cliclack::outro_cancel("Config generation cancelled.")?; + anyhow::bail!("cancelled"); + } + + for (src, dst) in backed_up_files.iter() { + std::fs::rename(dir.join(src), dir.join(dst))?; + } + + cliclack::log::info("Renamed old files")?; + + dircpy::copy_dir(default_config_dir, dir)?; + + cliclack::log::info("Copied new config over")?; + } + cliclack::log::info("HERE END")?; + } + Lang::Rust => { + default_config_dir.push("rust"); + } + } + + cliclack::outro("Done!")?; + + Ok(()) +} + +struct DirValidator Result<(), E>, E>(Rc>, PhantomData<(T, E)>); + +impl DirValidator +where + F: FnMut(&T) -> Result<(), E>, +{ + fn new(validator: F) -> Self { + Self(Rc::new(RefCell::new(validator)), PhantomData) + } +} + +impl Validate for DirValidator +where + F: FnMut(&T) -> Result<(), E>, +{ + type Err = E; + + fn validate(&self, input: &T) -> Result<(), Self::Err> { + let mut validator = self.0.borrow_mut(); + validator(input) + } +} diff --git a/src/config.rs b/src/config.rs index e3b1ce3..a964f28 100644 --- a/src/config.rs +++ b/src/config.rs @@ -225,7 +225,10 @@ impl State { tracing::info!("Starting config at {}", config_dir.display()); - let default_lua_config_dir = self.xdg_base_dirs.get_data_file("default_config"); + let default_lua_config_dir = self + .xdg_base_dirs + .get_data_file("default_config") + .join("lua"); let load_default_config = |state: &mut State, reason: &str| { tracing::error!( diff --git a/src/main.rs b/src/main.rs index f665d9c..5129ba4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,6 +13,7 @@ use anyhow::Context; use clap::Parser; +use cli::Cli; use nix::unistd::Uid; use tracing::{info, level_filters::LevelFilter, warn}; use tracing_appender::rolling::Rotation; @@ -21,6 +22,7 @@ use xdg::BaseDirectories; mod api; mod backend; +mod cli; mod config; mod cursor; mod focus; @@ -34,30 +36,6 @@ mod state; mod tag; mod window; -#[derive(clap::Args, Debug)] -#[group(id = "backend", required = false, multiple = false)] -struct Backends { - #[arg(long, group = "backend")] - /// Run Pinnacle in a window in your graphical environment - winit: bool, - #[arg(long, group = "backend")] - /// Run Pinnacle from a tty - udev: bool, -} - -#[derive(clap::Parser, Debug)] -#[command(author, version, about, long_about = None)] -struct Args { - #[command(flatten)] - backend: Backends, - #[arg(long)] - /// Allow running Pinnacle as root (this is NOT recommended) - allow_root: bool, - #[arg(long, requires = "backend")] - /// Force Pinnacle to run with the provided backend - force: bool, -} - #[tokio::main] async fn main() -> anyhow::Result<()> { let xdg_state_dir = BaseDirectories::with_prefix("pinnacle")?.get_state_home(); @@ -96,7 +74,12 @@ async fn main() -> anyhow::Result<()> { .with(stdout_layer) .init(); - let args = Args::parse(); + let args = Cli::parse_and_prompt(); + + tracing::info!("{args:#?}"); + + tracing::info!("Currently in cli debugging, remove this later"); + return Ok(()); if Uid::effective().is_root() { if !args.allow_root { @@ -118,8 +101,8 @@ async fn main() -> anyhow::Result<()> { warn!("You may see LOTS of file descriptors open under Pinnacle."); } - match (args.backend.winit, args.backend.udev, args.force) { - (false, false, _) => { + match (args.backend, args.force) { + (None, _) => { if in_graphical_env { info!("Starting winit backend"); crate::backend::winit::run_winit()?; @@ -128,7 +111,7 @@ async fn main() -> anyhow::Result<()> { crate::backend::udev::run_udev()?; } } - (true, false, force) => { + (Some(cli::Backend::Winit), force) => { if !in_graphical_env { if force { warn!("Starting winit backend with no detected graphical environment"); @@ -143,7 +126,7 @@ async fn main() -> anyhow::Result<()> { crate::backend::winit::run_winit()?; } } - (false, true, force) => { + (Some(cli::Backend::Udev), force) => { if in_graphical_env { if force { warn!("Starting udev backend with a detected graphical environment"); @@ -159,7 +142,6 @@ async fn main() -> anyhow::Result<()> { crate::backend::udev::run_udev()?; } } - _ => unreachable!(), } Ok(())