systemprompt_cloud/docker/
command.rs1use std::io;
7use std::path::{Path, PathBuf};
8use std::process::{Command, ExitStatus, Output, Stdio};
9
10#[derive(Debug, Clone)]
11pub struct CommandSpec {
12 pub program: String,
13 pub args: Vec<String>,
14 pub current_dir: Option<PathBuf>,
15}
16
17impl CommandSpec {
18 pub fn docker<I, S>(args: I) -> Self
19 where
20 I: IntoIterator<Item = S>,
21 S: Into<String>,
22 {
23 Self {
24 program: "docker".to_owned(),
25 args: args.into_iter().map(Into::into).collect(),
26 current_dir: None,
27 }
28 }
29
30 pub fn git<I, S>(repo: &Path, args: I) -> Self
31 where
32 I: IntoIterator<Item = S>,
33 S: Into<String>,
34 {
35 Self {
36 program: "git".to_owned(),
37 args: args.into_iter().map(Into::into).collect(),
38 current_dir: Some(repo.to_path_buf()),
39 }
40 }
41
42 #[must_use]
43 pub fn rendered(&self) -> String {
44 format!("{} {}", self.program, self.args.join(" "))
45 }
46}
47
48pub trait CommandRunner: Send + Sync {
49 fn output(&self, spec: &CommandSpec) -> io::Result<Output>;
50 fn status(&self, spec: &CommandSpec) -> io::Result<ExitStatus>;
51 fn status_with_stdin(&self, spec: &CommandSpec, stdin: &[u8]) -> io::Result<ExitStatus>;
52}
53
54#[derive(Debug, Clone, Copy, Default)]
55pub struct SystemCommandRunner;
56
57impl SystemCommandRunner {
58 fn command(spec: &CommandSpec) -> Command {
59 let mut command = Command::new(&spec.program);
60 command.args(&spec.args);
61 if let Some(dir) = &spec.current_dir {
62 command.current_dir(dir);
63 }
64 command
65 }
66}
67
68impl CommandRunner for SystemCommandRunner {
69 fn output(&self, spec: &CommandSpec) -> io::Result<Output> {
70 Self::command(spec).output()
71 }
72
73 fn status(&self, spec: &CommandSpec) -> io::Result<ExitStatus> {
74 Self::command(spec).status()
75 }
76
77 fn status_with_stdin(&self, spec: &CommandSpec, stdin: &[u8]) -> io::Result<ExitStatus> {
78 let mut command = Self::command(spec);
79 command.stdin(Stdio::piped());
80 let mut child = command.spawn()?;
81 if let Some(mut handle) = child.stdin.take() {
82 io::Write::write_all(&mut handle, stdin)?;
83 }
84 child.wait()
85 }
86}