diff --git a/Cargo.lock b/Cargo.lock index 72f317d..1eb6b8d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -135,6 +135,15 @@ dependencies = [ "strsim", ] +[[package]] +name = "clap_complete" +version = "4.5.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "375f9d8255adeeedd51053574fd8d4ba875ea5fa558e86617b07f09f1680c8b6" +dependencies = [ + "clap", +] + [[package]] name = "clap_derive" version = "4.5.24" @@ -153,12 +162,24 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" +[[package]] +name = "clap_mangen" +version = "0.2.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "724842fa9b144f9b89b3f3d371a89f3455eea660361d13a554f68f8ae5d6c13a" +dependencies = [ + "clap", + "roff", +] + [[package]] name = "clock-rs" version = "0.1.214" dependencies = [ "chrono", "clap", + "clap_complete", + "clap_mangen", "crossterm", "dirs", "serde", @@ -449,6 +470,12 @@ dependencies = [ "thiserror", ] +[[package]] +name = "roff" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88f8660c1ff60292143c98d08fc6e2f654d722db50410e3f3797d40baaf9d8f3" + [[package]] name = "rustix" version = "0.38.43" diff --git a/Cargo.toml b/Cargo.toml index 0788578..fa2d48a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,12 @@ dirs = "6.0.0" serde = { version = "1.0.217", features = ["derive"] } toml = "0.8.19" +[build-dependencies] +clap = { version = "4.5.27", features = ["derive"] } +clap_complete = "4.5.32" +clap_mangen = "0.2.23" +serde = { version = "1.0.217", features = ["derive"] } + [profile.release] strip = true opt-level = 3 diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..f6a321e --- /dev/null +++ b/build.rs @@ -0,0 +1,69 @@ +#[allow(dead_code)] +#[path = "src/color.rs"] +mod color; + +#[allow(dead_code)] +#[path = "src/position.rs"] +mod position; + +#[path = "src/cli/args.rs"] +mod args; + +use std::error::Error; +use std::fs; +use std::path::PathBuf; + +use clap::{Command, CommandFactory}; +use clap_complete::generate_to; +use clap_complete::Shell::{Bash, Fish, Zsh}; +use clap_mangen::Man; + +fn generate_man_pages(name: &str, cmd: &Command) -> Result<(), Box> { + let man_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("target/man"); + let mut buffer = Vec::default(); + + Man::new(cmd.clone()).render(&mut buffer)?; + fs::create_dir_all(&man_dir)?; + fs::write(man_dir.join(name.to_owned() + ".1"), buffer)?; + + for subcommand in cmd.get_subcommands() { + let mut buffer = Vec::default(); + + Man::new(subcommand.clone()).render(&mut buffer)?; + + fs::write( + man_dir.join(name.to_owned() + "-" + subcommand.get_name() + ".1"), + buffer, + )?; + } + + Ok(()) +} + +fn generate_shell_completions(name: &str, mut cmd: Command) -> Result<(), Box> { + let comp_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("target/completions"); + + fs::create_dir_all(&comp_dir)?; + + for shell in [Bash, Fish, Zsh] { + generate_to(shell, &mut cmd, name, &comp_dir)?; + } + + Ok(()) +} + +fn generate(name: &str, mut cmd: Command) { + cmd.set_bin_name(name); + + if let Err(err) = generate_man_pages(name, &cmd) { + println!("cargo::warning=error generating man page for {name}: {err}"); + } + + if let Err(err) = generate_shell_completions(name, cmd) { + println!("cargo::warning=error generating completions for {name}: {err}"); + } +} + +fn main() { + generate("clock-rs", args::Args::command()); +} diff --git a/src/cli.rs b/src/cli/args.rs similarity index 67% rename from src/cli.rs rename to src/cli/args.rs index fb7f563..feb51c5 100644 --- a/src/cli.rs +++ b/src/cli/args.rs @@ -1,4 +1,4 @@ -use crate::{color::Color, config::Config, position::Position}; +use crate::{color::Color, position::Position}; use clap::{ builder::styling::{AnsiColor, Effects, Styles}, @@ -69,38 +69,3 @@ pub struct TimerArgs { #[clap(long, short)] pub kill: bool, } - -impl Args { - pub fn overwrite(self, config: &mut Config) { - if let Some(color) = self.color { - config.general.color = color; - } - if let Some(interval) = self.interval { - config.general.interval = interval; - } - if let Some(x_pos) = self.x_pos { - config.position.x = x_pos; - } - if let Some(y_pos) = self.y_pos { - config.position.y = y_pos; - } - if self.blink { - config.general.blink = true; - } - if self.bold { - config.general.bold = true; - } - if let Some(fmt) = self.fmt { - config.date.fmt = fmt; - } - if self.use_12h { - config.date.use_12h = true; - } - if self.utc { - config.date.utc = true; - } - if self.hide_seconds { - config.date.hide_seconds = true; - } - } -} diff --git a/src/cli/mod.rs b/src/cli/mod.rs new file mode 100644 index 0000000..22b6073 --- /dev/null +++ b/src/cli/mod.rs @@ -0,0 +1,38 @@ +pub mod args; + +use crate::config::Config; + +impl args::Args { + pub fn overwrite(self, config: &mut Config) { + if let Some(color) = self.color { + config.general.color = color; + } + if let Some(interval) = self.interval { + config.general.interval = interval; + } + if let Some(x_pos) = self.x_pos { + config.position.x = x_pos; + } + if let Some(y_pos) = self.y_pos { + config.position.y = y_pos; + } + if self.blink { + config.general.blink = true; + } + if self.bold { + config.general.bold = true; + } + if let Some(fmt) = self.fmt { + config.date.fmt = fmt; + } + if self.use_12h { + config.date.use_12h = true; + } + if self.utc { + config.date.utc = true; + } + if self.hide_seconds { + config.date.hide_seconds = true; + } + } +} diff --git a/src/state.rs b/src/state.rs index 743c84d..0f9f6a1 100644 --- a/src/state.rs +++ b/src/state.rs @@ -12,7 +12,7 @@ use crossterm::{ }; use crate::{ - cli::{Args, Mode}, + cli::args::{Args, Mode}, clock::{counter::Counter, counter::CounterType, mode::ClockMode, time_zone::TimeZone, Clock}, config::Config, error::Error,