use clap::{Arg, ArgAction, Command};
use std::env;
#[derive(Debug)]
pub enum Error {
#[allow(dead_code)]
ModuleNotFound(String),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PrintOutput {
Yaml,
Json,
}
#[derive(Debug)]
pub struct Cli {
pub main_target: Option<String>,
pub only_download_modules: bool,
pub package_path: Option<String>,
pub package_target: String,
pub create_tar: bool,
pub no_run: bool,
pub download: bool,
pub print_yaml: bool,
pub print_output: PrintOutput,
pub test: bool,
pub test_filter: Option<String>,
pub var_main: Option<String>,
pub var_payload: Option<String>,
pub start_step: Option<String>,
pub analyzer: bool,
pub analyzer_files: bool,
pub analyzer_modules: bool,
pub analyzer_total_steps: bool,
pub analyzer_total_pipelines: bool,
pub analyzer_json: bool,
pub analyzer_inner: bool,
pub analyzer_all: bool,
}
impl Cli {
pub fn load() -> Result<Cli, Error> {
let command = Command::new("Phlow Runtime")
.version(env!("CARGO_PKG_VERSION"))
.arg(
Arg::new("main_path")
.help("Main path/file to load")
.required(false)
.index(1)
.num_args(1..), )
.arg(
Arg::new("install")
.long("install")
.short('i')
.action(ArgAction::SetTrue)
.value_parser(clap::builder::BoolishValueParser::new())
.help("Install dependencies")
.default_value("false"),
)
.arg(
Arg::new("download")
.long("download")
.short('d')
.help("Enable download modules before running")
.value_parser(clap::builder::BoolValueParser::new())
.default_value("true"),
)
.arg(
Arg::new("package")
.long("package")
.help("Path to the package file"),
)
.arg(
Arg::new("package_target")
.long("package-target")
.help("Target directory for package output")
.default_value("./phlow_packages"),
)
.arg(
Arg::new("tar")
.long("tar")
.help("Create a .tar.gz archive instead of extracting to phlow_packages/")
.value_parser(clap::builder::BoolishValueParser::new())
.action(ArgAction::SetTrue)
.default_value("false"),
)
.arg(
Arg::new("no_run")
.long("no-run")
.short('n')
.help("Do not run the main file")
.value_parser(clap::builder::BoolishValueParser::new())
.action(ArgAction::SetTrue)
.default_value("false"),
)
.arg(
Arg::new("print_yaml")
.long("print")
.short('p')
.help("Print the YAML file generated from the target file")
.value_parser(clap::builder::BoolishValueParser::new())
.action(ArgAction::SetTrue)
.default_value("false"),
)
.arg(
Arg::new("print_output")
.long("output")
.short('o')
.help("Output format for --print (yaml|json)")
.value_name("FORMAT")
.value_parser(["yaml", "json"])
.requires("print_yaml"),
)
.arg(
Arg::new("test")
.long("test")
.short('t')
.help("Run tests defined in the phlow file")
.value_parser(clap::builder::BoolishValueParser::new())
.action(ArgAction::SetTrue)
.default_value("false"),
)
.arg(
Arg::new("test_filter")
.long("test-filter")
.help("Filter tests by description (substring match)")
.requires("test")
.value_name("FILTER"),
)
.arg(
Arg::new("var_main")
.long("var-main")
.help("Set the main variable value")
.value_name("VALUE"),
)
.arg(
Arg::new("var_payload")
.long("var-payload")
.help("Set the initial payload value")
.value_name("VALUE"),
)
.arg(
Arg::new("var_pre")
.long("var-pre")
.help("Set the preprocessor variable value")
.value_name("PRE_VALUE"),
)
.arg(
Arg::new("start_step")
.long("step")
.help("Start execution from the step id")
.value_name("STEP_ID"),
);
let command = command
.arg(
Arg::new("analyzer")
.long("analyzer")
.help("Run analyzer on the .phlow and return info without executing the runtime")
.action(ArgAction::SetTrue)
.value_parser(clap::builder::BoolishValueParser::new())
.default_value("false"),
)
.arg(
Arg::new("files")
.long("files")
.help("Return all files loaded by the project, including files referenced by !include or !import")
.action(ArgAction::SetTrue),
)
.arg(
Arg::new("modules")
.long("modules")
.help("Return modules declared in the project and whether they are downloaded in phlow_packages")
.action(ArgAction::SetTrue),
)
.arg(
Arg::new("total_steps")
.long("total-steps")
.help("Return total steps in the project")
.action(ArgAction::SetTrue),
)
.arg(
Arg::new("total_pipelines")
.long("total-pipelines")
.help("Return total pipelines in the project")
.action(ArgAction::SetTrue),
)
.arg(
Arg::new("json")
.long("json")
.help("Output analyzer data as JSON")
.action(ArgAction::SetTrue),
)
.arg(
Arg::new("text")
.long("text")
.help("Output analyzer data as plain text (default)")
.action(ArgAction::SetTrue),
);
let command = command.arg(
Arg::new("inner")
.long("inner")
.help("When used with analyzer, allow analysis/recursive loading of internal modules (those declared with a leading '.')")
.action(ArgAction::SetTrue),
);
let command = command.arg(
Arg::new("all")
.long("all")
.help("When used with --analyzer, return all available analyzer information")
.action(ArgAction::SetTrue),
);
let matches = command.get_matches();
let main = match matches.get_one::<String>("main_path") {
Some(target) => Some(target.clone()),
None => None,
};
let install = *matches.get_one::<bool>("install").unwrap_or(&false);
let package_path = matches.get_one::<String>("package").map(|s| s.to_string());
let package_target = matches
.get_one::<String>("package_target")
.map(|s| s.to_string())
.unwrap_or_else(|| "./phlow_packages".to_string());
let create_tar = *matches.get_one::<bool>("tar").unwrap_or(&false);
let no_run = *matches.get_one::<bool>("no_run").unwrap_or(&false);
let download = *matches.get_one::<bool>("download").unwrap_or(&true);
let print_yaml = *matches.get_one::<bool>("print_yaml").unwrap_or(&false);
let print_output = matches
.get_one::<String>("print_output")
.map(|s| match s.as_str() {
"json" => PrintOutput::Json,
_ => PrintOutput::Yaml,
})
.unwrap_or(PrintOutput::Yaml);
let test = *matches.get_one::<bool>("test").unwrap_or(&false);
let test_filter = matches
.get_one::<String>("test_filter")
.map(|s| s.to_string());
let var_main = matches.get_one::<String>("var_main").map(|s| s.to_string());
let var_payload = matches
.get_one::<String>("var_payload")
.map(|s| s.to_string());
let start_step = matches
.get_one::<String>("start_step")
.map(|s| s.to_string());
let analyzer = *matches.get_one::<bool>("analyzer").unwrap_or(&false);
let analyzer_files = *matches.get_one::<bool>("files").unwrap_or(&false);
let analyzer_modules = *matches.get_one::<bool>("modules").unwrap_or(&false);
let analyzer_total_steps = *matches.get_one::<bool>("total_steps").unwrap_or(&false);
let analyzer_total_pipelines =
*matches.get_one::<bool>("total_pipelines").unwrap_or(&false);
let analyzer_json = *matches.get_one::<bool>("json").unwrap_or(&false);
let analyzer_inner = *matches.get_one::<bool>("inner").unwrap_or(&false);
let analyzer_all = *matches.get_one::<bool>("all").unwrap_or(&false);
Ok(Cli {
main_target: main,
only_download_modules: install,
package_path,
package_target,
create_tar,
no_run,
download,
print_yaml,
print_output,
test,
test_filter,
var_main,
var_payload,
start_step,
analyzer,
analyzer_files,
analyzer_modules,
analyzer_total_steps,
analyzer_total_pipelines,
analyzer_json,
analyzer_inner,
analyzer_all,
})
}
}