Added shell action
This commit is contained in:
parent
f5e1e3027a
commit
faf15d1398
21
Cargo.lock
generated
21
Cargo.lock
generated
@ -80,12 +80,33 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"clap",
|
"clap",
|
||||||
|
"envconfig",
|
||||||
"git2",
|
"git2",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_yaml",
|
"serde_yaml",
|
||||||
"walkdir",
|
"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]]
|
[[package]]
|
||||||
name = "form_urlencoded"
|
name = "form_urlencoded"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
|
@ -12,3 +12,4 @@ serde_yaml = "0.9.4"
|
|||||||
walkdir = "2.3.2"
|
walkdir = "2.3.2"
|
||||||
git2 = { version = "0.15.0", features = ["ssh"] }
|
git2 = { version = "0.15.0", features = ["ssh"] }
|
||||||
clap = "3.2.16"
|
clap = "3.2.16"
|
||||||
|
envconfig = "0.10.0"
|
||||||
|
1
cuddle_cli/src/actions/mod.rs
Normal file
1
cuddle_cli/src/actions/mod.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
pub mod shell;
|
54
cuddle_cli/src/actions/shell.rs
Normal file
54
cuddle_cli/src/actions/shell.rs
Normal 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(())
|
||||||
|
}
|
||||||
|
}
|
@ -3,9 +3,10 @@ use std::{
|
|||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use anyhow::anyhow;
|
||||||
use clap::Command;
|
use clap::Command;
|
||||||
|
|
||||||
use crate::{context::CuddleContext, model::CuddleScript};
|
use crate::{actions, context::CuddleContext, model::CuddleScript};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@ -22,8 +23,23 @@ impl CuddleAction {
|
|||||||
|
|
||||||
pub fn execute(self) {
|
pub fn execute(self) {
|
||||||
match self.script {
|
match self.script {
|
||||||
CuddleScript::Shell(s) => {}
|
CuddleScript::Shell(_s) => {
|
||||||
CuddleScript::Dagger(d) => {}
|
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")
|
.version("1.0")
|
||||||
.author("kjuulh <contact@kasperhermansen.com>")
|
.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")
|
.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)
|
.propagate_version(true);
|
||||||
.arg_required_else_help(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");
|
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());
|
let action_cmd = Command::new(script.name.clone());
|
||||||
|
|
||||||
// TODO: Some way to add an about for clap, requires conversion from String -> &str
|
// TODO: Some way to add an about for clap, requires conversion from String -> &str
|
||||||
|
|
||||||
execute_cmd = execute_cmd.subcommand(action_cmd);
|
execute_cmd = execute_cmd.subcommand(action_cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,11 +103,40 @@ impl<'a> CuddleCli<'a> {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn execute(self) -> Self {
|
pub fn execute(self) -> anyhow::Result<Self> {
|
||||||
if let Some(cli) = self.command.clone() {
|
if let Some(mut cli) = self.command.clone() {
|
||||||
let _ = cli.get_matches();
|
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
26
cuddle_cli/src/config.rs
Normal 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")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,7 +7,10 @@ use std::{
|
|||||||
|
|
||||||
use git2::{build::RepoBuilder, FetchOptions, RemoteCallbacks};
|
use git2::{build::RepoBuilder, FetchOptions, RemoteCallbacks};
|
||||||
|
|
||||||
use crate::model::{CuddleBase, CuddlePlan};
|
use crate::{
|
||||||
|
config::{CuddleConfig, CuddleFetchPolicy},
|
||||||
|
model::{CuddleBase, CuddlePlan},
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CuddleContext {
|
pub struct CuddleContext {
|
||||||
@ -15,12 +18,15 @@ pub struct CuddleContext {
|
|||||||
pub path: PathBuf,
|
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()?;
|
let mut curr_dir = current_dir()?;
|
||||||
curr_dir.push(".cuddle/");
|
curr_dir.push(".cuddle/");
|
||||||
|
let fetch_policy = config.get_fetch_policy()?;
|
||||||
|
if let CuddleFetchPolicy::Always = fetch_policy {
|
||||||
if let Err(res) = std::fs::remove_dir_all(curr_dir) {
|
if let Err(res) = std::fs::remove_dir_all(curr_dir) {
|
||||||
println!("{}", res);
|
println!("{}", res);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Load main cuddle file
|
// Load main cuddle file
|
||||||
let cuddle_yaml = find_root_cuddle()?;
|
let cuddle_yaml = find_root_cuddle()?;
|
||||||
@ -52,10 +58,12 @@ pub fn extract_cuddle() -> anyhow::Result<Arc<Mutex<Vec<CuddleContext>>>> {
|
|||||||
let mut cuddle_dest = destination_path.clone();
|
let mut cuddle_dest = destination_path.clone();
|
||||||
cuddle_dest.push("base");
|
cuddle_dest.push("base");
|
||||||
|
|
||||||
|
if !cuddle_dest.exists() {
|
||||||
pull_parent_cuddle_into_local(parent_plan, cuddle_dest.clone())?;
|
pull_parent_cuddle_into_local(parent_plan, cuddle_dest.clone())?;
|
||||||
recurse_parent(cuddle_dest, context.clone())?;
|
recurse_parent(cuddle_dest, context.clone())?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if let Ok(ctx) = context.clone().lock() {
|
if let Ok(ctx) = context.clone().lock() {
|
||||||
// TODO: set trace
|
// TODO: set trace
|
||||||
|
@ -1,13 +1,16 @@
|
|||||||
|
use config::CuddleConfig;
|
||||||
|
|
||||||
|
mod actions;
|
||||||
mod cli;
|
mod cli;
|
||||||
|
mod config;
|
||||||
mod context;
|
mod context;
|
||||||
mod model;
|
mod model;
|
||||||
|
|
||||||
fn main() -> anyhow::Result<()> {
|
fn main() -> anyhow::Result<()> {
|
||||||
let context = context::extract_cuddle()?;
|
let config = CuddleConfig::from_env()?;
|
||||||
let mut cuddle_cli = cli::CuddleCli::new(context.clone())?;
|
|
||||||
cuddle_cli = cuddle_cli.execute();
|
|
||||||
|
|
||||||
println!("{:?}", cuddle_cli);
|
let context = context::extract_cuddle(config.clone())?;
|
||||||
|
_ = cli::CuddleCli::new(context)?.execute()?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
3
examples/base/scripts/build.sh
Executable file
3
examples/base/scripts/build.sh
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
echo "Ran build"
|
Loading…
Reference in New Issue
Block a user