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