Skip to content

Commit

Permalink
Add list scheme system
Browse files Browse the repository at this point in the history
  • Loading branch information
JamyGolden committed Oct 22, 2024
1 parent 5cc49d0 commit 7ecbc51
Show file tree
Hide file tree
Showing 11 changed files with 228 additions and 65 deletions.
16 changes: 15 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions tinted-builder-rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ anyhow = "1.0.80"
clap = "4.5.2"
dirs = "5.0.1"
regex = "1.11.0"
ribboncurls = "0.4.1"
serde = { version = "1.0.197", features = ["derive"] }
serde_yaml = "0.9.32"

Expand Down
150 changes: 118 additions & 32 deletions tinted-builder-rust/src/operations/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use anyhow::{anyhow, Context, Result};
use std::collections::HashMap;
use std::fs::{self, create_dir_all, read_to_string};
use std::path::{Path, PathBuf};
use tinted_builder::{Scheme, SchemeSystem, Template};
use tinted_builder::{Base16Scheme, Scheme, SchemeSystem, Template};
use utils::{get_scheme_files, parse_filename, ParsedFilename, SchemeFile, TemplateConfig};

use crate::helpers::write_to_file;
Expand Down Expand Up @@ -82,7 +82,7 @@ pub fn build(
));
}

let template_config_content = read_to_string(template_config_path)?;
let template_config_content = read_to_string(&template_config_path)?;
let template_config: HashMap<String, TemplateConfig> =
serde_yaml::from_str(&template_config_content)?;

Expand All @@ -105,42 +105,118 @@ pub fn build(

// For each template definition in the templates/config.yaml file
for (template_item_config_name, template_item_config_value) in template_config.iter() {
let template_item_scheme_files: Vec<(PathBuf, Scheme)> = all_scheme_files
.iter()
.filter_map(|(path, scheme)| {
if template_item_config_value
.supported_systems
.clone()
.unwrap_or(vec![SchemeSystem::default()])
.contains(&scheme.get_scheme_system())
{
Some((path.clone(), scheme.clone()))
} else {
None
}
})
.collect();

generate_themes_for_config(
template_item_config_name,
template_item_config_value,
&theme_template_path,
&template_item_scheme_files,
is_quiet,
)?;
let supported_systems = template_item_config_value
.supported_systems
.clone()
.unwrap_or(vec![SchemeSystem::default()]);

if supported_systems.contains(&SchemeSystem::List) {
render_list(
&theme_template_path,
(template_item_config_name, template_item_config_value),
all_scheme_files.clone(),
is_quiet,
)?;
} else {
let template_item_scheme_files: Vec<(PathBuf, Scheme)> = all_scheme_files
.iter()
.filter_map(|(path, scheme)| {
if supported_systems.contains(&scheme.get_scheme_system()) {
Some((path.clone(), scheme.clone()))
} else {
None
}
})
.collect();

generate_themes_for_config(
template_item_config_name,
template_item_config_value,
&theme_template_path,
&template_item_scheme_files,
is_quiet,
)?;
}
}

Ok(())
}

fn generate_themes_for_config(
config_name: &str,
config_value: &TemplateConfig,
theme_template_path: impl AsRef<Path>,
scheme_files: &Vec<(PathBuf, Scheme)>,
fn render_list(
template_path: impl AsRef<Path>,
(config_name, config_value): (&str, &TemplateConfig),
all_scheme_files: Vec<(PathBuf, Scheme)>,
is_quiet: bool,
) -> Result<()> {
let filename = match (
let supported_systems = config_value
.supported_systems
.clone()
.unwrap_or(vec![SchemeSystem::default()]);
let filename = get_filename(config_value, is_quiet)?;
let mustache_template_path = template_path
.as_ref()
.join(format!("templates/{}.mustache", config_name));
let template_content = read_to_string(&mustache_template_path).context(format!(
"Mustache template missing: {}",
mustache_template_path.display()
))?;
let mut data: HashMap<&str, Vec<Base16Scheme>> = HashMap::new();
data.insert(
"schemes",
all_scheme_files
.clone()
.into_iter()
.filter_map(|(_, scheme)| match scheme {
Scheme::Base16(scheme) => {
if supported_systems.contains(&SchemeSystem::Base16) {
Some(scheme)
} else {
None
}
}
Scheme::Base24(scheme) => {
if supported_systems.contains(&SchemeSystem::Base24) {
Some(scheme)
} else {
None
}
}
_ => None,
})
.collect::<Vec<Base16Scheme>>(),
);
let data = serde_yaml::to_string(&data).unwrap_or_default();
let output = ribboncurls::render(&template_content, &data, None)?;
let parsed_filename = parse_filename(&template_path, &filename)?;
let output_path = parsed_filename.get_path();

if !parsed_filename.directory.exists() {
create_dir_all(&parsed_filename.directory)?
}

write_to_file(&output_path, &output)?;

if !is_quiet {
println!(
"Successfully generated \"{}\" list with filename \"{}\"",
supported_systems
.iter()
.filter_map(|item| if *item == SchemeSystem::List {
None
} else {
Some(item.as_str().to_string())
})
.collect::<Vec<String>>()
.join(", "),
template_path.as_ref().join(filename).display(),
);
}

Ok(())
}

fn get_filename(config_value: &TemplateConfig, is_quiet: bool) -> Result<String> {
match (
&config_value.filename,
#[allow(deprecated)]
&config_value.extension,
Expand Down Expand Up @@ -182,7 +258,17 @@ fn generate_themes_for_config(
_ => Err(anyhow!(
"Config file is missing \"filepath\" or \"extension\" and \"output\" properties"
)),
}?;
}
}

fn generate_themes_for_config(
config_name: &str,
config_value: &TemplateConfig,
theme_template_path: impl AsRef<Path>,
scheme_files: &Vec<(PathBuf, Scheme)>,
is_quiet: bool,
) -> Result<()> {
let filename = get_filename(config_value, is_quiet)?;
let mustache_template_path = theme_template_path
.as_ref()
.join(format!("templates/{}.mustache", config_name));
Expand Down
1 change: 1 addition & 0 deletions tinted-builder-rust/tests/fixtures/rendered/list.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
base16-silk-light - variant: light
3 changes: 3 additions & 0 deletions tinted-builder-rust/tests/fixtures/templates/list-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
list:
filename: list.md
supported-systems: [list, base16]
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{{#schemes}}
{{system}}-{{slug}} - variant: {{variant}}
{{/schemes}}
64 changes: 57 additions & 7 deletions tinted-builder-rust/tests/operation_build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ mod test_utils;
use anyhow::{Context, Result};
use std::fs;
use std::path::PathBuf;
use test_utils::{run_command, write_to_file};
use test_utils::{copy_dir_all, run_command, write_to_file};

fn setup(system: &str, scheme_name: &str) -> Result<(String, String, String, String)> {
let config_file_path: PathBuf =
Expand Down Expand Up @@ -275,9 +275,6 @@ fn test_operation_build_base24() -> Result<()> {
base24_template_rendered_content_fixture,
) = setup(system, scheme_name)?;

if themes_path.is_dir() {
fs::remove_dir_all(&themes_path)?;
}
if template_theme_path.is_dir() {
fs::remove_dir_all(&template_theme_path)?;
}
Expand Down Expand Up @@ -355,9 +352,6 @@ fn test_operation_build_mixed() -> Result<()> {
base24_template_rendered_content_fixture,
) = setup("base24", base24_scheme_name)?;

if themes_path.is_dir() {
fs::remove_dir_all(&themes_path)?;
}
if template_theme_path.is_dir() {
fs::remove_dir_all(&template_theme_path)?;
}
Expand Down Expand Up @@ -419,6 +413,62 @@ fn test_operation_build_mixed() -> Result<()> {
Ok(())
}

#[test]
fn test_operation_build_list() -> Result<()> {
// -------
// Arrange
// -------
let name = "operation_build_list";
let template_theme_path = PathBuf::from(format!("./template-{}", name));
let template_templates_path = template_theme_path.join("templates");
let schemes_path = template_theme_path.join("schemes");
let rendered_theme_path = template_theme_path.join("list.md");

if template_theme_path.is_dir() {
fs::remove_dir_all(&template_theme_path)?;
}
fs::create_dir_all(&template_templates_path)?;
fs::copy(
"./tests/fixtures/templates/list-config.yaml",
template_theme_path.join("templates/config.yaml"),
)?;
fs::copy(
"./tests/fixtures/templates/list-template.mustache",
template_theme_path.join("templates/list.mustache"),
)?;
copy_dir_all("./tests/fixtures/schemes", &schemes_path)?;

// ---
// Act
// ---
let (stdout, stderr) = run_command(vec![
"build".to_string(),
template_theme_path.display().to_string(),
format!("--schemes-dir={}", schemes_path.display()),
])
.unwrap();
let rendered_content = fs::read_to_string(rendered_theme_path)?;
let expected_content = fs::read_to_string("./tests/fixtures/rendered/list.md")?;

// ------
// Assert
// ------
assert_eq!(rendered_content, expected_content);
assert!(
stderr.is_empty(),
"stderr does not contain the expected output"
);
assert_eq!(
stdout,
format!(
"Successfully generated \"base16\" list with filename \"{}\"\n",
template_theme_path.join("list.md").display()
)
);

Ok(())
}

/// Tests error message when invalid scheme system is provided in config.yaml
#[test]
fn test_operation_build_invalid_system() -> Result<()> {
Expand Down
26 changes: 20 additions & 6 deletions tinted-builder-rust/tests/test_utils.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
use std::fs::{self, remove_file, File};
use std::io::Write;
use std::{
error::Error,
fs::{remove_file, File},
path::Path,
process::Command,
};
use std::{error::Error, path::Path, process::Command};

use anyhow::{Context, Result};

Expand Down Expand Up @@ -44,3 +40,21 @@ pub fn write_to_file(path: impl AsRef<Path>, contents: &str) -> Result<()> {

Ok(())
}

#[allow(dead_code)]
pub fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> Result<()> {
fs::create_dir_all(&dst)?;

for entry in fs::read_dir(src)? {
let entry = entry?;
let file_type = entry.file_type()?;
let dest_path = dst.as_ref().join(entry.file_name());

if file_type.is_dir() {
copy_dir_all(entry.path(), &dest_path)?;
} else {
fs::copy(entry.path(), &dest_path)?;
}
}
Ok(())
}
21 changes: 2 additions & 19 deletions tinted-builder-rust/tests/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ mod test_utils;

use anyhow::Result;
use std::fs;
use std::path::{Path, PathBuf};
use test_utils::write_to_file;
use std::path::PathBuf;
use test_utils::{copy_dir_all, write_to_file};
use tinted_builder::{SchemeSystem, SchemeVariant};
use tinted_builder_rust::utils::get_scheme_files;

Expand Down Expand Up @@ -159,20 +159,3 @@ palette:

Ok(())
}

fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> Result<()> {
fs::create_dir_all(&dst)?;

for entry in fs::read_dir(src)? {
let entry = entry?;
let file_type = entry.file_type()?;
let dest_path = dst.as_ref().join(entry.file_name());

if file_type.is_dir() {
copy_dir_all(entry.path(), &dest_path)?;
} else {
fs::copy(entry.path(), &dest_path)?;
}
}
Ok(())
}
Loading

0 comments on commit 7ecbc51

Please sign in to comment.