@@ -24,7 +24,7 @@ clap = { version = "4.3.4", features = ["env", "string"] }
|
||||
envconfig = "0.10.0"
|
||||
dirs = "5.0.1"
|
||||
tracing = "0.1.36"
|
||||
tracing-subscriber = { version = "0.3.15", features = ["json"] }
|
||||
tracing-subscriber = { version = "0.3.15", features = ["json", "env-filter"] }
|
||||
log = { version = "0.4.17", features = ["std", "kv_unstable"] }
|
||||
tera = "1.17.0"
|
||||
openssl = { version = "0.10.54", features = ["vendored"] }
|
||||
|
@@ -1,5 +1,7 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use clap::ArgMatches;
|
||||
|
||||
use crate::{
|
||||
actions::shell::ShellAction,
|
||||
model::{CuddleScript, CuddleShellScriptArg, CuddleVariable},
|
||||
@@ -12,15 +14,30 @@ pub mod shell;
|
||||
pub struct CuddleAction {
|
||||
pub script: CuddleScript,
|
||||
pub path: PathBuf,
|
||||
pub description: Option<String>,
|
||||
pub name: String,
|
||||
}
|
||||
#[allow(dead_code)]
|
||||
impl CuddleAction {
|
||||
pub fn new(script: CuddleScript, path: PathBuf, name: String) -> Self {
|
||||
Self { script, path, name }
|
||||
pub fn new(
|
||||
script: CuddleScript,
|
||||
path: PathBuf,
|
||||
name: String,
|
||||
description: Option<String>,
|
||||
) -> Self {
|
||||
Self {
|
||||
script,
|
||||
path,
|
||||
name,
|
||||
description,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn execute(self, variables: Vec<CuddleVariable>) -> anyhow::Result<()> {
|
||||
pub fn execute(
|
||||
self,
|
||||
matches: &ArgMatches,
|
||||
variables: Vec<CuddleVariable>,
|
||||
) -> anyhow::Result<()> {
|
||||
match self.script {
|
||||
CuddleScript::Shell(s) => {
|
||||
let mut arg_variables: Vec<CuddleVariable> = vec![];
|
||||
@@ -28,15 +45,18 @@ impl CuddleAction {
|
||||
for (k, v) in args {
|
||||
let var = match v {
|
||||
CuddleShellScriptArg::Env(e) => {
|
||||
let env_var = match std::env::var(e.key.clone()) {
|
||||
Ok(var) => var,
|
||||
Err(e) => {
|
||||
log::error!("env_variable not found: {}", k);
|
||||
return Err(anyhow::anyhow!(e));
|
||||
}
|
||||
};
|
||||
let env_var = matches.get_one::<String>(&e.key).cloned().unwrap();
|
||||
|
||||
CuddleVariable::new(k.clone(), env_var)
|
||||
}
|
||||
CuddleShellScriptArg::Flag(flag) => {
|
||||
match matches.get_one::<String>(&flag.name) {
|
||||
Some(flag_var) => {
|
||||
CuddleVariable::new(k.clone(), flag_var.clone())
|
||||
}
|
||||
None => continue,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
arg_variables.push(var);
|
||||
|
@@ -43,6 +43,7 @@ impl CuddleCli {
|
||||
|
||||
match context {
|
||||
Some(_) => {
|
||||
tracing::debug!("build full cli");
|
||||
cli = cli
|
||||
.process_variables()
|
||||
.process_scripts()
|
||||
@@ -50,6 +51,7 @@ impl CuddleCli {
|
||||
.build_cli();
|
||||
}
|
||||
None => {
|
||||
tracing::debug!("build bare cli");
|
||||
cli = cli.build_bare_cli();
|
||||
}
|
||||
}
|
||||
@@ -98,8 +100,17 @@ impl CuddleCli {
|
||||
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))
|
||||
match &script {
|
||||
CuddleScript::Shell(shell_script) => {
|
||||
self.scripts.push(CuddleAction::new(
|
||||
script.clone(),
|
||||
ctx.path.clone(),
|
||||
name,
|
||||
shell_script.description.clone(),
|
||||
))
|
||||
}
|
||||
CuddleScript::Dagger(_) => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
use clap::{ArgMatches, Command};
|
||||
use clap::{Arg, ArgMatches, Command};
|
||||
|
||||
use crate::cli::CuddleCli;
|
||||
|
||||
@@ -9,11 +9,7 @@ pub fn build_command(root_cmd: Command, cli: CuddleCli) -> Command {
|
||||
.about(execute_cmd_about)
|
||||
.subcommand_required(true);
|
||||
|
||||
for script in cli.scripts.iter() {
|
||||
let action_cmd = Command::new(&script.name).about(&script.name);
|
||||
|
||||
execute_cmd = execute_cmd.subcommand(action_cmd);
|
||||
}
|
||||
execute_cmd = execute_cmd.subcommands(&build_scripts(cli));
|
||||
|
||||
root_cmd.subcommand(execute_cmd)
|
||||
} else {
|
||||
@@ -21,13 +17,62 @@ pub fn build_command(root_cmd: Command, cli: CuddleCli) -> Command {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build_scripts(cli: CuddleCli) -> Vec<Command> {
|
||||
let mut cmds = Vec::new();
|
||||
for script in cli.scripts.iter() {
|
||||
let mut cmd = Command::new(&script.name);
|
||||
|
||||
if let Some(desc) = &script.description {
|
||||
cmd = cmd.about(desc)
|
||||
}
|
||||
|
||||
match &script.script {
|
||||
crate::model::CuddleScript::Shell(shell_script) => {
|
||||
if let Some(args) = &shell_script.args {
|
||||
for (arg_name, arg) in args {
|
||||
cmd = match arg {
|
||||
crate::model::CuddleShellScriptArg::Env(arg_env) => cmd.arg(
|
||||
Arg::new(arg_name.clone())
|
||||
.env(arg_name.to_uppercase().replace(".", "_"))
|
||||
.required(true),
|
||||
),
|
||||
crate::model::CuddleShellScriptArg::Flag(arg_flag) => {
|
||||
let mut arg_val = Arg::new(arg_name.clone())
|
||||
.env(arg_name.to_uppercase().replace(".", "_"))
|
||||
.long(arg_name);
|
||||
|
||||
if let Some(true) = arg_flag.required {
|
||||
arg_val = arg_val.required(true);
|
||||
}
|
||||
|
||||
if let Some(def) = &arg_flag.default_value {
|
||||
arg_val = arg_val.default_value(def);
|
||||
}
|
||||
|
||||
cmd.arg(arg_val)
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
crate::model::CuddleScript::Dagger(_) => todo!(),
|
||||
}
|
||||
|
||||
cmds.push(cmd)
|
||||
}
|
||||
|
||||
cmds
|
||||
}
|
||||
|
||||
pub fn execute_x(exe_submatch: &ArgMatches, cli: CuddleCli) -> anyhow::Result<()> {
|
||||
match exe_submatch.subcommand() {
|
||||
Some((name, _action_matches)) => {
|
||||
Some((name, action_matches)) => {
|
||||
log::trace!(action=name; "running action; name={}", name);
|
||||
match cli.scripts.iter().find(|ele| ele.name == name) {
|
||||
Some(script) => {
|
||||
script.clone().execute(cli.variables.clone())?;
|
||||
script
|
||||
.clone()
|
||||
.execute(action_matches, cli.variables.clone())?;
|
||||
Ok(())
|
||||
}
|
||||
_ => Err(anyhow::anyhow!("could not find a match")),
|
||||
|
@@ -1,5 +1,7 @@
|
||||
use config::CuddleConfig;
|
||||
use tracing::Level;
|
||||
use tracing_subscriber::prelude::*;
|
||||
use tracing_subscriber::{fmt, EnvFilter};
|
||||
|
||||
mod actions;
|
||||
mod cli;
|
||||
@@ -20,7 +22,10 @@ fn main() -> anyhow::Result<()> {
|
||||
}
|
||||
|
||||
fn init_logging() -> anyhow::Result<()> {
|
||||
tracing_subscriber::fmt().with_max_level(Level::INFO).init();
|
||||
tracing_subscriber::registry()
|
||||
.with(fmt::layer())
|
||||
.with(EnvFilter::from_default_env())
|
||||
.init();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@@ -14,11 +14,21 @@ pub struct CuddleShellScriptArgEnv {
|
||||
pub key: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Deserialize)]
|
||||
pub struct CuddleShellScriptArgFlag {
|
||||
pub name: String,
|
||||
pub description: Option<String>,
|
||||
pub required: Option<bool>,
|
||||
pub default_value: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Deserialize)]
|
||||
#[serde(tag = "type")]
|
||||
pub enum CuddleShellScriptArg {
|
||||
#[serde(alias = "env")]
|
||||
Env(CuddleShellScriptArgEnv),
|
||||
#[serde(alias = "flag")]
|
||||
Flag(CuddleShellScriptArgFlag),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Deserialize)]
|
||||
|
Reference in New Issue
Block a user