diff --git a/Cargo.lock b/Cargo.lock index b40ba0a..e4f894a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2255,7 +2255,7 @@ dependencies = [ "serde_yaml", "time", "tokio", - "toml", + "toml 0.7.8", "tracing", "url", "winapi", @@ -3467,6 +3467,23 @@ dependencies = [ "smallvec", ] +[[package]] +name = "rust_scaffolding_utils" +version = "0.1.0" +dependencies = [ + "anyhow", + "build-fs-tree", + "clap 4.5.4", + "colored", + "dialoguer", + "file_tree_utils", + "ignore", + "regex", + "serde", + "thiserror", + "toml 0.8.13", +] + [[package]] name = "rustc-demangle" version = "0.1.24" @@ -4444,6 +4461,18 @@ dependencies = [ "toml_edit 0.19.15", ] +[[package]] +name = "toml" +version = "0.8.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4e43f8cc456c9704c851ae29c67e17ef65d2c30017c17a9765b89c382dc8bba" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.22.13", +] + [[package]] name = "toml_datetime" version = "0.6.6" @@ -4463,7 +4492,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "winnow", + "winnow 0.5.40", ] [[package]] @@ -4474,7 +4503,20 @@ checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ "indexmap 2.2.6", "toml_datetime", - "winnow", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.22.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c127785850e8c20836d49732ae6abfa47616e60bf9d9f57c43c250361a9db96c" +dependencies = [ + "indexmap 2.2.6", + "serde", + "serde_spanned", + "toml_datetime", + "winnow 0.6.8", ] [[package]] @@ -5306,6 +5348,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3c52e9c97a68071b23e836c9380edae937f17b9c4667bd021973efc689f618d" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.52.0" diff --git a/crates/rust_scaffolding_utils/Cargo.toml b/crates/rust_scaffolding_utils/Cargo.toml new file mode 100644 index 0000000..b5d44b2 --- /dev/null +++ b/crates/rust_scaffolding_utils/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "rust_scaffolding_utils" +version = "0.1.0" +edition = "2021" + +[lib] +name = "rust_scaffolding_utils" +path = "src/lib.rs" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = "1.0.81" +ignore = "0.4" +toml = "0.8" +serde = "1" +clap = {version = "4.5.4", features = ["derive"]} +regex = "1.10.4" +thiserror = "1.0.58" +file_tree_utils = { path = "../file_tree_utils" } +build-fs-tree = "0.4" +dialoguer = "0.11" +colored = "2.1.0" diff --git a/crates/rust_scaffolding_utils/src/lib.rs b/crates/rust_scaffolding_utils/src/lib.rs new file mode 100644 index 0000000..072cdfa --- /dev/null +++ b/crates/rust_scaffolding_utils/src/lib.rs @@ -0,0 +1,91 @@ +use std::path::PathBuf; + +use dialoguer::{theme::ColorfulTheme, Select}; +use file_tree_utils::{ + file_content, file_exists, find_files_by_name, map_file, FileTree, FileTreeError, +}; +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum RustScaffoldingUtilsError { + #[error(transparent)] + FileTreeError(#[from] FileTreeError), + + #[error(transparent)] + DialoguerError(#[from] dialoguer::Error), + + #[error("TOML deserialization error: {0}")] + TomlDeError(#[from] toml::de::Error), + + #[error("TOML serialization error: {0}")] + TomlSerError(#[from] toml::ser::Error), + + #[error("Malformed Cargo.toml {0}: {1}")] + MalformedCargoTomlError(PathBuf, String), +} + +pub fn add_member_to_workspace( + cargo_toml: &(PathBuf, String), + new_workspace_member: String, +) -> Result { + let mut workspace_cargo_toml: toml::Value = toml::from_str(cargo_toml.1.as_str())?; + + let workspace_table = workspace_cargo_toml + .as_table_mut() + .ok_or(RustScaffoldingUtilsError::MalformedCargoTomlError( + cargo_toml.0.clone(), + String::from("file does not conform to toml"), + ))? + .get_mut("workspace") + .ok_or(RustScaffoldingUtilsError::MalformedCargoTomlError( + cargo_toml.0.clone(), + String::from("no workspace table found in workspace root"), + ))? + .as_table_mut() + .ok_or(RustScaffoldingUtilsError::MalformedCargoTomlError( + cargo_toml.0.clone(), + String::from("workspace key is not a table"), + ))?; + + let members = workspace_table + .get_mut("members") + .ok_or(RustScaffoldingUtilsError::MalformedCargoTomlError( + cargo_toml.0.clone(), + String::from("should have a members field in the workspace table"), + ))? + .as_array_mut() + .ok_or(RustScaffoldingUtilsError::MalformedCargoTomlError( + cargo_toml.0.clone(), + String::from("the members field in the workspace table should be an array"), + ))?; + + members.push(toml::Value::String(new_workspace_member)); + + let cargo_toml_str = toml::to_string(&workspace_cargo_toml)?; + + Ok(cargo_toml_str) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn add_member_to_workspace_test() { + let cargo_toml = r#"[workspace] +members = ["tauri-plugin-holochain", "crates/*"] +resolver = "2" +"#; + assert_eq!( + add_member_to_workspace( + &(PathBuf::from("/"), cargo_toml.to_string()), + String::from("src-tauri") + ) + .unwrap(), + r#"[workspace] +members = ["tauri-plugin-holochain", "crates/*", "src-tauri"] +resolver = "2" +"# + ); + } +} diff --git a/crates/templates_scaffolding_utils/src/lib.rs b/crates/templates_scaffolding_utils/src/lib.rs index 5fd16b6..ab337d5 100644 --- a/crates/templates_scaffolding_utils/src/lib.rs +++ b/crates/templates_scaffolding_utils/src/lib.rs @@ -242,3 +242,26 @@ pub fn register_case_helpers<'a>(mut h: Handlebars<'a>) -> Handlebars<'a> { h } + +#[cfg(test)] +mod tests { + use handlebars::{no_escape, Context, Handlebars}; + use serde_json::json; + + #[test] + fn test_render_with_quotes_quotes() { + let mut h = Handlebars::new(); + h.register_escape_fn(no_escape); + + let code = r#""With quotes""#; + let value = json!({"previous_file_content": code}); + println!("value, {value:?}"); + let context = Context::from(value); + let template = r#"{{previous_file_content}}"#; + + assert_eq!( + h.render_template_with_context(template, &context).unwrap(), + code + ); + } +}