crankshaft_engine/task/
execution.rs

1//! A unit of executable work.
2
3use std::collections::BTreeMap;
4
5use bon::Builder;
6use indexmap::IndexMap;
7
8/// An execution.
9#[derive(Builder, Clone, Debug)]
10#[builder(builder_type = Builder)]
11pub struct Execution {
12    /// The container image.
13    #[builder(into)]
14    pub(crate) image: String,
15
16    /// The program to execute.
17    #[builder(into)]
18    pub(crate) program: String,
19
20    /// The arguments to the program.
21    #[builder(into, default)]
22    pub(crate) args: Vec<String>,
23
24    /// The working directory, if configured.
25    #[builder(into)]
26    pub(crate) work_dir: Option<String>,
27
28    /// The path inside the container to a file whose contents will be piped to
29    /// the standard input, if configured.
30    #[builder(into)]
31    pub(crate) stdin: Option<String>,
32
33    /// The path inside the container to a file where the contents of the
34    /// standard output stream will be written, if configured.
35    #[builder(into)]
36    pub(crate) stdout: Option<String>,
37
38    /// The path inside the container to a file where the contents of the
39    /// standard error stream will be written, if configured.
40    #[builder(into)]
41    pub(crate) stderr: Option<String>,
42
43    /// A map of environment variables, if configured.
44    #[builder(into, default)]
45    pub(crate) env: IndexMap<String, String>,
46}
47
48impl Execution {
49    /// The image for the execution to run within.
50    pub fn image(&self) -> &str {
51        &self.image
52    }
53
54    /// The program to execute.
55    pub fn program(&self) -> &str {
56        &self.program
57    }
58
59    /// The arguments to the execution.
60    pub fn args(&self) -> &[String] {
61        &self.args
62    }
63
64    /// The working directory.
65    pub fn work_dir(&self) -> Option<&str> {
66        self.work_dir.as_deref()
67    }
68
69    /// The file to pipe the standard input stream from.
70    pub fn stdin(&self) -> Option<&str> {
71        self.stdin.as_deref()
72    }
73
74    /// The file to pipe the standard output stream to.
75    pub fn stdout(&self) -> Option<&str> {
76        self.stdout.as_deref()
77    }
78
79    /// The file to pipe the standard error stream to.
80    pub fn stderr(&self) -> Option<&str> {
81        self.stderr.as_deref()
82    }
83
84    /// The environment variables for the execution.
85    pub fn env(&self) -> &IndexMap<String, String> {
86        &self.env
87    }
88}
89
90impl From<Execution> for tes::v1::types::task::Executor {
91    fn from(execution: Execution) -> Self {
92        let env = execution
93            .env
94            .into_iter()
95            .collect::<BTreeMap<String, String>>();
96
97        let env = if env.is_empty() { None } else { Some(env) };
98
99        let mut command = Vec::with_capacity(execution.args.len() + 1);
100        command.push(execution.program);
101        command.extend(execution.args);
102
103        tes::v1::types::task::Executor {
104            image: execution.image.to_owned(),
105            command,
106            workdir: execution.work_dir,
107            stdin: execution.stdin,
108            stdout: execution.stdout,
109            stderr: execution.stderr,
110            env,
111            ignore_error: Some(true),
112        }
113    }
114}