vdev/commands/
mod.rs

1use clap::Parser;
2use clap_verbosity_flag::{InfoLevel, Verbosity};
3
4mod compose_tests;
5
6/// This macro simplifies the generation of CLI subcommand invocation structures by combining the
7/// creation of the command enum and implementation of the dispatch function into one simple list.
8// Module declaration in here was removed due to https://github.com/rust-lang/rustfmt/issues/3253
9#[macro_export]
10macro_rules! cli_commands {
11    ( :: $( $list:ident, )* :: $mod:ident, $( $rest:tt )* ) => {
12        $crate::cli_commands! { :: $( $list, )* $mod, :: $( $rest )* }
13    };
14    // All the identifiers are parsed out, build up the enum and impl blocks
15    ( :: $( $mod:ident, )* :: ) => {
16        paste::paste! {
17            #[derive(clap::Subcommand, Debug)]
18            enum Commands {
19                $( [<$mod:camel>]($mod::Cli), )*
20            }
21
22            impl Cli {
23                pub fn exec(self) -> anyhow::Result<()> {
24                    match self.command {
25                        $( Commands::[<$mod:camel>](cli) => cli.exec(), )*
26                    }
27                }
28            }
29        }
30    };
31    // Start the above patterns
32    ( $( $rest:tt )+ ) => { $crate::cli_commands! { :: :: $( $rest )+ } };
33}
34
35#[macro_export]
36macro_rules! cli_subcommands {
37    ( $doc:literal $( $rest:tt )* ) => {
38        #[derive(clap::Args, Debug)]
39        #[doc = $doc]
40        #[command()]
41        pub(super) struct Cli {
42            #[command(subcommand)]
43            command: Commands,
44        }
45
46        $crate::cli_commands! { $( $rest )* }
47    }
48}
49
50/// Vector's unified dev tool
51#[derive(Parser, Debug)]
52#[command(
53    version,
54    bin_name = "vdev",
55    infer_subcommands = true,
56    disable_help_subcommand = true,
57    after_help = r#"Environment variables:
58  $CONTAINER_TOOL  Set the tool used to run containers (Defaults to autodetect)
59                   Valid values are either "docker" or "podman".
60"#
61)]
62pub struct Cli {
63    #[clap(flatten)]
64    pub verbose: Verbosity<InfoLevel>,
65
66    #[command(subcommand)]
67    command: Commands,
68}
69
70mod build;
71mod check;
72mod complete;
73mod crate_versions;
74mod e2e;
75mod exec;
76mod features;
77mod fmt;
78mod info;
79mod integration;
80mod meta;
81mod package;
82mod release;
83mod run;
84mod status;
85mod test;
86mod test_vrl;
87mod version;
88
89cli_commands! {
90    build,
91    check,
92    complete,
93    crate_versions,
94    e2e,
95    exec,
96    features,
97    fmt,
98    info,
99    integration,
100    meta,
101    package,
102    release,
103    run,
104    status,
105    test,
106    test_vrl,
107    version,
108}
109
110/// This macro creates a wrapper for an existing script.
111#[macro_export]
112macro_rules! script_wrapper {
113    ( $mod:ident = $doc:literal => $script:literal ) => {
114        paste::paste! {
115            mod $mod {
116                #[doc = $doc]
117                #[derive(clap::Args, Debug)]
118                #[command()]
119                pub(super) struct Cli {
120                    args: Vec<String>,
121                }
122
123                impl Cli {
124                    pub(super) fn exec(self) -> anyhow::Result<()> {
125                        $crate::app::exec(concat!("scripts/", $script), self.args, true)
126                    }
127                }
128            }
129        }
130    };
131}