bare_script/proc/
builder.rs1use std::ffi::OsStr;
7use std::process::Stdio;
8
9use tokio::process::Command;
10
11use crate::error::{ScriptError, ScriptResult};
12use crate::output::Output;
13
14#[derive(Debug)]
16pub struct CommandBuilder {
17 cmd: Command,
18}
19
20impl CommandBuilder {
21 pub fn new<S: AsRef<OsStr>>(program: S) -> Self {
23 Self {
24 cmd: Command::new(program),
25 }
26 }
27
28 pub fn arg<S: AsRef<OsStr>>(mut self, arg: S) -> Self {
30 let _ = self.cmd.arg(arg);
31 self
32 }
33
34 pub fn args<I, S>(mut self, args: I) -> Self
36 where
37 I: IntoIterator<Item = S>,
38 S: AsRef<OsStr>,
39 {
40 let _ = self.cmd.args(args);
41 self
42 }
43
44 pub fn env<K, V>(mut self, key: K, value: V) -> Self
46 where
47 K: AsRef<OsStr>,
48 V: AsRef<OsStr>,
49 {
50 let _ = self.cmd.env(key, value);
51 self
52 }
53
54 pub fn envs<I, K, V>(mut self, vars: I) -> Self
56 where
57 I: IntoIterator<Item = (K, V)>,
58 K: AsRef<OsStr>,
59 V: AsRef<OsStr>,
60 {
61 let _ = self.cmd.envs(vars);
62 self
63 }
64
65 pub fn env_clear(mut self) -> Self {
67 let _ = self.cmd.env_clear();
68 self
69 }
70
71 pub fn env_remove<K>(mut self, key: K) -> Self
73 where
74 K: AsRef<OsStr>,
75 {
76 let _ = self.cmd.env_remove(key);
77 self
78 }
79
80 pub fn current_dir<D>(mut self, dir: D) -> Self
82 where
83 D: AsRef<std::path::Path>,
84 {
85 let _ = self.cmd.current_dir(dir);
86 self
87 }
88
89 pub fn stdin<T: Into<Stdio>>(mut self, stdin: T) -> Self {
91 let _ = self.cmd.stdin(stdin);
92 self
93 }
94
95 pub fn stdout<T: Into<Stdio>>(mut self, stdout: T) -> Self {
97 let _ = self.cmd.stdout(stdout);
98 self
99 }
100
101 pub fn stderr<T: Into<Stdio>>(mut self, stderr: T) -> Self {
103 let _ = self.cmd.stderr(stderr);
104 self
105 }
106
107 pub fn capture_output(mut self) -> Self {
109 let _ = self.cmd.stdout(Stdio::piped());
110 let _ = self.cmd.stderr(Stdio::piped());
111 self
112 }
113
114 pub fn inherit_stdin(mut self) -> Self {
116 let _ = self.cmd.stdin(Stdio::inherit());
117 self
118 }
119
120 pub fn inherit_stdout(mut self) -> Self {
122 let _ = self.cmd.stdout(Stdio::inherit());
123 self
124 }
125
126 pub fn inherit_stderr(mut self) -> Self {
128 let _ = self.cmd.stderr(Stdio::inherit());
129 self
130 }
131
132 pub fn null_stdin(mut self) -> Self {
134 let _ = self.cmd.stdin(Stdio::null());
135 self
136 }
137
138 pub fn null_stdout(mut self) -> Self {
140 let _ = self.cmd.stdout(Stdio::null());
141 self
142 }
143
144 pub fn null_stderr(mut self) -> Self {
146 let _ = self.cmd.stderr(Stdio::null());
147 self
148 }
149
150 pub fn kill_on_drop(mut self, kill: bool) -> Self {
152 let _ = self.cmd.kill_on_drop(kill);
153 self
154 }
155
156 pub async fn spawn(&mut self) -> std::io::Result<tokio::process::Child> {
158 self.cmd.spawn()
159 }
160
161 pub async fn output(&mut self) -> std::io::Result<Output> {
163 let output = self.cmd.output().await?;
164 Ok(Output::new(output.stdout, output.stderr, output.status))
165 }
166
167 pub async fn execute(&mut self) -> ScriptResult<Output> {
169 self.output().await.map_err(ScriptError::IoError)
170 }
171
172 pub async fn execute_with_timeout(
174 mut self,
175 timeout: std::time::Duration,
176 ) -> ScriptResult<Output> {
177 use tokio::time;
178
179 match time::timeout(timeout, self.cmd.output()).await {
180 Ok(Ok(output)) => Ok(Output::new(output.stdout, output.stderr, output.status)),
181 Ok(Err(e)) => Err(ScriptError::IoError(e)),
182 Err(_) => Err(ScriptError::Timeout(timeout)),
183 }
184 }
185
186 pub async fn status(&mut self) -> std::io::Result<std::process::ExitStatus> {
188 self.cmd.status().await
189 }
190}