From 2f7912ce6ffce1540b5083ff1d2bd25c49f6d376 Mon Sep 17 00:00:00 2001 From: Jamy Golden Date: Sun, 13 Oct 2024 11:44:05 +0200 Subject: [PATCH] Remove outfile option for generate-scheme subcommand for simplicity --- CHANGELOG.md | 8 + README.md | 2 +- src/cli.rs | 13 +- src/main.rs | 5 +- src/operations/generate_scheme.rs | 2 +- tests/cli_generatescheme_subcommand_tests.rs | 196 ++++++++++++++++++ .../assets/article-featured-image.webp | Bin 0 -> 6642 bytes tests/utils.rs | 2 + 8 files changed, 211 insertions(+), 17 deletions(-) create mode 100644 tests/cli_generatescheme_subcommand_tests.rs create mode 100644 tests/fixtures/assets/article-featured-image.webp diff --git a/CHANGELOG.md b/CHANGELOG.md index 722b378..542df10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## Unreleased + +### Changed + +- Change `tinty generate-scheme` API by removing the `OUTFILE` option + and only printing to stdout or saving to the tinty data directory with + the `--save` flag + ## [0.22.0] - 2024-10-09 ### Added diff --git a/README.md b/README.md index c931e3b..189e1fe 100644 --- a/README.md +++ b/README.md @@ -169,7 +169,7 @@ The following is a table of the available subcommands for the CLI tool (Tinty), | `info` | Provides information about themes. | `[-]`: Optional argument `--custom-schemes` to provide information on any custom schemes | `tinty info base16-mocha` | | `build` | Builds the provided base16 or base24 template using [tinted-builder-rust]. | ``: Path to the base16 or base24 template directory. | `tinty build path/to/tinted-tmux` | | `generate-completion` | Generates a shell completion file to source in your shell startup file (`*rc`). | ``: Name of the shell to generate a completion script for. Supports `bash`, `elvish`, `fish`, `powershell`, `zsh` | `tinty generate-completion bash` | -| `generate-scheme` | Generates a yaml scheme file with colors inferred from provided image. | ``: Path to image. Either `` (`-` value to print to stdout) or `--save` to save for use within `tinty` | `tinty generate-completion bash` | +| `generate-scheme` | Generates a yaml scheme file with colors inferred from provided image. | ``: Path to image. Prints to stdout unless `--save` is provided which saves to `~/.local/share/tinted-theming/tinty/custom-schemes` for use within Tinty | `tinty generate-scheme --system=base16 --save /path/to/image.png` | | `install` | Installs requirements for the configuration. (Use `tinty sync`) | - | `tinty install` | | `update` | Updates the templates and schemes. (Use `tinty sync`) | - | `tinty update` | diff --git a/src/cli.rs b/src/cli.rs index 65289d7..20857a3 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,6 +1,6 @@ use clap::{ builder::{styling, PossibleValue}, - Arg, ArgAction, ArgGroup, ArgMatches, Command, ValueHint, + Arg, ArgAction, ArgMatches, Command, ValueHint, }; use clap_complete::Shell; @@ -79,13 +79,7 @@ pub fn build_cli() -> Command { Arg::new("image_path") .help("Which image file to use.") .required(true) - .value_name("INFILE") - .value_hint(ValueHint::FilePath) - ) - .arg( - Arg::new("outfile") - .help("Output path to save the .yaml file to. Use '-' for stdout") - .value_name("OUTFILE") + .value_name("IMAGE_FILE") .value_hint(ValueHint::FilePath) ) .arg( @@ -132,9 +126,6 @@ pub fn build_cli() -> Command { ]) .value_hint(ValueHint::Other) ) - .group(ArgGroup::new("required_flags") - .args(["outfile", "save"]) - .required(true)), ) .subcommand( Command::new("info").about(format!("Shows scheme colors for all schemes matching - (Eg: {} info base16-mocha)", REPO_NAME)) diff --git a/src/main.rs b/src/main.rs index 851ecba..11ef126 100644 --- a/src/main.rs +++ b/src/main.rs @@ -213,10 +213,7 @@ fn main() -> Result<()> { Some(custom_scheme_path.join(format!("{}/{}", system, filename))) } else { - match sub_matches.get_one::("outfile").map(|s| s.as_str()) { - Some("-") | None => None, - Some(value) => Some(PathBuf::from(value)), - } + None } }; diff --git a/src/operations/generate_scheme.rs b/src/operations/generate_scheme.rs index 709bbbf..ce1af40 100644 --- a/src/operations/generate_scheme.rs +++ b/src/operations/generate_scheme.rs @@ -35,7 +35,7 @@ pub(crate) fn generate_scheme( println!("Scheme created: {}", path.display()); } - None => println!("scheme:\n{}", scheme), + None => print!("{scheme}"), // Scheme .display() already ends with a newline }; Ok(()) diff --git a/tests/cli_generatescheme_subcommand_tests.rs b/tests/cli_generatescheme_subcommand_tests.rs new file mode 100644 index 0000000..8ad72c6 --- /dev/null +++ b/tests/cli_generatescheme_subcommand_tests.rs @@ -0,0 +1,196 @@ +mod utils; + +use std::fs; + +use crate::utils::setup; +use anyhow::Result; +use utils::CUSTOM_SCHEMES_DIR_NAME; + +#[test] +fn test_cli_generatescheme_subcommand_custom_properties() -> Result<()> { + // --- + // Act + // --- + let system = "base24"; + let author = "Some Author (https://github.com/tinted-theming)"; + let name = "Some custom name"; + let slug = "some-custom-slug"; + let variant = "light"; + let (_, _, command_vec, cleanup) = setup( + "test_cli_generatescheme_subcommand_custom_properties", + format!( + "generate-scheme --author \"{}\" --name \"{}\" --slug {} --system {} --variant {} ./tests/fixtures/assets/article-featured-image.webp", + author, + name, + slug, + system, + variant, + ) + .as_str(), + )?; + let expected_output = format!( + r#"author: "{author}" +name: "{name}" +slug: "{slug}" +system: "{system}" +variant: "{variant}" +palette: + base00: "f7f7f7" + base01: "d5d9d6" + base02: "b3bbb6" + base03: "919d95" + base04: "707f75" + base05: "4e6154" + base06: "2c4334" + base07: "0b2614" + base08: "dd5319" + base09: "e29c0d" + base0A: "e29c0d" + base0B: "079f31" + base0C: "00fffe" + base0D: "055de1" + base0E: "66495d" + base0F: "97421d" + base10: "ab674a" + base11: "ab8943" + base12: "ab8943" + base13: "2d7842" + base14: "41bdbd" + base15: "3d68a8" + base16: "5e505a" + base17: "774e3c" +"# + ); + + // --- + // Act + // --- + let (stdout, stderr) = utils::run_command(command_vec).unwrap(); + + // ------ + // Assert + // ------ + assert_eq!(stdout, expected_output); + assert!( + stderr.is_empty(), + "stdout does not contain the expected output" + ); + + cleanup()?; + Ok(()) +} + +#[test] +fn test_cli_generatescheme_subcommand_with_image() -> Result<()> { + // --- + // Act + // --- + let (_, _, command_vec, cleanup) = setup( + "test_cli_generatescheme_subcommand_with_image", + "generate-scheme --system base16 ./tests/fixtures/assets/article-featured-image.webp", + )?; + let expected_output = r#"author: "Tinty" +name: "Tinty Generated" +slug: "tinty-generated" +system: "base16" +variant: "dark" +palette: + base00: "0e2d19" + base01: "2f4938" + base02: "506658" + base03: "718378" + base04: "93a097" + base05: "b4bdb7" + base06: "d5dad7" + base07: "f7f7f7" + base08: "dd5319" + base09: "e29c0d" + base0A: "e29c0d" + base0B: "079f31" + base0C: "00fffe" + base0D: "055de1" + base0E: "66495d" + base0F: "97421d" +"#; + + // --- + // Act + // --- + let (stdout, stderr) = utils::run_command(command_vec).unwrap(); + + // ------ + // Assert + // ------ + assert_eq!(stdout, expected_output); + assert!( + stderr.is_empty(), + "stdout does not contain the expected output" + ); + + cleanup()?; + Ok(()) +} + +#[test] +fn test_cli_generatescheme_subcommand_with_save() -> Result<()> { + // --- + // Act + // --- + let scheme_system = "base16"; + let scheme_slug = "test-scheme-slug"; + let (_, data_path, command_vec, cleanup) = setup( + "test_cli_generatescheme_subcommand_with_save", + format!("generate-scheme --slug {scheme_slug} --system {scheme_system} --save ./tests/fixtures/assets/article-featured-image.webp").as_str(), + )?; + let out_scheme_path = data_path.join(format!( + "{CUSTOM_SCHEMES_DIR_NAME}/{scheme_system}/{scheme_slug}.yaml" + )); + let expected_output = format!( + r#"system: {scheme_system} +name: Tinty Generated +slug: {scheme_slug} +author: Tinty +description: null +variant: dark +palette: + base00: 0e2d19 + base01: 2f4938 + base02: '506658' + base03: '718378' + base04: 93a097 + base05: b4bdb7 + base06: d5dad7 + base07: f7f7f7 + base08: dd5319 + base09: e29c0d + base0A: e29c0d + base0B: 079f31 + base0C: 00fffe + base0D: 055de1 + base0E: 66495d + base0F: 97421d +"# + ); + + // --- + // Act + // --- + let (stdout, stderr) = utils::run_command(command_vec).unwrap(); + let actual_output = fs::read_to_string(&out_scheme_path)?; + + // ------ + // Assert + // ------ + assert_eq!(actual_output, expected_output); + assert_eq!( + stdout, + format!("Scheme created: {}\n", out_scheme_path.display()) + ); + assert!( + stderr.is_empty(), + "stdout does not contain the expected output" + ); + + cleanup()?; + Ok(()) +} diff --git a/tests/fixtures/assets/article-featured-image.webp b/tests/fixtures/assets/article-featured-image.webp new file mode 100644 index 0000000000000000000000000000000000000000..e3f4d9e4598a5968bbe8ee7f40579b061eab4be0 GIT binary patch literal 6642 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 literal 0 HcmV?d00001 diff --git a/tests/utils.rs b/tests/utils.rs index 776f5bd..50e108c 100644 --- a/tests/utils.rs +++ b/tests/utils.rs @@ -17,6 +17,8 @@ pub const CURRENT_SCHEME_FILE_NAME: &str = "current_scheme"; pub const REPO_DIR: &str = "repos"; #[allow(dead_code)] pub const SCHEMES_REPO_NAME: &str = "schemes"; +#[allow(dead_code)] +pub const CUSTOM_SCHEMES_DIR_NAME: &str = "custom-schemes"; pub fn run_command(command_vec: Vec) -> Result<(String, String), Box> { let output = Command::new(&command_vec[0])