Skip to content

Commit

Permalink
Clean up builtin commands and update README.
Browse files Browse the repository at this point in the history
  • Loading branch information
tao-guo committed Oct 18, 2023
1 parent a2eea51 commit 9fee93f
Show file tree
Hide file tree
Showing 8 changed files with 38 additions and 79 deletions.
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ assert!(run_cmd!(mkdir /tmp/"$dir"; ls /tmp/"$dir"; rmdir /tmp/"$dir").is_err())
```

It is using rust [log crate](https://crates.io/crates/log), and you can use your actual favorite
logging implementation. Notice that if you don't provide any logger, the stderr output will be discarded.
logging implementation. **Notice that if you don't provide any logger, the stderr from process will be discarded**.

#### Builtin commands
##### cd
Expand All @@ -205,13 +205,19 @@ working directory for the whole program.

Ignore errors for command execution, which can be used without importing.

##### die
Print fatal message and exit (with status code 1).

##### echo
Print messages to stdout

##### error, warn, info, debug, trace

Print messages to stdout, which needs to be imported with `use_builtin_cmd!` macro.
Print messages to logging (if provided) with different levels.

```rust
use_builtin_cmd!(echo, warn); // find more builtin commands in src/builtins.rs
run_cmd!(echo "This is from builtin command!")?;
run_cmd!(info "This is from builtin command!")?;
run_cmd!(warn "This is from builtin command!")?;
```

Expand Down
1 change: 0 additions & 1 deletion examples/dd_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ struct Opt {
}

fn main() -> MainResult {
use_builtin_cmd!(echo, info);
init_builtin_logger();
let Opt {
block_size,
Expand Down
1 change: 0 additions & 1 deletion examples/pipes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,6 @@ fn rand() -> i32 {
}

fn main() -> MainResult {
use_builtin_cmd!(info);
init_builtin_logger();

// simple pre-check of TERM, tput's error message should be enough
Expand Down
29 changes: 0 additions & 29 deletions macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,35 +80,6 @@ pub fn use_custom_cmd(item: proc_macro::TokenStream) -> proc_macro::TokenStream
.into()
}

/// import library predefined builtin command
/// ```
/// # use cmd_lib::*;
/// use_builtin_cmd!(info); // import only one builtin command
/// use_builtin_cmd!(echo, info, warn, err, die, cat); // import all the builtins
/// ```
/// `cd` builtin command is always enabled without importing it.
#[proc_macro]
#[proc_macro_error]
pub fn use_builtin_cmd(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
let item: proc_macro2::TokenStream = item.into();
let mut ret = TokenStream::new();
for t in item {
if let TokenTree::Punct(ref ch) = t {
if ch.as_char() != ',' {
abort!(t, "only comma is allowed");
}
} else if let TokenTree::Ident(cmd) = t {
let cmd_name = cmd.to_string();
let cmd_fn = syn::Ident::new(&format!("builtin_{}", cmd_name), Span::call_site());
ret.extend(quote!(::cmd_lib::export_cmd(#cmd_name, ::cmd_lib::#cmd_fn);));
} else {
abort!(t, "expect a list of comma separated commands");
}
}

ret.into()
}

/// Run commands, returning result handle to check status
/// ```
/// # use cmd_lib::run_cmd;
Expand Down
41 changes: 8 additions & 33 deletions src/builtins.rs
Original file line number Diff line number Diff line change
@@ -1,63 +1,38 @@
use crate::{CmdEnv, CmdResult};
use log::*;
use std::io::{Read, Write};
use std::path::PathBuf;
use std::io::Write;

#[doc(hidden)]
pub fn builtin_echo(env: &mut CmdEnv) -> CmdResult {
pub(crate) fn builtin_echo(env: &mut CmdEnv) -> CmdResult {
let msg = env.args()[1..].join(" ");
writeln!(env.stdout(), "{}", msg)
}

#[doc(hidden)]
pub fn builtin_die(env: &mut CmdEnv) -> CmdResult {
pub(crate) fn builtin_die(env: &mut CmdEnv) -> CmdResult {
error!("FATAL: {}", env.args()[1..].join(" "));
std::process::exit(1);
}

#[doc(hidden)]
pub fn builtin_error(env: &mut CmdEnv) -> CmdResult {
pub(crate) fn builtin_error(env: &mut CmdEnv) -> CmdResult {
error!("{}", env.args()[1..].join(" "));
Ok(())
}

#[doc(hidden)]
pub fn builtin_warn(env: &mut CmdEnv) -> CmdResult {
pub(crate) fn builtin_warn(env: &mut CmdEnv) -> CmdResult {
warn!("{}", env.args()[1..].join(" "));
Ok(())
}

#[doc(hidden)]
pub fn builtin_info(env: &mut CmdEnv) -> CmdResult {
pub(crate) fn builtin_info(env: &mut CmdEnv) -> CmdResult {
info!("{}", env.args()[1..].join(" "));
Ok(())
}

#[doc(hidden)]
pub fn builtin_debug(env: &mut CmdEnv) -> CmdResult {
pub(crate) fn builtin_debug(env: &mut CmdEnv) -> CmdResult {
debug!("{}", env.args()[1..].join(" "));
Ok(())
}

#[doc(hidden)]
pub fn builtin_trace(env: &mut CmdEnv) -> CmdResult {
pub(crate) fn builtin_trace(env: &mut CmdEnv) -> CmdResult {
trace!("{}", env.args()[1..].join(" "));
Ok(())
}

#[doc(hidden)]
pub fn builtin_cat(env: &mut CmdEnv) -> CmdResult {
if env.args().len() == 1 {
let mut buf = vec![];
env.stdin().read_to_end(&mut buf)?;
env.stdout().write_all(&buf)?;
return Ok(());
}

let mut file = PathBuf::from(env.args()[1].to_owned());
if file.is_relative() {
file = PathBuf::from(env.current_dir()).join(file);
}
env.stdout().write_all(&std::fs::read(file)?)?;
Ok(())
}
20 changes: 11 additions & 9 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@
//! ```
//!
//! It is using rust [log crate](https://crates.io/crates/log), and you can use your actual favorite
//! logging implementation. Notice that if you don't provide any logger, the stderr output will be discarded.
//! logging implementation. **Notice that if you don't provide any logger, the stderr from process will be discarded**.
//!
//! ### Builtin commands
//! #### cd
Expand All @@ -225,14 +225,20 @@
//!
//! Ignore errors for command execution, which can be used without importing.
//!
//! #### die
//! Print fatal message and exit (with status code 1).
//!
//! #### echo
//! Print messages to stdout
//!
//! #### error, warn, info, debug, trace
//!
//! Print messages to stdout, which needs to be imported with `use_builtin_cmd!` macro.
//! Print messages to logging (if provided) with different levels.
//!
//! ```
//! # use cmd_lib::{run_cmd, use_builtin_cmd};
//! use_builtin_cmd!(echo, warn); // find more builtin commands in src/builtins.rs
//! # use cmd_lib::*;
//! run_cmd!(echo "This is from builtin command!")?;
//! run_cmd!(info "This is from builtin command!")?;
//! run_cmd!(warn "This is from builtin command!")?;
//! # Ok::<(), std::io::Error>(())
//! ```
Expand Down Expand Up @@ -349,16 +355,12 @@
pub use cmd_lib_macros::{
cmd_debug, cmd_die, cmd_echo, cmd_error, cmd_info, cmd_trace, cmd_warn, export_cmd, run_cmd,
run_fun, spawn, spawn_with_output, use_builtin_cmd, use_custom_cmd,
run_fun, spawn, spawn_with_output, use_custom_cmd,
};
/// Return type for run_fun!() macro
pub type FunResult = std::io::Result<String>;
/// Return type for run_cmd!() macro
pub type CmdResult = std::io::Result<()>;
pub use builtins::{
builtin_cat, builtin_debug, builtin_die, builtin_echo, builtin_error, builtin_info,
builtin_trace, builtin_warn,
};
pub use child::{CmdChildren, FunChildren};
#[doc(hidden)]
pub use log;
Expand Down
11 changes: 10 additions & 1 deletion src/process.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::builtins::*;
use crate::child::{CmdChild, CmdChildHandle, CmdChildren, FunChildren};
use crate::io::{CmdIn, CmdOut};
use crate::{CmdResult, FunResult};
Expand Down Expand Up @@ -64,7 +65,15 @@ type FnFun = fn(&mut CmdEnv) -> CmdResult;
lazy_static! {
static ref CMD_MAP: Mutex<HashMap<OsString, FnFun>> = {
// needs explicit type, or it won't compile
let m: HashMap<OsString, FnFun> = HashMap::new();
let mut m: HashMap<OsString, FnFun> = HashMap::new();
m.insert("echo".into(), builtin_echo);
m.insert("trace".into(), builtin_trace);
m.insert("debug".into(), builtin_debug);
m.insert("info".into(), builtin_info);
m.insert("warn".into(), builtin_warn);
m.insert("error".into(), builtin_error);
m.insert("die".into(), builtin_die);

Mutex::new(m)
};
}
Expand Down
2 changes: 0 additions & 2 deletions tests/test_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,6 @@ fn test_tls_set() {

#[test]
fn test_pipe() {
use_builtin_cmd!(echo);
assert!(run_cmd!(echo "xx").is_ok());
assert_eq!(run_fun!(echo "xx").unwrap(), "xx");
assert!(run_cmd!(echo xx | wc).is_ok());
Expand Down Expand Up @@ -237,7 +236,6 @@ fn test_redirect_fail() {}

#[test]
fn test_buitin_stdout_redirect() {
use_builtin_cmd!(echo);
let f = "/tmp/builtin";
let msg = run_fun!(echo xx &> $f).unwrap();
assert_eq!(msg, "");
Expand Down

0 comments on commit 9fee93f

Please sign in to comment.