open_sesame/core/
launcher.rs1use crate::util::load_env_files;
6use std::collections::HashMap;
7use std::process::Command;
8
9#[derive(Debug, Clone)]
37pub struct LaunchCommand {
38 pub command: String,
40 pub args: Vec<String>,
42 pub env_files: Vec<String>,
44 pub env: HashMap<String, String>,
46}
47
48impl LaunchCommand {
49 pub fn simple(command: impl Into<String>) -> Self {
51 Self {
52 command: command.into(),
53 args: Vec::new(),
54 env_files: Vec::new(),
55 env: HashMap::new(),
56 }
57 }
58
59 pub fn advanced(
61 command: impl Into<String>,
62 args: Vec<String>,
63 env_files: Vec<String>,
64 env: HashMap<String, String>,
65 ) -> Self {
66 Self {
67 command: command.into(),
68 args,
69 env_files,
70 env,
71 }
72 }
73
74 pub fn execute(&self, global_env_files: &[String]) -> Result<u32, std::io::Error> {
82 tracing::info!("Launching: {} {}", self.command, self.args.join(" "));
83
84 let mut cmd = Command::new(&self.command);
85 cmd.args(&self.args);
86
87 let global_env = load_env_files(global_env_files);
89 let app_env = load_env_files(&self.env_files);
90
91 cmd.envs(&global_env).envs(&app_env).envs(&self.env);
92
93 let total = global_env.len() + app_env.len() + self.env.len();
94 if total > 0 {
95 tracing::debug!("Set {} environment variables", total);
96 }
97
98 let child = cmd.spawn()?;
99 let pid = child.id();
100 tracing::debug!("Launched PID: {}", pid);
101
102 Ok(pid)
103 }
104}
105
106#[cfg(test)]
107mod tests {
108 use super::*;
109
110 #[test]
111 fn test_simple_command() {
112 let cmd = LaunchCommand::simple("firefox");
113 assert_eq!(cmd.command, "firefox");
114 assert!(cmd.args.is_empty());
115 assert!(cmd.env_files.is_empty());
116 assert!(cmd.env.is_empty());
117 }
118
119 #[test]
120 fn test_advanced_command() {
121 let mut env = HashMap::new();
122 env.insert("MY_VAR".to_string(), "value".to_string());
123
124 let cmd = LaunchCommand::advanced(
125 "firefox",
126 vec!["--private-window".to_string()],
127 vec!["~/.env".to_string()],
128 env,
129 );
130
131 assert_eq!(cmd.command, "firefox");
132 assert_eq!(cmd.args, vec!["--private-window"]);
133 assert_eq!(cmd.env_files, vec!["~/.env"]);
134 assert_eq!(cmd.env.get("MY_VAR"), Some(&"value".to_string()));
135 }
136}