Fun Run
What does the "Zombie Zoom 5K", the "Wibbly wobbly log jog", and the "Turkey Trot" have in common?
They're runs with a fun name! The fun_run library adds display and safety features to make
running a Rust Command better for you and your users.
Stream the command and raise on non-zero exit:
use CommandWithName;
use Command;
let mut cmd = new;
cmd.args;
// Advertise the command being run before execution
println!;
// Stream output to the end user
// Turn non-zero status results into an error
let error = cmd
.stream_output
.unwrap_err;
assert_eq!;
Run the command quietly, capture stdout/stderr and raise on non-zero exit:
let error = cmd.named_output.unwrap_err;
assert_eq!;
Output of the command is preserved in success and error cases:
// Both Ok and Err from result store the output for inspection
assert!;
Install
$ cargo add fun_run
Renaming a command
If you need to provide an alternate display for your command you can rename it, this is useful for omitting implementation details.
use CommandWithName;
use Command;
let mut cmd = new;
cmd
.args
.arg;
let mut renamed_cmd = cmd.named;
assert_eq!;
This is also useful for adding additional information, such as environment variables:
use CommandWithName;
use Command;
let mut cmd = new;
cmd.arg;
let env_vars = vars;
let mut renamed_cmd = cmd.named_fn;
assert_eq!
What won't it do?
The fun_run library doesn't support executing a Command in ways that do not produce an
Output, for example calling Command::spawn returns a std::process::Child
(Which doesn't contain an Output). If you want to run-for-fun in the background, spawn a thread
and join it manually:
use CommandWithName;
use Command;
use thread;
let mut cmd = new;
cmd.args;
// Advertise the command being run before execution
println!;
let result = spawn.join.unwrap;
// Command name is persisted on success or failure
match result
Async
This library uses synchronous command execution. If you’re using this library in an async context, you’ll want to use an async wrapper like tokio::task::spawn_blocking.
Clippy
To ensure all commands have their exit status checked you can add this to your clippy.toml to
prevent accidentally spawning an un-checked plain Command:
[[]]
= "std::process::Command::output"
= "Use fun_run::CommandWithName::named_output"
[[]]
= "std::process::Command::status"
= "Use fun_run::CommandWithName::named_output and read the status from the result"
[[]]
= "std::process::Command::spawn"
= "Use fun_run::CommandWithName::stream_output(std::io::stdout(), std::io::stderr())"
Debugging system failures with which_problem
When a command execution returns an Err due to a system error (and not because the program it executed launched but returned non-zero status), it's usually because the executable couldn't be found, or if it was found, it couldn't be launched, for example due to a permissions error. The which_problem crate is designed to add debugging errors to help you identify why the command couldn't be launched.
The crate which_problem works like which but helps you identify common mistakes such as typos:
$ cargo whichp zuby
Program "zuby" not found
Info: No other executables with the same name are found on the PATH
Info: These executables have the closest spelling to "zuby" but did not match:
"hub", "ruby", "subl"
Fun run supports which_problem integration through the which_problem feature. In your Cargo.toml:
# Cargo.toml
= { = <version.here>, features = ["which_problem"] }
And annotate errors:
use CommandWithName;
use Command;
let mut cmd = new;
cmd.args;
cmd.stream_output
.map_err.unwrap;
Now if the system cannot find a becho program on your system the output will give you all the
info you need to diagnose the underlying issue.
Note that which_problem integration is not enabled by default because it outputs information
about the contents of your disk such as layout and file permissions.
Nightly-only items
A few items (display_env_vars and CommandWithName::named_env_vars) require a
nightly toolchain. They depend on the unstable
command_resolved_envs
feature, auto-detected at build time, and are absent on stable. Because
https://docs.rs builds on nightly, these appear in the published docs even
though stable users cannot use them.
Development
Update the readme:
$ cargo install cargo-rdme
$ cargo rdme