Skip to main content

greentic_dev/
cli.rs

1use std::{ffi::OsString, path::PathBuf};
2
3use crate::dw_cmd::DwCommand;
4use crate::secrets_cli::SecretsCommand;
5use clap::{Arg, ArgAction, Args, CommandFactory, Parser, Subcommand};
6
7#[derive(Parser, Debug)]
8#[command(name = "greentic-dev")]
9#[command(version)]
10#[command(about = "cli.root.about")]
11pub struct Cli {
12    #[command(subcommand)]
13    pub command: Command,
14}
15
16pub fn localized_help_command(locale: &str) -> clap::Command {
17    let mut command = Cli::command()
18        .about(crate::i18n::t(locale, "cli.root.about"))
19        .disable_help_subcommand(true)
20        .disable_help_flag(true)
21        .disable_version_flag(true)
22        .arg(
23            Arg::new("help")
24                .short('h')
25                .long("help")
26                .action(ArgAction::Help)
27                .help(crate::i18n::t(locale, "cli.help.flag")),
28        )
29        .arg(
30            Arg::new("version")
31                .short('V')
32                .long("version")
33                .action(ArgAction::Version)
34                .help(crate::i18n::t(locale, "cli.version.flag")),
35        )
36        .arg(
37            Arg::new("locale")
38                .long("locale")
39                .global(true)
40                .value_name("LOCALE")
41                .help(crate::i18n::t(locale, "cli.option.locale")),
42        );
43
44    for (name, key) in [
45        ("flow", "cli.command.flow.about"),
46        ("pack", "cli.command.pack.about"),
47        ("component", "cli.command.component.about"),
48        ("bundle", "cli.command.bundle.about"),
49        ("runner", "cli.command.runner.about"),
50        ("config", "cli.command.config.about"),
51        ("coverage", "cli.command.coverage.about"),
52        ("security", "cli.command.security.about"),
53        ("mcp", "cli.command.mcp.about"),
54        ("gui", "cli.command.gui.about"),
55        ("secrets", "cli.command.secrets.about"),
56        ("dw", "cli.command.dw.about"),
57        ("tools", "cli.command.tools.about"),
58        ("install", "cli.command.install.about"),
59        ("release", "cli.command.release.about"),
60        ("cbor", "cli.command.cbor.about"),
61        ("wizard", "cli.command.wizard.about"),
62    ] {
63        command = command.mut_subcommand(name, |sub| sub.about(crate::i18n::t(locale, key)));
64    }
65
66    command = command.mut_subcommand("secrets", |sub| {
67        sub.about(crate::i18n::t(locale, "cli.command.secrets.about"))
68            .mut_subcommand("init", |sub| {
69                sub.about(crate::i18n::t(locale, "cli.command.secrets.init.about"))
70                    .mut_arg("pack", |arg| {
71                        arg.help(crate::i18n::t(locale, "cli.command.secrets.init.pack"))
72                    })
73                    .mut_arg("passthrough", |arg| {
74                        arg.help(crate::i18n::t(
75                            locale,
76                            "cli.command.secrets.init.passthrough",
77                        ))
78                    })
79            })
80    });
81
82    command = command.mut_subcommand("dw", |sub| {
83        sub.about(crate::i18n::t(locale, "cli.command.dw.about"))
84            .mut_subcommand("publish", |sub| {
85                sub.about(crate::i18n::t(locale, "cli.command.dw.publish.about"))
86                    .mut_arg("artifact", |arg| {
87                        arg.help(crate::i18n::t(locale, "cli.command.dw.publish.artifact"))
88                    })
89                    .mut_arg("describe", |arg| {
90                        arg.help(crate::i18n::t(locale, "cli.command.dw.publish.describe"))
91                    })
92                    .mut_arg("store", |arg| {
93                        arg.help(crate::i18n::t(locale, "cli.command.dw.publish.store"))
94                    })
95                    .mut_arg("token", |arg| {
96                        arg.help(crate::i18n::t(locale, "cli.command.dw.publish.token"))
97                    })
98            })
99            .mut_subcommand("install", |sub| {
100                sub.about(crate::i18n::t(locale, "cli.command.dw.install.about"))
101                    .mut_arg("name", |arg| {
102                        arg.help(crate::i18n::t(locale, "cli.command.dw.install.name"))
103                    })
104                    .mut_arg("version", |arg| {
105                        arg.help(crate::i18n::t(locale, "cli.command.dw.install.version"))
106                    })
107                    .mut_arg("store", |arg| {
108                        arg.help(crate::i18n::t(locale, "cli.command.dw.install.store"))
109                    })
110                    .mut_arg("out", |arg| {
111                        arg.help(crate::i18n::t(locale, "cli.command.dw.install.out"))
112                    })
113            })
114    });
115    command = command
116        .mut_subcommand("config", |sub| {
117            sub.about(crate::i18n::t(locale, "cli.command.config.about"))
118                .mut_subcommand("set", |sub| {
119                    sub.about(crate::i18n::t(locale, "cli.command.config.set.about"))
120                        .mut_arg("key", |arg| {
121                            arg.help(crate::i18n::t(locale, "cli.command.config.set.key"))
122                        })
123                        .mut_arg("value", |arg| {
124                            arg.help(crate::i18n::t(locale, "cli.command.config.set.value"))
125                        })
126                        .mut_arg("file", |arg| {
127                            arg.help(crate::i18n::t(locale, "cli.command.config.set.file"))
128                        })
129                })
130        })
131        .mut_subcommand("mcp", |sub| {
132            sub.about(crate::i18n::t(locale, "cli.command.mcp.about"))
133                .mut_subcommand("doctor", |sub| {
134                    sub.about(crate::i18n::t(locale, "cli.command.mcp.doctor.about"))
135                        .mut_arg("provider", |arg| {
136                            arg.help(crate::i18n::t(locale, "cli.command.mcp.doctor.provider"))
137                        })
138                        .mut_arg("json", |arg| {
139                            arg.help(crate::i18n::t(locale, "cli.command.mcp.doctor.json"))
140                        })
141                })
142        })
143        .mut_subcommand("tools", |sub| {
144            sub.about(crate::i18n::t(locale, "cli.command.tools.about"))
145                .mut_subcommand("install", |sub| {
146                    sub.about(crate::i18n::t(locale, "cli.command.tools.install.about"))
147                        .mut_arg("latest", |arg| {
148                            arg.help(crate::i18n::t(locale, "cli.command.tools.install.latest"))
149                        })
150                })
151        })
152        .mut_subcommand("install", |sub| {
153            sub.about(crate::i18n::t(locale, "cli.command.install.about"))
154                .mut_subcommand("tools", |sub| {
155                    sub.about(crate::i18n::t(locale, "cli.command.install.tools.about"))
156                        .mut_arg("latest", |arg| {
157                            arg.help(crate::i18n::t(locale, "cli.command.tools.install.latest"))
158                        })
159                })
160                .mut_arg("tenant", |arg| {
161                    arg.help(crate::i18n::t(locale, "cli.command.install.tenant"))
162                })
163                .mut_arg("token", |arg| {
164                    arg.help(crate::i18n::t(locale, "cli.command.install.token"))
165                })
166                .mut_arg("bin_dir", |arg| {
167                    arg.help(crate::i18n::t(locale, "cli.command.install.bin_dir"))
168                })
169                .mut_arg("docs_dir", |arg| {
170                    arg.help(crate::i18n::t(locale, "cli.command.install.docs_dir"))
171                })
172                .mut_arg("locale", |arg| {
173                    arg.help(crate::i18n::t(locale, "cli.command.install.locale"))
174                })
175        })
176        .mut_subcommand("release", |sub| {
177            sub.about(crate::i18n::t(locale, "cli.command.release.about"))
178                .mut_subcommand("generate", |sub| {
179                    sub.about(crate::i18n::t(locale, "cli.command.release.generate.about"))
180                        .mut_arg("release", |arg| {
181                            arg.help(crate::i18n::t(locale, "cli.command.release.release"))
182                        })
183                        .mut_arg("from", |arg| {
184                            arg.help(crate::i18n::t(locale, "cli.command.release.from"))
185                        })
186                        .mut_arg("repo", |arg| {
187                            arg.help(crate::i18n::t(locale, "cli.command.release.repo"))
188                        })
189                        .mut_arg("token", |arg| {
190                            arg.help(crate::i18n::t(locale, "cli.command.release.token"))
191                        })
192                        .mut_arg("out", |arg| {
193                            arg.help(crate::i18n::t(locale, "cli.command.release.out"))
194                        })
195                        .mut_arg("dry_run", |arg| {
196                            arg.help(crate::i18n::t(locale, "cli.command.release.dry_run"))
197                        })
198                })
199                .mut_subcommand("publish", |sub| {
200                    sub.about(crate::i18n::t(locale, "cli.command.release.publish.about"))
201                        .mut_arg("release", |arg| {
202                            arg.help(crate::i18n::t(locale, "cli.command.release.release"))
203                        })
204                        .mut_arg("from", |arg| {
205                            arg.help(crate::i18n::t(locale, "cli.command.release.from"))
206                        })
207                        .mut_arg("tag", |arg| {
208                            arg.help(crate::i18n::t(locale, "cli.command.release.tag"))
209                        })
210                        .mut_arg("manifest", |arg| {
211                            arg.help(crate::i18n::t(locale, "cli.command.release.manifest"))
212                        })
213                        .mut_arg("repo", |arg| {
214                            arg.help(crate::i18n::t(locale, "cli.command.release.repo"))
215                        })
216                        .mut_arg("token", |arg| {
217                            arg.help(crate::i18n::t(locale, "cli.command.release.token"))
218                        })
219                        .mut_arg("out", |arg| {
220                            arg.help(crate::i18n::t(locale, "cli.command.release.out"))
221                        })
222                        .mut_arg("dry_run", |arg| {
223                            arg.help(crate::i18n::t(locale, "cli.command.release.dry_run"))
224                        })
225                        .mut_arg("force", |arg| {
226                            arg.help(crate::i18n::t(locale, "cli.command.release.force"))
227                        })
228                })
229                .mut_subcommand("view", |sub| {
230                    sub.about(crate::i18n::t(locale, "cli.command.release.view.about"))
231                        .mut_arg("release", |arg| {
232                            arg.help(crate::i18n::t(locale, "cli.command.release.release"))
233                        })
234                        .mut_arg("tag", |arg| {
235                            arg.help(crate::i18n::t(locale, "cli.command.release.tag"))
236                        })
237                        .mut_arg("repo", |arg| {
238                            arg.help(crate::i18n::t(locale, "cli.command.release.repo"))
239                        })
240                        .mut_arg("token", |arg| {
241                            arg.help(crate::i18n::t(locale, "cli.command.release.token"))
242                        })
243                })
244                .mut_subcommand("latest", |sub| {
245                    sub.about(crate::i18n::t(locale, "cli.command.release.latest.about"))
246                        .mut_arg("repo", |arg| {
247                            arg.help(crate::i18n::t(locale, "cli.command.release.repo"))
248                        })
249                        .mut_arg("token", |arg| {
250                            arg.help(crate::i18n::t(locale, "cli.command.release.token"))
251                        })
252                        .mut_arg("dry_run", |arg| {
253                            arg.help(crate::i18n::t(locale, "cli.command.release.dry_run"))
254                        })
255                        .mut_arg("force", |arg| {
256                            arg.help(crate::i18n::t(locale, "cli.command.release.force"))
257                        })
258                })
259                .mut_subcommand("promote", |sub| {
260                    sub.about(crate::i18n::t(locale, "cli.command.release.promote.about"))
261                        .mut_arg("release", |arg| {
262                            arg.help(crate::i18n::t(locale, "cli.command.release.release"))
263                        })
264                        .mut_arg("tag", |arg| {
265                            arg.help(crate::i18n::t(locale, "cli.command.release.tag"))
266                        })
267                        .mut_arg("repo", |arg| {
268                            arg.help(crate::i18n::t(locale, "cli.command.release.repo"))
269                        })
270                        .mut_arg("token", |arg| {
271                            arg.help(crate::i18n::t(locale, "cli.command.release.token"))
272                        })
273                        .mut_arg("dry_run", |arg| {
274                            arg.help(crate::i18n::t(locale, "cli.command.release.dry_run"))
275                        })
276                })
277        })
278        .mut_subcommand("cbor", |sub| {
279            sub.about(crate::i18n::t(locale, "cli.command.cbor.about"))
280                .mut_arg("path", |arg| {
281                    arg.help(crate::i18n::t(locale, "cli.command.cbor.path"))
282                })
283        })
284        .mut_subcommand("coverage", |sub| {
285            sub.about(crate::i18n::t(locale, "cli.command.coverage.about"))
286                .mut_arg("skip_run", |arg| {
287                    arg.help(crate::i18n::t(locale, "cli.command.coverage.skip_run"))
288                })
289        })
290        .mut_subcommand("security", |sub| {
291            sub.about(crate::i18n::t(locale, "cli.command.security.about"))
292                .mut_arg("format", |arg| {
293                    arg.help(crate::i18n::t(locale, "cli.command.security.format"))
294                })
295                .mut_arg("prompt", |arg| {
296                    arg.help(crate::i18n::t(locale, "cli.command.security.prompt"))
297                })
298                .mut_arg("no_errors", |arg| {
299                    arg.help(crate::i18n::t(locale, "cli.command.security.no_errors"))
300                })
301                .mut_arg("severity", |arg| {
302                    arg.help(crate::i18n::t(locale, "cli.command.security.severity"))
303                })
304                .mut_arg("security_severity", |arg| {
305                    arg.help(crate::i18n::t(
306                        locale,
307                        "cli.command.security.security_severity",
308                    ))
309                })
310                .mut_arg("state", |arg| {
311                    arg.help(crate::i18n::t(locale, "cli.command.security.state"))
312                })
313                .mut_arg("repo", |arg| {
314                    arg.help(crate::i18n::t(locale, "cli.command.security.repo"))
315                })
316                .mut_arg("branch", |arg| {
317                    arg.help(crate::i18n::t(locale, "cli.command.security.branch"))
318                })
319        })
320        .mut_subcommand("wizard", |sub| {
321            sub.about(crate::i18n::t(locale, "cli.command.wizard.about"))
322                .mut_arg("answers", |arg| {
323                    arg.help(crate::i18n::t(locale, "cli.command.wizard.answers"))
324                })
325                .mut_arg("frontend", |arg| {
326                    arg.help(crate::i18n::t(locale, "cli.command.wizard.frontend"))
327                })
328                .mut_arg("locale", |arg| {
329                    arg.help(crate::i18n::t(locale, "cli.command.wizard.locale"))
330                })
331                .mut_arg("emit_answers", |arg| {
332                    arg.help(crate::i18n::t(locale, "cli.command.wizard.emit_answers"))
333                })
334                .mut_arg("schema", |arg| {
335                    arg.help(crate::i18n::t(locale, "cli.command.wizard.schema"))
336                        .long_help(crate::i18n::t(locale, "cli.command.wizard.schema_long"))
337                })
338                .mut_arg("schema_version", |arg| {
339                    arg.help(crate::i18n::t(locale, "cli.command.wizard.schema_version"))
340                })
341                .mut_arg("migrate", |arg| {
342                    arg.help(crate::i18n::t(locale, "cli.command.wizard.migrate"))
343                })
344                .mut_arg("out", |arg| {
345                    arg.help(crate::i18n::t(locale, "cli.command.wizard.out"))
346                })
347                .mut_arg("dry_run", |arg| {
348                    arg.help(crate::i18n::t(locale, "cli.command.wizard.dry_run"))
349                })
350                .mut_arg("yes", |arg| {
351                    arg.help(crate::i18n::t(locale, "cli.command.wizard.yes"))
352                })
353                .mut_arg("non_interactive", |arg| {
354                    arg.help(crate::i18n::t(locale, "cli.command.wizard.non_interactive"))
355                })
356                .mut_arg("unsafe_commands", |arg| {
357                    arg.help(crate::i18n::t(locale, "cli.command.wizard.unsafe_commands"))
358                })
359                .mut_arg("allow_destructive", |arg| {
360                    arg.help(crate::i18n::t(
361                        locale,
362                        "cli.command.wizard.allow_destructive",
363                    ))
364                })
365                .mut_subcommand("validate", |sub| {
366                    sub.about(crate::i18n::t(locale, "cli.command.wizard.validate.about"))
367                        .mut_arg("answers", |arg| {
368                            arg.help(crate::i18n::t(locale, "cli.command.wizard.answers"))
369                        })
370                        .mut_arg("frontend", |arg| {
371                            arg.help(crate::i18n::t(locale, "cli.command.wizard.frontend"))
372                        })
373                        .mut_arg("locale", |arg| {
374                            arg.help(crate::i18n::t(locale, "cli.command.wizard.locale"))
375                        })
376                        .mut_arg("emit_answers", |arg| {
377                            arg.help(crate::i18n::t(locale, "cli.command.wizard.emit_answers"))
378                        })
379                        .mut_arg("schema_version", |arg| {
380                            arg.help(crate::i18n::t(locale, "cli.command.wizard.schema_version"))
381                        })
382                        .mut_arg("migrate", |arg| {
383                            arg.help(crate::i18n::t(locale, "cli.command.wizard.migrate"))
384                        })
385                        .mut_arg("out", |arg| {
386                            arg.help(crate::i18n::t(locale, "cli.command.wizard.out"))
387                        })
388                })
389                .mut_subcommand("apply", |sub| {
390                    sub.about(crate::i18n::t(locale, "cli.command.wizard.apply.about"))
391                        .mut_arg("answers", |arg| {
392                            arg.help(crate::i18n::t(locale, "cli.command.wizard.answers"))
393                        })
394                        .mut_arg("frontend", |arg| {
395                            arg.help(crate::i18n::t(locale, "cli.command.wizard.frontend"))
396                        })
397                        .mut_arg("locale", |arg| {
398                            arg.help(crate::i18n::t(locale, "cli.command.wizard.locale"))
399                        })
400                        .mut_arg("emit_answers", |arg| {
401                            arg.help(crate::i18n::t(locale, "cli.command.wizard.emit_answers"))
402                        })
403                        .mut_arg("schema_version", |arg| {
404                            arg.help(crate::i18n::t(locale, "cli.command.wizard.schema_version"))
405                        })
406                        .mut_arg("migrate", |arg| {
407                            arg.help(crate::i18n::t(locale, "cli.command.wizard.migrate"))
408                        })
409                        .mut_arg("out", |arg| {
410                            arg.help(crate::i18n::t(locale, "cli.command.wizard.out"))
411                        })
412                        .mut_arg("yes", |arg| {
413                            arg.help(crate::i18n::t(locale, "cli.command.wizard.yes"))
414                        })
415                        .mut_arg("non_interactive", |arg| {
416                            arg.help(crate::i18n::t(locale, "cli.command.wizard.non_interactive"))
417                        })
418                        .mut_arg("unsafe_commands", |arg| {
419                            arg.help(crate::i18n::t(locale, "cli.command.wizard.unsafe_commands"))
420                        })
421                        .mut_arg("allow_destructive", |arg| {
422                            arg.help(crate::i18n::t(
423                                locale,
424                                "cli.command.wizard.allow_destructive",
425                            ))
426                        })
427                })
428        });
429
430    localize_help_tree(command, locale, true)
431}
432
433fn localize_help_tree(mut command: clap::Command, locale: &str, is_root: bool) -> clap::Command {
434    command = command
435        .disable_help_subcommand(true)
436        .disable_help_flag(true);
437    let arg_ids = command
438        .get_arguments()
439        .map(|arg| arg.get_id().as_str().to_string())
440        .collect::<Vec<_>>();
441    if arg_ids.iter().any(|id| id == "help") {
442        command = command.mut_arg("help", |arg| {
443            arg.help(crate::i18n::t(locale, "cli.help.flag"))
444        });
445    } else {
446        command = command.arg(
447            Arg::new("help")
448                .short('h')
449                .long("help")
450                .action(ArgAction::Help)
451                .help(crate::i18n::t(locale, "cli.help.flag")),
452        );
453    }
454    if is_root && arg_ids.iter().any(|id| id == "version") {
455        command = command.mut_arg("version", |arg| {
456            arg.help(crate::i18n::t(locale, "cli.version.flag"))
457        });
458    }
459
460    let sub_names = command
461        .get_subcommands()
462        .map(|sub| sub.get_name().to_string())
463        .collect::<Vec<_>>();
464    for name in sub_names {
465        command = command.mut_subcommand(name, |sub| localize_help_tree(sub, locale, false));
466    }
467
468    command
469}
470
471#[derive(Subcommand, Debug)]
472pub enum Command {
473    /// cli.command.flow.about
474    Flow(PassthroughArgs),
475    /// cli.command.pack.about
476    Pack(PassthroughArgs),
477    /// cli.command.component.about
478    Component(PassthroughArgs),
479    /// cli.command.bundle.about
480    Bundle(PassthroughArgs),
481    /// cli.command.runner.about
482    Runner(PassthroughArgs),
483    /// cli.command.config.about
484    #[command(subcommand)]
485    Config(ConfigCommand),
486    /// cli.command.coverage.about
487    Coverage(CoverageArgs),
488    /// cli.command.security.about
489    Security(SecurityArgs),
490    /// cli.command.mcp.about
491    #[command(subcommand)]
492    Mcp(McpCommand),
493    /// cli.command.gui.about
494    Gui(PassthroughArgs),
495    /// cli.command.secrets.about
496    #[command(subcommand)]
497    Secrets(SecretsCommand),
498    /// cli.command.dw.about
499    #[command(subcommand)]
500    Dw(DwCommand),
501    /// cli.command.tools.about
502    #[command(subcommand)]
503    Tools(ToolsCommand),
504    /// cli.command.install.about
505    Install(InstallArgs),
506    /// cli.command.release.about
507    #[command(subcommand)]
508    Release(ReleaseCommand),
509    /// cli.command.cbor.about
510    Cbor(CborArgs),
511    /// cli.command.wizard.about
512    Wizard(Box<WizardCommand>),
513}
514
515#[derive(Args, Debug, Clone)]
516#[command(disable_help_flag = true)]
517pub struct PassthroughArgs {
518    /// cli.command.passthrough.args
519    #[arg(
520        value_name = "ARGS",
521        trailing_var_arg = true,
522        allow_hyphen_values = true
523    )]
524    pub args: Vec<OsString>,
525}
526
527#[derive(Subcommand, Debug)]
528pub enum McpCommand {
529    /// cli.command.mcp.doctor.about
530    Doctor(McpDoctorArgs),
531}
532
533#[derive(Args, Debug)]
534pub struct McpDoctorArgs {
535    /// cli.command.mcp.doctor.provider
536    pub provider: String,
537    /// cli.command.mcp.doctor.json
538    #[arg(long = "json")]
539    pub json: bool,
540}
541
542#[derive(Subcommand, Debug)]
543pub enum ConfigCommand {
544    /// cli.command.config.set.about
545    Set(ConfigSetArgs),
546}
547
548#[derive(Subcommand, Debug)]
549pub enum ToolsCommand {
550    /// cli.command.tools.install.about
551    Install(ToolsInstallArgs),
552}
553
554#[derive(Subcommand, Debug)]
555pub enum InstallSubcommand {
556    /// cli.command.install.tools.about
557    Tools(ToolsInstallArgs),
558}
559
560#[derive(Subcommand, Debug)]
561pub enum ReleaseCommand {
562    /// cli.command.release.generate.about
563    Generate(ReleaseGenerateArgs),
564    /// cli.command.release.publish.about
565    Publish(ReleasePublishArgs),
566    /// cli.command.release.view.about
567    View(ReleaseViewArgs),
568    /// cli.command.release.latest.about
569    Latest(ReleaseLatestArgs),
570    /// cli.command.release.promote.about
571    Promote(ReleasePromoteArgs),
572    /// cli.command.release.snapshot.about
573    Snapshot(ReleaseSnapshotArgs),
574}
575
576#[derive(Args, Debug)]
577pub struct InstallArgs {
578    #[command(subcommand)]
579    pub command: Option<InstallSubcommand>,
580    /// cli.command.install.tenant
581    #[arg(long = "tenant")]
582    pub tenant: Option<String>,
583    /// cli.command.install.token
584    #[arg(long = "token")]
585    pub token: Option<String>,
586    /// cli.command.install.bin_dir
587    #[arg(long = "bin-dir")]
588    pub bin_dir: Option<PathBuf>,
589    /// cli.command.install.docs_dir
590    #[arg(long = "docs-dir")]
591    pub docs_dir: Option<PathBuf>,
592    /// cli.command.install.locale
593    #[arg(long = "locale")]
594    pub locale: Option<String>,
595}
596
597#[derive(Args, Debug)]
598pub struct ToolsInstallArgs {
599    /// cli.command.tools.install.latest
600    #[arg(long = "latest")]
601    pub latest: bool,
602}
603
604#[derive(Args, Debug)]
605pub struct ReleaseGenerateArgs {
606    /// cli.command.release.release
607    #[arg(long = "release")]
608    pub release: String,
609    /// cli.command.release.from
610    #[arg(long = "from", default_value = "latest")]
611    pub from: String,
612    /// cli.command.release.repo
613    #[arg(
614        long = "repo",
615        default_value = "ghcr.io/greenticai/greentic-versions/gtc"
616    )]
617    pub repo: String,
618    /// cli.command.release.token
619    #[arg(long = "token")]
620    pub token: Option<String>,
621    /// cli.command.release.out
622    #[arg(long = "out", default_value = "dist/toolchains")]
623    pub out: PathBuf,
624    /// cli.command.release.dry_run
625    #[arg(long = "dry-run")]
626    pub dry_run: bool,
627}
628
629#[derive(Args, Debug)]
630pub struct ReleasePublishArgs {
631    /// cli.command.release.release
632    #[arg(long = "release", required_unless_present = "manifest")]
633    pub release: Option<String>,
634    /// cli.command.release.from
635    #[arg(long = "from", default_value = "latest", requires = "release")]
636    pub from: Option<String>,
637    /// cli.command.release.tag
638    #[arg(long = "tag")]
639    pub tag: Option<String>,
640    /// cli.command.release.manifest
641    #[arg(long = "manifest", required_unless_present = "release")]
642    pub manifest: Option<PathBuf>,
643    /// cli.command.release.repo
644    #[arg(
645        long = "repo",
646        default_value = "ghcr.io/greenticai/greentic-versions/gtc"
647    )]
648    pub repo: String,
649    /// cli.command.release.token
650    #[arg(long = "token")]
651    pub token: Option<String>,
652    /// cli.command.release.out
653    #[arg(long = "out", default_value = "dist/toolchains")]
654    pub out: PathBuf,
655    /// cli.command.release.dry_run
656    #[arg(long = "dry-run")]
657    pub dry_run: bool,
658    /// cli.command.release.force
659    #[arg(long = "force")]
660    pub force: bool,
661    /// cli.command.release.no_notify_updater
662    #[arg(long = "no-notify-updater")]
663    pub no_notify_updater: bool,
664}
665
666#[derive(Args, Debug)]
667pub struct ReleaseViewArgs {
668    /// cli.command.release.release
669    #[arg(
670        long = "release",
671        conflicts_with = "tag",
672        required_unless_present = "tag"
673    )]
674    pub release: Option<String>,
675    /// cli.command.release.tag
676    #[arg(
677        long = "tag",
678        conflicts_with = "release",
679        required_unless_present = "release"
680    )]
681    pub tag: Option<String>,
682    /// cli.command.release.repo
683    #[arg(
684        long = "repo",
685        default_value = "ghcr.io/greenticai/greentic-versions/gtc"
686    )]
687    pub repo: String,
688    /// cli.command.release.token
689    #[arg(long = "token")]
690    pub token: Option<String>,
691}
692
693#[derive(Args, Debug)]
694pub struct ReleaseLatestArgs {
695    /// cli.command.release.repo
696    #[arg(
697        long = "repo",
698        default_value = "ghcr.io/greenticai/greentic-versions/gtc"
699    )]
700    pub repo: String,
701    /// cli.command.release.token
702    #[arg(long = "token")]
703    pub token: Option<String>,
704    /// cli.command.release.dry_run
705    #[arg(long = "dry-run")]
706    pub dry_run: bool,
707    /// cli.command.release.force
708    #[arg(long = "force")]
709    pub force: bool,
710}
711
712#[derive(Args, Debug)]
713pub struct ReleasePromoteArgs {
714    /// cli.command.release.release
715    #[arg(long = "release")]
716    pub release: String,
717    /// cli.command.release.tag
718    #[arg(long = "tag")]
719    pub tag: String,
720    /// cli.command.release.repo
721    #[arg(
722        long = "repo",
723        default_value = "ghcr.io/greenticai/greentic-versions/gtc"
724    )]
725    pub repo: String,
726    /// cli.command.release.token
727    #[arg(long = "token")]
728    pub token: Option<String>,
729    /// cli.command.release.dry_run
730    #[arg(long = "dry-run")]
731    pub dry_run: bool,
732    /// cli.command.release.no_notify_updater
733    #[arg(long = "no-notify-updater")]
734    pub no_notify_updater: bool,
735}
736
737#[derive(Args, Debug)]
738pub struct ReleaseSnapshotArgs {
739    /// cli.command.release.release
740    #[arg(long = "release")]
741    pub release: String,
742    /// cli.command.release.snapshot.channel
743    #[arg(long = "channel", default_value = "dev")]
744    pub channel: String,
745    /// cli.command.release.tag
746    #[arg(long = "tag")]
747    pub tag: Option<String>,
748    /// cli.command.release.repo
749    #[arg(
750        long = "repo",
751        default_value = "ghcr.io/greenticai/greentic-versions/gtc"
752    )]
753    pub repo: String,
754    /// cli.command.release.token
755    #[arg(long = "token")]
756    pub token: Option<String>,
757    /// cli.command.release.out
758    #[arg(long = "out", default_value = "dist/toolchains")]
759    pub out: PathBuf,
760    /// cli.command.release.dry_run
761    #[arg(long = "dry-run")]
762    pub dry_run: bool,
763    /// cli.command.release.force
764    #[arg(long = "force")]
765    pub force: bool,
766    /// cli.command.release.no_notify_updater
767    #[arg(long = "no-notify-updater")]
768    pub no_notify_updater: bool,
769}
770
771#[derive(Args, Debug)]
772pub struct ConfigSetArgs {
773    /// cli.command.config.set.key
774    pub key: String,
775    /// cli.command.config.set.value
776    pub value: String,
777    /// cli.command.config.set.file
778    #[arg(long = "file")]
779    pub file: Option<PathBuf>,
780}
781
782#[derive(Args, Debug)]
783pub struct CborArgs {
784    /// cli.command.cbor.path
785    #[arg(value_name = "PATH")]
786    pub path: PathBuf,
787}
788
789#[derive(Args, Debug, Clone)]
790pub struct CoverageArgs {
791    /// cli.command.coverage.skip_run
792    #[arg(long = "skip-run")]
793    pub skip_run: bool,
794}
795
796#[derive(Clone, Copy, Debug, Eq, PartialEq, clap::ValueEnum)]
797pub enum SecurityFormat {
798    Markdown,
799    Json,
800}
801
802#[derive(Args, Debug, Clone)]
803pub struct SecurityArgs {
804    /// cli.command.security.format
805    #[arg(long = "format", value_enum, default_value_t = SecurityFormat::Markdown)]
806    pub format: SecurityFormat,
807    /// cli.command.security.prompt
808    #[arg(long = "prompt")]
809    pub prompt: bool,
810    /// cli.command.security.no_errors
811    #[arg(long = "ignore-errors", alias = "no-errors")]
812    pub no_errors: bool,
813    /// cli.command.security.severity
814    #[arg(long = "severity")]
815    pub severity: Option<String>,
816    /// cli.command.security.security_severity
817    #[arg(long = "security-severity")]
818    pub security_severity: Option<String>,
819    /// cli.command.security.state
820    #[arg(long = "state", default_value = "open")]
821    pub state: String,
822    /// cli.command.security.repo
823    #[arg(long = "repo")]
824    pub repo: Option<String>,
825    /// cli.command.security.branch
826    #[arg(long = "branch")]
827    pub branch: Option<String>,
828}
829
830#[derive(Args, Debug, Clone)]
831pub struct WizardCommand {
832    #[command(subcommand)]
833    pub command: Option<WizardSubcommand>,
834    #[command(flatten)]
835    pub launch: WizardLaunchArgs,
836}
837
838#[derive(Subcommand, Debug, Clone)]
839pub enum WizardSubcommand {
840    /// cli.command.wizard.validate.about
841    Validate(WizardValidateArgs),
842    /// cli.command.wizard.apply.about
843    Apply(WizardApplyArgs),
844}
845
846#[derive(Args, Debug, Clone)]
847pub struct WizardLaunchArgs {
848    /// cli.command.wizard.answers (local path, http/https URL, or oci://|ghcr:// reference)
849    #[arg(long = "answers")]
850    pub answers: Option<String>,
851    /// cli.command.wizard.frontend
852    #[arg(long = "frontend", default_value = "json")]
853    pub frontend: String,
854    /// cli.command.wizard.locale
855    #[arg(long = "locale")]
856    pub locale: Option<String>,
857    /// cli.command.wizard.emit_answers
858    #[arg(long = "emit-answers")]
859    pub emit_answers: Option<PathBuf>,
860    /// cli.command.wizard.schema
861    #[arg(long = "schema")]
862    pub schema: bool,
863    /// cli.command.wizard.schema_version
864    #[arg(long = "schema-version")]
865    pub schema_version: Option<String>,
866    /// cli.command.wizard.migrate
867    #[arg(long = "migrate")]
868    pub migrate: bool,
869    /// cli.command.wizard.out
870    #[arg(long = "out")]
871    pub out: Option<PathBuf>,
872    /// cli.command.wizard.dry_run
873    #[arg(long = "dry-run")]
874    pub dry_run: bool,
875    /// cli.command.wizard.yes
876    #[arg(long = "yes")]
877    pub yes: bool,
878    /// cli.command.wizard.non_interactive
879    #[arg(long = "non-interactive")]
880    pub non_interactive: bool,
881    /// cli.command.wizard.unsafe_commands
882    #[arg(long = "unsafe-commands")]
883    pub unsafe_commands: bool,
884    /// cli.command.wizard.allow_destructive
885    #[arg(long = "allow-destructive")]
886    pub allow_destructive: bool,
887}
888
889#[derive(Args, Debug, Clone)]
890pub struct WizardValidateArgs {
891    /// cli.command.wizard.answers (local path, http/https URL, or oci://|ghcr:// reference)
892    #[arg(long = "answers")]
893    pub answers: String,
894    /// cli.command.wizard.frontend
895    #[arg(long = "frontend", default_value = "json")]
896    pub frontend: String,
897    /// cli.command.wizard.locale
898    #[arg(long = "locale")]
899    pub locale: Option<String>,
900    /// cli.command.wizard.emit_answers
901    #[arg(long = "emit-answers")]
902    pub emit_answers: Option<PathBuf>,
903    /// cli.command.wizard.schema_version
904    #[arg(long = "schema-version")]
905    pub schema_version: Option<String>,
906    /// cli.command.wizard.migrate
907    #[arg(long = "migrate")]
908    pub migrate: bool,
909    /// cli.command.wizard.out
910    #[arg(long = "out")]
911    pub out: Option<PathBuf>,
912}
913
914#[derive(Args, Debug, Clone)]
915pub struct WizardApplyArgs {
916    /// cli.command.wizard.answers (local path, http/https URL, or oci://|ghcr:// reference)
917    #[arg(long = "answers")]
918    pub answers: String,
919    /// cli.command.wizard.frontend
920    #[arg(long = "frontend", default_value = "json")]
921    pub frontend: String,
922    /// cli.command.wizard.locale
923    #[arg(long = "locale")]
924    pub locale: Option<String>,
925    /// cli.command.wizard.emit_answers
926    #[arg(long = "emit-answers")]
927    pub emit_answers: Option<PathBuf>,
928    /// cli.command.wizard.schema_version
929    #[arg(long = "schema-version")]
930    pub schema_version: Option<String>,
931    /// cli.command.wizard.migrate
932    #[arg(long = "migrate")]
933    pub migrate: bool,
934    /// cli.command.wizard.out
935    #[arg(long = "out")]
936    pub out: Option<PathBuf>,
937    /// cli.command.wizard.yes
938    #[arg(long = "yes")]
939    pub yes: bool,
940    /// cli.command.wizard.non_interactive
941    #[arg(long = "non-interactive")]
942    pub non_interactive: bool,
943    /// cli.command.wizard.unsafe_commands
944    #[arg(long = "unsafe-commands")]
945    pub unsafe_commands: bool,
946    /// cli.command.wizard.allow_destructive
947    #[arg(long = "allow-destructive")]
948    pub allow_destructive: bool,
949}