Skip to main content

greentic_dev/
cli.rs

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