From 2bc99dd639a3e8d39bea32debef5cc6680a6f077 Mon Sep 17 00:00:00 2001 From: Qrius Date: Thu, 26 Sep 2024 00:11:05 +0200 Subject: Add static file copying --- skaldpress.1 | 7 ++++-- src/skaldpress/main.rs | 54 +++++++++++++++++++++++++++++++++++++++++++++ src/skaldpress/parseopts.rs | 24 +++++++++++++++----- 3 files changed, 78 insertions(+), 7 deletions(-) diff --git a/skaldpress.1 b/skaldpress.1 index c6928e7..718557a 100644 --- a/skaldpress.1 +++ b/skaldpress.1 @@ -20,10 +20,13 @@ If a field to sort by is specified, it will output ascending based on that field or reversed if a fourth argument \fBreversed\fR is specified. .SH OPTIONS -.IP "\fB-o, --out\fR \fIpath\fR +.IP "\fB-o, --out, --output\fR \fIpath\fR Specifies the directory to output the compiled files to, defaults to \fIbuild\fR. -.IP "\fB-s, --source\fR \fIpath\fR +.IP "\fB-i, --input\fR \fIpath\fR +Specifies the directory where all files are iterated, defaults to \fIcontent\fR. + +.IP "\fB-s, --static\fR \fIpath\fR Specifies the directory where all files are iterated, defaults to \fIcontent\fR. .IP "\fB-t, --templates\fR \fIpath\fR diff --git a/src/skaldpress/main.rs b/src/skaldpress/main.rs index 9c9332c..c96f304 100644 --- a/src/skaldpress/main.rs +++ b/src/skaldpress/main.rs @@ -419,6 +419,56 @@ fn compile_files_in_directory(directory: &Path, opts: &Opts) -> Result<(), Skald Ok(()) } +fn copy_files_in_directory(directory: &Path, opts: &Opts) -> Result<(), SkaldpressError> { + for entry in fs::read_dir(directory).map_err(|e| { + SkaldpressError::DirectoryReadError( + 8, + e, + directory.to_str().unwrap_or("unknown dir").to_string(), + ) + })? { + let entry = match entry { + Ok(entry) => entry, + Err(e) => { + println!("\x1b[31mError getting file info {:#?}\x1b[0m", e); + continue; + } + }; + let path = entry.path(); + let metadata = match fs::metadata(&path) { + Ok(metadata) => metadata, + Err(e) => { + println!("\x1b[31mError getting file metadata {:#?}\x1b[0m", e); + continue; + } + }; + + if metadata.is_file() { + println!("< Copying {:#?}", path.as_path()); + let real_path = match path.strip_prefix(&opts.static_dir) { + Ok(r) => r, + Err(e) => { + println!("\x1b[31mError copying {:#?}: {}\x1b[0m", path.as_path(), e); + continue; + } + }; + let dest_file_path = Path::new(&opts.static_dir).join(real_path); + if let Err(e) = std::fs::copy(&path, dest_file_path) { + println!("\x1b[31mError copying {:#?}: {}\x1b[0m", path.as_path(), e); + } + } else if metadata.is_dir() { + if let Err(e) = compile_files_in_directory(path.as_path(), opts) { + println!( + "\x1b[31mError processing directory {:#?}: {}\x1b[0m", + path.as_path(), + e + ); + }; + } + } + Ok(()) +} + fn main() { unsafe { COMPILED_FILES_BY_TAG = Some(HashMap::new()); @@ -428,8 +478,12 @@ fn main() { println!("Removing {:#?}", opts.build_dir); let _ = std::fs::remove_dir_all(Path::new(&opts.build_dir)); + println!("Copying static content"); + let _ = copy_files_in_directory(Path::new(&opts.static_dir), &opts); // Running twice, we should make macro_processor emit list of macros which was executed, such // that we can re-compile only the files we need to + // We should also make some kind of file-list, and only re-compile files which has changed. + println!("Compiling content"); let _ = compile_files_in_directory(Path::new(&opts.content_dir), &opts); println!("Rerun compilation"); opts.first_run = false; diff --git a/src/skaldpress/parseopts.rs b/src/skaldpress/parseopts.rs index 3985684..163b387 100644 --- a/src/skaldpress/parseopts.rs +++ b/src/skaldpress/parseopts.rs @@ -4,6 +4,8 @@ pub struct Opts { pub template_dir: String, /// Directory where the content which will be recursively iterated is, will be relative to CWD pub content_dir: String, + /// Directory where static content which will be recursively iterated is, will be relative to CWD + pub static_dir: String, /// Directory where to put result, THIS WILL BE DELETED FIRST pub build_dir: String, /// Filters, limit to compiling specified files @@ -19,6 +21,8 @@ pub struct OptsBuilder { pub template_dir: String, /// Directory where the content which will be recursively iterated is, will be relative to CWD pub content_dir: String, + /// Directory where static content which will be recursively iterated is, will be relative to CWD + pub static_dir: String, /// Directory where to put result, THIS WILL BE DELETED FIRST pub build_dir: String, /// Filters, limit to compiling specified files @@ -30,6 +34,7 @@ impl OptsBuilder { Opts { template_dir: self.template_dir, content_dir: self.content_dir, + static_dir: self.static_dir, build_dir: self.build_dir, filter: self.filter, first_run: true, @@ -46,7 +51,8 @@ macro_rules! parseopts_panic { println!("OPTIONS:"); println!(" -h, --help Show this help text"); println!(" See also 'man skaldpress'"); - println!(" -s, --source DIR Location of content to compile"); + 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"); @@ -65,20 +71,27 @@ macro_rules! parseopts_panic { /// * `progname` - The first argument of the program, this is used for error messages. pub fn parseopt(opts: &mut OptsBuilder, arg: &str, value: Option, progname: &str) { match arg { - "o" | "out" => { + "o" | "out" | "output" => { let Some(out) = value else { println!("Missing value for {}\n", arg); parseopts_panic!(progname); }; opts.build_dir = out; } - "s" | "source" => { + "i" | "input" => { let Some(source) = value else { println!("Missing value for {}\n", arg); parseopts_panic!(progname); }; opts.content_dir = source; } + "s" | "static" => { + let Some(s) = value else { + println!("Missing value for {}\n", arg); + parseopts_panic!(progname); + }; + opts.static_dir = s; + } "t" | "templates" => { let Some(templates) = value else { println!("Missing value for {}\n", arg); @@ -113,6 +126,7 @@ pub fn parseopts() -> OptsBuilder { build_dir: String::from("build/"), template_dir: String::from("templates/"), content_dir: String::from("content/"), + static_dir: String::from("static/"), filter: Vec::new(), }; @@ -135,7 +149,7 @@ pub fn parseopts() -> OptsBuilder { } else { arg_name = arg.clone(); match arg_name.as_str() { - "out" | "source" | "templates" | "filter" => { + "out" | "output" | "input" | "static" | "templates" | "filter" => { arg_value = it.next(); } _ => (), @@ -146,7 +160,7 @@ pub fn parseopts() -> OptsBuilder { arg.remove(0); for arg_name in arg.chars() { match arg_name { - 'o' | 's' | 't' | 'f' => { + 'o' | 'i' | 's' | 't' | 'f' => { parseopt(&mut opts, &arg_name.to_string(), it.next(), &progname); } _ => { -- cgit v1.2.3