command_error/lib.rs
1//! `command_error` provides the [`CommandExt`] trait, which runs a command and checks its exit
2//! status:
3//!
4//! ```
5//! # use indoc::indoc;
6//! use std::process::Command;
7//! use command_error::CommandExt;
8//!
9//! let err = Command::new("sh")
10//! .args(["-c", "echo puppy; false"])
11//! .output_checked_utf8()
12//! .unwrap_err();
13//!
14//! assert_eq!(
15//! err.to_string(),
16//! indoc!(
17//! "`sh` failed: exit status: 1
18//! Command failed: `sh -c 'echo puppy; false'`
19//! Stdout:
20//! puppy"
21//! )
22//! );
23//! ```
24//!
25//! Error messages are detailed and helpful. Additional methods are provided for overriding
26//! the default success logic (for that weird tool that thinks `2` is a reasonable exit code) and
27//! for transforming the output (for example, to parse command output as JSON while retaining
28//! information about the command that produced the output in the error message).
29//!
30//! ## Enforcing use of `command_error`
31//!
32//! If you'd like to make sure that [`CommandExt`] methods are used instead of the plain
33//! [`Command`] methods in your project, you can add a stanza like this to
34//! [`clippy.toml`][clippy-config] at your project root:
35//!
36//! ```toml
37//! [[disallowed-methods]]
38//! path = "std::process::Command::output"
39//! reason = "Use command_error::CommandExt::output_checked[_with][_utf8]"
40//!
41//! [[disallowed-methods]]
42//! path = "std::process::Command::status"
43//! reason = "Use command_error::CommandExt::status_checked[_with]"
44//!
45//! [[disallowed-methods]]
46//! path = "std::process::Command::spawn"
47//! reason = "Use command_error::CommandExt::spawn_checked"
48//!
49//! [[disallowed-methods]]
50//! path = "std::process::Child::try_wait"
51//! reason = "Use command_error::ChildExt::try_wait_checked[_with]"
52//!
53//! [[disallowed-methods]]
54//! path = "std::process::Child::wait"
55//! reason = "Use command_error::ChildExt::wait_checked[_with]"
56//!
57//! [[disallowed-methods]]
58//! path = "std::process::Child::wait_with_output"
59//! reason = "Use command_error::ChildExt::output_checked[_with][_utf8]"
60//! ```
61//!
62//! [clippy-config]: https://doc.rust-lang.org/clippy/configuration.html
63
64#![deny(missing_docs)]
65
66#[cfg(doc)]
67use std::process::Command;
68
69mod output_context;
70pub use output_context::OutputContext;
71
72mod try_wait_context;
73pub use try_wait_context::TryWaitContext;
74
75mod child_context;
76pub use child_context::ChildContext;
77
78mod output_like;
79pub use output_like::OutputLike;
80
81mod exec_error;
82pub use exec_error::ExecError;
83
84mod output_error;
85pub use output_error::OutputError;
86
87mod output_conversion_error;
88pub use output_conversion_error::OutputConversionError;
89
90mod wait_error;
91pub use wait_error::WaitError;
92
93mod error;
94pub use error::Error;
95
96mod command_display;
97pub use command_display::CommandDisplay;
98
99mod utf8_program_and_args;
100pub use utf8_program_and_args::Utf8ProgramAndArgs;
101
102mod debug_display;
103pub(crate) use debug_display::DebugDisplay;
104
105mod command_ext;
106pub use command_ext::CommandExt;
107
108mod child_ext;
109pub use child_ext::ChildExt;
110
111#[cfg(feature = "process-wrap")]
112mod process_wrap;