diff --git a/Cargo.lock b/Cargo.lock index 1531e7e..8cbed05 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -57,61 +57,6 @@ dependencies = [ "os_str_bytes", ] -[[package]] -name = "darling" -version = "0.14.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0dd3cd20dc6b5a876612a6e5accfe7f3dd883db6d07acfbf14c128f61550dfa" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.14.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a784d2ccaf7c98501746bf0be29b2022ba41fd62a2e622af997a03e9f972859f" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "darling_macro" -version = "0.14.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7618812407e9402654622dd402b0a89dff9ba93badd6540781526117b92aab7e" -dependencies = [ - "darling_core", - "quote", - "syn", -] - -[[package]] -name = "enumset" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19be8061a06ab6f3a6cf21106c873578bf01bd42ad15e0311a9c76161cb1c753" -dependencies = [ - "enumset_derive", -] - -[[package]] -name = "enumset_derive" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03e7b551eba279bf0fa88b83a46330168c1560a52a94f5126f892f0b364ab3e0" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "errno" version = "0.2.8" @@ -133,12 +78,6 @@ dependencies = [ "libc", ] -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - [[package]] name = "hashbrown" version = "0.12.3" @@ -160,12 +99,6 @@ dependencies = [ "libc", ] -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - [[package]] name = "indexmap" version = "1.9.2" @@ -345,7 +278,6 @@ name = "system-updater" version = "0.1.0" dependencies = [ "clap", - "enumset", "serde", "serde_yaml", ] diff --git a/Cargo.toml b/Cargo.toml index 0abd2ee..b1a7be5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,5 @@ name = "sup" [dependencies] clap = { version = "4.1", features = ["derive"] } -enumset = { version = "1.0" , feature = ["serde"] } serde = { version = "1.0", features = ["derive"] } serde_yaml = "0.9" diff --git a/examples/debian.yml b/examples/debian.yml index cd89727..a391f8b 100644 --- a/examples/debian.yml +++ b/examples/debian.yml @@ -28,5 +28,4 @@ systems: - -a current_dir: null env: {} -steps: Install nice: null diff --git a/examples/openSUSE.yml b/examples/openSUSE.yml index f921950..74427c9 100644 --- a/examples/openSUSE.yml +++ b/examples/openSUSE.yml @@ -27,4 +27,3 @@ systems: - -a current_dir: null env: {} -steps: Install diff --git a/src/command.rs b/src/command.rs index 7cfeff5..3acc450 100644 --- a/src/command.rs +++ b/src/command.rs @@ -1,5 +1,4 @@ use crate::*; -use enumset::EnumSetType; use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::fmt; @@ -7,8 +6,7 @@ use std::io::{stdout, Write}; use std::path::PathBuf; use std::process::Command; -#[derive(Debug, Serialize, Deserialize, EnumSetType)] -//#[enumset(serialize_as_list)] // TODO: use it or not? +#[derive(Debug, Serialize, Deserialize, PartialEq)] enum UpdateSteps { Fetch, Compile, @@ -18,7 +16,6 @@ enum UpdateSteps { #[derive(Debug, Serialize, Deserialize)] pub struct Updater { systems: Vec, - steps: UpdateSteps, } #[derive(Debug, Serialize, Deserialize)] @@ -31,20 +28,52 @@ pub struct System { // exclusive_with : List } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize, Clone)] struct Cmd { + exe: String, + params: Vec, + yes: Option, + current_dir: Option, + env: HashMap, +} + +#[derive(Debug, Serialize, Deserialize)] +struct ActualCmd { exe: String, params: Vec, current_dir: Option, env: HashMap, } +// QUESTION: Would String be less awkward? +impl From<&str> for UpdateSteps { + fn from(value: &str) -> Self { + match &*value.to_lowercase() { + "fetch" => UpdateSteps::Fetch, + "compile" => UpdateSteps::Compile, + "install" => UpdateSteps::Install, + + _ => panic!("Step {} not recognized", value), + } + } +} + +// QUESTION: Would String be less awkward? +impl From<&String> for UpdateSteps { + fn from(value: &String) -> Self { + match &*value.to_lowercase() { + "fetch" => UpdateSteps::Fetch, + "compile" => UpdateSteps::Compile, + "install" => UpdateSteps::Install, + + _ => panic!("Step {} not recognized", value), + } + } +} + impl Updater { fn new() -> Updater { - let mut up = Updater { - systems: vec![], - steps: UpdateSteps::Fetch, - }; + let mut up = Updater { systems: vec![] }; up.systems.push(System { fetch: None, compile: None, @@ -78,13 +107,18 @@ impl Updater { } pub fn update_all(&self, opt: &Opt) -> Result<()> { - let mut errors = vec![]; - for sys in &self.systems { - if let Err(err) = self.update(sys, opt) { - eprintln!("Error catched {}", err); - errors.push(err); - } - } + let errors: Vec<_> = self + .systems + .iter() + .filter_map(|sys| { + if let Err(err) = self.update(sys, opt) { + eprintln!("Error catched {}", err); + Some(err) + } else { + None + } + }) + .collect(); // TODO: if errors.len() == 0 { @@ -98,13 +132,22 @@ impl Updater { } fn update(&self, sys: &System, opt: &Opt) -> Result<()> { - if self.steps == UpdateSteps::Fetch { + let steps = match &opt.steps { + Some(v) => v.iter().map(|u| u.into()).collect(), + None => vec![ + UpdateSteps::Fetch, + UpdateSteps::Compile, + UpdateSteps::Install, + ], + }; + + if steps.contains(&UpdateSteps::Fetch) { sys.fetch(opt)?; } - if self.steps == UpdateSteps::Compile { + if steps.contains(&UpdateSteps::Compile) { sys.compile(opt)?; } - if self.steps == UpdateSteps::Install { + if steps.contains(&UpdateSteps::Install) { sys.install(opt)?; } @@ -115,20 +158,20 @@ impl Updater { impl System { pub fn fetch(&self, opt: &Opt) -> Result<()> { if let Some(fetch) = &self.fetch { - fetch.execute(opt)?; + fetch.clone().prepare(opt).execute(&opt)?; } Ok(()) } pub fn compile(&self, opt: &Opt) -> Result<()> { if let Some(compile) = &self.compile { - compile.execute(opt)?; + compile.clone().prepare(opt).execute(opt)?; } Ok(()) } pub fn install(&self, opt: &Opt) -> Result<()> { - self.install.execute(opt)?; + self.install.clone().prepare(opt).execute(opt)?; Ok(()) } } @@ -138,16 +181,40 @@ impl Cmd { Cmd { exe: "".into(), params: vec![], + yes: None, current_dir: None, env: HashMap::new(), } } - fn execute(&self, opt: &Opt) -> Result<()> { + fn prepare(self, opt: &Opt) -> ActualCmd { + let mut params = self.params; + if opt.yes { + if let Some(y) = &self.yes { + params.push(y.to_owned()); + } + }; + + let mut env = self.env; + if !env.contains_key("PATH") { + env.insert("PATH".to_owned(), std::env!("PATH").to_owned()); + } + + ActualCmd { + exe: self.exe, + params, + current_dir: self.current_dir, + env, + } + } +} + +impl ActualCmd { + fn execute(&self, opt: &Opt) -> Result { let mut cmd = Command::new(&self.exe); + cmd.args(&self.params) .env_clear() - .env("PATH", std::env!("PATH")) .envs(&self.env) // .stdout(cfg) // .stderr(cfg) @@ -170,20 +237,20 @@ impl Cmd { .expect("Unable to read user’s input"); } - if !yes_no.to_lowercase().starts_with('n') { - if cmd.status().unwrap().success() { - eprintln!("Youpi !"); - // Other checks? - } else { - eprintln!("Error executing the command") - } + if yes_no.to_lowercase().starts_with('n') { + eprintln!( + "yes_no? {} {}", + yes_no, + yes_no.to_lowercase().starts_with('n') + ); + return Ok(false); } - Ok(()) + Ok(cmd.status().unwrap().success()) } } -impl fmt::Display for Cmd { +impl fmt::Display for ActualCmd { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let command = if !self.params.is_empty() { format!("{} {}", &self.exe, &self.params.join(" ")) @@ -198,7 +265,7 @@ impl fmt::Display for Cmd { if !self.env.is_empty() { writeln!(f, " with the following environment variable:")?; - writeln!(f, "{:?}", self.env) + writeln!(f, "{:#?}", self.env) } else { write!(f, " without any environment variable. ") } diff --git a/src/lib.rs b/src/lib.rs index 0665b34..d34d18d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,6 +26,8 @@ pub struct Opt { #[arg(short)] pub yes: bool, //pub quiet: bool, // imply yes + #[arg(short, long)] + pub steps: Option>, } pub fn run(opt: &Opt) {