diff --git a/Maidfile.toml b/Maidfile.toml index 17d1a7dc4d6e96e8117e071c472f207bfef95fcf..96c076da387ac28e07793f6687bef3cc7b43046b 100644 --- a/Maidfile.toml +++ b/Maidfile.toml @@ -29,14 +29,15 @@ depends = ["clean"] script = [ "cargo zigbuild --release --no-default-features --features client --color always", # "cargo zigbuild --release --all-features --color always", - "mv target/release/maid bin/maid", - "mv target/release/maid-server bin/maid-server", + "cp target/release/maid bin/maid", + # "cp target/release/maid-server bin/maid-server", ] # Build cache [tasks.build.cache] path = "maid" -target = ["bin/maid", "bin/maid-server"] +# target = ["bin/maid", "bin/maid-server"] +target = ["bin/maid"] # Remote build target [tasks.build.remote] diff --git a/maid/client/cli/butler.rs b/maid/client/cli/butler.rs index 484553b8d6bd2c542c40bbbe37dd43a7f88b441b..c92f2385485da7c946f9f338a97b809dc53e0fe4 100644 --- a/maid/client/cli/butler.rs +++ b/maid/client/cli/butler.rs @@ -27,7 +27,9 @@ pub fn watch(path: &Path) { pub fn update() { println!("check and retrive updates") } -pub fn init(path: String) { +pub fn init() { + let path = "maidfile"; + let example_maidfile = "[tasks.example]\ninfo = \"this is a comment\"\nscript = \"echo 'hello world'\""; if !helpers::Exists::file(path.to_owned()).unwrap() { diff --git a/maid/client/cli/mod.rs b/maid/client/cli/mod.rs index 6085ff9aea8b3d5690334b93faf5b3cf4eb261c1..8c788e0dae0b6951b0a0bbdaa77d6ef8cad4bfa7 100644 --- a/maid/client/cli/mod.rs +++ b/maid/client/cli/mod.rs @@ -18,7 +18,7 @@ pub fn get_version(short: bool) -> String { }; } -pub fn info(path: &String) { +pub fn info(path: &String) { let values = helpers::maidfile::merge(path); let project_root = parse::file::find_maidfile_root(path); diff --git a/maid/client/cli/tasks.rs b/maid/client/cli/tasks.rs index e64569d6ab1a044dcaa00931a96dfa150e0f61ae..ebd170d8abbd0cf1becc32252ead02e038e870a8 100644 --- a/maid/client/cli/tasks.rs +++ b/maid/client/cli/tasks.rs @@ -9,7 +9,7 @@ use inquire::Select; use macros_rs::{string, ternary}; use text_placeholder::Template; -pub fn json(path: &String, args: &Vec<String>, hydrate: &bool) { +pub fn json(path: &String, args: &Vec<String>, hydrate: bool) { let values = helpers::maidfile::merge(path); let project_root = parse::file::find_maidfile_root(path); let json = values.clone().to_json(); diff --git a/maid/client/main.rs b/maid/client/main.rs index 8316a7ac021401f573fcbd9d34b8e570cdc06b2c..4b5fc25320b157b4350eee4acc7144dcc7385c70 100644 --- a/maid/client/main.rs +++ b/maid/client/main.rs @@ -8,87 +8,89 @@ mod structs; mod table; mod task; -use clap::{Parser, Subcommand}; +use clap::{Parser, ValueEnum}; use clap_verbosity_flag::Verbosity; use macros_rs::str; -use std::{io::Result, path::Path}; +use std::path::Path; -type File = Option<String>; - -fn parse_init(arg: &str) -> Result<File> { - let s = arg.to_string(); - let path = match s.starts_with('-') { - true => Some("maidfile".into()), - false => Some(s), - }; - Ok(path) +macro_rules! dispatch { + ($cli:expr, { $($flag:ident => $func:expr),+ $(,)? }) => {$( + if $cli.$flag { + return $func; + } + )+}; } #[derive(Parser)] #[command(version = str!(cli::get_version(false)))] +#[clap(disable_help_flag = true, disable_help_subcommand = true)] struct Cli { /// Run a task defined in maidfile #[arg(default_value = "", hide_default_value = true)] task: Vec<String>, + /// Base path for Maidfile - #[arg(global = true, short, long, default_value = "maidfile")] + #[arg(short, long, default_value = "maidfile")] path: String, + /// Ignore cache on build #[arg(short, long)] force: bool, + + /// Switch Maid to server mode + #[arg(short, long, visible_alias = "online")] + remote: bool, + + /// Clear build cache + #[arg(short = 'C', long, visible_alias = "purge", group = "commands")] + clean_cache: bool, + /// Create new Maid project - #[arg(short, long, value_parser = parse_init)] - init: Option<File>, - #[command(subcommand)] - command: Option<Commands>, + #[arg(short, long, group = "commands")] + init: bool, + + /// List all runnable tasks + #[arg(short, long, visible_alias = "tasks", visible_alias = "ls", group = "commands")] + list: bool, + + /// Watch for changes in specified path + #[arg(short, long)] + watch: Option<String>, + + /// View Maid health (server health if enabled) + #[arg(short = 'H', long, group = "commands")] + health: bool, + + /// Per project commands + #[arg(short = 'w', long, group = "commands")] + project: Option<Project>, + + /// Management Maid commands + #[arg(short = 'g', long, group = "commands")] + system: Option<System>, + #[clap(flatten)] verbose: Verbosity, + + /// Shows this quick reference + #[clap(short, long, action = clap::ArgAction::HelpLong)] + help: Option<bool>, } -#[derive(Subcommand)] -enum Commands { - /// All internal maid commands - Butler { - #[command(subcommand)] - internal: Butler, - }, - /// All remote maid commands - Remote { - #[arg(default_value = "", hide_default_value = true)] - task: Vec<String>, - #[command(subcommand)] - server: Option<Remote>, - }, +#[derive(ValueEnum, Clone)] +enum System { + /// Check for new Maid updates + Update, + /// Return the Maidfile in json + Json, + /// Hydrate json output with environment + HydrateJson, } -#[derive(Subcommand)] -enum Butler { - /// List all maidfile tasks - #[command(visible_alias = "ls", visible_alias = "list")] - Tasks, +#[derive(ValueEnum, Clone)] +enum Project { /// Get Project Info Info, - /// Clear maid cache - Clean, - /// Watch maidfile task - Watch, - /// Check/Retrieve updates - Update, - /// Return the maidfile in json - Json { - #[arg(long, default_value_t = false, help = "Hydrate json output with env")] - hydrate: bool, - }, -} - -#[derive(Subcommand)] -enum Remote { - /// List all remote maidfile tasks - List, - /// Test server specified in maidfile - Connect, - /// Clear remote maid cache - Clean, } fn main() { @@ -96,26 +98,41 @@ fn main() { globals::init(); env_logger::Builder::new().filter_level(cli.verbose.log_level_filter()).init(); - - if let Some(path) = cli.init { - return cli::butler::init(path.expect("Expected valid path")); - } - - match &cli.command { - Some(Commands::Butler { internal }) => match internal { - Butler::Json { hydrate } => cli::tasks::json(&cli.path, &cli.task, hydrate), - Butler::Info => cli::info(&cli.path), - Butler::Clean => cli::butler::clean(), - Butler::Watch => cli::butler::watch(Path::new("src")), - Butler::Update => cli::butler::update(), - Butler::Tasks => cli::tasks::List::all(&cli.path, cli.verbose.is_silent(), cli.verbose.log_level(), cli.force), + + dispatch!(cli, { + init => cli::butler::init(), + health => server::cli::connect(&cli.path), + health => match cli.remote { + true => server::cli::connect(&cli.path), + false => server::cli::connect(&cli.path), // improve health command for later }, - Some(Commands::Remote { task, server }) => match server { - Some(Remote::Connect) => server::cli::connect(&cli.path), - Some(Remote::Clean) => server::cli::connect(&cli.path), - Some(Remote::List) => cli::tasks::List::remote(&cli.path, cli.verbose.is_silent(), cli.verbose.log_level()), - None => cli::exec(task[0].trim(), &task, &cli.path, cli.verbose.is_silent(), false, true, cli.verbose.log_level(), false), + clean_cache => match cli.remote { + true => server::cli::connect(&cli.path), + false => cli::butler::clean(), }, - None => cli::exec(cli.task[0].trim(), &cli.task, &cli.path, cli.verbose.is_silent(), false, false, cli.verbose.log_level(), cli.force), + list => match cli.remote { + true => cli::tasks::List::remote(&cli.path, cli.verbose.is_silent(), cli.verbose.log_level()), + false => cli::tasks::List::all(&cli.path, cli.verbose.is_silent(), cli.verbose.log_level(), cli.force), + } + }); + + if let Some(project) = cli.project { + return match project { + Project::Info => cli::info(&cli.path), // add more info + }; + } + + if let Some(system) = cli.system { + return match system { + System::Update => cli::butler::update(), // add real update checker + System::Json => cli::tasks::json(&cli.path, &cli.task, false), + System::HydrateJson => cli::tasks::json(&cli.path, &cli.task, true), + }; + } + + if let Some(path) = cli.watch { + return cli::butler::watch(Path::new(&path)); // migrate watch path into executer below } + + cli::exec(cli.task[0].trim(), &cli.task, &cli.path, cli.verbose.is_silent(), false, cli.remote, cli.verbose.log_level(), cli.force) }