1use serde::Deserialize;
2use std::path::PathBuf;
3use std::str::FromStr;
4use structopt::StructOpt;
5
6pub mod compiler;
7pub mod config;
8pub mod display;
9pub mod engine;
10pub mod env;
11pub mod execution_plan;
12pub mod executor;
13pub mod git;
14pub mod gitlab;
15pub mod history;
16pub mod logging;
17pub mod model;
18pub mod naming;
19pub mod pipeline;
20pub mod runner;
21pub mod runtime;
22pub mod secrets;
23pub mod terminal;
24pub mod ui;
25
26#[derive(StructOpt)]
27pub struct Cli {
28 #[structopt(
29 short,
30 long,
31 default_value = "info",
32 possible_values = &["trace", "debug", "info", "warn", "error"]
33 )]
34 pub log_level: tracing::Level,
35
36 #[structopt(subcommand)]
37 pub commands: Commands,
38}
39
40#[derive(StructOpt)]
41pub enum Commands {
42 Run(RunArgs),
43 Plan(PlanArgs),
44 View(ViewArgs),
45}
46
47#[derive(StructOpt)]
48pub struct RunArgs {
49 #[structopt(short, long)]
51 pub pipeline: Option<PathBuf>,
52
53 #[structopt(short, long)]
54 pub workdir: Option<PathBuf>,
56
57 #[structopt(short, long)]
58 pub base_image: Option<String>,
60
61 #[structopt(
62 short = "E",
63 long = "env",
64 value_name = "GLOB",
65 help = "Include host env vars matching this glob (e.g. APP_*). Repeat to add more."
66 )]
67 pub env_includes: Vec<String>,
68
69 #[structopt(long = "max-parallel-jobs", default_value = "5")]
70 pub max_parallel_jobs: usize,
72
73 #[structopt(long = "trace-scripts")]
74 pub trace_scripts: bool,
76
77 #[structopt(
78 long = "engine",
79 default_value = "auto",
80 possible_values = EngineChoice::VARIANTS,
81 help = "Container runtime to use (auto, container, docker, podman, nerdctl, orbstack). nerdctl is Linux-specific in Opal."
82 )]
83 pub engine: EngineChoice,
84
85 #[structopt(long = "no-tui")]
86 pub no_tui: bool,
88
89 #[structopt(long = "gitlab-base-url", env = "OPAL_GITLAB_BASE_URL")]
90 pub gitlab_base_url: Option<String>,
92
93 #[structopt(long = "gitlab-token", env = "OPAL_GITLAB_TOKEN")]
94 pub gitlab_token: Option<String>,
96
97 #[structopt(long = "job", value_name = "NAME")]
98 pub jobs: Vec<String>,
100}
101
102#[derive(StructOpt)]
103pub struct ViewArgs {
104 #[structopt(short, long)]
105 pub workdir: Option<PathBuf>,
107}
108
109#[derive(StructOpt)]
110pub struct PlanArgs {
111 #[structopt(short, long)]
113 pub pipeline: Option<PathBuf>,
114
115 #[structopt(short, long)]
116 pub workdir: Option<PathBuf>,
118
119 #[structopt(long = "gitlab-base-url", env = "OPAL_GITLAB_BASE_URL")]
120 pub gitlab_base_url: Option<String>,
122
123 #[structopt(long = "gitlab-token", env = "OPAL_GITLAB_TOKEN")]
124 pub gitlab_token: Option<String>,
126
127 #[structopt(long = "job", value_name = "NAME")]
128 pub jobs: Vec<String>,
130
131 #[structopt(long = "no-pager")]
132 pub no_pager: bool,
134
135 #[structopt(long = "json")]
136 pub json: bool,
138}
139
140#[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize)]
141#[serde(rename_all = "lowercase")]
142pub enum EngineChoice {
143 Auto,
144 Container,
145 Docker,
146 Podman,
147 Nerdctl,
148 Orbstack,
149}
150
151impl EngineChoice {
152 pub const VARIANTS: &'static [&'static str] = &[
153 "auto",
154 "container",
155 "docker",
156 "podman",
157 "nerdctl",
158 "orbstack",
159 ];
160}
161
162impl FromStr for EngineChoice {
163 type Err = String;
164
165 fn from_str(s: &str) -> Result<Self, Self::Err> {
166 match s.to_ascii_lowercase().as_str() {
167 "auto" => Ok(Self::Auto),
168 "container" => Ok(Self::Container),
169 "docker" => Ok(Self::Docker),
170 "podman" => Ok(Self::Podman),
171 "nerdctl" => Ok(Self::Nerdctl),
172 "orbstack" => Ok(Self::Orbstack),
173 other => Err(format!("unknown engine '{other}'")),
174 }
175 }
176}
177
178#[derive(Clone, Copy, Debug)]
179pub enum EngineKind {
180 ContainerCli,
181 Docker,
182 Podman,
183 Nerdctl,
184 Orbstack,
185}
186
187#[derive(Debug, Clone)]
188pub struct ExecutorConfig {
189 pub image: Option<String>,
190 pub workdir: PathBuf,
191 pub pipeline: PathBuf,
192 pub env_includes: Vec<String>,
193 pub selected_jobs: Vec<String>,
194 pub max_parallel_jobs: usize,
195 pub enable_tui: bool,
196 pub engine: EngineKind,
197 pub gitlab: Option<GitLabRemoteConfig>,
198 pub settings: config::OpalConfig,
199 pub trace_scripts: bool,
200}
201
202#[derive(Clone, Debug)]
203pub struct GitLabRemoteConfig {
204 pub base_url: String,
205 pub token: String,
206}