Added shell action

This commit is contained in:
Kasper Juul Hermansen 2022-08-10 16:46:56 +02:00
parent f5e1e3027a
commit faf15d1398
Signed by: kjuulh
GPG Key ID: 0F95C140730F2F23
9 changed files with 181 additions and 19 deletions

21
Cargo.lock generated
View File

@ -80,12 +80,33 @@ version = "0.1.0"
dependencies = [
"anyhow",
"clap",
"envconfig",
"git2",
"serde",
"serde_yaml",
"walkdir",
]
[[package]]
name = "envconfig"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea81cc7e21f55a9d9b1efb6816904978d0bfbe31a50347cb24b2e75564bcac9b"
dependencies = [
"envconfig_derive",
]
[[package]]
name = "envconfig_derive"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dfca278e5f84b45519acaaff758ebfa01f18e96998bc24b8f1b722dd804b9bf"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "form_urlencoded"
version = "1.0.1"

View File

@ -12,3 +12,4 @@ serde_yaml = "0.9.4"
walkdir = "2.3.2"
git2 = { version = "0.15.0", features = ["ssh"] }
clap = "3.2.16"
envconfig = "0.10.0"

View File

@ -0,0 +1 @@
pub mod shell;

View File

@ -0,0 +1,54 @@
use std::{
io::{BufRead, BufReader},
process::{Command, Stdio},
};
pub struct ShellAction {
path: String,
}
impl ShellAction {
pub fn new(path: String) -> Self {
Self { path }
}
pub fn execute(self) -> anyhow::Result<()> {
println!("executing shell action: {}", self.path.clone());
println!(
"
===
Starting running shell action: {}
===
",
self.path.clone()
);
let mut process = Command::new(self.path)
.current_dir(".")
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()?;
{
let stdout = process.stdout.as_mut().unwrap();
let stdout_reader = BufReader::new(stdout);
let mut stdout_lines = stdout_reader.lines();
while let Some(Ok(line)) = stdout_lines.next() {
println!("{}", line);
}
}
process.wait()?;
println!(
"
===
Finished running shell action
===
"
);
Ok(())
}
}

View File

@ -3,9 +3,10 @@ use std::{
sync::{Arc, Mutex},
};
use anyhow::anyhow;
use clap::Command;
use crate::{context::CuddleContext, model::CuddleScript};
use crate::{actions, context::CuddleContext, model::CuddleScript};
#[derive(Debug, Clone)]
#[allow(dead_code)]
@ -22,8 +23,23 @@ impl CuddleAction {
pub fn execute(self) {
match self.script {
CuddleScript::Shell(s) => {}
CuddleScript::Dagger(d) => {}
CuddleScript::Shell(_s) => {
match actions::shell::ShellAction::new(format!(
"{}/scripts/{}.sh",
self.path
.to_str()
.expect("action doesn't have a name, this should never happen"),
self.name
))
.execute()
{
Ok(()) => {}
Err(e) => {
eprintln!("{}", e)
}
}
}
CuddleScript::Dagger(_d) => {}
}
}
}
@ -68,8 +84,7 @@ impl<'a> CuddleCli<'a> {
.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")
.propagate_version(true)
.arg_required_else_help(true);
.propagate_version(true);
let mut execute_cmd = Command::new("x").about("x is your entry into your domains scripts, scripts inherited from parents will also be present here");
@ -77,6 +92,7 @@ impl<'a> CuddleCli<'a> {
let action_cmd = Command::new(script.name.clone());
// TODO: Some way to add an about for clap, requires conversion from String -> &str
execute_cmd = execute_cmd.subcommand(action_cmd);
}
@ -87,11 +103,40 @@ impl<'a> CuddleCli<'a> {
self
}
pub fn execute(self) -> Self {
if let Some(cli) = self.command.clone() {
let _ = cli.get_matches();
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)) => {
println!("executing: x");
match exe_submatch.subcommand() {
Some((name, _action_matches)) => {
println!("running action: {}", name);
match self.scripts.iter().find(|ele| ele.name == name) {
Some(script) => {
script.clone().execute();
Ok(())
}
_ => (Err(anyhow!("could not find a match"))),
}
}
_ => (Err(anyhow!("could not find a match"))),
}
}
_ => (Err(anyhow!("could not find a match"))),
};
match res {
Ok(()) => {}
Err(e) => {
eprintln!("{}", e);
let _ = cli.print_long_help();
}
}
}
self
Ok(self)
}
}

26
cuddle_cli/src/config.rs Normal file
View File

@ -0,0 +1,26 @@
use envconfig::Envconfig;
pub enum CuddleFetchPolicy {
Always,
Once,
}
#[derive(Envconfig, Clone)]
pub struct CuddleConfig {
#[envconfig(from = "CUDDLE_FETCH_POLICY", default = "once")]
fetch_policy: String,
}
impl CuddleConfig {
pub fn from_env() -> anyhow::Result<Self> {
CuddleConfig::init_from_env().map_err(|e| anyhow::Error::from(e))
}
pub fn get_fetch_policy(&self) -> anyhow::Result<CuddleFetchPolicy> {
match self.fetch_policy.clone().to_lowercase().as_str() {
"always" => Ok(CuddleFetchPolicy::Always),
"once" => Ok(CuddleFetchPolicy::Once),
_ => Err(anyhow::anyhow!("could not parse fetch policy")),
}
}
}

View File

@ -7,7 +7,10 @@ use std::{
use git2::{build::RepoBuilder, FetchOptions, RemoteCallbacks};
use crate::model::{CuddleBase, CuddlePlan};
use crate::{
config::{CuddleConfig, CuddleFetchPolicy},
model::{CuddleBase, CuddlePlan},
};
#[derive(Debug)]
pub struct CuddleContext {
@ -15,11 +18,14 @@ pub struct CuddleContext {
pub path: PathBuf,
}
pub fn extract_cuddle() -> anyhow::Result<Arc<Mutex<Vec<CuddleContext>>>> {
pub fn extract_cuddle(config: CuddleConfig) -> anyhow::Result<Arc<Mutex<Vec<CuddleContext>>>> {
let mut curr_dir = current_dir()?;
curr_dir.push(".cuddle/");
if let Err(res) = std::fs::remove_dir_all(curr_dir) {
println!("{}", res);
let fetch_policy = config.get_fetch_policy()?;
if let CuddleFetchPolicy::Always = fetch_policy {
if let Err(res) = std::fs::remove_dir_all(curr_dir) {
println!("{}", res);
}
}
// Load main cuddle file
@ -52,8 +58,10 @@ pub fn extract_cuddle() -> anyhow::Result<Arc<Mutex<Vec<CuddleContext>>>> {
let mut cuddle_dest = destination_path.clone();
cuddle_dest.push("base");
pull_parent_cuddle_into_local(parent_plan, cuddle_dest.clone())?;
recurse_parent(cuddle_dest, context.clone())?;
if !cuddle_dest.exists() {
pull_parent_cuddle_into_local(parent_plan, cuddle_dest.clone())?;
recurse_parent(cuddle_dest, context.clone())?;
}
}
}

View File

@ -1,13 +1,16 @@
use config::CuddleConfig;
mod actions;
mod cli;
mod config;
mod context;
mod model;
fn main() -> anyhow::Result<()> {
let context = context::extract_cuddle()?;
let mut cuddle_cli = cli::CuddleCli::new(context.clone())?;
cuddle_cli = cuddle_cli.execute();
let config = CuddleConfig::from_env()?;
println!("{:?}", cuddle_cli);
let context = context::extract_cuddle(config.clone())?;
_ = cli::CuddleCli::new(context)?.execute()?;
Ok(())
}

3
examples/base/scripts/build.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/bash
echo "Ran build"