From 670411b72ce59341e45d5fbecfa6f232f682d374 Mon Sep 17 00:00:00 2001 From: Qrius Date: Tue, 12 Nov 2024 10:24:17 +0100 Subject: Add some more options for dealing with different input environments --- src/skaldpress/main.rs | 89 ++++++++++++++++++++++++++++++++------- src/skaldpress/metadata_parser.rs | 2 +- src/skaldpress/parseopts.rs | 82 ++++++++++++++++++++++++++++++++---- 3 files changed, 147 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/skaldpress/main.rs b/src/skaldpress/main.rs index 574bc6a..9ab988e 100644 --- a/src/skaldpress/main.rs +++ b/src/skaldpress/main.rs @@ -308,25 +308,40 @@ fn compile_file(file_path: &Path, opts: &Opts) -> Result (map, file_content), None => (HashMap::new(), file_content.as_str()), }; + map.extend(opts.metadata.clone()); - if let Some(skip_smp) = &map.get("skip_smp") { - if let YamlValue::Scalar(skip_smp) = skip_smp { - if skip_smp.to_lowercase() == "true" { - return Ok(CompiledFile { - content: file_content.to_string(), - metadata: map, - extension: String::from(extension), - source_path: String::from(file_path.to_str().unwrap_or("")), - needs_recompilation: false, - stored_smp_state: HashMap::new(), - }); + let mut skip_smp = false; + if let Some(_skip_smp) = &map.get("skip_smp") { + if let YamlValue::Scalar(_skip_smp) = _skip_smp { + if _skip_smp.to_lowercase() == "true" { + skip_smp = true; } } } + if opts.compilefilter.len() != 0 { + let e: Vec = Vec::new(); + if !file_filtered( + &file_path.to_str().unwrap_or("").to_string(), + &opts.compilefilter, + &e, + ) { + skip_smp = true; + } + } + if skip_smp { + return Ok(CompiledFile { + content: file_content.to_string(), + metadata: map, + extension: String::from(extension), + source_path: String::from(file_path.to_str().unwrap_or("")), + needs_recompilation: false, + stored_smp_state: HashMap::new(), + }); + } let mut stored_smp_state = None; if let Some(cfile_i) = cached_file_id_by_path(&file_path.to_str().unwrap_or("").to_string()) { @@ -481,6 +496,36 @@ fn compile_file_and_write( Ok(()) } +fn file_pat_match(file: &String, pat: &str) -> bool { + if file == pat { + return true; + } + if pat.starts_with("*") && file.ends_with(pat.trim_start_matches("*")) { + return true; + } + if pat.ends_with("*") && file.starts_with(pat.trim_end_matches("*")) { + return true; + } + false +} + +fn file_filtered(file: &String, filters: &Vec, exclude: &Vec) -> bool { + for filter in exclude { + if file_pat_match(file, filter) { + return true; + } + } + if filters.len() == 0 { + return false; + } + for filter in filters { + if file_pat_match(file, filter) { + return true; + } + } + true +} + fn compile_files_in_directory(directory: &Path, opts: &Opts) -> Result<(), SkaldpressError> { for entry in fs::read_dir(directory).map_err(|e| { SkaldpressError::DirectoryReadError( @@ -514,11 +559,15 @@ fn compile_files_in_directory(directory: &Path, opts: &Opts) -> Result<(), Skald } } + //let should_compile = (opts.first_run || needs_recompilation) + // && ((opts.filter.len() == 0) + // || !file_filtered(&path.as_path().to_str().unwrap_or("").to_string(), &opts.filter)); let should_compile = (opts.first_run || needs_recompilation) - && ((opts.filter.len() == 0) - || opts - .filter - .contains(&path.as_path().to_str().unwrap_or("").to_string())); + && !file_filtered( + &path.as_path().to_str().unwrap_or("").to_string(), + &opts.filter, + &opts.exclude, + ); if metadata.is_file() && should_compile { println!("< Compiling {:#?}", path.as_path()); if let Err(e) = compile_file_and_write(path.as_path(), opts) { @@ -573,6 +622,14 @@ fn copy_files_in_directory(directory: &Path, opts: &Opts) -> Result<(), Skaldpre continue; } }; + let e: Vec = Vec::new(); + if file_filtered( + &path.to_str().unwrap_or("").to_string(), + &e, + &opts.static_exclude, + ) { + continue; + } let dest_file_path = Path::new(&opts.build_dir).join(real_path); println!( "< Copying {:#?} -> {:#?}", diff --git a/src/skaldpress/metadata_parser.rs b/src/skaldpress/metadata_parser.rs index 66a96b6..e73c953 100644 --- a/src/skaldpress/metadata_parser.rs +++ b/src/skaldpress/metadata_parser.rs @@ -63,7 +63,7 @@ impl Ord for YamlValue { } } -fn str_to_yaml_value(in_str: &str) -> YamlValue { +pub fn str_to_yaml_value(in_str: &str) -> YamlValue { let in_str = in_str.trim(); if let Ok(int) = in_str.parse::() { return YamlValue::Integer(int); diff --git a/src/skaldpress/parseopts.rs b/src/skaldpress/parseopts.rs index 163b387..ec32bfd 100644 --- a/src/skaldpress/parseopts.rs +++ b/src/skaldpress/parseopts.rs @@ -1,3 +1,7 @@ +use crate::skaldpress::metadata_parser::str_to_yaml_value; +use crate::skaldpress::metadata_parser::YamlValue; +use std::collections::HashMap; + /// Struct containing command line options pub struct Opts { /// Directory where templates are, will be relative to CWD @@ -10,6 +14,14 @@ pub struct Opts { pub build_dir: String, /// Filters, limit to compiling specified files pub filter: Vec, + /// Excludes, limit to compiling specified files + pub exclude: Vec, + /// Static excludes, limit to copying specified files + pub static_exclude: Vec, + /// Filters, limit to compiling specified files + pub compilefilter: Vec, + /// Metadata that will be added to compiled files, useful for global options + pub metadata: HashMap, pub first_run: bool, } @@ -27,6 +39,14 @@ pub struct OptsBuilder { pub build_dir: String, /// Filters, limit to compiling specified files pub filter: Vec, + /// Excludes, limit to compiling specified files + pub exclude: Vec, + /// Static excludes, limit to copying specified files + pub static_exclude: Vec, + /// Filters, limit to compiling specified files + pub compilefilter: Vec, + /// Metadata that will be added to compiled files, useful for global options + pub metadata: HashMap, } impl OptsBuilder { @@ -37,6 +57,10 @@ impl OptsBuilder { static_dir: self.static_dir, build_dir: self.build_dir, filter: self.filter, + exclude: self.exclude, + static_exclude: self.static_exclude, + compilefilter: self.compilefilter, + metadata: self.metadata, first_run: true, } } @@ -47,15 +71,20 @@ impl OptsBuilder { /// the program exited. macro_rules! parseopts_panic { ($progname:expr) => { + println!("Skaldpress {}", env!("CARGO_PKG_VERSION")); println!("Usage: {} [OPTIONS]\n", $progname); println!("OPTIONS:"); - println!(" -h, --help Show this help text"); - println!(" See also 'man skaldpress'"); - println!(" -i, --input DIR Location of content to compile"); - println!(" -s, --static DIR Location of static content to copy"); - println!(" -t, --templates DIR Location of templates"); - println!(" -o, --out DIR Location to write compiled data, THIS WILL BE DELETED AND RECREATED!"); - println!(" -f, --filter FILES Only run on files, comma separated string"); + println!(" -h, --help Show this help text"); + println!(" See also 'man skaldpress'"); + println!(" -i, --input DIR Location of content to compile"); + println!(" -s, --static DIR Location of static content to copy"); + println!(" -t, --templates DIR Location of templates"); + println!(" -o, --out DIR Location to write compiled data, THIS WILL BE DELETED AND RECREATED!"); + println!(" -f, --filter FILES Only run on files, comma separated string"); + println!(" -c, --compilefilter FILES Only compile files, comma separated string, non-matching will still be copied"); + println!(" -e, --exclude FILES Exclude files, comma separated string"); + println!(" -x, --xclude FILES Exclude files from static, comma separated string"); + println!(" -m, --metadata KEY=VAL Extra metadata to set for every compiled file"); std::process::exit(1); }; } @@ -106,6 +135,36 @@ pub fn parseopt(opts: &mut OptsBuilder, arg: &str, value: Option, progna }; opts.filter = filter.split(",").map(|x| x.to_string()).collect(); } + "e" | "exclude" => { + let Some(exclude) = value else { + println!("Missing value for {}\n", arg); + parseopts_panic!(progname); + }; + opts.exclude = exclude.split(",").map(|x| x.to_string()).collect(); + } + "x" | "xclude" => { + let Some(exclude) = value else { + println!("Missing value for {}\n", arg); + parseopts_panic!(progname); + }; + opts.static_exclude = exclude.split(",").map(|x| x.to_string()).collect(); + } + "c" | "compilefilter" => { + let Some(compilefilter) = value else { + println!("Missing value for {}\n", arg); + parseopts_panic!(progname); + }; + opts.exclude = compilefilter.split(",").map(|x| x.to_string()).collect(); + } + "m" | "metadata" => { + let Some(meta) = value else { + println!("Missing value for {}\n", arg); + parseopts_panic!(progname); + }; + let parts: Vec<&str> = meta.split("=").collect(); + opts.metadata + .insert(String::from(parts[0]), str_to_yaml_value(parts[1])); + } "help" => { parseopts_panic!(progname); } @@ -128,6 +187,10 @@ pub fn parseopts() -> OptsBuilder { content_dir: String::from("content/"), static_dir: String::from("static/"), filter: Vec::new(), + exclude: Vec::new(), + static_exclude: Vec::new(), + compilefilter: Vec::new(), + metadata: HashMap::new(), }; let mut it = std::env::args(); @@ -149,7 +212,8 @@ pub fn parseopts() -> OptsBuilder { } else { arg_name = arg.clone(); match arg_name.as_str() { - "out" | "output" | "input" | "static" | "templates" | "filter" => { + "out" | "output" | "input" | "static" | "templates" | "filter" | "exclude" + | "compilefilter" | "xclude" | "metadata" => { arg_value = it.next(); } _ => (), @@ -160,7 +224,7 @@ pub fn parseopts() -> OptsBuilder { arg.remove(0); for arg_name in arg.chars() { match arg_name { - 'o' | 'i' | 's' | 't' | 'f' => { + 'o' | 'i' | 's' | 't' | 'f' | 'e' | 'm' | 'c' | 'x' => { parseopt(&mut opts, &arg_name.to_string(), it.next(), &progname); } _ => { -- cgit v1.2.3