diff --git a/Cargo.toml b/Cargo.toml index f34255f..31d04fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,10 @@ keywords = ["cli"] categories = ["command-line-utilities"] edition = "2021" +[[bin]] +name = "purr" +path = "src/main.rs" + [dependencies] catppuccin = { version = "2.4.0", features = ["css-colors"] } clap = { version = "4.5.4", features = ["derive", "env"] } diff --git a/src/cli.rs b/src/cli.rs index 25d8b26..0094205 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -7,7 +7,7 @@ use url::Url; use crate::models::shared::CATEGORIES; #[derive(Parser)] -#[command(version, arg_required_else_help(true))] +#[command(name = "purr", version, arg_required_else_help(true))] pub struct Cli { #[command(subcommand)] pub command: Commands, @@ -15,66 +15,85 @@ pub struct Cli { #[derive(Subcommand)] pub enum Commands { + /// Query about the ports.yml data source Query { #[command(subcommand)] command: Option, + /// Query data for a specific port #[arg(long, name = "PORT", conflicts_with = "count", requires = "get")] r#for: Option, + /// Count the number of results #[arg(short, long)] count: bool, + /// Extract a specific property each result #[arg(short, long, value_enum, default_value_t)] get: Key, }, + /// Initialize a new port from catppuccin/template Init { + /// Name of the application #[arg(long)] name: Option, + /// URL to the application #[arg(long, value_parser = valid_url)] url: Option, }, + /// Userstyles-related subcommands Userstyles { #[command(subcommand)] command: Userstyles, }, + /// Convert a theme file to a Whiskers template Whiskerify { - path: PathBuf, + input: PathBuf, #[arg(short, long)] - dry_run: bool, + output: Option, }, } #[derive(Subcommand)] pub enum Userstyles { + /// Query about the userstyles.yml data source Query { #[command(subcommand)] command: Option, + /// Query data for a specific userstyle #[arg(long, name = "USERSTYLE", conflicts_with = "count", requires = "get")] r#for: Option, + /// Count the number of results #[arg(short, long)] count: bool, + /// Extract a specific property each result #[arg(short, long, value_enum, default_value_t)] get: UserstyleKey, }, + /// Initialize a new userstyle from the template Init { + /// Name of the application #[arg(long)] name: Option, + /// Categories that represent the application #[arg(long = "category", value_delimiter = ',', value_parser = valid_category)] categories: Option>, + /// Icon for the application (from simpleicons.org) #[arg(long)] icon: Option, + /// Name of a Catppuccin color that matches the application's brand color #[arg(long)] color: Option, + /// URL to the application #[arg(long, value_parser = valid_url)] url: Option, }, @@ -82,39 +101,50 @@ pub enum Userstyles { #[derive(Subcommand)] pub enum Query { + /// Query maintained ports and who maintains them Maintained { + /// Name of the maintainer to search for #[arg(long, name = "NAME")] by: Option, #[command(flatten)] options: ExtraOptions, }, + /// Query about the Whiskers migration Whiskers { + /// Name of the repository to query #[arg(long, name = "REPOSITORY", conflicts_with_all = ["count"])] r#for: Option, + /// Whiskers state to check for #[arg(short, long, name = "STATE")] is: Option, + /// Invert matched results #[arg(short, long)] not: bool, + /// Count the number of results #[arg(short, long)] count: bool, #[arg(long, env = "GITHUB_TOKEN")] token: String, }, + /// Query star counts of the whole organization or per-repository Stars { + /// Name of the repository to query #[arg(long, name = "REPOSITORY", conflicts_with = "archived")] r#for: Option, + /// Whether to include archived repositories in the total count #[arg(long)] archived: bool, #[arg(long, env = "GITHUB_TOKEN")] token: String, }, + /// Query ports with matching fields Has { #[arg(long)] name: Option, @@ -147,6 +177,7 @@ pub enum Query { #[derive(Subcommand)] pub enum UserstylesQuery { + /// Query maintained userstyles and who maintains them Maintained { #[arg(long, name = "NAME")] by: Option, @@ -154,6 +185,7 @@ pub enum UserstylesQuery { #[command(flatten)] options: ExtraOptions, }, + /// Query ports with matching fields Has { #[arg(long)] name: Option, @@ -177,12 +209,15 @@ pub enum UserstylesQuery { #[derive(Args)] pub struct ExtraOptions { + /// Invert matched results #[arg(short, long)] pub not: bool, + /// Count the number of results #[arg(short, long)] pub count: bool, + /// Extract a specific property each result #[arg(short, long, value_enum, default_value_t)] pub get: K, } diff --git a/src/main.rs b/src/main.rs index f1b2188..fd2b199 100644 --- a/src/main.rs +++ b/src/main.rs @@ -36,7 +36,7 @@ fn main() -> Result<()> { url, } => userstyles::init(name, categories, icon, color, url)?, }, - Commands::Whiskerify { path, dry_run } => whiskerify::convert(path, dry_run)?, + Commands::Whiskerify { input, output } => whiskerify::convert(input, output)?, } Ok(()) diff --git a/src/whiskerify.rs b/src/whiskerify.rs index 9338805..28eb950 100644 --- a/src/whiskerify.rs +++ b/src/whiskerify.rs @@ -5,8 +5,8 @@ use log::warn; use fancy_regex::Regex; -pub fn convert(path: PathBuf, dry_run: bool) -> Result<()> { - let mut contents = fs::read_to_string(&path)?; +pub fn convert(input: PathBuf, output: Option) -> Result<()> { + let mut contents = fs::read_to_string(&input)?; let mut color_matches = Regex::new("rgba?\\(.*\\)") .unwrap() @@ -63,15 +63,15 @@ pub fn convert(path: PathBuf, dry_run: bool) -> Result<()> { warn!( "could not replace non-Catppuccin color '{}' at {}:{}", text.yellow(), - path.to_string_lossy(), + input.to_string_lossy(), &get_location_in_text(&text, &contents) ); } - if dry_run { - println!("{contents}"); - } else { + if let Some(path) = output { fs::write(path, contents)?; + } else { + println!("{contents}"); } Ok(())