oxdock_process/
contract.rs1use std::collections::HashMap;
2
3use anyhow::Result;
4use oxdock_fs::{GuardedPath, PolicyPath};
5#[allow(clippy::disallowed_types, clippy::disallowed_methods)]
6use std::process::ExitStatus;
7
8use std::sync::{Arc, Mutex};
9
10#[derive(Clone, Debug)]
14pub struct CommandContext {
15 cwd: PolicyPath,
16 envs: Arc<HashMap<String, String>>,
17 cargo_target_dir: GuardedPath,
18 workspace_root: GuardedPath,
19 build_context: GuardedPath,
20}
21
22impl CommandContext {
23 pub fn new(
24 cwd: &PolicyPath,
25 envs: Arc<HashMap<String, String>>,
26 cargo_target_dir: &GuardedPath,
27 workspace_root: &GuardedPath,
28 build_context: &GuardedPath,
29 ) -> Self {
30 Self {
31 cwd: cwd.clone(),
32 envs,
33 cargo_target_dir: cargo_target_dir.clone(),
34 workspace_root: workspace_root.clone(),
35 build_context: build_context.clone(),
36 }
37 }
38
39 pub fn from_map(
41 cwd: &PolicyPath,
42 envs: &HashMap<String, String>,
43 cargo_target_dir: &GuardedPath,
44 workspace_root: &GuardedPath,
45 build_context: &GuardedPath,
46 ) -> Self {
47 Self::new(
48 cwd,
49 Arc::new(envs.clone()),
50 cargo_target_dir,
51 workspace_root,
52 build_context,
53 )
54 }
55
56 pub fn cwd(&self) -> &PolicyPath {
57 &self.cwd
58 }
59
60 pub fn envs(&self) -> &Arc<HashMap<String, String>> {
61 &self.envs
62 }
63
64 pub fn cargo_target_dir(&self) -> &GuardedPath {
65 &self.cargo_target_dir
66 }
67
68 pub fn workspace_root(&self) -> &GuardedPath {
69 &self.workspace_root
70 }
71
72 pub fn build_context(&self) -> &GuardedPath {
73 &self.build_context
74 }
75}
76
77pub trait BackgroundHandle {
79 fn try_wait(&mut self) -> Result<Option<ExitStatus>>;
80 fn kill(&mut self) -> Result<()>;
81 fn wait(&mut self) -> Result<ExitStatus>;
82}
83
84pub type SharedInput = Arc<Mutex<dyn std::io::Read + Send>>;
85pub type SharedOutput = Arc<Mutex<dyn std::io::Write + Send>>;
86
87#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
88pub enum CommandMode {
89 #[default]
90 Foreground,
91 Background,
92}
93
94#[derive(Clone, Default)]
95pub enum CommandStdout {
96 #[default]
97 Inherit,
98 Stream(SharedOutput),
99 Capture,
100}
101
102#[derive(Clone, Default)]
103pub enum CommandStderr {
104 #[default]
105 Inherit,
106 Stream(SharedOutput),
107}
108
109#[derive(Clone, Default)]
110pub struct CommandOptions {
111 pub mode: CommandMode,
112 pub stdin: Option<SharedInput>,
113 pub stdout: CommandStdout,
114 pub stderr: CommandStderr,
115}
116
117impl CommandOptions {
118 pub fn foreground() -> Self {
119 Self::default()
120 }
121
122 pub fn background() -> Self {
123 Self {
124 mode: CommandMode::Background,
125 ..Self::default()
126 }
127 }
128}
129
130pub enum CommandResult<H> {
131 Completed,
132 Captured(Vec<u8>),
133 Background(H),
134}
135
136pub trait ProcessManager: Clone {
141 type Handle: BackgroundHandle;
142
143 fn run_command(
144 &mut self,
145 ctx: &CommandContext,
146 script: &str,
147 options: CommandOptions,
148 ) -> Result<CommandResult<Self::Handle>>;
149}