feat: with redone output

Signed-off-by: kjuulh <contact@kjuulh.io>
This commit is contained in:
Kasper Juul Hermansen 2023-06-17 13:33:10 +02:00
parent 04e8baeefc
commit dc0fa589a5
Signed by: kjuulh
GPG Key ID: 57B6E1465221F912
6 changed files with 82 additions and 46 deletions

View File

@ -7,6 +7,8 @@ vars:
registry: kasperhermansen
scripts:
install:
type: shell
build_cuddle_image:
type: shell
args:

View File

@ -1,8 +1,6 @@
use std::{
env::current_dir,
path::PathBuf,
process::{Command},
};
use std::io::{BufRead, BufReader};
use std::process::Stdio;
use std::{env::current_dir, path::PathBuf, process::Command};
use crate::model::CuddleVariable;
@ -20,15 +18,7 @@ impl ShellAction {
pub fn execute(self, variables: Vec<CuddleVariable>) -> anyhow::Result<()> {
log::debug!("executing shell action: {}", self.path.clone());
log::info!(
"
===
Starting running shell action: {}
===
",
self.path.clone()
);
log::info!("Starting running shell action: {}", self.path.clone());
let path = PathBuf::from(self.path.clone());
if !path.exists() {
@ -41,6 +31,8 @@ Starting running shell action: {}
let mut process = Command::new(path.clone())
.current_dir(current_dir)
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.envs(variables.iter().map(|v| {
log::trace!("{:?}", v);
@ -48,6 +40,20 @@ Starting running shell action: {}
}))
.spawn()?;
if let Some(ref mut stdout) = process.stdout {
for line in BufReader::new(stdout).lines() {
let line = line.unwrap();
println!("[{}] {}", self.name, line);
}
}
if let Some(ref mut stderr) = process.stderr {
for line in BufReader::new(stderr).lines() {
let line = line.unwrap();
println!("[{}] {}", self.name, line);
}
}
let status = process.wait()?;
match status.code() {
@ -55,8 +61,6 @@ Starting running shell action: {}
log::warn!("process exited without code")
}
Some(n) => {
log::info!("process exited with code: {}", n);
if n > 0 {
return Err(anyhow::anyhow!(
"{} exited with: {}",
@ -67,14 +71,7 @@ Starting running shell action: {}
}
}
log::info!(
"
===
Finished running shell action
===
"
);
log::info!("Finished running shell action");
Ok(())
}

View File

@ -21,7 +21,7 @@ use self::subcommands::render_template::RenderTemplateCommand;
pub struct CuddleCli {
scripts: Vec<CuddleAction>,
variables: Vec<CuddleVariable>,
context: Arc<Mutex<Vec<CuddleContext>>>,
context: Option<Arc<Mutex<Vec<CuddleContext>>>>,
command: Option<Command>,
tmp_dir: Option<PathBuf>,
config: CuddleConfig,
@ -29,7 +29,7 @@ pub struct CuddleCli {
impl CuddleCli {
pub fn new(
context: Arc<Mutex<Vec<CuddleContext>>>,
context: Option<Arc<Mutex<Vec<CuddleContext>>>>,
config: CuddleConfig,
) -> anyhow::Result<CuddleCli> {
let mut cli = CuddleCli {
@ -41,17 +41,24 @@ impl CuddleCli {
config,
};
match context {
Some(_) => {
cli = cli
.process_variables()
.process_scripts()
.process_templates()?
.build_cli();
}
None => {
cli = cli.build_bare_cli();
}
}
Ok(cli)
}
fn process_variables(mut self) -> Self {
if let Ok(context_iter) = self.context.clone().lock() {
if let Ok(context_iter) = self.context.clone().unwrap().lock() {
for ctx in context_iter.iter() {
if let Some(variables) = ctx.plan.vars.clone() {
for (name, var) in variables {
@ -87,7 +94,7 @@ impl CuddleCli {
}
fn process_scripts(mut self) -> Self {
if let Ok(context_iter) = self.context.clone().lock() {
if let Ok(context_iter) = self.context.clone().unwrap().lock() {
for ctx in context_iter.iter() {
if let Some(scripts) = ctx.plan.scripts.clone() {
for (name, script) in scripts {
@ -124,7 +131,7 @@ impl CuddleCli {
// 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() {
if let Ok(context_iter) = self.context.clone().unwrap().lock() {
for ctx in context_iter.iter() {
let mut template_path = ctx.path.clone();
template_path.push("templates");
@ -166,6 +173,22 @@ impl CuddleCli {
self
}
fn build_bare_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::init::build_command(root_cmd, self.clone());
self.command = Some(root_cmd);
self
}
pub fn execute(self) -> anyhow::Result<Self> {
if let Some(cli) = self.command.clone() {
let matches = cli.clone().get_matches();

View File

@ -1,7 +1,6 @@
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};

View File

@ -25,7 +25,9 @@ pub struct CuddleContext {
pub node_type: CuddleTreeType,
}
pub fn extract_cuddle(config: CuddleConfig) -> anyhow::Result<Arc<Mutex<Vec<CuddleContext>>>> {
pub fn extract_cuddle(
config: CuddleConfig,
) -> anyhow::Result<Option<Arc<Mutex<Vec<CuddleContext>>>>> {
let mut curr_dir = current_dir()?;
curr_dir.push(".cuddle/");
let fetch_policy = config.get_fetch_policy()?;
@ -39,6 +41,10 @@ pub fn extract_cuddle(config: CuddleConfig) -> anyhow::Result<Arc<Mutex<Vec<Cudd
// Load main cuddle file.
let cuddle_yaml = find_root_cuddle()?;
if let None = cuddle_yaml {
return Ok(None);
}
let cuddle_yaml = cuddle_yaml.unwrap();
log::trace!(cuddle_yaml=log::as_debug!(cuddle_yaml); "Find root cuddle");
let cuddle_plan = serde_yaml::from_str::<CuddlePlan>(cuddle_yaml.as_str())?;
@ -74,7 +80,7 @@ pub fn extract_cuddle(config: CuddleConfig) -> anyhow::Result<Arc<Mutex<Vec<Cudd
}
}
Ok(context)
Ok(Some(context))
}
fn create_cuddle_local() -> anyhow::Result<PathBuf> {
@ -131,9 +137,15 @@ fn pull_parent_cuddle_into_local(
Ok(())
}
fn recurse_parent(path: PathBuf, context: Arc<Mutex<Vec<CuddleContext>>>) -> anyhow::Result<()> {
fn recurse_parent(
path: PathBuf,
context: Arc<Mutex<Vec<CuddleContext>>>,
) -> anyhow::Result<Option<()>> {
let cuddle_contents = find_cuddle(path.clone())?;
let cuddle_plan = serde_yaml::from_str::<CuddlePlan>(&cuddle_contents)?;
if let None = cuddle_contents {
return Ok(None);
}
let cuddle_plan = serde_yaml::from_str::<CuddlePlan>(&cuddle_contents.unwrap())?;
let ctx = context.clone();
if let Ok(mut ctxs) = ctx.lock() {
@ -154,7 +166,7 @@ fn recurse_parent(path: PathBuf, context: Arc<Mutex<Vec<CuddleContext>>>) -> any
}
CuddleBase::Bool(false) => {
log::debug!("plan is root: finishing up");
return Ok(());
return Ok(Some(()));
}
CuddleBase::String(parent_plan) => {
let destination_path = create_cuddle(path.clone())?;
@ -169,24 +181,22 @@ fn recurse_parent(path: PathBuf, context: Arc<Mutex<Vec<CuddleContext>>>) -> any
}
}
fn find_root_cuddle() -> anyhow::Result<String> {
fn find_root_cuddle() -> anyhow::Result<Option<String>> {
// TODO: Make recursive towards root
let current_dir = env::current_dir()?;
find_cuddle(current_dir)
}
fn find_cuddle(path: PathBuf) -> anyhow::Result<String> {
fn find_cuddle(path: PathBuf) -> anyhow::Result<Option<String>> {
for entry in std::fs::read_dir(path)? {
let entry = entry?;
let path = entry.path();
let metadata = std::fs::metadata(&path)?;
if metadata.is_file() && path.file_name().unwrap() == OsStr::new("cuddle.yaml") {
return Ok(std::fs::read_to_string(path)?);
return Ok(Some(std::fs::read_to_string(path)?));
}
}
Err(anyhow::anyhow!(
"Could not find 'cuddle.yaml' in the current directory"
))
Ok(None)
}

5
scripts/install.sh Executable file
View File

@ -0,0 +1,5 @@
#!/bin/bash
cargo install --path cuddle_cli/
cuddle --version