feat: with schema
Signed-off-by: kjuulh <contact@kjuulh.io>
This commit is contained in:
parent
6a82e0c10a
commit
12bd424f18
29
Cargo.lock
generated
29
Cargo.lock
generated
@ -1280,6 +1280,15 @@ dependencies = [
|
|||||||
"value-bag",
|
"value-bag",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "matchers"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
|
||||||
|
dependencies = [
|
||||||
|
"regex-automata",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.5.0"
|
version = "2.5.0"
|
||||||
@ -1675,9 +1684,24 @@ checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick 1.0.2",
|
"aho-corasick 1.0.2",
|
||||||
"memchr",
|
"memchr",
|
||||||
"regex-syntax",
|
"regex-syntax 0.7.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-automata"
|
||||||
|
version = "0.1.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
|
||||||
|
dependencies = [
|
||||||
|
"regex-syntax 0.6.29",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-syntax"
|
||||||
|
version = "0.6.29"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-syntax"
|
name = "regex-syntax"
|
||||||
version = "0.7.2"
|
version = "0.7.2"
|
||||||
@ -2215,7 +2239,10 @@ version = "0.3.17"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77"
|
checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"matchers",
|
||||||
"nu-ansi-term",
|
"nu-ansi-term",
|
||||||
|
"once_cell",
|
||||||
|
"regex",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sharded-slab",
|
"sharded-slab",
|
||||||
|
@ -24,7 +24,7 @@ clap = { version = "4.3.4", features = ["env", "string"] }
|
|||||||
envconfig = "0.10.0"
|
envconfig = "0.10.0"
|
||||||
dirs = "5.0.1"
|
dirs = "5.0.1"
|
||||||
tracing = "0.1.36"
|
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"] }
|
log = { version = "0.4.17", features = ["std", "kv_unstable"] }
|
||||||
tera = "1.17.0"
|
tera = "1.17.0"
|
||||||
openssl = { version = "0.10.54", features = ["vendored"] }
|
openssl = { version = "0.10.54", features = ["vendored"] }
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use clap::ArgMatches;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
actions::shell::ShellAction,
|
actions::shell::ShellAction,
|
||||||
model::{CuddleScript, CuddleShellScriptArg, CuddleVariable},
|
model::{CuddleScript, CuddleShellScriptArg, CuddleVariable},
|
||||||
@ -12,15 +14,30 @@ pub mod shell;
|
|||||||
pub struct CuddleAction {
|
pub struct CuddleAction {
|
||||||
pub script: CuddleScript,
|
pub script: CuddleScript,
|
||||||
pub path: PathBuf,
|
pub path: PathBuf,
|
||||||
|
pub description: Option<String>,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
}
|
}
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
impl CuddleAction {
|
impl CuddleAction {
|
||||||
pub fn new(script: CuddleScript, path: PathBuf, name: String) -> Self {
|
pub fn new(
|
||||||
Self { script, path, name }
|
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 {
|
match self.script {
|
||||||
CuddleScript::Shell(s) => {
|
CuddleScript::Shell(s) => {
|
||||||
let mut arg_variables: Vec<CuddleVariable> = vec![];
|
let mut arg_variables: Vec<CuddleVariable> = vec![];
|
||||||
@ -28,15 +45,18 @@ impl CuddleAction {
|
|||||||
for (k, v) in args {
|
for (k, v) in args {
|
||||||
let var = match v {
|
let var = match v {
|
||||||
CuddleShellScriptArg::Env(e) => {
|
CuddleShellScriptArg::Env(e) => {
|
||||||
let env_var = match std::env::var(e.key.clone()) {
|
let env_var = matches.get_one::<String>(&e.key).cloned().unwrap();
|
||||||
Ok(var) => var,
|
|
||||||
Err(e) => {
|
|
||||||
log::error!("env_variable not found: {}", k);
|
|
||||||
return Err(anyhow::anyhow!(e));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
CuddleVariable::new(k.clone(), env_var)
|
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);
|
arg_variables.push(var);
|
||||||
|
@ -43,6 +43,7 @@ impl CuddleCli {
|
|||||||
|
|
||||||
match context {
|
match context {
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
|
tracing::debug!("build full cli");
|
||||||
cli = cli
|
cli = cli
|
||||||
.process_variables()
|
.process_variables()
|
||||||
.process_scripts()
|
.process_scripts()
|
||||||
@ -50,6 +51,7 @@ impl CuddleCli {
|
|||||||
.build_cli();
|
.build_cli();
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
|
tracing::debug!("build bare cli");
|
||||||
cli = cli.build_bare_cli();
|
cli = cli.build_bare_cli();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -98,8 +100,17 @@ impl CuddleCli {
|
|||||||
for ctx in context_iter.iter() {
|
for ctx in context_iter.iter() {
|
||||||
if let Some(scripts) = ctx.plan.scripts.clone() {
|
if let Some(scripts) = ctx.plan.scripts.clone() {
|
||||||
for (name, script) in scripts {
|
for (name, script) in scripts {
|
||||||
self.scripts
|
match &script {
|
||||||
.push(CuddleAction::new(script.clone(), ctx.path.clone(), name))
|
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;
|
use crate::cli::CuddleCli;
|
||||||
|
|
||||||
@ -9,11 +9,7 @@ pub fn build_command(root_cmd: Command, cli: CuddleCli) -> Command {
|
|||||||
.about(execute_cmd_about)
|
.about(execute_cmd_about)
|
||||||
.subcommand_required(true);
|
.subcommand_required(true);
|
||||||
|
|
||||||
for script in cli.scripts.iter() {
|
execute_cmd = execute_cmd.subcommands(&build_scripts(cli));
|
||||||
let action_cmd = Command::new(&script.name).about(&script.name);
|
|
||||||
|
|
||||||
execute_cmd = execute_cmd.subcommand(action_cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
root_cmd.subcommand(execute_cmd)
|
root_cmd.subcommand(execute_cmd)
|
||||||
} else {
|
} 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<()> {
|
pub fn execute_x(exe_submatch: &ArgMatches, cli: CuddleCli) -> anyhow::Result<()> {
|
||||||
match exe_submatch.subcommand() {
|
match exe_submatch.subcommand() {
|
||||||
Some((name, _action_matches)) => {
|
Some((name, action_matches)) => {
|
||||||
log::trace!(action=name; "running action; name={}", name);
|
log::trace!(action=name; "running action; name={}", name);
|
||||||
match cli.scripts.iter().find(|ele| ele.name == name) {
|
match cli.scripts.iter().find(|ele| ele.name == name) {
|
||||||
Some(script) => {
|
Some(script) => {
|
||||||
script.clone().execute(cli.variables.clone())?;
|
script
|
||||||
|
.clone()
|
||||||
|
.execute(action_matches, cli.variables.clone())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
_ => Err(anyhow::anyhow!("could not find a match")),
|
_ => Err(anyhow::anyhow!("could not find a match")),
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
use config::CuddleConfig;
|
use config::CuddleConfig;
|
||||||
use tracing::Level;
|
use tracing::Level;
|
||||||
|
use tracing_subscriber::prelude::*;
|
||||||
|
use tracing_subscriber::{fmt, EnvFilter};
|
||||||
|
|
||||||
mod actions;
|
mod actions;
|
||||||
mod cli;
|
mod cli;
|
||||||
@ -20,7 +22,10 @@ fn main() -> anyhow::Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn init_logging() -> 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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -14,11 +14,21 @@ pub struct CuddleShellScriptArgEnv {
|
|||||||
pub key: String,
|
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)]
|
#[derive(Debug, Clone, PartialEq, Deserialize)]
|
||||||
#[serde(tag = "type")]
|
#[serde(tag = "type")]
|
||||||
pub enum CuddleShellScriptArg {
|
pub enum CuddleShellScriptArg {
|
||||||
#[serde(alias = "env")]
|
#[serde(alias = "env")]
|
||||||
Env(CuddleShellScriptArgEnv),
|
Env(CuddleShellScriptArgEnv),
|
||||||
|
#[serde(alias = "flag")]
|
||||||
|
Flag(CuddleShellScriptArgFlag),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Deserialize)]
|
||||||
|
@ -70,6 +70,29 @@
|
|||||||
"patternProperties": {
|
"patternProperties": {
|
||||||
"^.*$": {
|
"^.*$": {
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"name"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"enum": [
|
||||||
|
"flag"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"required": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
|
Loading…
Reference in New Issue
Block a user