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