Add a yes argument for commands
This commit is contained in:
parent
976fd7bd96
commit
10496f75db
68
Cargo.lock
generated
68
Cargo.lock
generated
@ -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",
|
||||
]
|
||||
|
@ -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"
|
||||
|
@ -28,5 +28,4 @@ systems:
|
||||
- -a
|
||||
current_dir: null
|
||||
env: {}
|
||||
steps: Install
|
||||
nice: null
|
||||
|
@ -27,4 +27,3 @@ systems:
|
||||
- -a
|
||||
current_dir: null
|
||||
env: {}
|
||||
steps: Install
|
||||
|
135
src/command.rs
135
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<System>,
|
||||
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<String>,
|
||||
yes: Option<String>,
|
||||
current_dir: Option<PathBuf>,
|
||||
env: HashMap<String, String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct ActualCmd {
|
||||
exe: String,
|
||||
params: Vec<String>,
|
||||
current_dir: Option<PathBuf>,
|
||||
env: HashMap<String, String>,
|
||||
}
|
||||
|
||||
// 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<bool> {
|
||||
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. ")
|
||||
}
|
||||
|
@ -26,6 +26,8 @@ pub struct Opt {
|
||||
#[arg(short)]
|
||||
pub yes: bool,
|
||||
//pub quiet: bool, // imply yes
|
||||
#[arg(short, long)]
|
||||
pub steps: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
pub fn run(opt: &Opt) {
|
||||
|
Loading…
Reference in New Issue
Block a user