feat: add templating to project
Signed-off-by: kjuulh <contact@kjuulh.io>
This commit is contained in:
parent
2f2fdb9631
commit
2241941f0e
59
Cargo.lock
generated
59
Cargo.lock
generated
@ -2,6 +2,15 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97"
|
||||
dependencies = [
|
||||
"gimli",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
@ -95,6 +104,9 @@ name = "anyhow"
|
||||
version = "1.0.71"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ascii"
|
||||
@ -119,6 +131,21 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.67"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"miniz_oxide 0.6.2",
|
||||
"object",
|
||||
"rustc-demangle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base"
|
||||
version = "0.1.0"
|
||||
@ -644,7 +671,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"miniz_oxide",
|
||||
"miniz_oxide 0.7.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -787,6 +814,12 @@ dependencies = [
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.27.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e"
|
||||
|
||||
[[package]]
|
||||
name = "git2"
|
||||
version = "0.17.2"
|
||||
@ -1244,6 +1277,15 @@ version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa"
|
||||
dependencies = [
|
||||
"adler",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.7.1"
|
||||
@ -1303,6 +1345,15 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.30.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03b4680b86d9cfafba8fc491dc9b6df26b68cf40e9e6cd73909194759a63c385"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.18.0"
|
||||
@ -1674,6 +1725,12 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.37.19"
|
||||
|
@ -11,7 +11,7 @@ path = "src/main.rs"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.60"
|
||||
anyhow = { version = "1.0.60", features = ["backtrace"] }
|
||||
serde = { version = "1.0.143", features = ["derive"] }
|
||||
serde_yaml = "0.9.4"
|
||||
walkdir = "2.3.2"
|
||||
|
@ -1,7 +1,11 @@
|
||||
use std::collections::BTreeMap;
|
||||
use std::fs::{create_dir_all, read, read_dir};
|
||||
use std::io::Write;
|
||||
use std::mem::replace;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use clap::{ArgMatches, Command};
|
||||
use walkdir::WalkDir;
|
||||
|
||||
use crate::cli::CuddleCli;
|
||||
|
||||
@ -105,7 +109,7 @@ pub fn execute_init(exe_submatch: &ArgMatches, _cli: CuddleCli) -> anyhow::Resul
|
||||
}
|
||||
};
|
||||
|
||||
let (_name, template_dir, _template) = template?;
|
||||
let (_name, template_dir, mut template) = template?;
|
||||
|
||||
let path = match path {
|
||||
Some(path) => path.clone(),
|
||||
@ -128,21 +132,61 @@ pub fn execute_init(exe_submatch: &ArgMatches, _cli: CuddleCli) -> anyhow::Resul
|
||||
}
|
||||
}
|
||||
|
||||
for entry in read_dir(template_dir)? {
|
||||
{
|
||||
if let Some(ref mut prompt) = template.prompt {
|
||||
for (name, prompt) in prompt {
|
||||
let value = inquire::Text::new(&name)
|
||||
.with_help_message(&prompt.description)
|
||||
.prompt()?;
|
||||
prompt.value = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for entry in WalkDir::new(&template_dir).follow_links(false) {
|
||||
let entry = entry?;
|
||||
let entry_path = entry.path();
|
||||
|
||||
let new_path = PathBuf::from(&path).join(entry_path.strip_prefix(&template_dir)?);
|
||||
let new_path = replace_with_variables(&new_path.to_string_lossy().to_string(), &template)?;
|
||||
let new_path = PathBuf::from(new_path);
|
||||
|
||||
if entry_path.is_dir() {
|
||||
create_dir_all(&new_path)?;
|
||||
}
|
||||
|
||||
if entry_path.is_file() {
|
||||
let name = entry.file_name();
|
||||
if let Some(parent) = entry_path.parent() {
|
||||
create_dir_all(parent)?;
|
||||
}
|
||||
|
||||
if name == "cuddle-template.json" || name == "cuddle-templates.json" {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::fs::rename(entry_path, std::path::PathBuf::from(&path).join(name))?;
|
||||
tracing::info!("writing to: {}", new_path.display());
|
||||
let new_content =
|
||||
replace_with_variables(&std::fs::read_to_string(entry_path)?, &template)?;
|
||||
|
||||
std::fs::write(new_path, new_content.as_bytes())?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn replace_with_variables(content: &str, template: &CuddleTemplate) -> anyhow::Result<String> {
|
||||
let mut content = content.to_string();
|
||||
if let Some(prompt) = &template.prompt {
|
||||
for (name, value) in prompt {
|
||||
content = content.replace(&format!("%%{}%%", name), &value.value);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(content)
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
struct CuddleTemplates {
|
||||
pub templates: Vec<String>,
|
||||
@ -151,4 +195,12 @@ struct CuddleTemplates {
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
struct CuddleTemplate {
|
||||
pub name: String,
|
||||
pub prompt: Option<BTreeMap<String, CuddleTemplatePrompt>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
struct CuddleTemplatePrompt {
|
||||
pub description: String,
|
||||
#[serde(skip)]
|
||||
pub value: String,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user