Enhance CLI arguments with new options, validation, and detailed help messages
This commit is contained in:
@@ -10,6 +10,8 @@ clap = { version = "^4", features = ["derive"] }
|
||||
|
||||
rayon = "^1"
|
||||
|
||||
once_cell = "^1"
|
||||
|
||||
mago-syntax = "^1.13"
|
||||
mago-interner = "^1.0.0-alpha"
|
||||
mago-source = "^1.0.0-alpha"
|
||||
@@ -18,4 +20,5 @@ mago-names = "^1.13"
|
||||
mago-project = "^0.26"
|
||||
mago-semantics = "^1.13"
|
||||
|
||||
regex = "^1"
|
||||
walkdir = "^2"
|
||||
|
||||
@@ -12,20 +12,35 @@ use crate::util::fs;
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(name = "pmp", about, version)]
|
||||
pub struct Args {
|
||||
#[arg(long, value_hint = FilePath, value_parser = fs::path_exists)]
|
||||
#[arg(long, value_hint = FilePath, value_parser = fs::path_exists, help = "Path to PHP binary")]
|
||||
php: Option<PathBuf>,
|
||||
|
||||
#[arg(long, short = 'd', hide = true)]
|
||||
debug: bool,
|
||||
#[arg(long, short = 'v')]
|
||||
#[arg(long, short = 'v', help = "Verbose output")]
|
||||
verbose: bool,
|
||||
#[arg(long, short = 'n', help = "Dry run, does not modify files or cache")]
|
||||
dry_run: bool,
|
||||
|
||||
#[arg(default_value_os = OsStr::new("."), value_hint = FilePath, value_parser = fs::path_exists)]
|
||||
#[arg(long, short = 'e', value_hint = FilePath, value_parser = fs::path_exists, default_values_os = [OsStr::new(".gitignore"), OsStr::new("vendor/")], help = "Exclude files from pre-processing, e.g. vendor/")]
|
||||
exclude: Vec<PathBuf>,
|
||||
#[arg(long, short = 'c', value_hint = FilePath, value_parser = fs::valid_possible_path, default_value_os = OsStr::new(".cache"), help = "Cache directory location")]
|
||||
cache_dir: Option<PathBuf>,
|
||||
#[arg(long, short = 'o', value_hint = FilePath, value_parser = fs::valid_possible_path, default_value_os = OsStr::new("."), help = "Output directory location")]
|
||||
output_dir: Option<PathBuf>,
|
||||
#[arg(long, short = 'i', conflicts_with = "dry_run", help = "Invalidate cache and re-process all files")]
|
||||
invalidate_cache: bool,
|
||||
|
||||
#[arg(value_hint = FilePath, value_parser = fs::path_exists, default_value_os = OsStr::new("."), help = "Directory to recursively scan and pre-process")]
|
||||
directory: Option<PathBuf>,
|
||||
#[arg(last = true)]
|
||||
passthrough: Vec<String>,
|
||||
}
|
||||
|
||||
// todo: ignore .gitignore marked content per default
|
||||
// todo: diff output with verbose and ofc trace for warnings/errors
|
||||
// todo: cache with file hashes and system last edited timestamp
|
||||
|
||||
impl Args
|
||||
{
|
||||
pub fn parse() -> Self {
|
||||
|
||||
@@ -1,6 +1,27 @@
|
||||
use regex::Regex;
|
||||
use std::path::PathBuf;
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
static PATH_REGEX: Lazy<Regex> = Lazy::new(|| {
|
||||
Regex::new(r"^[+-]?(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?$").unwrap()
|
||||
});
|
||||
|
||||
pub fn path_exists(s: &str) -> Result<PathBuf, String> {
|
||||
let p = PathBuf::from(s);
|
||||
p.exists().then_some(p).ok_or("path does not exist".to_string())
|
||||
}
|
||||
|
||||
pub fn valid_possible_path(s: &str) -> Result<PathBuf, String>
|
||||
{
|
||||
let lower = s.to_ascii_lowercase();
|
||||
|
||||
if lower == "true" || lower == "false" {
|
||||
return Err("boolean literal is not allowed".into());
|
||||
}
|
||||
|
||||
if PATH_REGEX.is_match(s) {
|
||||
return Err("numeric literal is not allowed".into());
|
||||
}
|
||||
|
||||
Ok(PathBuf::from(s))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user