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}
662
663#[derive(Args, Debug)]
664pub struct ReleaseViewArgs {
665    /// cli.command.release.release
666    #[arg(
667        long = "release",
668        conflicts_with = "tag",
669        required_unless_present = "tag"
670    )]
671    pub release: Option<String>,
672    /// cli.command.release.tag
673    #[arg(
674        long = "tag",
675        conflicts_with = "release",
676        required_unless_present = "release"
677    )]
678    pub tag: Option<String>,
679    /// cli.command.release.repo
680    #[arg(
681        long = "repo",
682        default_value = "ghcr.io/greenticai/greentic-versions/gtc"
683    )]
684    pub repo: String,
685    /// cli.command.release.token
686    #[arg(long = "token")]
687    pub token: Option<String>,
688}
689
690#[derive(Args, Debug)]
691pub struct ReleaseLatestArgs {
692    /// cli.command.release.repo
693    #[arg(
694        long = "repo",
695        default_value = "ghcr.io/greenticai/greentic-versions/gtc"
696    )]
697    pub repo: String,
698    /// cli.command.release.token
699    #[arg(long = "token")]
700    pub token: Option<String>,
701    /// cli.command.release.dry_run
702    #[arg(long = "dry-run")]
703    pub dry_run: bool,
704    /// cli.command.release.force
705    #[arg(long = "force")]
706    pub force: bool,
707}
708
709#[derive(Args, Debug)]
710pub struct ReleasePromoteArgs {
711    /// cli.command.release.release
712    #[arg(long = "release")]
713    pub release: String,
714    /// cli.command.release.tag
715    #[arg(long = "tag")]
716    pub tag: String,
717    /// cli.command.release.repo
718    #[arg(
719        long = "repo",
720        default_value = "ghcr.io/greenticai/greentic-versions/gtc"
721    )]
722    pub repo: String,
723    /// cli.command.release.token
724    #[arg(long = "token")]
725    pub token: Option<String>,
726    /// cli.command.release.dry_run
727    #[arg(long = "dry-run")]
728    pub dry_run: bool,
729}
730
731#[derive(Args, Debug)]
732pub struct ReleaseSnapshotArgs {
733    /// cli.command.release.release
734    #[arg(long = "release")]
735    pub release: String,
736    /// cli.command.release.snapshot.channel
737    #[arg(long = "channel", default_value = "dev")]
738    pub channel: String,
739    /// cli.command.release.tag
740    #[arg(long = "tag")]
741    pub tag: Option<String>,
742    /// cli.command.release.repo
743    #[arg(
744        long = "repo",
745        default_value = "ghcr.io/greenticai/greentic-versions/gtc"
746    )]
747    pub repo: String,
748    /// cli.command.release.token
749    #[arg(long = "token")]
750    pub token: Option<String>,
751    /// cli.command.release.out
752    #[arg(long = "out", default_value = "dist/toolchains")]
753    pub out: PathBuf,
754    /// cli.command.release.dry_run
755    #[arg(long = "dry-run")]
756    pub dry_run: bool,
757    /// cli.command.release.force
758    #[arg(long = "force")]
759    pub force: bool,
760}
761
762#[derive(Args, Debug)]
763pub struct ConfigSetArgs {
764    /// cli.command.config.set.key
765    pub key: String,
766    /// cli.command.config.set.value
767    pub value: String,
768    /// cli.command.config.set.file
769    #[arg(long = "file")]
770    pub file: Option<PathBuf>,
771}
772
773#[derive(Args, Debug)]
774pub struct CborArgs {
775    /// cli.command.cbor.path
776    #[arg(value_name = "PATH")]
777    pub path: PathBuf,
778}
779
780#[derive(Args, Debug, Clone)]
781pub struct CoverageArgs {
782    /// cli.command.coverage.skip_run
783    #[arg(long = "skip-run")]
784    pub skip_run: bool,
785}
786
787#[derive(Clone, Copy, Debug, Eq, PartialEq, clap::ValueEnum)]
788pub enum SecurityFormat {
789    Markdown,
790    Json,
791}
792
793#[derive(Args, Debug, Clone)]
794pub struct SecurityArgs {
795    /// cli.command.security.format
796    #[arg(long = "format", value_enum, default_value_t = SecurityFormat::Markdown)]
797    pub format: SecurityFormat,
798    /// cli.command.security.prompt
799    #[arg(long = "prompt")]
800    pub prompt: bool,
801    /// cli.command.security.no_errors
802    #[arg(long = "ignore-errors", alias = "no-errors")]
803    pub no_errors: bool,
804    /// cli.command.security.severity
805    #[arg(long = "severity")]
806    pub severity: Option<String>,
807    /// cli.command.security.security_severity
808    #[arg(long = "security-severity")]
809    pub security_severity: Option<String>,
810    /// cli.command.security.state
811    #[arg(long = "state", default_value = "open")]
812    pub state: String,
813    /// cli.command.security.repo
814    #[arg(long = "repo")]
815    pub repo: Option<String>,
816    /// cli.command.security.branch
817    #[arg(long = "branch")]
818    pub branch: Option<String>,
819}
820
821#[derive(Args, Debug, Clone)]
822pub struct WizardCommand {
823    #[command(subcommand)]
824    pub command: Option<WizardSubcommand>,
825    #[command(flatten)]
826    pub launch: WizardLaunchArgs,
827}
828
829#[derive(Subcommand, Debug, Clone)]
830pub enum WizardSubcommand {
831    /// cli.command.wizard.validate.about
832    Validate(WizardValidateArgs),
833    /// cli.command.wizard.apply.about
834    Apply(WizardApplyArgs),
835}
836
837#[derive(Args, Debug, Clone)]
838pub struct WizardLaunchArgs {
839    /// cli.command.wizard.answers (local path or http/https URL)
840    #[arg(long = "answers")]
841    pub answers: Option<String>,
842    /// cli.command.wizard.frontend
843    #[arg(long = "frontend", default_value = "json")]
844    pub frontend: String,
845    /// cli.command.wizard.locale
846    #[arg(long = "locale")]
847    pub locale: Option<String>,
848    /// cli.command.wizard.emit_answers
849    #[arg(long = "emit-answers")]
850    pub emit_answers: Option<PathBuf>,
851    /// cli.command.wizard.schema
852    #[arg(long = "schema")]
853    pub schema: bool,
854    /// cli.command.wizard.schema_version
855    #[arg(long = "schema-version")]
856    pub schema_version: Option<String>,
857    /// cli.command.wizard.migrate
858    #[arg(long = "migrate")]
859    pub migrate: bool,
860    /// cli.command.wizard.out
861    #[arg(long = "out")]
862    pub out: Option<PathBuf>,
863    /// cli.command.wizard.dry_run
864    #[arg(long = "dry-run")]
865    pub dry_run: bool,
866    /// cli.command.wizard.yes
867    #[arg(long = "yes")]
868    pub yes: bool,
869    /// cli.command.wizard.non_interactive
870    #[arg(long = "non-interactive")]
871    pub non_interactive: bool,
872    /// cli.command.wizard.unsafe_commands
873    #[arg(long = "unsafe-commands")]
874    pub unsafe_commands: bool,
875    /// cli.command.wizard.allow_destructive
876    #[arg(long = "allow-destructive")]
877    pub allow_destructive: bool,
878}
879
880#[derive(Args, Debug, Clone)]
881pub struct WizardValidateArgs {
882    /// cli.command.wizard.answers (local path or http/https URL)
883    #[arg(long = "answers")]
884    pub answers: String,
885    /// cli.command.wizard.frontend
886    #[arg(long = "frontend", default_value = "json")]
887    pub frontend: String,
888    /// cli.command.wizard.locale
889    #[arg(long = "locale")]
890    pub locale: Option<String>,
891    /// cli.command.wizard.emit_answers
892    #[arg(long = "emit-answers")]
893    pub emit_answers: Option<PathBuf>,
894    /// cli.command.wizard.schema_version
895    #[arg(long = "schema-version")]
896    pub schema_version: Option<String>,
897    /// cli.command.wizard.migrate
898    #[arg(long = "migrate")]
899    pub migrate: bool,
900    /// cli.command.wizard.out
901    #[arg(long = "out")]
902    pub out: Option<PathBuf>,
903}
904
905#[derive(Args, Debug, Clone)]
906pub struct WizardApplyArgs {
907    /// cli.command.wizard.answers (local path or http/https URL)
908    #[arg(long = "answers")]
909    pub answers: String,
910    /// cli.command.wizard.frontend
911    #[arg(long = "frontend", default_value = "json")]
912    pub frontend: String,
913    /// cli.command.wizard.locale
914    #[arg(long = "locale")]
915    pub locale: Option<String>,
916    /// cli.command.wizard.emit_answers
917    #[arg(long = "emit-answers")]
918    pub emit_answers: Option<PathBuf>,
919    /// cli.command.wizard.schema_version
920    #[arg(long = "schema-version")]
921    pub schema_version: Option<String>,
922    /// cli.command.wizard.migrate
923    #[arg(long = "migrate")]
924    pub migrate: bool,
925    /// cli.command.wizard.out
926    #[arg(long = "out")]
927    pub out: Option<PathBuf>,
928    /// cli.command.wizard.yes
929    #[arg(long = "yes")]
930    pub yes: bool,
931    /// cli.command.wizard.non_interactive
932    #[arg(long = "non-interactive")]
933    pub non_interactive: bool,
934    /// cli.command.wizard.unsafe_commands
935    #[arg(long = "unsafe-commands")]
936    pub unsafe_commands: bool,
937    /// cli.command.wizard.allow_destructive
938    #[arg(long = "allow-destructive")]
939    pub allow_destructive: bool,
940}