greentic_operator/
runner_integration.rs1use std::path::Path;
2use std::process::Command;
3
4use serde_json::Value;
5
6#[derive(Clone, Copy, Debug, Eq, PartialEq)]
7pub enum RunnerFlavor {
8 RunSubcommand,
9 RunnerCli,
10}
11
12pub struct RunFlowOptions<'a> {
13 pub dist_offline: bool,
14 pub tenant: Option<&'a str>,
15 pub team: Option<&'a str>,
16 pub artifacts_dir: Option<&'a Path>,
17 pub runner_flavor: RunnerFlavor,
18}
19
20pub struct RunnerOutput {
21 pub status: std::process::ExitStatus,
22 pub stdout: String,
23 pub stderr: String,
24 pub parsed: Option<Value>,
25}
26
27pub fn run_flow(
28 runner: &Path,
29 pack: &Path,
30 flow: &str,
31 input: &Value,
32) -> anyhow::Result<RunnerOutput> {
33 run_flow_with_options(
34 runner,
35 pack,
36 flow,
37 input,
38 RunFlowOptions {
39 dist_offline: false,
40 tenant: None,
41 team: None,
42 artifacts_dir: None,
43 runner_flavor: RunnerFlavor::RunSubcommand,
44 },
45 )
46}
47
48pub fn run_flow_with_options(
49 runner: &Path,
50 pack: &Path,
51 flow: &str,
52 input: &Value,
53 options: RunFlowOptions<'_>,
54) -> anyhow::Result<RunnerOutput> {
55 let input_str = serde_json::to_string(input)?;
56 let mut command = Command::new(runner);
57 match options.runner_flavor {
58 RunnerFlavor::RunSubcommand => {
59 command
60 .args(["run", "--pack"])
61 .arg(pack)
62 .args(["--flow", flow, "--input"])
63 .arg(&input_str);
64 if options.dist_offline {
65 command.arg("--offline");
66 }
67 }
68 RunnerFlavor::RunnerCli => {
69 command
70 .arg("--pack")
71 .arg(pack)
72 .args(["--flow", flow, "--input"])
73 .arg(&input_str);
74 if let Some(tenant) = options.tenant {
75 command.args(["--tenant", tenant]);
76 }
77 if let Some(team) = options.team {
78 command.args(["--team", team]);
79 }
80 if let Some(artifacts_dir) = options.artifacts_dir {
81 command.arg("--artifacts-dir").arg(artifacts_dir);
82 }
83 if options.dist_offline {
84 command.arg("--offline");
85 }
86 }
87 }
88 let output = command.output()?;
89
90 let stdout = String::from_utf8_lossy(&output.stdout).to_string();
91 let stderr = String::from_utf8_lossy(&output.stderr).to_string();
92 let parsed = serde_json::from_str(&stdout).ok();
93
94 Ok(RunnerOutput {
95 status: output.status,
96 stdout,
97 stderr,
98 parsed,
99 })
100}
101
102pub fn detect_runner_flavor(runner: &Path) -> RunnerFlavor {
103 let name = runner
104 .file_name()
105 .and_then(|value| value.to_str())
106 .unwrap_or_default();
107 if name.contains("runner-cli") {
108 RunnerFlavor::RunnerCli
109 } else {
110 RunnerFlavor::RunSubcommand
111 }
112}