diff --git a/Cargo.lock b/Cargo.lock index 171caddb779aead920384a7efd531a5b26ad5bf3..fef3be67c3b6f545559c356a6cc18791da386fd0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1467,9 +1467,12 @@ dependencies = [ [[package]] name = "macros-rs" -version = "0.5.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb1feaac5c34086868f3f439dabbd71baf6a785f256aacdde7c66c95b56b12d6" +checksum = "9cfca1250b52a785fbe49de29612471f59592b6b659159dcfcb976af08c803b4" +dependencies = [ + "termcolor", +] [[package]] name = "maid" diff --git a/Cargo.toml b/Cargo.toml index d0a1963740a8cfb1f7f0f6be8bdd432c95c6a791..49a246a9d820ebbbdb9c6289269ad72610220aa6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -77,7 +77,7 @@ flate2 = "1.0.35" anyhow = "1.0.93" tracing = "0.1.40" termcolor = "1.4.1" -macros-rs = "0.5.2" +macros-rs = "1.4.1" indicatif = "0.17.9" serde_json = "1.0.133" text_placeholder = "0.5.1" diff --git a/maid/client/cli/dispatch.rs b/maid/client/cli/dispatch.rs index b908b31c9e70a7b70a591ba00b288105d138b6b2..ece144cb680778992d36bb8d0b2cf870d30e1f67 100644 --- a/maid/client/cli/dispatch.rs +++ b/maid/client/cli/dispatch.rs @@ -1,8 +1,7 @@ -use crate::helpers; use maid::log::prelude::*; use inquire::Text; -use macros_rs::string; +use macros_rs::fs::file_exists; use notify::RecursiveMode; use notify_debouncer_mini::new_debouncer; use std::{fs::File, io::Write, path::Path, time::Duration}; @@ -41,7 +40,7 @@ pub(crate) 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() { + if !file_exists!(path) { println!("This utility will walk you through creating a maidfile.\n"); let mut file = File::create(&path).unwrap(); @@ -62,7 +61,7 @@ pub(crate) fn init() { writeln!(&mut file, "\n{example_maidfile}").unwrap(); println!("{}", "\n✨ success, saved maidfile".yellow()); - if helpers::Exists::file(string!(".git")).unwrap() { + if file_exists!(".git") { println!("{}", "dont forget to add '.maid' to your .gitignore".white()); } } else { diff --git a/maid/client/cli/mod.rs b/maid/client/cli/mod.rs index 3fea7553b75ef67bb29d0891813bff278a4935fe..fb24243155626d75f7441912de2d048f32e709ca 100644 --- a/maid/client/cli/mod.rs +++ b/maid/client/cli/mod.rs @@ -2,20 +2,24 @@ pub(crate) mod dispatch; pub(crate) mod run; pub(crate) mod tasks; -use crate::helpers; use crate::parse; use crate::server; -use crate::structs::{Cache, CacheConfig, Task}; use crate::task; -use maid::log::prelude::*; +use maid::models::client::{Cache, CacheConfig, Task}; +use maid::{helpers, log::prelude::*}; use fs_extra::dir::get_size; use global_placeholders::global; use human_bytes::human_bytes; -use macros_rs::{crashln, fmtstr, string, ternary}; use std::{env, path::Path, time::Instant}; +use macros_rs::{ + exp::ternary, + fmt::{fmtstr, string}, + fs::{file_exists, folder_exists}, +}; + pub fn get_version(short: bool) -> String { return match short { true => format!("{} {}", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION")), @@ -24,7 +28,7 @@ pub fn get_version(short: bool) -> String { } pub fn info(path: &String) { - let values = helpers::maidfile::merge(path); + let values = parse::merge(path); let project_root = parse::file::find_maidfile_root(path); let name = match &values.project { @@ -62,22 +66,22 @@ pub fn exec(task: &str, args: &Vec<String>, path: &String, silent: bool, is_dep: tasks::List::all(path, silent, log_level, force); } } else { - let values = helpers::maidfile::merge(path); + let values = parse::merge(path); let project_root = parse::file::find_maidfile_root(path); let cwd = &helpers::file::get_current_working_dir(); if values.tasks.get(task).is_none() { - crashln!("Maid could not find the task '{task}'. Does it exist?"); + error!("Could not find the task '{task}'. Does it exist?"); } if is_remote && values.tasks.get(task).unwrap().remote.is_none() { - crashln!("Maid could not find the remote task '{task}'. Does it exist?"); + error!("Could not find the remote task '{task}'. Does it exist?"); } match values.tasks.get(task).unwrap().remote.as_ref() { Some(val) => { if val.exclusive && !is_remote { - crashln!("Task '{task}' is remote only."); + error!("Task '{task}' is remote only."); } } None => {} @@ -125,7 +129,7 @@ pub fn exec(task: &str, args: &Vec<String>, path: &String, silent: bool, is_dep: .to_string(); if !cache.path.trim().is_empty() && !cache.target.is_empty() && !is_remote { - if !helpers::Exists::folder(global!("maid.cache_dir", task)).unwrap() { + if !folder_exists!(&global!("maid.cache_dir", task)) { std::fs::create_dir_all(global!("maid.cache_dir", task)).unwrap(); debug!("created maid cache dir"); } @@ -133,7 +137,7 @@ pub fn exec(task: &str, args: &Vec<String>, path: &String, silent: bool, is_dep: let hash = task::cache::create_hash(&cache.path); let config_path = format!(".maid/cache/{task}/{}.toml", task); - if !helpers::Exists::file(config_path.clone()).unwrap() { + if !file_exists!(&config_path) { match std::fs::write( config_path.clone(), toml::to_string(&CacheConfig { @@ -142,19 +146,19 @@ pub fn exec(task: &str, args: &Vec<String>, path: &String, silent: bool, is_dep: }) .unwrap(), ) { - Ok(_) => debug!("created {task} cache config"), - Err(err) => crashln!("error {err} creating cache config"), + Ok(_) => debug!("Created {task} cache config"), + Err(err) => error!(%err, "Cannot create cache config"), }; } let contents = match std::fs::read_to_string(config_path.clone()) { Ok(content) => content, - Err(err) => crashln!("Cannot read cache config: {err}"), + Err(err) => error!(%err, "Cannot read cache config"), }; let json = match toml::from_str::<CacheConfig>(&contents) { Ok(contents) => contents, - Err(err) => crashln!("Cannot read cache config: {err}"), + Err(err) => error!(%err, "Cannot read cache config"), }; if json.hash == hash && !is_dep && !force { diff --git a/maid/client/cli/run.rs b/maid/client/cli/run.rs index 59ded4eb331225195f202e06258a03186df51b2e..b0ff970f9a9ede716ab5dfb5f318fad14fc602dc 100644 --- a/maid/client/cli/run.rs +++ b/maid/client/cli/run.rs @@ -1,14 +1,12 @@ -use maid::log::prelude::*; +use maid::models::client::{Cache, Runner}; +use maid::{helpers, log::prelude::*, table}; use crate::cli; -use crate::helpers; use crate::shell::IntoArgs; -use crate::structs::{Cache, Runner}; -use crate::table; use fs_extra::dir::get_size; use human_bytes::human_bytes; -use macros_rs::{crashln, string}; + use std::env; use std::io::Error; use std::path::Path; @@ -71,7 +69,7 @@ fn run_script(runner: Runner) { let cache = match &runner.maidfile.tasks[runner.name].cache { Some(cache) => cache.clone(), - None => Cache { path: string!(""), target: vec![] }, + None => Cache { path: "".to_string(), target: vec![] }, }; let exit_code = helpers::status::code(status); @@ -128,18 +126,18 @@ pub fn task(task: cli::Task) { if task.script.is_str() { match task.script.as_str() { Some(cmd) => script.push(cmd), - None => crashln!("Unable to parse maidfile. Missing string value."), + None => error!("Unable to parse Maidfile. Missing string value."), }; } else if task.script.is_array() { match IntoIterator::into_iter(match task.script.as_array() { Some(iter) => iter, - None => crashln!("Unable to parse maidfile. Missing array value."), + None => error!("Unable to parse Maidfile. Missing array value."), }) { mut iter => loop { match Iterator::next(&mut iter) { Some(val) => match val.as_str() { Some(cmd) => script.push(cmd), - None => crashln!("Unable to parse maidfile. Missing string value."), + None => error!("Unable to parse Maidfile. Missing string value."), }, None => break, }; diff --git a/maid/client/cli/tasks.rs b/maid/client/cli/tasks.rs index 49d64ac4a2986593f348542979024aad91790388..ac7a2265c949596c753520a088b36ab6ad85d37d 100644 --- a/maid/client/cli/tasks.rs +++ b/maid/client/cli/tasks.rs @@ -1,16 +1,14 @@ use crate::cli; -use crate::helpers; use crate::parse; -use crate::structs; -use crate::table; use inquire::Select; -use macros_rs::{string, ternary}; +use macros_rs::{exp::ternary, fmt::string}; use maid::log::prelude::*; +use maid::{models::client::DisplayTask, table}; use text_placeholder::Template; pub fn json(path: &String, args: &Vec<String>, hydrate: bool) { - let values = helpers::maidfile::merge(path); + let values = parse::merge(path); let project_root = parse::file::find_maidfile_root(path); let json = values.clone().to_json(); let table = table::create(values.clone(), args, project_root); @@ -22,7 +20,7 @@ pub fn json(path: &String, args: &Vec<String>, hydrate: bool) { pub struct List; impl List { pub fn all(path: &String, silent: bool, log_level: Option<tracing::Level>, force: bool) { - let values = helpers::maidfile::merge(path); + let values = parse::merge(path); let mut options: Vec<_> = values .tasks .iter() @@ -51,7 +49,7 @@ impl List { }, }; - return structs::DisplayTask { + return DisplayTask { name: key.clone(), formatted: format!("{} {} {}", format!("{key}").bright_yellow(), info, verbose.bright_blue()), hidden: hidden.clone(), @@ -71,7 +69,7 @@ impl List { } pub fn remote(path: &String, silent: bool, log_level: Option<tracing::Level>) { - let values = helpers::maidfile::merge(path); + let values = parse::merge(path); let mut options: Vec<_> = values .tasks .iter() @@ -94,7 +92,7 @@ impl List { None => true, }; - return structs::DisplayTask { + return DisplayTask { name: key.clone(), formatted: format!("{} {} {}", format!("{key}").bright_yellow(), info, verbose.bright_blue()), hidden: hidden.clone(), diff --git a/maid/client/helpers/maidfile.rs b/maid/client/helpers/maidfile.rs deleted file mode 100644 index 6c7aad8f7c9a5ecbab7ec934986ce7fa4ce9f190..0000000000000000000000000000000000000000 --- a/maid/client/helpers/maidfile.rs +++ /dev/null @@ -1,31 +0,0 @@ -use crate::parse; -use crate::structs::{DisplayTask, Maidfile}; -use maid::log::prelude::*; - -pub fn merge(path: &String) -> Maidfile { - let mut values = parse::file::read_maidfile(path); - let imported_values = parse::import::push(values.import.clone()); - - for import in imported_values.iter() { - values = match merge_struct::merge(&values, &import) { - Ok(merge) => merge, - Err(err) => error!(%err, "Unable to import tasks"), - }; - } - - return values; -} - -impl Maidfile { - pub fn to_json(&self) -> String { - match serde_json::to_string(&self) { - Ok(contents) => contents, - Err(err) => error!(%err, "Cannot read Maidfile"), - } - } -} - -impl std::fmt::Display for DisplayTask { - #[inline] - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(&self.formatted, f) } -} diff --git a/maid/client/helpers/mod.rs b/maid/client/helpers/mod.rs index 19ab9a6c15fa3652f8eb9886ff294c98bafcd926..cbcf28ec0ba73e0a6c15886b5a4dbd6a86233139 100644 --- a/maid/client/helpers/mod.rs +++ b/maid/client/helpers/mod.rs @@ -1,15 +1 @@ -use anyhow::Error; -use macros_rs::str; -use std::path::Path; - -pub struct Exists; -impl Exists { - pub fn folder(dir_name: String) -> Result<bool, Error> { Ok(Path::new(str!(dir_name)).is_dir()) } - pub fn file(file_name: String) -> Result<bool, Error> { Ok(Path::new(str!(file_name)).exists()) } -} - -pub mod file; -pub mod logger; -pub mod maidfile; -pub mod status; -pub mod string; +pub(crate) mod logger; diff --git a/maid/client/main.rs b/maid/client/main.rs index 588217d50c5d5840c25ac70a4d723086ae8147a2..f493e1a33466419cdcedae84e94c6b2fba604c8b 100644 --- a/maid/client/main.rs +++ b/maid/client/main.rs @@ -4,8 +4,6 @@ mod helpers; mod parse; mod server; mod shell; -mod structs; -mod table; mod task; use maid::log::{ @@ -14,7 +12,7 @@ use maid::log::{ }; use clap::{Parser, ValueEnum}; -use macros_rs::str; +use macros_rs::fmt::str; use std::path::Path; macro_rules! dispatch { diff --git a/maid/client/parse/file.rs b/maid/client/parse/file.rs index 49380a220df4728ef4f831f58d7914289f49c342..75875090b8d866a9559a5dfb192d3442639478ab 100644 --- a/maid/client/parse/file.rs +++ b/maid/client/parse/file.rs @@ -1,7 +1,7 @@ -use crate::structs::Maidfile; use maid::log::prelude::*; +use maid::models::client::Maidfile; -use macros_rs::{crashln, string, then}; +use macros_rs::{exp::then, fmt::string}; use std::{env, fs, io::Result, path::Path, path::PathBuf}; macro_rules! create_path { @@ -22,9 +22,7 @@ struct Filesystem { fn working_dir() -> PathBuf { match env::current_dir() { Ok(path) => path, - Err(_) => { - crashln!("Unable to find current working dir"); - } + Err(_) => error!("Unable to find current working dir"), } } @@ -80,10 +78,7 @@ fn find_file(starting_directory: &Path, file_name: &String) -> Option<PathBuf> { fn read_file(path: PathBuf, kind: &str) -> Maidfile { let contents = match fs::read_to_string(&path) { Ok(contents) => contents, - Err(err) => { - warn!("{}", err); - crashln!("Cannot find maidfile. Does it exist?"); - } + Err(_) => error!("Cannot find Maidfile. Does it exist?"), }; let result = match kind { diff --git a/maid/client/parse/import.rs b/maid/client/parse/import.rs index 69c6ea8bd1ccc50723ea7127cb3d7f0d8a6fb85e..0b0f789d256b1241ffe8564359c0b84131fba05d 100644 --- a/maid/client/parse/import.rs +++ b/maid/client/parse/import.rs @@ -1,6 +1,6 @@ use crate::parse; -use crate::structs::Maidfile; -use macros_rs::fmtstr; +use macros_rs::fmt::fmtstr; +use maid::models::client::Maidfile; pub fn push(path_list: Option<Vec<String>>) -> Vec<Maidfile> { let mut values: Vec<Maidfile> = vec![]; diff --git a/maid/client/parse/mod.rs b/maid/client/parse/mod.rs index 27d98a3270795f0898a516ca6ba574e60b31e588..5cc7f0fba8ad6d6d983f5437a5690906ad5e51c9 100644 --- a/maid/client/parse/mod.rs +++ b/maid/client/parse/mod.rs @@ -1,2 +1,19 @@ pub mod file; pub mod import; + +use maid::log::prelude::*; +use maid::models::client::Maidfile; + +pub(crate) fn merge(path: &String) -> Maidfile { + let mut values = file::read_maidfile(path); + let imported_values = import::push(values.import.clone()); + + for import in imported_values.iter() { + values = match merge_struct::merge(&values, &import) { + Ok(merge) => merge, + Err(err) => error!(%err, "Unable to import tasks"), + }; + } + + return values; +} diff --git a/maid/client/server/cli.rs b/maid/client/server/cli.rs index 4f4f6aa3722d3ca0ce48ea29bc4ebfe8b0d3a451..c98c5b8ec0eabd73dfc8ecb2faca9abfec159621 100644 --- a/maid/client/server/cli.rs +++ b/maid/client/server/cli.rs @@ -1,9 +1,10 @@ -use crate::helpers; +use crate::parse; use crate::server; -use crate::structs::{ConnectionData, ConnectionInfo, Kind, Level, Maidfile, Task, Websocket}; -use macros_rs::{crashln, fmtstr}; -use maid::log::prelude::*; +use maid::models::client::{ConnectionData, ConnectionInfo, Kind, Level, Maidfile, Task, Websocket}; +use maid::{helpers, log::prelude::*}; + +use macros_rs::fmt::fmtstr; use reqwest::blocking::Client; use tungstenite::protocol::frame::{coding::CloseCode::Normal, CloseFrame}; use tungstenite::{client::connect_with_config, client::IntoClientRequest, protocol::WebSocketConfig, Message}; @@ -26,7 +27,7 @@ fn health(client: Client, values: Maidfile) -> server::api::health::Route { } pub fn connect(path: &String) { - let values = helpers::maidfile::merge(path); + let values = parse::merge(path); let client = Client::new(); let body = health(client, values); @@ -53,18 +54,18 @@ pub fn remote(task: Task) { if task.script.is_str() { match task.script.as_str() { Some(cmd) => script.push(cmd), - None => crashln!("Unable to parse maidfile. Missing string value."), + None => error!("Unable to parse Maidfile. Missing string value."), }; } else if task.script.is_array() { match IntoIterator::into_iter(match task.script.as_array() { Some(iter) => iter, - None => crashln!("Unable to parse maidfile. Missing array value."), + None => error!("Unable to parse Maidfile. Missing array value."), }) { mut iter => loop { match Iterator::next(&mut iter) { Some(val) => match val.as_str() { Some(cmd) => script.push(cmd), - None => crashln!("Unable to parse maidfile. Missing string value."), + None => error!("Unable to parse Maidfile. Missing string value."), }, None => break, }; @@ -109,9 +110,7 @@ pub fn remote(task: Task) { let file_name = match server::file::write_tar(&task.remote.unwrap().push) { Ok(name) => name, - Err(err) => { - crashln!("Unable to create archive.\nError: {err}") - } + Err(err) => error!(%err, "Unable to create archive"), }; debug!("sending information"); @@ -131,13 +130,11 @@ pub fn remote(task: Task) { Ok(Message::Binary(archive)) => { let archive_name = match server::file::read_tar(&archive) { Ok(name) => name, - Err(err) => { - crashln!("Unable to read archive.\nError: {err}") - } + Err(err) => error!(%err, "Unable to read archive"), }; if let Err(err) = server::file::unpack_tar(&archive_name) { - crashln!("Unable to create archive.\nError: {err}") + error!(%err, "Unable to create archive") } server::file::remove_tar(&archive_name); @@ -160,6 +157,6 @@ pub fn remote(task: Task) { // run.rs:96 implement that later reason: std::borrow::Cow::Borrowed("finished task successfully"), })) { - crashln!("Unable to close socket.\nError: {err}") + error!(%err, "Unable to close socket") }; } diff --git a/maid/client/server/file.rs b/maid/client/server/file.rs index 0e864a9ae78473aad465c131d081470b67bf771f..72ea0d7806e571e9b45ad4d771ff281ffb458666 100644 --- a/maid/client/server/file.rs +++ b/maid/client/server/file.rs @@ -1,8 +1,6 @@ -use crate::helpers; - use flate2::{read::GzDecoder, write::GzEncoder, Compression}; use global_placeholders::global; -use macros_rs::crashln; +use macros_rs::fs::folder_exists; use maid::log::prelude::*; use std::{fs::write, fs::File, path::PathBuf}; use tar::{Archive, Builder}; @@ -21,12 +19,12 @@ fn append_to_tar(builder: &mut Builder<GzEncoder<File>>, path: &String) -> Resul pub fn remove_tar(file: &String) { if let Err(_) = std::fs::remove_file(file) { - crashln!("Unable to remove temporary archive. does it exist?"); + error!("Unable to remove temporary archive. does it exist?"); } } pub fn read_tar(archive: &Vec<u8>) -> Result<String, std::io::Error> { - if !helpers::Exists::folder(global!("maid.temp_dir")).unwrap() { + if !folder_exists!(&global!("maid.temp_dir")) { std::fs::create_dir_all(global!("maid.temp_dir")).unwrap(); debug!("created maid temp dir"); } @@ -46,7 +44,7 @@ pub fn unpack_tar(path: &String) -> std::io::Result<()> { } pub fn write_tar(files: &Vec<String>) -> Result<String, std::io::Error> { - if !helpers::Exists::folder(global!("maid.temp_dir")).unwrap() { + if !folder_exists!(&global!("maid.temp_dir")) { std::fs::create_dir_all(global!("maid.temp_dir")).unwrap(); debug!("created maid temp dir"); } diff --git a/maid/client/server/parse.rs b/maid/client/server/parse.rs index 0701cae032c0e00a69ef3f9883a761854f70289d..80b2e6bb49d8c5eaf9f99f120d1c3e41245da459 100644 --- a/maid/client/server/parse.rs +++ b/maid/client/server/parse.rs @@ -1,5 +1,5 @@ -use crate::structs::Maidfile; -use macros_rs::{string, ternary}; +use macros_rs::{exp::ternary, fmt::string}; +use maid::models::client::Maidfile; pub fn address(values: &Maidfile) -> String { match &values.project { diff --git a/maid/client/task/progress.rs b/maid/client/task/progress.rs index 8ac4f0a50d0db92f845a83bebe525e88d320a96c..94847f86f7f71951bd683fd1acb5874fd3bf1037 100644 --- a/maid/client/task/progress.rs +++ b/maid/client/task/progress.rs @@ -1,5 +1,5 @@ use indicatif::{ProgressBar, ProgressStyle}; -use macros_rs::fmtstr; +use macros_rs::fmt::fmtstr; pub fn init(ticks: Vec<&str>, template: &str, tick: u64) -> ProgressBar { let pb = ProgressBar::new_spinner(); diff --git a/maid/server/docker/run.rs b/maid/server/docker/run.rs index 91f858c79d607a30bbad7f341a9ddc5203ee6e22..feb8421b349ce4f35f2ead6e7fef88cd4d1c471f 100644 --- a/maid/server/docker/run.rs +++ b/maid/server/docker/run.rs @@ -16,11 +16,15 @@ use bytes::Bytes; use flate2::{write::GzEncoder, Compression}; use futures_core::Stream; use futures_util::{stream::TryStreamExt, SinkExt, StreamExt}; -use macros_rs::{fmtstr, str, string, then}; use rocket_ws::{stream::DuplexStream, Message}; use std::{default::Default, io::Write, path::PathBuf}; use text_placeholder::Template; +use macros_rs::{ + exp::then, + fmt::{fmtstr, str, string}, +}; + use bollard::{ container::{Config, DownloadFromContainerOptions, RemoveContainerOptions, UploadToContainerOptions}, errors::Error, diff --git a/maid/server/helpers/file.rs b/maid/server/helpers/file.rs deleted file mode 100644 index 4c1eb7250eaa8329572a441016a4821274bb1ac6..0000000000000000000000000000000000000000 --- a/maid/server/helpers/file.rs +++ /dev/null @@ -1,66 +0,0 @@ -use crate::helpers; -use maid::log::prelude::*; - -use flate2::{read::GzDecoder, write::GzEncoder, Compression}; -use global_placeholders::global; -use macros_rs::crashln; -use std::{fs::write, fs::File, path::PathBuf}; -use tar::{Archive, Builder}; -use uuid::Uuid; - -fn append_to_tar(builder: &mut Builder<GzEncoder<File>>, path: &String) -> Result<(), std::io::Error> { - let pathbuf = PathBuf::from(path); - - if pathbuf.is_file() { - builder.append_path(&pathbuf)?; - } else if pathbuf.is_dir() { - builder.append_dir_all(&pathbuf, &pathbuf)?; - } - Ok(()) -} - -pub fn remove_tar(file: &String) { - if let Err(_) = std::fs::remove_file(file) { - crashln!("Unable to remove temporary archive. does it exist?"); - } -} - -pub fn read_tar(archive: &Vec<u8>) -> Result<String, std::io::Error> { - if !helpers::Exists::folder(global!("maid.temp_dir")).unwrap() { - std::fs::create_dir_all(global!("maid.temp_dir")).unwrap(); - info!("created maid temp dir"); - } - - let file_name = format!("{}/{}.tgz", global!("maid.temp_dir"), Uuid::new_v4()); - write(&file_name, archive)?; - - Ok(file_name) -} - -pub fn unpack_tar(path: &String) -> std::io::Result<()> { - let archive = File::open(&path)?; - let tar = GzDecoder::new(archive); - let mut archive = Archive::new(tar); - - archive.unpack(".") -} - -pub fn write_tar(files: &Vec<String>) -> Result<String, std::io::Error> { - if !helpers::Exists::folder(global!("maid.temp_dir")).unwrap() { - std::fs::create_dir_all(global!("maid.temp_dir")).unwrap(); - info!("created maid temp dir"); - } - - let file_name = format!("{}/{}.tgz", global!("maid.temp_dir"), Uuid::new_v4()); - let archive = File::create(&file_name)?; - let enc = GzEncoder::new(archive, Compression::default()); - let mut tar = Builder::new(enc); - - info!("compressing to {}", &file_name); - for path in files { - append_to_tar(&mut tar, path)?; - info!("{} {:?}", helpers::string::add_icon(), path); - } - - Ok(file_name) -} diff --git a/maid/server/helpers/mod.rs b/maid/server/helpers/mod.rs index 34eaa3eb76937338f15e0eb66b130b3139a20b5f..fb8c6f9ded9de353855f9a5d18a6c879a4e2beb1 100644 --- a/maid/server/helpers/mod.rs +++ b/maid/server/helpers/mod.rs @@ -1,15 +1,3 @@ -use anyhow::Error; -use macros_rs::str; -use std::path::Path; - -pub struct Exists; -impl Exists { - pub fn folder(dir_name: String) -> Result<bool, Error> { Ok(Path::new(str!(dir_name)).is_dir()) } - pub fn file(file_name: String) -> Result<bool, Error> { Ok(Path::new(str!(file_name)).exists()) } -} - -pub mod os; -pub mod file; pub mod format; -pub mod string; -pub mod logger; \ No newline at end of file +pub mod logger; +pub mod os; diff --git a/maid/server/helpers/string.rs b/maid/server/helpers/string.rs deleted file mode 100644 index b02f4afb4da9fe3e764da902e51d503728b2bd3e..0000000000000000000000000000000000000000 --- a/maid/server/helpers/string.rs +++ /dev/null @@ -1,17 +0,0 @@ -use colored::{ColoredString, Colorize}; -use std::path::Path; - -pub fn seperator() -> ColoredString { ":".white() } -pub fn arrow_icon() -> ColoredString { "»".white() } -pub fn add_icon() -> ColoredString { "+".green() } -pub fn cross_icon() -> ColoredString { "✖".red() } -pub fn check_icon() -> ColoredString { "✔".green() } - -pub fn path_to_str(path: &Path) -> &'static str { Box::leak(String::from(path.to_string_lossy()).into_boxed_str()) } - -pub fn trim_start_end(value: &str) -> &str { - let mut chars = value.chars(); - chars.next(); - chars.next_back(); - chars.as_str() -} diff --git a/maid/server/main.rs b/maid/server/main.rs index 95621965b377bf9a694df3e168b44963d1fa6e0e..44d2744e18cb651f6562ce662e7cd8249f0870de 100644 --- a/maid/server/main.rs +++ b/maid/server/main.rs @@ -6,7 +6,7 @@ mod table; use bollard::{Docker, API_DEFAULT_VERSION}; use docker::container; -use macros_rs::{fmtstr, ternary}; +use macros_rs::{exp::ternary, fmt::fmtstr}; use maid::log::prelude::*; use rocket::futures::SinkExt; use rocket::{get, http::Status, launch, outcome::Outcome, routes, State}; @@ -64,7 +64,7 @@ impl From<Response> for Message { } #[derive(Debug)] -struct Token(String); +struct Token; #[rocket::async_trait] impl<'r> rocket::request::FromRequest<'r> for Token { @@ -76,8 +76,7 @@ impl<'r> rocket::request::FromRequest<'r> for Token { if let Some(header_value) = authorization_header { if header_value == fmtstr!("Bearer {token}") { - let token = header_value.trim_start_matches("Bearer ").to_owned(); - return Outcome::Success(Token(token)); + return Outcome::Success(Token); } } diff --git a/maid/server/table.rs b/maid/server/table.rs index 10f21939072608fd35d9b752b5b771bf263ae525..30f1e7ebb513f359b9a53846df43c553ada9e7ec 100644 --- a/maid/server/table.rs +++ b/maid/server/table.rs @@ -1,8 +1,7 @@ -use crate::helpers; use crate::structs::Maidfile; -use maid::log::prelude::*; +use maid::{helpers, log::prelude::*}; -use macros_rs::{str, ternary}; +use macros_rs::{exp::ternary, fmt::str}; use serde_json::Value; use std::path::PathBuf; use std::{collections::BTreeMap, collections::HashMap, env}; diff --git a/maid/client/helpers/file.rs b/maid/shared/helpers/file.rs similarity index 59% rename from maid/client/helpers/file.rs rename to maid/shared/helpers/file.rs index 3b4b7ed469f0b78ec571e17f875ac751abf66293..d5dc9feac5daffe7ca054de2c7043d8b8206a5a2 100644 --- a/maid/client/helpers/file.rs +++ b/maid/shared/helpers/file.rs @@ -1,11 +1,9 @@ -use macros_rs::crashln; +use crate::log::prelude::*; use std::env; pub fn get_current_working_dir() -> String { match env::current_dir() { Ok(path) => path.into_os_string().into_string().unwrap(), - Err(_) => { - crashln!("Unable to find current working dir"); - } + Err(err) => error!(%err, "Unable to find current working dir"), } } diff --git a/maid/shared/helpers/maidfile.rs b/maid/shared/helpers/maidfile.rs new file mode 100644 index 0000000000000000000000000000000000000000..f06e7c49a0f3787dcaa024c0af7bedc8bad82983 --- /dev/null +++ b/maid/shared/helpers/maidfile.rs @@ -0,0 +1,16 @@ +use crate::log::prelude::*; +use crate::models::client::{DisplayTask, Maidfile}; + +impl Maidfile { + pub fn to_json(&self) -> String { + match serde_json::to_string(&self) { + Ok(contents) => contents, + Err(err) => error!(%err, "Cannot read Maidfile"), + } + } +} + +impl std::fmt::Display for DisplayTask { + #[inline] + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(&self.formatted, f) } +} diff --git a/maid/shared/helpers/mod.rs b/maid/shared/helpers/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..655613b429042b93ac6dd8bd4bbaa7444b4edda2 --- /dev/null +++ b/maid/shared/helpers/mod.rs @@ -0,0 +1,4 @@ +pub mod file; +pub mod maidfile; +pub mod status; +pub mod string; diff --git a/maid/client/helpers/status.rs b/maid/shared/helpers/status.rs similarity index 95% rename from maid/client/helpers/status.rs rename to maid/shared/helpers/status.rs index 12bdb71d0a0640f67eeb85406854f486b1375942..8fba557a154d634152c61893bae85adbd164a925 100644 --- a/maid/client/helpers/status.rs +++ b/maid/shared/helpers/status.rs @@ -1,4 +1,4 @@ -use maid::log::prelude::*; +use crate::log::prelude::*; use std::{io::Error, process::ExitStatus}; pub fn error(debug_err: &str) { diff --git a/maid/client/helpers/string.rs b/maid/shared/helpers/string.rs similarity index 75% rename from maid/client/helpers/string.rs rename to maid/shared/helpers/string.rs index 0a05c959a2b3bf642994a969dd059f5c347060a3..a185af6c96f07bdc0b69c57c3725a0c8581bba0b 100644 --- a/maid/client/helpers/string.rs +++ b/maid/shared/helpers/string.rs @@ -1,12 +1,9 @@ -use std::path::Path; - -// cache -use std::collections::HashMap; use std::sync::{LazyLock, Mutex}; +use std::{collections::HashMap, path::Path}; static STRING_CACHE: LazyLock<Mutex<HashMap<String, &'static str>>> = LazyLock::new(|| Mutex::new(HashMap::new())); -pub(crate) fn path_to_str(path: &Path) -> &'static str { +pub fn path_to_str(path: &Path) -> &'static str { let string = path.to_string_lossy().into_owned(); if let Some(cached) = STRING_CACHE.lock().unwrap().get(&string) { return cached; @@ -17,7 +14,7 @@ pub(crate) fn path_to_str(path: &Path) -> &'static str { leaked } -pub(crate) fn trim_start_end(value: &str) -> &str { +pub fn trim_start_end(value: &str) -> &str { let mut chars = value.chars(); chars.next(); chars.next_back(); diff --git a/maid/shared/lib.rs b/maid/shared/lib.rs index 7746688323b6f61592b1756f309a21cbedd4a960..e452e21a2930656fbafe9a3bcbd7071f2a60a38a 100644 --- a/maid/shared/lib.rs +++ b/maid/shared/lib.rs @@ -1,2 +1,5 @@ pub mod colors; +pub mod helpers; pub mod log; +pub mod models; +pub mod table; diff --git a/maid/client/structs.rs b/maid/shared/models/client.rs similarity index 96% rename from maid/client/structs.rs rename to maid/shared/models/client.rs index 5b14cbbcc1139772d69bbdbdc00767dddbb9a8ae..1cabfef2ce69b45f5bf8a686543e4baa3821fbd3 100644 --- a/maid/client/structs.rs +++ b/maid/shared/models/client.rs @@ -1,14 +1,14 @@ use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; use std::path::PathBuf; -use toml::Value as TomlValue; +use toml::Value; #[derive(Clone, Debug, Deserialize, Serialize)] pub struct Maidfile { #[serde(skip_serializing_if = "Option::is_none")] pub import: Option<Vec<String>>, #[serde(skip_serializing_if = "Option::is_none")] - pub env: Option<BTreeMap<String, TomlValue>>, + pub env: Option<BTreeMap<String, Value>>, #[serde(skip_serializing_if = "Option::is_none")] pub project: Option<Project>, pub tasks: BTreeMap<String, Tasks>, @@ -39,7 +39,7 @@ pub struct Address { #[derive(Clone, Debug, Deserialize, Serialize)] pub struct Tasks { - pub script: TomlValue, + pub script: Value, #[serde(skip_serializing_if = "Option::is_none")] pub hide: Option<bool>, #[serde(skip_serializing_if = "Option::is_none")] @@ -83,7 +83,7 @@ pub struct Task { #[serde(skip_serializing_if = "Option::is_none")] pub remote: Option<Remote>, pub project: PathBuf, - pub script: TomlValue, + pub script: Value, pub path: String, pub args: Vec<String>, pub silent: bool, diff --git a/maid/shared/models/mod.rs b/maid/shared/models/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..17f582a527ab3aad9aeacfc2a6f1d931ad49f1bc --- /dev/null +++ b/maid/shared/models/mod.rs @@ -0,0 +1,3 @@ +pub mod client; +pub mod server; +pub mod shared; diff --git a/maid/shared/models/server.rs b/maid/shared/models/server.rs new file mode 100644 index 0000000000000000000000000000000000000000..ddb7b023ff6eeac39244fe358dc84ab4758d4501 --- /dev/null +++ b/maid/shared/models/server.rs @@ -0,0 +1,90 @@ +use serde::{Deserialize, Serialize}; +use serde_json::Value; +use std::collections::BTreeMap; + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct ConnectionInfo { + pub name: String, + pub args: Vec<String>, + pub remote: Remote, + pub script: Vec<String>, +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct ConnectionData { + pub info: ConnectionInfo, + pub maidfile: Maidfile, +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct Maidfile { + #[serde(skip_serializing_if = "Option::is_none")] + pub import: Option<Vec<String>>, + #[serde(skip_serializing_if = "Option::is_none")] + pub env: Option<BTreeMap<String, Value>>, + #[serde(skip_serializing_if = "Option::is_none")] + pub project: Option<Project>, + pub tasks: BTreeMap<String, Tasks>, +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct Project { + #[serde(skip_serializing_if = "Option::is_none")] + pub name: Option<String>, + #[serde(skip_serializing_if = "Option::is_none")] + pub version: Option<String>, + #[serde(skip_serializing_if = "Option::is_none")] + pub server: Option<Server>, // wip +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct Server { + pub address: Address, // wip + pub token: String, // wip +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct Address { + pub host: String, + pub port: i64, + pub ssl: bool, +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct Tasks { + pub script: Value, + #[serde(skip_serializing_if = "Option::is_none")] + pub hide: Option<bool>, + #[serde(skip_serializing_if = "Option::is_none")] + pub path: Option<String>, + #[serde(skip_serializing_if = "Option::is_none")] + pub info: Option<String>, + #[serde(skip_serializing_if = "Option::is_none")] + pub cache: Option<Cache>, + #[serde(skip_serializing_if = "Option::is_none")] + pub remote: Option<Remote>, + #[serde(skip_serializing_if = "Option::is_none")] + pub depends: Option<Vec<String>>, +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct Cache { + pub path: String, + pub target: Vec<String>, +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct CacheConfig { + pub target: Vec<String>, + pub hash: String, +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct Remote { + pub push: Vec<String>, + pub pull: String, + pub image: String, + pub shell: String, + pub silent: bool, + pub exclusive: bool, +} diff --git a/maid/shared/models/shared.rs b/maid/shared/models/shared.rs new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/maid/client/table.rs b/maid/shared/table.rs similarity index 95% rename from maid/client/table.rs rename to maid/shared/table.rs index bc5e705e055eff5ec5f4c05914bc8da5993cd0be..b3db9da3ed89890d078c179c151b3e77a19acba1 100644 --- a/maid/client/table.rs +++ b/maid/shared/table.rs @@ -1,8 +1,8 @@ use crate::helpers; -use crate::structs::Maidfile; -use maid::log::prelude::*; +use crate::log::prelude::*; +use crate::models::client::Maidfile; -use macros_rs::{str, ternary}; +use macros_rs::{exp::ternary, fmt::str}; use std::path::PathBuf; use std::{collections::BTreeMap, collections::HashMap, env}; use text_placeholder::Template;