Skip to main content

phlow_runtime/settings/
cli.rs

1use clap::{Arg, ArgAction, Command};
2use std::env;
3
4#[derive(Debug)]
5pub enum Error {
6    #[allow(dead_code)]
7    ModuleNotFound(String),
8}
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum PrintOutput {
12    Yaml,
13    Json,
14}
15
16#[derive(Debug)]
17pub struct Cli {
18    pub main_target: Option<String>,
19    pub only_download_modules: bool,
20    pub package_path: Option<String>,
21    pub package_target: String,
22    pub create_tar: bool,
23    pub no_run: bool,
24    pub download: bool,
25    pub print_yaml: bool,
26    pub print_output: PrintOutput,
27    pub test: bool,
28    pub test_filter: Option<String>,
29    pub var_main: Option<String>,
30    pub var_payload: Option<String>,
31    pub start_step: Option<String>,
32    // analyzer options
33    pub analyzer: bool,
34    pub analyzer_files: bool,
35    pub analyzer_modules: bool,
36    pub analyzer_total_steps: bool,
37    pub analyzer_total_pipelines: bool,
38    pub analyzer_json: bool,
39    pub analyzer_inner: bool,
40    pub analyzer_all: bool,
41}
42
43impl Cli {
44    pub fn load() -> Result<Cli, Error> {
45        let command = Command::new("Phlow Runtime")
46            .version(env!("CARGO_PKG_VERSION"))
47            .arg(
48                Arg::new("main_path")
49                    .help("Main path/file to load")
50                    .required(false)
51                    .index(1)
52                    .num_args(1..), // <= Aqui adiciona mĂșltiplos valores possĂ­veis
53            )
54            .arg(
55                Arg::new("install")
56                    .long("install")
57                    .short('i')
58                    .action(ArgAction::SetTrue)
59                    .value_parser(clap::builder::BoolishValueParser::new())
60                    .help("Install dependencies")
61                    .default_value("false"),
62            )
63            .arg(
64                Arg::new("download")
65                    .long("download")
66                    .short('d')
67                    .help("Enable download modules before running")
68                    .value_parser(clap::builder::BoolValueParser::new())
69                    .default_value("true"),
70            )
71            .arg(
72                Arg::new("package")
73                    .long("package")
74                    .help("Path to the package file"),
75            )
76            .arg(
77                Arg::new("package_target")
78                    .long("package-target")
79                    .help("Target directory for package output")
80                    .default_value("./phlow_packages"),
81            )
82            .arg(
83                Arg::new("tar")
84                    .long("tar")
85                    .help("Create a .tar.gz archive instead of extracting to phlow_packages/")
86                    .value_parser(clap::builder::BoolishValueParser::new())
87                    .action(ArgAction::SetTrue)
88                    .default_value("false"),
89            )
90            .arg(
91                Arg::new("no_run")
92                    .long("no-run")
93                    .short('n')
94                    .help("Do not run the main file")
95                    .value_parser(clap::builder::BoolishValueParser::new())
96                    .action(ArgAction::SetTrue)
97                    .default_value("false"),
98            )
99            .arg(
100                Arg::new("print_yaml")
101                    .long("print")
102                    .short('p')
103                    .help("Print the YAML file generated from the target file")
104                    .value_parser(clap::builder::BoolishValueParser::new())
105                    .action(ArgAction::SetTrue)
106                    .default_value("false"),
107            )
108            .arg(
109                Arg::new("print_output")
110                    .long("output")
111                    .short('o')
112                    .help("Output format for --print (yaml|json)")
113                    .value_name("FORMAT")
114                    .value_parser(["yaml", "json"])
115                    .requires("print_yaml"),
116            )
117            .arg(
118                Arg::new("test")
119                    .long("test")
120                    .short('t')
121                    .help("Run tests defined in the phlow file")
122                    .value_parser(clap::builder::BoolishValueParser::new())
123                    .action(ArgAction::SetTrue)
124                    .default_value("false"),
125            )
126            .arg(
127                Arg::new("test_filter")
128                    .long("test-filter")
129                    .help("Filter tests by description (substring match)")
130                    .requires("test")
131                    .value_name("FILTER"),
132            )
133            .arg(
134                Arg::new("var_main")
135                    .long("var-main")
136                    .help("Set the main variable value")
137                    .value_name("VALUE"),
138            )
139            .arg(
140                Arg::new("var_payload")
141                    .long("var-payload")
142                    .help("Set the initial payload value")
143                    .value_name("VALUE"),
144            )
145            .arg(
146                Arg::new("var_pre")
147                    .long("var-pre")
148                    .help("Set the preprocessor variable value")
149                    .value_name("PRE_VALUE"),
150            )
151            .arg(
152                Arg::new("start_step")
153                    .long("step")
154                    .help("Start execution from the step id")
155                    .value_name("STEP_ID"),
156            );
157        // Analyzer flags
158        let command = command
159            .arg(
160                Arg::new("analyzer")
161                    .long("analyzer")
162                    .help("Run analyzer on the .phlow and return info without executing the runtime")
163                    .action(ArgAction::SetTrue)
164                    .value_parser(clap::builder::BoolishValueParser::new())
165                    .default_value("false"),
166            )
167            .arg(
168                Arg::new("files")
169                    .long("files")
170                    .help("Return all files loaded by the project, including files referenced by !include or !import")
171                    .action(ArgAction::SetTrue),
172            )
173            .arg(
174                Arg::new("modules")
175                    .long("modules")
176                    .help("Return modules declared in the project and whether they are downloaded in phlow_packages")
177                    .action(ArgAction::SetTrue),
178            )
179            .arg(
180                Arg::new("total_steps")
181                    .long("total-steps")
182                    .help("Return total steps in the project")
183                    .action(ArgAction::SetTrue),
184            )
185            .arg(
186                Arg::new("total_pipelines")
187                    .long("total-pipelines")
188                    .help("Return total pipelines in the project")
189                    .action(ArgAction::SetTrue),
190            )
191            .arg(
192                Arg::new("json")
193                    .long("json")
194                    .help("Output analyzer data as JSON")
195                    .action(ArgAction::SetTrue),
196            )
197            .arg(
198                Arg::new("text")
199                    .long("text")
200                    .help("Output analyzer data as plain text (default)")
201                    .action(ArgAction::SetTrue),
202            );
203
204        // analyzer --inner: enable recursive analysis/loading of internal modules (./module)
205        let command = command.arg(
206            Arg::new("inner")
207                .long("inner")
208                .help("When used with analyzer, allow analysis/recursive loading of internal modules (those declared with a leading '.')")
209                .action(ArgAction::SetTrue),
210        );
211
212        // analyzer --all: print everything available
213        let command = command.arg(
214            Arg::new("all")
215                .long("all")
216                .help("When used with --analyzer, return all available analyzer information")
217                .action(ArgAction::SetTrue),
218        );
219
220        let matches = command.get_matches();
221
222        let main = match matches.get_one::<String>("main_path") {
223            Some(target) => Some(target.clone()),
224            None => None,
225        };
226
227        let install = *matches.get_one::<bool>("install").unwrap_or(&false);
228        let package_path = matches.get_one::<String>("package").map(|s| s.to_string());
229        let package_target = matches
230            .get_one::<String>("package_target")
231            .map(|s| s.to_string())
232            .unwrap_or_else(|| "./phlow_packages".to_string());
233        let create_tar = *matches.get_one::<bool>("tar").unwrap_or(&false);
234
235        let no_run = *matches.get_one::<bool>("no_run").unwrap_or(&false);
236
237        let download = *matches.get_one::<bool>("download").unwrap_or(&true);
238
239        let print_yaml = *matches.get_one::<bool>("print_yaml").unwrap_or(&false);
240        let print_output = matches
241            .get_one::<String>("print_output")
242            .map(|s| match s.as_str() {
243                "json" => PrintOutput::Json,
244                _ => PrintOutput::Yaml,
245            })
246            .unwrap_or(PrintOutput::Yaml);
247
248        let test = *matches.get_one::<bool>("test").unwrap_or(&false);
249
250        let test_filter = matches
251            .get_one::<String>("test_filter")
252            .map(|s| s.to_string());
253
254        let var_main = matches.get_one::<String>("var_main").map(|s| s.to_string());
255        let var_payload = matches
256            .get_one::<String>("var_payload")
257            .map(|s| s.to_string());
258        let start_step = matches
259            .get_one::<String>("start_step")
260            .map(|s| s.to_string());
261
262        let analyzer = *matches.get_one::<bool>("analyzer").unwrap_or(&false);
263        let analyzer_files = *matches.get_one::<bool>("files").unwrap_or(&false);
264        let analyzer_modules = *matches.get_one::<bool>("modules").unwrap_or(&false);
265        let analyzer_total_steps = *matches.get_one::<bool>("total_steps").unwrap_or(&false);
266        let analyzer_total_pipelines =
267            *matches.get_one::<bool>("total_pipelines").unwrap_or(&false);
268        let analyzer_json = *matches.get_one::<bool>("json").unwrap_or(&false);
269        let analyzer_inner = *matches.get_one::<bool>("inner").unwrap_or(&false);
270        let analyzer_all = *matches.get_one::<bool>("all").unwrap_or(&false);
271        Ok(Cli {
272            main_target: main,
273            only_download_modules: install,
274            package_path,
275            package_target,
276            create_tar,
277            no_run,
278            download,
279            print_yaml,
280            print_output,
281            test,
282            test_filter,
283            var_main,
284            var_payload,
285            start_step,
286            analyzer,
287            analyzer_files,
288            analyzer_modules,
289            analyzer_total_steps,
290            analyzer_total_pipelines,
291            analyzer_json,
292            analyzer_inner,
293            analyzer_all,
294        })
295    }
296}