diff --git a/src/cli/import.rs b/src/cli/import.rs index 3f8822aea786f8f549cc72145efeb0262205217b..928a98de6455bbb2d85e73e2a2f1f3a6277105a4 100644 --- a/src/cli/import.rs +++ b/src/cli/import.rs @@ -1,9 +1,16 @@ +use super::Item; use colored::Colorize; use macros_rs::{crashln, string}; -use serde::Deserialize; -use std::{collections::HashMap, fs}; +use serde::{Deserialize, Serialize}; + +use std::{ + collections::HashMap, + fs::{self, OpenOptions}, + io::prelude::*, +}; use pmc::{ + file::Exists, helpers, process::{Env, Runner}, }; @@ -14,7 +21,7 @@ struct ProcessWrapper { list: HashMap, } -#[derive(Deserialize, Debug)] +#[derive(Serialize, Deserialize, Debug)] struct Process { script: String, server: Option, @@ -23,7 +30,7 @@ struct Process { env: Env, } -#[derive(Deserialize, Debug)] +#[derive(Serialize, Deserialize, Debug)] struct Watch { path: String, } @@ -80,3 +87,64 @@ pub fn read_hcl(path: &String) { servers.iter().for_each(|server| super::Internal::list(&string!("default"), &server)); println!("{} Applied startProcess to imported items", *helpers::SUCCESS); } + +pub fn export_hcl(item: &Item, path: &Option) { + println!("{} Applying action exportProcess", *helpers::SUCCESS); + + let runner = Runner::new(); + + let fetch_process = |id: usize| { + let process = runner.try_info(id); + let mut watch_parsed = None; + let mut env_parsed = HashMap::new(); + + let current_env: HashMap = std::env::vars().collect(); + let path = path.clone().unwrap_or(format!("{}.hcl", process.name.clone())); + + if process.watch.enabled { + watch_parsed = Some(Watch { path: process.watch.path.clone() }) + } + + for (key, value) in process.env.clone() { + if let Some(current_value) = current_env.get(&key) { + if current_value != &value { + env_parsed.insert(key, value); + } + } else { + env_parsed.insert(key, value); + } + } + + let data = hcl::block! { + process (process.name.clone()) { + script = (process.script.clone()) + server = ("") + watch = (watch_parsed) + env = (env_parsed) + } + }; + + let serialized = hcl::to_string(&data).unwrap(); + + if Exists::check(&path).file() { + let mut file = OpenOptions::new().write(true).append(true).open(path.clone()).unwrap(); + if let Err(err) = writeln!(file, "{}", serialized) { + crashln!("{} Error writing to file.\n{}", *helpers::FAIL, string!(err).white()) + } + } else { + if let Err(err) = fs::write(path.clone(), serialized) { + crashln!("{} Error writing file.\n{}", *helpers::FAIL, string!(err).white()) + } + } + + println!("{} Exported process {id} to {path}", *helpers::SUCCESS); + }; + + match item { + Item::Id(id) => fetch_process(*id), + Item::Name(name) => match runner.find(&name, &string!("internal")) { + Some(id) => fetch_process(id), + None => crashln!("{} Process ({name}) not found", *helpers::FAIL), + }, + } +} diff --git a/src/main.rs b/src/main.rs index 134d280ff722b4ea89cc7f25cdf6fe6e9ba5c208..5eb3aeda5894b406cfb6facae288b5edc7d50596 100644 --- a/src/main.rs +++ b/src/main.rs @@ -90,6 +90,14 @@ enum Commands { /// Path of file to import path: String, }, + /// Export environment file from process + #[command(visible_alias = "get")] + Export { + #[clap(value_parser = cli::validate::)] + item: Item, + /// Path to export file + path: Option, + }, /// Start/Restart a process #[command(visible_alias = "restart")] Start { @@ -220,6 +228,7 @@ fn main() { match &cli.command { Commands::Import { path } => cli::import::read_hcl(path), + Commands::Export { item, path } => cli::import::export_hcl(item, path), Commands::Start { name, args, watch, server, reset_env } => cli::start(name, args, watch, reset_env, &defaults(server)), Commands::Stop { item, server } => cli::stop(item, &defaults(server)), Commands::Remove { item, server } => cli::remove(item, &defaults(server)), @@ -250,6 +259,7 @@ fn main() { && !matches!(&cli.command, Commands::Server { .. }) && !matches!(&cli.command, Commands::Save { .. }) && !matches!(&cli.command, Commands::Env { .. }) + && !matches!(&cli.command, Commands::Export { .. }) { then!(!daemon::pid::exists(), daemon::restart(&false, &false, false)); } diff --git a/src/process/mod.rs b/src/process/mod.rs index 23e8e463a613e68a221cf9be275a7c147327b6f3..632e223af4e17356ff99cdd6e6055a442a36b775 100644 --- a/src/process/mod.rs +++ b/src/process/mod.rs @@ -357,6 +357,8 @@ impl Runner { pub fn info(&self, id: usize) -> Option<&Process> { self.list.get(&id) } + pub fn try_info(&self, id: usize) -> &Process { self.list.get(&id).unwrap_or_else(|| crashln!("{} Process ({id}) not found", *helpers::FAIL)) } + pub fn size(&self) -> Option<&usize> { self.list.iter().map(|(k, _)| k).max() } pub fn list<'l>(&'l mut self) -> impl Iterator { self.list.iter_mut().map(|(k, v)| (k, v)) }