Skip to main content

ironflow_engine/config/
shell.rs

1//! [`ShellConfig`] — serializable configuration for a shell step.
2
3use serde::{Deserialize, Serialize};
4
5/// Serializable configuration for a shell step.
6///
7/// # Examples
8///
9/// ```
10/// use ironflow_engine::config::ShellConfig;
11///
12/// let config = ShellConfig::new("cargo build --release")
13///     .timeout_secs(300)
14///     .dir("/app");
15/// ```
16#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct ShellConfig {
18    /// The shell command to execute.
19    pub command: String,
20    /// Timeout in seconds (default: 300).
21    pub timeout_secs: Option<u64>,
22    /// Working directory.
23    pub dir: Option<String>,
24    /// Environment variables to set.
25    pub env: Vec<(String, String)>,
26    /// If true, start with a clean environment.
27    pub clean_env: bool,
28}
29
30impl ShellConfig {
31    /// Create a new shell config with the given command.
32    ///
33    /// # Examples
34    ///
35    /// ```
36    /// use ironflow_engine::config::ShellConfig;
37    ///
38    /// let config = ShellConfig::new("echo hello");
39    /// assert_eq!(config.command, "echo hello");
40    /// ```
41    pub fn new(command: &str) -> Self {
42        Self {
43            command: command.to_string(),
44            timeout_secs: None,
45            dir: None,
46            env: Vec::new(),
47            clean_env: false,
48        }
49    }
50
51    /// Set the timeout in seconds.
52    pub fn timeout_secs(mut self, secs: u64) -> Self {
53        self.timeout_secs = Some(secs);
54        self
55    }
56
57    /// Set the working directory.
58    pub fn dir(mut self, dir: &str) -> Self {
59        self.dir = Some(dir.to_string());
60        self
61    }
62
63    /// Add an environment variable.
64    pub fn env(mut self, key: &str, value: &str) -> Self {
65        self.env.push((key.to_string(), value.to_string()));
66        self
67    }
68
69    /// Start with a clean environment (no inherited vars).
70    pub fn clean_env(mut self) -> Self {
71        self.clean_env = true;
72        self
73    }
74}
75
76#[cfg(test)]
77mod tests {
78    use super::*;
79
80    #[test]
81    fn builder() {
82        let config = ShellConfig::new("cargo test")
83            .timeout_secs(60)
84            .dir("/app")
85            .env("RUST_LOG", "debug")
86            .clean_env();
87
88        assert_eq!(config.command, "cargo test");
89        assert_eq!(config.timeout_secs, Some(60));
90        assert_eq!(config.dir, Some("/app".to_string()));
91        assert_eq!(
92            config.env,
93            vec![("RUST_LOG".to_string(), "debug".to_string())]
94        );
95        assert!(config.clean_env);
96    }
97}