feat: make sure dir is there as well

Signed-off-by: kjuulh <contact@kjuulh.io>
This commit is contained in:
2024-01-28 16:41:50 +01:00
parent cc7aaf14eb
commit 85cc1d46db
15 changed files with 1153 additions and 447 deletions

View File

@@ -1,11 +1,12 @@
use std::{path::PathBuf, str::FromStr};
use clap::{Arg, ArgGroup, ArgMatches, Command};
use anyhow::Context;
use clap::{Arg, ArgMatches, Command};
use crate::{cli::CuddleCli, model::CuddleVariable};
const DESTINATION: &'static str = "destination is the output path of the template once done, but default .tmpl is stripped and the normal file extension is used. this can be overwritten if a file path is entered instead. I.e. (/some/file/name.txt)";
const TEMPLATE_FILE: &'static str = "template-file is the input file path of the .tmpl file (or inferred) that you would like to render";
const DESTINATION: &str = "destination is the output path of the template once done, but default .tmpl is stripped and the normal file extension is used. this can be overwritten if a file path is entered instead. I.e. (/some/file/name.txt)";
const TEMPLATE_FILE: &str = "template-file is the input file path of the .tmpl file (or inferred) that you would like to render";
pub fn build_command(root_cmd: Command) -> Command {
root_cmd.subcommand(
@@ -51,18 +52,19 @@ impl RenderTemplateCommand {
.get_one::<String>("destination")
.ok_or(anyhow::anyhow!("destination was not found"))
.and_then(get_path_buf_and_check_dir_exists)
.and_then(RenderTemplateCommand::transform_extension)?;
.and_then(RenderTemplateCommand::transform_extension)
.context("failed to access dest directory")?;
let mut extra_vars: Vec<CuddleVariable> =
if let Some(extra_vars) = matches.get_many::<String>("extra-var") {
let mut vars = Vec::with_capacity(extra_vars.len());
for var in extra_vars.into_iter() {
let parts: Vec<&str> = var.split("=").collect();
let parts: Vec<&str> = var.split('=').collect();
if parts.len() != 2 {
return Err(anyhow::anyhow!("extra-var: is not set correctly: {}", var));
}
vars.push(CuddleVariable::new(parts[0].into(), parts[1].into()));
vars.push(CuddleVariable::new(parts[0], parts[1]));
}
vars
} else {
@@ -82,10 +84,7 @@ impl RenderTemplateCommand {
// Prepare context
let mut context = tera::Context::new();
for var in self.variables {
context.insert(
var.name.to_lowercase().replace(" ", "_").replace("-", "_"),
&var.value,
)
context.insert(var.name.to_lowercase().replace([' ', '-'], "_"), &var.value)
}
// Load source template
@@ -93,8 +92,15 @@ impl RenderTemplateCommand {
let output = tera::Tera::one_off(source.as_str(), &context, false)?;
if let Some(parent) = self.destination.parent() {
std::fs::create_dir_all(parent)?;
}
// Put template in final destination
std::fs::write(&self.destination, output)?;
std::fs::write(&self.destination, output).context(format!(
"failed to write to destination: {}",
&self.destination.display(),
))?;
log::info!(
"finished writing template to: {}",
@@ -123,8 +129,8 @@ impl RenderTemplateCommand {
}
}
fn get_path_buf_and_check_exists(raw_path: &String) -> anyhow::Result<PathBuf> {
match PathBuf::from_str(&raw_path) {
fn get_path_buf_and_check_exists(raw_path: impl Into<String>) -> anyhow::Result<PathBuf> {
match PathBuf::from_str(&raw_path.into()) {
Ok(pb) => {
if pb.exists() {
Ok(pb)
@@ -139,17 +145,9 @@ fn get_path_buf_and_check_exists(raw_path: &String) -> anyhow::Result<PathBuf> {
}
}
fn get_path_buf_and_check_dir_exists(raw_path: &String) -> anyhow::Result<PathBuf> {
match PathBuf::from_str(&raw_path) {
Ok(pb) => {
if pb.is_dir() && pb.exists() {
Ok(pb)
} else if pb.is_file() {
Ok(pb)
} else {
Ok(pb)
}
}
fn get_path_buf_and_check_dir_exists(raw_path: impl Into<String>) -> anyhow::Result<PathBuf> {
match PathBuf::from_str(&raw_path.into()) {
Ok(pb) => Ok(pb),
Err(e) => Err(anyhow::anyhow!(e)),
}
}