mirror of
https://github.com/jht5945/rust_util.git
synced 2025-12-27 15:40:03 +08:00
feat: add runtime
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "rust_util"
|
||||
version = "0.6.35"
|
||||
version = "0.6.36"
|
||||
authors = ["Hatter Jiang <jht5945@gmail.com>"]
|
||||
edition = "2018"
|
||||
description = "Hatter's Rust Util"
|
||||
|
||||
@@ -20,6 +20,7 @@ pub mod util_git;
|
||||
#[cfg(feature = "use_clap")]
|
||||
pub mod util_clap;
|
||||
pub mod util_tlv;
|
||||
pub mod util_runtime;
|
||||
|
||||
/// iff!(condition, result_when_true, result_when_false)
|
||||
#[macro_export] macro_rules! iff {
|
||||
@@ -47,6 +48,7 @@ pub mod util_tlv;
|
||||
#[macro_export] macro_rules! failure_and_exit {
|
||||
($($arg:tt)+) => ( {
|
||||
rust_util::util_msg::print_error(&format!($($arg)+));
|
||||
rsut_util::util_runtime::register_callback();
|
||||
std::process::exit(-1);
|
||||
} )
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ pub trait DefaultCommand {
|
||||
}
|
||||
|
||||
pub struct DefaultCommandImpl;
|
||||
|
||||
impl DefaultCommand for DefaultCommandImpl {
|
||||
fn process_command<'a>(&self, app: App<'a, 'a>) -> App<'a, 'a> {
|
||||
app.arg(Arg::with_name("verbose").long("verbose").short("v").multiple(true).help("Show verbose info"))
|
||||
@@ -40,7 +41,7 @@ impl CommandExecutor {
|
||||
}
|
||||
|
||||
pub fn new(default_cmd: Option<Box<dyn DefaultCommand>>) -> Self {
|
||||
CommandExecutor{
|
||||
CommandExecutor {
|
||||
default_cmd,
|
||||
commands: Vec::new(),
|
||||
}
|
||||
@@ -77,18 +78,25 @@ impl CommandExecutor {
|
||||
if let Some(sub_cmd_matches) = matches.subcommand_matches(command.name()) {
|
||||
match command.run(&matches, sub_cmd_matches)? {
|
||||
None => return Ok(()),
|
||||
Some(code) => process::exit(code),
|
||||
Some(code) => {
|
||||
crate::util_runtime::invoke_callbacks();
|
||||
process::exit(code);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
match &self.default_cmd {
|
||||
None => {
|
||||
util_msg::print_error("No default command, please try help (--help)");
|
||||
crate::util_runtime::invoke_callbacks();
|
||||
process::exit(1);
|
||||
},
|
||||
}
|
||||
Some(default_cmd) => match default_cmd.run(&matches)? {
|
||||
None => return Ok(()),
|
||||
Some(code) => process::exit(code),
|
||||
Some(code) => {
|
||||
crate::util_runtime::invoke_callbacks();
|
||||
process::exit(code);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::io::{self, Error, ErrorKind};
|
||||
use std::process::{Command, ExitStatus, Output};
|
||||
use crate::util_msg::{print_debug, print_error, MessageType};
|
||||
use crate::util_msg::{print_debug, print_error, MessageType, print_message};
|
||||
|
||||
pub fn run_command_or_exit(cmd: &str, args: &[&str]) -> Output {
|
||||
let mut c = Command::new(cmd);
|
||||
@@ -12,11 +12,21 @@ pub fn run_command_or_exit(cmd: &str, args: &[&str]) -> Output {
|
||||
match output {
|
||||
Err(e) => {
|
||||
print_error(&format!("Run command: {:?}, failed: {}", c, e));
|
||||
crate::util_runtime::invoke_callbacks();
|
||||
std::process::exit(-1);
|
||||
},
|
||||
}
|
||||
Ok(output) => {
|
||||
if !output.status.success() {
|
||||
print_error(&format!(r##"Run command failed, code: {:?}
|
||||
print_output(MessageType::ERROR, &output);
|
||||
}
|
||||
output
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print_output(message_type: MessageType, output: &Output) {
|
||||
crate::util_msg::when(message_type, || {
|
||||
print_message(message_type, &format!(r##"Run command failed, code: {:?}
|
||||
-----std out---------------------------------------------------------------
|
||||
{}
|
||||
-----std err---------------------------------------------------------------
|
||||
@@ -25,10 +35,7 @@ pub fn run_command_or_exit(cmd: &str, args: &[&str]) -> Output {
|
||||
output.status.code(),
|
||||
String::from_utf8_lossy(&output.stdout),
|
||||
String::from_utf8_lossy(&output.stderr)));
|
||||
}
|
||||
output
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub fn run_command_and_wait(cmd: &mut Command) -> io::Result<ExitStatus> {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub fn is_macos() -> bool {
|
||||
cfg!(target_os = "macos")
|
||||
@@ -10,3 +11,9 @@ pub fn is_linux() -> bool {
|
||||
pub fn is_macos_or_linux() -> bool {
|
||||
is_macos() || is_linux()
|
||||
}
|
||||
|
||||
pub fn get_full_work_dir() -> Option<String> {
|
||||
PathBuf::from(".").canonicalize().ok().map(|p| {
|
||||
p.to_str().map(ToString::to_string)
|
||||
}).flatten()
|
||||
}
|
||||
24
src/util_runtime.rs
Normal file
24
src/util_runtime.rs
Normal file
@@ -0,0 +1,24 @@
|
||||
use std::sync::Mutex;
|
||||
use crate::util_msg::MessageType;
|
||||
|
||||
lazy_static! {
|
||||
static ref EXIT_CALLBACK: Mutex<Vec<Box<dyn Fn() -> () + Send + 'static>>> = Mutex::new(vec![]);
|
||||
}
|
||||
|
||||
pub fn register_callback<F>(f: F) where F: Fn() -> () + Send + 'static {
|
||||
let mut exit_callbacks = EXIT_CALLBACK.lock().unwrap();
|
||||
exit_callbacks.push(Box::new(f));
|
||||
}
|
||||
|
||||
pub fn invoke_callbacks() {
|
||||
let mut exit_callbacks = EXIT_CALLBACK.lock().unwrap();
|
||||
let total = exit_callbacks.len();
|
||||
let mut index = 0;
|
||||
while exit_callbacks.len() > 0 {
|
||||
crate::util_msg::when(MessageType::DEBUG, || {
|
||||
crate::util_msg::print_debug(&format!("Running exit callbacks: {} of {}", index, total));
|
||||
});
|
||||
exit_callbacks.remove(0)();
|
||||
index += 1;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user