1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
//! `processkit` — child-process management for Rust.
//!
//! Two layers:
//!
//! - **[`ProcessGroup`]** — a kill-on-drop container for a process *tree*. Every
//! child spawned into the group, and everything those children spawn, dies
//! with the group, so an exiting or panicking owner never leaks subprocesses.
//! Containment is a Windows [Job Object], a Linux [cgroup v2] (with a POSIX
//! process-group fallback), a POSIX process group on macOS/BSD, or nothing on
//! other targets — observable via [`Mechanism`].
//! - **runner** — async run-and-capture built on the group. Describe a run with
//! [`Command`], then drive it to completion ([`Command::output_string`],
//! [`Command::run`], …) or start it via a [`ProcessRunner`] for streaming or a
//! shared group. The trait is the mock seam (see [`ScriptedRunner`]).
//!
//! Async throughout (tokio). Errors are the structured [`Error`]; a non-zero
//! exit is reported in [`ProcessResult`], not raised, until you call
//! [`ProcessResult::ensure_success`].
//!
//! **Run vocabulary** — the same verb means the same thing at every layer
//! ([`Command`], [`ProcessRunner`]/[`ProcessRunnerExt`], [`CliClient`]):
//!
//! - **`run` / `text`** — require a zero exit and return stdout as a `String`,
//! trailing whitespace trimmed (`trim_end`: the final newline is noise, but
//! leading whitespace can be significant).
//! - **`output` / `capture` / `output_string` / `output_bytes`** — return the
//! full [`ProcessResult`]; a non-zero exit is *not* an error here.
//! - **`exit_code` / `code`** — the exit code. On a [`ProcessResult`],
//! [`code`](ProcessResult::code) is `Option<i32>` (`None` for a run killed by
//! its timeout or a signal — there is no `-1` sentinel); the `exit_code`
//! helpers instead surface a missing code as an error.
//!
//! ```no_run
//! # async fn demo() -> processkit::Result<()> {
//! use processkit::Command;
//!
//! // Capture output; a non-zero exit does not error on its own.
//! let result = Command::new("git").args(["rev-parse", "HEAD"]).output_string().await?;
//! println!("HEAD is {}", result.stdout().trim());
//!
//! // Or require success and get trimmed stdout directly.
//! let version = Command::new("cargo").arg("--version").run().await?;
//! # let _ = version;
//! # Ok(())
//! # }
//! ```
//!
//! [Job Object]: https://learn.microsoft.com/windows/win32/procthread/job-objects
//! [cgroup v2]: https://docs.kernel.org/admin-guide/cgroup-v2.html
pub use ;
pub use CliClient;
pub use Command;
pub use ;
pub use Encoding;
pub use ;
pub use ;
pub use Mechanism;
pub use ProcessResult;
pub use ;
pub use ;
pub use ProcessGroupStats;
pub use ;
// Re-exported so callers can `use processkit::StreamExt;` to consume
// [`RunningProcess::stdout_lines`]'s [`StdoutLines`] stream (`.next().await`,
// combinators) without depending on `tokio-stream` directly.
pub use StreamExt;
// `cli_client!` is exported at the crate root via `#[macro_export]`.
use OsStr;
/// Run `program` with `args` inside a private job and return trimmed stdout, or
/// an [`Error`] on a non-zero exit / spawn failure / timeout. A thin shim over
/// [`Command`]; use the builder for a working directory, env, stdin, or timeout.
pub async
/// Run `program` with `args` inside a private job and capture the result
/// without erroring on a non-zero exit — for commands whose exit code is meaningful.
pub async
/// The `mockall`-generated mock of [`ProcessRunner`] (enabled by the `mock`
/// feature), re-exported under a friendlier name.
pub use MockProcessRunner as MockRunner;