From 626e4329f1087faadf104726ad46205c65894f86 Mon Sep 17 00:00:00 2001 From: Huck Boles Date: Sat, 20 May 2023 12:34:12 -0500 Subject: [PATCH] added: single file flag and functions --- src/lib.rs | 22 ++++++++++++++++++---- src/main.rs | 10 ++++++++-- src/options/arg_parser.rs | 29 ++++++++++++++++------------- src/options/opt_struct.rs | 6 ++++++ 4 files changed, 48 insertions(+), 19 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 04df235..a99ab4c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,16 +23,16 @@ pub fn get_opts() -> Result { let exists = opts.build.exists(); if exists && opts.clean { - std::fs::remove_dir_all(&opts.build)?; - std::fs::create_dir(&opts.build)?; + fs::remove_dir_all(&opts.build)?; + fs::create_dir(&opts.build)?; } else if !exists { - std::fs::create_dir(&opts.build)?; + fs::create_dir(&opts.build)?; } Ok(opts) } -pub fn build_dir(opts: &Options) -> Result<()> { +pub fn build_site(opts: &Options) -> Result<()> { let mut source = DirNode::build(opts.source.clone(), opts)?; let global_init = MetaFile::new(opts); @@ -42,6 +42,20 @@ pub fn build_dir(opts: &Options) -> Result<()> { source.build_dir() } +pub fn single_file(opts: &Options) -> Result { + let path = opts.file.as_ref().ok_or(MetaError::Unknown)?; + let source = match fs::read_to_string(&path) { + Ok(str) => Ok(str), + Err(_) => Err(eyre::Error::from(MetaError::FileNotFound { + path: path.to_string_lossy().to_string(), + })), + }?; + + let file = parse_string(source, opts)?; + + Ok(build_metafile(&file)?) +} + pub fn new_site(opts: &Options) -> Result<()> { macro_rules! exist_or_build( ($p:expr) => { diff --git a/src/main.rs b/src/main.rs index efd4f0a..d51cac3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,8 +2,14 @@ fn main() -> eyre::Result<()> { let opts = metaforge::get_opts()?; if opts.new { - metaforge::new_site(&opts) + return metaforge::new_site(&opts); + } + + if let Some(_) = &opts.file { + let str = metaforge::single_file(&opts)?; + println!("{str}"); + Ok(()) } else { - metaforge::build_dir(&opts) + return metaforge::build_site(&opts); } } diff --git a/src/options/arg_parser.rs b/src/options/arg_parser.rs index c40aa10..a24b727 100644 --- a/src/options/arg_parser.rs +++ b/src/options/arg_parser.rs @@ -6,43 +6,46 @@ use clap::Parser; #[command(about = "A customizable template driven static site generator")] #[command(long_about = None)] pub struct Opts { - /// Root directory [CURRENT_DIR] + /// root directory [CURRENT_DIR] #[arg(short, long, value_name = "ROOT_DIR")] pub root: Option, - /// Source file directory [CURRENT_DIR/source] + /// source file directory [CURRENT_DIR/source] #[arg(short, long, value_name = "SOURCE_DIR")] pub source: Option, - /// Build directory [CURRENT_DIR/build] + /// build directory [current_dir/build] #[arg(short, long, value_name = "BUILD_DIR")] pub build: Option, - /// Pattern directory [CURRENT_DIR/pattern] + /// pattern directory [current_dir/pattern] #[arg(short, long, value_name = "PATTERN_DIR")] pub pattern: Option, - /// Create a new skeleton directory + /// only build a single file + #[arg(short, long, value_name = "FILENAME")] + pub file: Option, + /// create a new skeleton directory #[arg(long, default_value_t = false)] pub new: bool, - /// Enable extra output. Repeated flags give more info + /// enable extra output. Repeated flags give more info #[arg(short, long, action = clap::ArgAction::Count)] pub verbose: u8, - /// Minimal output + /// minimal output #[arg(short, long, default_value_t = false)] pub quiet: bool, - /// Don't stop on file failure [FALSE] + /// don't stop on file failure [FALSE] #[arg(long, default_value_t = false)] pub force: bool, - /// Stop on undefined variables and arrays [FALSE] + /// stop on undefined variables and arrays [FALSE] #[arg(long, default_value_t = false)] pub undefined: bool, - /// Clean build directory before building site [FALSE] + /// clean build directory before building site [FALSE] #[arg(long, default_value_t = false)] pub clean: bool, - /// Don't call pandoc on source files + /// don't call pandoc on source files #[arg(long, default_value_t = false)] pub no_pandoc: bool, - /// Output filetype [html] + /// output filetype [html] #[arg(short, long, value_name = "OUTPUT_FILETYPE")] pub output: Option, - /// Input filetype [markdown] + /// input filetype [markdown] #[arg(short, long, value_name = "INPUT_FILETYPE")] pub input: Option, } diff --git a/src/options/opt_struct.rs b/src/options/opt_struct.rs index eab5a40..0f6da5a 100644 --- a/src/options/opt_struct.rs +++ b/src/options/opt_struct.rs @@ -7,6 +7,7 @@ pub struct Options { pub source: PathBuf, pub build: PathBuf, pub pattern: PathBuf, + pub file: Option, pub input: String, pub output: String, pub verbose: u8, @@ -25,6 +26,7 @@ impl Options { source: PathBuf::new(), build: PathBuf::new(), pattern: PathBuf::new(), + file: None, input: String::default(), output: String::default(), verbose: 0, @@ -75,6 +77,10 @@ impl TryFrom for Options { opts.pattern = opts.root.join("pattern"); } + if let Some(file) = value.file.as_deref() { + opts.file = Some(PathBuf::from(file).canonicalize()?); + } + if let Some(input) = value.input { opts.input = input; } else { -- 2.45.2