1use anyhow::Result;
4use std::process::{Command, Stdio};
5
6use crate::config::ShimConfig;
7use crate::platform::PlatformExecutor;
8
9pub struct Executor {
11 config: ShimConfig,
12 platform: PlatformExecutor,
13}
14
15impl Executor {
16 pub fn new(config: ShimConfig) -> Self {
18 Self {
19 config,
20 platform: PlatformExecutor::new(),
21 }
22 }
23
24 pub fn execute(&self, args: &[String]) -> Result<i32> {
26 let target_path = self.config.resolved_path();
27 let mut cmd_args = self.config.resolved_args();
28 cmd_args.extend_from_slice(args);
29
30 let mut command = Command::new(&target_path);
32 command.args(&cmd_args);
33
34 if let Some(working_dir) = self.config.resolved_working_dir() {
36 command.current_dir(working_dir);
37 }
38
39 for (key, value) in self.config.resolved_env() {
41 command.env(key, value);
42 }
43
44 command
46 .stdin(Stdio::inherit())
47 .stdout(Stdio::inherit())
48 .stderr(Stdio::inherit());
49
50 self.platform.execute(command, &self.config)
52 }
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58 use crate::config::ShimConfig;
59 use std::collections::HashMap;
60
61 #[test]
62 fn test_executor_creation() {
63 let config = ShimConfig {
64 path: "/bin/echo".to_string(),
65 args: Some(vec!["hello".to_string()]),
66 working_dir: None,
67 env: None,
68 hide_console: None,
69 run_as_admin: None,
70 signal_handling: None,
71 };
72
73 let executor = Executor::new(config);
74 assert_eq!(executor.config.path, "/bin/echo");
75 }
76
77 #[test]
78 fn test_executor_with_env() {
79 let mut env = HashMap::new();
80 env.insert("TEST_VAR".to_string(), "test_value".to_string());
81
82 let config = ShimConfig {
83 path: "/bin/echo".to_string(),
84 args: None,
85 working_dir: None,
86 env: Some(env),
87 hide_console: None,
88 run_as_admin: None,
89 signal_handling: None,
90 };
91
92 let executor = Executor::new(config);
93 let resolved_env = executor.config.resolved_env();
94 assert_eq!(
95 resolved_env.get("TEST_VAR"),
96 Some(&"test_value".to_string())
97 );
98 }
99}