1use std::path::PathBuf;
4
5use clap::{Args, Parser, Subcommand};
6
7#[derive(Parser, Debug)]
8#[command(name = "greentic-setup")]
9#[command(version)]
10#[command(about = "Greentic bundle setup CLI")]
11#[command(after_help = r#"EXAMPLES:
12 Interactive wizard:
13 greentic-setup ./my-bundle
14
15 Preview without executing:
16 greentic-setup --dry-run ./my-bundle
17
18 Generate answers template:
19 greentic-setup --dry-run --emit-answers answers.json ./my-bundle
20
21 Apply answers file:
22 greentic-setup --answers answers.json ./my-bundle.gtbundle
23
24 Deploy a bundle into an environment:
25 greentic-setup env-deploy ./my-bundle.gtbundle
26 greentic-setup env-deploy ./my-bundle.gtbundle --env staging
27 greentic-setup env-deploy --dry-run ./my-bundle.gtbundle
28
29 Add a messaging provider to an environment:
30 greentic-setup provider add telegram
31 greentic-setup provider add slack --env staging
32 greentic-setup provider add telegram --answers answers.json --non-interactive
33 greentic-setup provider list
34 greentic-setup provider remove <endpoint-id>
35
36 Advanced (bundle subcommands):
37 greentic-setup bundle init ./my-bundle
38 greentic-setup bundle add pack.gtpack --bundle ./my-bundle
39 greentic-setup bundle status --bundle ./my-bundle
40"#)]
41pub struct Cli {
42 #[arg(value_name = "BUNDLE")]
44 pub bundle: Option<PathBuf>,
45
46 #[arg(long = "dry-run", global = true)]
48 pub dry_run: bool,
49
50 #[arg(long = "emit-answers", value_name = "FILE", global = true)]
52 pub emit_answers: Option<PathBuf>,
53
54 #[arg(long = "answers", short = 'a', value_name = "FILE", global = true)]
56 pub answers: Option<PathBuf>,
57
58 #[arg(long = "key", value_name = "KEY", global = true)]
60 pub key: Option<String>,
61
62 #[arg(long = "tenant", short = 't', default_value = "demo", global = true)]
64 pub tenant: String,
65
66 #[arg(long = "team", global = true)]
68 pub team: Option<String>,
69
70 #[arg(long = "env", short = 'e', default_value = "local", global = true)]
73 pub env: String,
74
75 #[arg(long = "locale", global = true)]
77 pub locale: Option<String>,
78
79 #[arg(long = "advanced", global = true)]
81 pub advanced: bool,
82
83 #[arg(long = "ui", global = true, default_value_t = true)]
86 pub ui: bool,
87
88 #[arg(long = "no-ui", global = true)]
90 pub no_ui: bool,
91
92 #[arg(long = "non-interactive", global = true)]
94 pub non_interactive: bool,
95
96 #[command(subcommand)]
97 pub command: Option<Command>,
98}
99
100#[derive(Subcommand, Debug)]
101pub enum Command {
102 Doctor(DoctorArgs),
104 EnvDeploy(EnvDeployArgs),
106 #[command(subcommand)]
108 Provider(ProviderCommand),
109 #[command(subcommand)]
111 Bundle(Box<BundleCommand>),
112}
113
114#[derive(Args, Debug, Clone)]
115pub struct EnvDeployArgs {
116 #[arg(value_name = "BUNDLE")]
118 pub bundle: PathBuf,
119}
120
121#[derive(Args, Debug, Clone)]
122pub struct DoctorArgs {
123 #[arg(value_name = "BUNDLE")]
125 pub bundle: Option<PathBuf>,
126 #[command(subcommand)]
127 pub command: Option<DoctorCommand>,
128 #[arg(long = "json")]
130 pub json: bool,
131 #[arg(long = "strict")]
133 pub strict: bool,
134 #[arg(long = "fix-hints")]
136 pub fix_hints: bool,
137 #[arg(long = "show-info")]
139 pub show_info: bool,
140 #[arg(long = "stage", value_enum)]
142 pub stage: Option<DoctorStageArg>,
143}
144
145#[derive(Subcommand, Debug, Clone)]
146pub enum DoctorCommand {
147 Provider(DoctorProviderArgs),
149}
150
151#[derive(Args, Debug, Clone)]
152pub struct DoctorProviderArgs {
153 #[arg(value_name = "PACK")]
155 pub pack: PathBuf,
156}
157
158#[derive(clap::ValueEnum, Debug, Clone, Copy, PartialEq, Eq)]
159pub enum DoctorStageArg {
160 Setup,
161 Cache,
162 Locks,
163 Answers,
164 Runtime,
165 Routes,
166}
167
168#[derive(Subcommand, Debug, Clone)]
169pub enum BundleCommand {
170 Init(BundleInitArgs),
172 Add(BundleAddArgs),
174 Setup(BundleSetupArgs),
176 Update(BundleSetupArgs),
178 SetupStatus(BundleSetupStatusArgs),
180 SetupNext(BundleSetupNextArgs),
182 SetupRetry(BundleSetupRetryArgs),
184 SetupReset(BundleSetupResetArgs),
186 SetupMigrate(BundleSetupMigrateArgs),
188 Remove(BundleRemoveArgs),
190 Build(BundleBuildArgs),
192 List(BundleListArgs),
194 Status(BundleStatusArgs),
196}
197
198#[derive(Args, Debug, Clone)]
199pub struct BundleInitArgs {
200 #[arg(value_name = "PATH")]
202 pub path: Option<PathBuf>,
203 #[arg(long = "name", short = 'n')]
205 pub name: Option<String>,
206}
207
208#[derive(Args, Debug, Clone)]
209pub struct BundleAddArgs {
210 #[arg(value_name = "PACK_REF")]
212 pub pack_ref: String,
213 #[arg(long = "bundle", short = 'b')]
215 pub bundle: Option<PathBuf>,
216 #[arg(long = "tenant", short = 't', default_value = "demo")]
218 pub tenant: String,
219 #[arg(long = "team")]
221 pub team: Option<String>,
222 #[arg(long = "env", short = 'e', default_value = "local")]
225 pub env: String,
226 #[arg(long = "dry-run")]
228 pub dry_run: bool,
229}
230
231#[derive(Args, Debug, Clone)]
232pub struct BundleSetupArgs {
233 #[arg(value_name = "PROVIDER_ID")]
235 pub provider_id: Option<String>,
236 #[arg(long = "bundle", short = 'b')]
238 pub bundle: Option<PathBuf>,
239 #[arg(long = "answers", short = 'a')]
241 pub answers: Option<PathBuf>,
242 #[arg(long = "key", value_name = "KEY")]
244 pub key: Option<String>,
245 #[arg(long = "tenant", short = 't', default_value = "demo")]
247 pub tenant: String,
248 #[arg(long = "team")]
250 pub team: Option<String>,
251 #[arg(long = "env", short = 'e', default_value = "local")]
254 pub env: String,
255 #[arg(long = "domain", short = 'd', default_value = "all")]
257 pub domain: String,
258 #[arg(long = "parallel", default_value = "1")]
260 pub parallel: usize,
261 #[arg(long = "backup")]
263 pub backup: bool,
264 #[arg(long = "skip-secrets-init")]
266 pub skip_secrets_init: bool,
267 #[arg(long = "best-effort")]
269 pub best_effort: bool,
270 #[arg(skip)]
272 pub non_interactive: bool,
273 #[arg(long = "dry-run")]
275 pub dry_run: bool,
276 #[arg(long = "emit-answers")]
278 pub emit_answers: Option<PathBuf>,
279 #[arg(long = "advanced")]
281 pub advanced: bool,
282}
283
284#[derive(Args, Debug, Clone)]
285pub struct BundleSetupStatusArgs {
286 #[arg(value_name = "PROVIDER_ID")]
288 pub provider_id: String,
289 #[arg(long = "bundle", short = 'b')]
291 pub bundle: Option<PathBuf>,
292 #[arg(long = "tenant", short = 't', default_value = "demo")]
294 pub tenant: String,
295 #[arg(long = "team")]
297 pub team: Option<String>,
298 #[arg(long = "env", short = 'e', default_value = "dev")]
300 pub env: String,
301 #[arg(long = "format", default_value = "text")]
303 pub format: String,
304}
305
306#[derive(Args, Debug, Clone)]
307pub struct BundleSetupNextArgs {
308 #[arg(value_name = "PROVIDER_ID")]
310 pub provider_id: String,
311 #[arg(long = "bundle", short = 'b')]
313 pub bundle: Option<PathBuf>,
314 #[arg(long = "tenant", short = 't', default_value = "demo")]
316 pub tenant: String,
317 #[arg(long = "team")]
319 pub team: Option<String>,
320 #[arg(long = "env", short = 'e', default_value = "dev")]
322 pub env: String,
323 #[arg(long = "format", default_value = "text")]
325 pub format: String,
326 #[arg(long = "dry-run")]
328 pub dry_run: bool,
329}
330
331#[derive(Args, Debug, Clone)]
332pub struct BundleSetupRetryArgs {
333 #[arg(value_name = "PROVIDER_ID")]
335 pub provider_id: String,
336 #[arg(long = "bundle", short = 'b')]
338 pub bundle: Option<PathBuf>,
339 #[arg(long = "tenant", short = 't', default_value = "demo")]
341 pub tenant: String,
342 #[arg(long = "team")]
344 pub team: Option<String>,
345 #[arg(long = "env", short = 'e', default_value = "dev")]
347 pub env: String,
348 #[arg(long = "step")]
350 pub step: Option<String>,
351 #[arg(long = "json")]
353 pub json: bool,
354}
355
356#[derive(Args, Debug, Clone)]
357pub struct BundleSetupResetArgs {
358 #[arg(value_name = "PROVIDER_ID")]
360 pub provider_id: String,
361 #[arg(long = "bundle", short = 'b')]
363 pub bundle: Option<PathBuf>,
364 #[arg(long = "tenant", short = 't', default_value = "demo")]
366 pub tenant: String,
367 #[arg(long = "team")]
369 pub team: Option<String>,
370 #[arg(long = "yes")]
372 pub yes: bool,
373 #[arg(long = "json")]
375 pub json: bool,
376}
377
378#[derive(Args, Debug, Clone)]
379pub struct BundleSetupMigrateArgs {
380 #[arg(value_name = "PROVIDER_ID")]
382 pub provider_id: String,
383 #[arg(long = "bundle", short = 'b')]
385 pub bundle: Option<PathBuf>,
386 #[arg(long = "tenant", short = 't', default_value = "demo")]
388 pub tenant: String,
389 #[arg(long = "team")]
391 pub team: Option<String>,
392 #[arg(long = "env", short = 'e', default_value = "dev")]
394 pub env: String,
395 #[arg(long = "json")]
397 pub json: bool,
398}
399
400#[derive(Args, Debug, Clone)]
401pub struct BundleRemoveArgs {
402 #[arg(value_name = "PROVIDER_ID")]
404 pub provider_id: String,
405 #[arg(long = "bundle", short = 'b')]
407 pub bundle: Option<PathBuf>,
408 #[arg(long = "tenant", short = 't', default_value = "demo")]
410 pub tenant: String,
411 #[arg(long = "team")]
413 pub team: Option<String>,
414 #[arg(long = "force", short = 'f')]
416 pub force: bool,
417}
418
419#[derive(Args, Debug, Clone)]
420pub struct BundleBuildArgs {
421 #[arg(long = "bundle", short = 'b')]
423 pub bundle: Option<PathBuf>,
424 #[arg(long = "out", short = 'o')]
426 pub out: PathBuf,
427 #[arg(long = "tenant", short = 't')]
429 pub tenant: Option<String>,
430 #[arg(long = "team")]
432 pub team: Option<String>,
433 #[arg(long = "only-used-providers")]
435 pub only_used_providers: bool,
436 #[arg(long = "doctor")]
438 pub doctor: bool,
439 #[arg(long = "skip-doctor")]
441 pub skip_doctor: bool,
442}
443
444#[derive(Args, Debug, Clone)]
445pub struct BundleListArgs {
446 #[arg(long = "bundle", short = 'b')]
448 pub bundle: Option<PathBuf>,
449 #[arg(long = "domain", short = 'd', default_value = "messaging")]
451 pub domain: String,
452 #[arg(long = "pack", short = 'p')]
454 pub pack: Option<String>,
455 #[arg(long = "format", default_value = "text")]
457 pub format: String,
458}
459
460#[derive(Args, Debug, Clone)]
461pub struct BundleStatusArgs {
462 #[arg(long = "bundle", short = 'b')]
464 pub bundle: Option<PathBuf>,
465 #[arg(long = "format", default_value = "text")]
467 pub format: String,
468}
469
470#[derive(Subcommand, Debug, Clone)]
473pub enum ProviderCommand {
474 Add(ProviderAddArgs),
476 List(ProviderListArgs),
478 Remove(ProviderRemoveArgs),
480}
481
482#[derive(Args, Debug, Clone)]
483pub struct ProviderAddArgs {
484 #[arg(value_name = "KIND")]
486 pub kind: String,
487 #[arg(long = "bundle-id")]
489 pub bundle_id: Option<String>,
490 #[arg(long = "pack")]
492 pub pack: Option<PathBuf>,
493 #[arg(long = "pack-version")]
496 pub pack_version: Option<String>,
497 #[arg(long = "provider-id")]
499 pub provider_id: Option<String>,
500 #[arg(long = "display-name")]
502 pub display_name: Option<String>,
503}
504
505#[derive(Args, Debug, Clone)]
506pub struct ProviderListArgs {}
507
508#[derive(Args, Debug, Clone)]
509pub struct ProviderRemoveArgs {
510 #[arg(value_name = "ENDPOINT_ID")]
512 pub endpoint_id: String,
513}