Skip to main content

solti_model/domain/environment/
runner.rs

1//! # Runner-level environment variables.
2//!
3//! [`RunnerEnv`] provides base environment variables shared across all tasks on a runner.
4
5env_newtype! {
6    /// Environment variables injected by the runner.
7    ///
8    /// ```text
9    ///  RunnerEnv (runner-level defaults)
10    ///  ┌───────────────────────────────┐
11    ///  │  PATH=/safe/bin               │  ← enforced by runner
12    ///  │  RUNNER_NAME=prod-01          │
13    ///  │  FOO=from-runner              │  ← overrides task FOO
14    ///  └───────────────────────────────┘
15    /// ```
16    ///
17    pub struct RunnerEnv;
18}
19
20#[cfg(test)]
21mod tests {
22    use super::RunnerEnv;
23
24    #[test]
25    fn new_is_empty() {
26        let env = RunnerEnv::new();
27
28        assert_eq!(env.len(), 0);
29        assert!(env.is_empty());
30        assert!(env.get("FOO").is_none());
31    }
32
33    #[test]
34    fn push_and_get() {
35        let mut env = RunnerEnv::new();
36        env.push("PATH", "/safe/bin");
37        env.push("RUNNER", "prod-01");
38
39        assert_eq!(env.len(), 2);
40        assert_eq!(env.get("PATH"), Some("/safe/bin"));
41        assert_eq!(env.get("RUNNER"), Some("prod-01"));
42    }
43
44    #[test]
45    fn last_wins() {
46        let mut env = RunnerEnv::new();
47        env.push("FOO", "first");
48        env.push("FOO", "second");
49
50        assert_eq!(env.get("FOO"), Some("second"));
51    }
52
53    #[test]
54    fn serde_transparent_roundtrip() {
55        let mut env = RunnerEnv::new();
56        env.push("K", "V");
57
58        let json = serde_json::to_string(&env).unwrap();
59        let back: RunnerEnv = serde_json::from_str(&json).unwrap();
60        assert_eq!(back.get("K"), Some("V"));
61    }
62}