Compare commits
5 Commits
e464dae53d
...
1fdb825793
| Author | SHA1 | Date | |
|---|---|---|---|
| 1fdb825793 | |||
| baca32e57c | |||
| ccc993976f | |||
| 08aa198b00 | |||
| e8cf10eee3 |
9
.gitignore
vendored
Normal file
9
.gitignore
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
.idea/
|
||||
.vscode/
|
||||
|
||||
target/
|
||||
|
||||
Cargo.lock
|
||||
|
||||
*.pdb
|
||||
**/*.rs.bk
|
||||
24
Cargo.toml
Normal file
24
Cargo.toml
Normal file
@@ -0,0 +1,24 @@
|
||||
[package]
|
||||
name = "pmp"
|
||||
description = "PHP Macro Pre-processor (PMP) written in Rust."
|
||||
|
||||
version = "0.1.0-alpha"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
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"
|
||||
mago-span = "^1.13"
|
||||
mago-names = "^1.13"
|
||||
mago-project = "^0.26"
|
||||
mago-semantics = "^1.13"
|
||||
|
||||
regex = "^1"
|
||||
walkdir = "^2"
|
||||
49
src/cli/flags.rs
Normal file
49
src/cli/flags.rs
Normal file
@@ -0,0 +1,49 @@
|
||||
use std::{
|
||||
ffi::OsStr,
|
||||
path::PathBuf
|
||||
};
|
||||
use clap::{
|
||||
Parser,
|
||||
ValueHint::FilePath,
|
||||
};
|
||||
|
||||
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, help = "Path to PHP binary")]
|
||||
php: Option<PathBuf>,
|
||||
|
||||
#[arg(long, short = 'd', hide = true)]
|
||||
debug: bool,
|
||||
#[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(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 {
|
||||
<Self as Parser>::parse()
|
||||
}
|
||||
}
|
||||
3
src/cli/mod.rs
Normal file
3
src/cli/mod.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
mod flags;
|
||||
|
||||
pub use flags::Args;
|
||||
2
src/lib.rs
Normal file
2
src/lib.rs
Normal file
@@ -0,0 +1,2 @@
|
||||
pub mod cli;
|
||||
pub mod util;
|
||||
8
src/main.rs
Normal file
8
src/main.rs
Normal file
@@ -0,0 +1,8 @@
|
||||
use pmp::{ cli::Args };
|
||||
|
||||
fn main()
|
||||
{
|
||||
let args = Args::parse();
|
||||
|
||||
println!("{:#?}", args);
|
||||
}
|
||||
27
src/util/fs.rs
Normal file
27
src/util/fs.rs
Normal file
@@ -0,0 +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))
|
||||
}
|
||||
1
src/util/mod.rs
Normal file
1
src/util/mod.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub mod fs;
|
||||
Reference in New Issue
Block a user