183 lines
5.6 KiB
Rust
183 lines
5.6 KiB
Rust
mod subcommands;
|
|
|
|
use std::{
|
|
path::PathBuf,
|
|
sync::{Arc, Mutex},
|
|
};
|
|
|
|
use clap::Command;
|
|
|
|
use crate::{
|
|
actions::CuddleAction,
|
|
context::{CuddleContext, CuddleTreeType},
|
|
model::*,
|
|
util::git::GitCommit,
|
|
};
|
|
|
|
use self::subcommands::render_template::RenderTemplateCommand;
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct CuddleCli<'a> {
|
|
scripts: Vec<CuddleAction>,
|
|
variables: Vec<CuddleVariable>,
|
|
context: Arc<Mutex<Vec<CuddleContext>>>,
|
|
command: Option<Command<'a>>,
|
|
tmp_dir: Option<PathBuf>,
|
|
}
|
|
|
|
impl<'a> CuddleCli<'a> {
|
|
pub fn new(context: Arc<Mutex<Vec<CuddleContext>>>) -> anyhow::Result<CuddleCli<'a>> {
|
|
let mut cli = CuddleCli {
|
|
scripts: vec![],
|
|
variables: vec![],
|
|
context: context.clone(),
|
|
command: None,
|
|
tmp_dir: None,
|
|
};
|
|
|
|
cli = cli
|
|
.process_variables()
|
|
.process_scripts()
|
|
.process_templates()?
|
|
.build_cli();
|
|
|
|
Ok(cli)
|
|
}
|
|
|
|
fn process_variables(mut self) -> Self {
|
|
if let Ok(context_iter) = self.context.clone().lock() {
|
|
for ctx in context_iter.iter() {
|
|
if let Some(variables) = ctx.plan.vars.clone() {
|
|
for (name, var) in variables {
|
|
self.variables.push(CuddleVariable::new(name, var))
|
|
}
|
|
}
|
|
|
|
if let CuddleTreeType::Root = ctx.node_type {
|
|
let mut temp_path = ctx.path.clone();
|
|
temp_path.push(".cuddle/tmp");
|
|
|
|
self.variables.push(CuddleVariable::new(
|
|
"tmp".into(),
|
|
temp_path.clone().to_string_lossy().to_string(),
|
|
));
|
|
|
|
self.tmp_dir = Some(temp_path);
|
|
}
|
|
}
|
|
}
|
|
|
|
match GitCommit::new() {
|
|
Ok(commit) => self.variables.push(CuddleVariable::new(
|
|
"commit_sha".into(),
|
|
commit.commit_sha.clone(),
|
|
)),
|
|
Err(e) => {
|
|
log::debug!("{}", e);
|
|
}
|
|
}
|
|
|
|
self
|
|
}
|
|
|
|
fn process_scripts(mut self) -> Self {
|
|
if let Ok(context_iter) = self.context.clone().lock() {
|
|
for ctx in context_iter.iter() {
|
|
if let Some(scripts) = ctx.plan.scripts.clone() {
|
|
for (name, script) in scripts {
|
|
self.scripts
|
|
.push(CuddleAction::new(script.clone(), ctx.path.clone(), name))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
self
|
|
}
|
|
|
|
fn process_templates(self) -> anyhow::Result<Self> {
|
|
if let None = self.tmp_dir {
|
|
log::debug!("cannot process template as bare bones cli");
|
|
return Ok(self);
|
|
}
|
|
|
|
// Make sure tmp_dir exists and clean it up first
|
|
let tmp_dir = self
|
|
.tmp_dir
|
|
.clone()
|
|
.ok_or(anyhow::anyhow!("tmp_dir does not exist aborting"))?;
|
|
if tmp_dir.exists() && tmp_dir.ends_with("tmp") {
|
|
std::fs::remove_dir_all(tmp_dir.clone())?;
|
|
}
|
|
std::fs::create_dir_all(tmp_dir.clone())?;
|
|
// Handle all templating with variables and such.
|
|
// TODO: use actual templating engine, for new we just copy templates to the final folder
|
|
|
|
if let Ok(context_iter) = self.context.clone().lock() {
|
|
for ctx in context_iter.iter() {
|
|
let mut template_path = ctx.path.clone();
|
|
template_path.push("templates");
|
|
|
|
log::trace!("template path: {}", template_path.clone().to_string_lossy());
|
|
|
|
if !template_path.exists() {
|
|
continue;
|
|
}
|
|
|
|
for file in std::fs::read_dir(template_path)?.into_iter() {
|
|
let f = file?;
|
|
let mut dest_file = tmp_dir.clone();
|
|
dest_file.push(f.file_name());
|
|
|
|
std::fs::copy(f.path(), dest_file)?;
|
|
}
|
|
}
|
|
}
|
|
|
|
Ok(self)
|
|
}
|
|
|
|
fn build_cli(mut self) -> Self {
|
|
let mut root_cmd = Command::new("cuddle")
|
|
.version("1.0")
|
|
.author("kjuulh <contact@kasperhermansen.com>")
|
|
.about("cuddle is your domain specific organization tool. It enabled widespread sharing through repositories, as well as collaborating while maintaining speed and integrity")
|
|
.subcommand_required(true)
|
|
.arg_required_else_help(true)
|
|
.propagate_version(true);
|
|
|
|
root_cmd = subcommands::x::build_command(root_cmd, self.clone());
|
|
root_cmd = subcommands::render_template::build_command(root_cmd);
|
|
|
|
self.command = Some(root_cmd);
|
|
|
|
self
|
|
}
|
|
|
|
pub fn execute(self) -> anyhow::Result<Self> {
|
|
if let Some(mut cli) = self.command.clone() {
|
|
let matches = cli.clone().get_matches();
|
|
|
|
let res = match matches.subcommand() {
|
|
Some(("x", exe_submatch)) => subcommands::x::execute_x(exe_submatch, self.clone()),
|
|
Some(("render_template", sub_matches)) => {
|
|
RenderTemplateCommand::from_matches(sub_matches, self.clone())
|
|
.and_then(|cmd| cmd.execute())?;
|
|
Ok(())
|
|
}
|
|
_ => Err(anyhow::anyhow!("could not find a match")),
|
|
};
|
|
|
|
match res {
|
|
Ok(()) => {}
|
|
Err(e) => {
|
|
let _ = cli.print_long_help();
|
|
return Err(e);
|
|
}
|
|
}
|
|
}
|
|
|
|
Ok(self)
|
|
}
|
|
}
|