rework generation to support multiple files; introduce a more proper CLI
This commit is contained in:
		
							parent
							
								
									27414d4254
								
							
						
					
					
						commit
						7e84005a6b
					
				
					 9 changed files with 302 additions and 49 deletions
				
			
		
							
								
								
									
										60
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										60
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							| 
						 | 
				
			
			@ -17,6 +17,15 @@ version = "1.0.2"
 | 
			
		|||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "aho-corasick"
 | 
			
		||||
version = "1.0.4"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "6748e8def348ed4d14996fa801f4122cd763fff530258cdc03f64b25f89d3a5a"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "memchr",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "anstream"
 | 
			
		||||
version = "0.3.2"
 | 
			
		||||
| 
						 | 
				
			
			@ -290,6 +299,19 @@ dependencies = [
 | 
			
		|||
 "crypto-common",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "env_logger"
 | 
			
		||||
version = "0.10.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "humantime",
 | 
			
		||||
 "is-terminal",
 | 
			
		||||
 "log",
 | 
			
		||||
 "regex",
 | 
			
		||||
 "termcolor",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "errno"
 | 
			
		||||
version = "0.3.2"
 | 
			
		||||
| 
						 | 
				
			
			@ -447,6 +469,12 @@ version = "1.0.3"
 | 
			
		|||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "humantime"
 | 
			
		||||
version = "2.1.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "hyper"
 | 
			
		||||
version = "0.14.27"
 | 
			
		||||
| 
						 | 
				
			
			@ -731,6 +759,35 @@ dependencies = [
 | 
			
		|||
 "bitflags 1.3.2",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "regex"
 | 
			
		||||
version = "1.9.3"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "81bc1d4caf89fac26a70747fe603c130093b53c773888797a6329091246d651a"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "aho-corasick",
 | 
			
		||||
 "memchr",
 | 
			
		||||
 "regex-automata",
 | 
			
		||||
 "regex-syntax",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "regex-automata"
 | 
			
		||||
version = "0.3.6"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "aho-corasick",
 | 
			
		||||
 "memchr",
 | 
			
		||||
 "regex-syntax",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "regex-syntax"
 | 
			
		||||
version = "0.7.4"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "rustc-demangle"
 | 
			
		||||
version = "0.1.23"
 | 
			
		||||
| 
						 | 
				
			
			@ -1068,13 +1125,16 @@ dependencies = [
 | 
			
		|||
 "clap",
 | 
			
		||||
 "codespan-reporting",
 | 
			
		||||
 "copy_dir",
 | 
			
		||||
 "env_logger",
 | 
			
		||||
 "handlebars",
 | 
			
		||||
 "log",
 | 
			
		||||
 "pulldown-cmark",
 | 
			
		||||
 "serde",
 | 
			
		||||
 "tokio",
 | 
			
		||||
 "tower-http",
 | 
			
		||||
 "tower-livereload",
 | 
			
		||||
 "treehouse-format",
 | 
			
		||||
 "walkdir",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,5 +3,6 @@ members = ["crates/*"]
 | 
			
		|||
resolver = "2"
 | 
			
		||||
 | 
			
		||||
[workspace.dependencies]
 | 
			
		||||
log = "0.4.20"
 | 
			
		||||
 | 
			
		||||
treehouse-format = { path = "crates/treehouse-format" }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										1
									
								
								content/secret.tree
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								content/secret.tree
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
- He is behind the tree.
 | 
			
		||||
| 
						 | 
				
			
			@ -4,17 +4,22 @@ version = "0.1.0"
 | 
			
		|||
edition = "2021"
 | 
			
		||||
 | 
			
		||||
[dependencies]
 | 
			
		||||
 | 
			
		||||
treehouse-format = { workspace = true }
 | 
			
		||||
 | 
			
		||||
anyhow = "1.0.75"
 | 
			
		||||
axum = "0.6.20"
 | 
			
		||||
clap = { version = "4.3.22", features = ["derive"] }
 | 
			
		||||
codespan-reporting = "0.11.1"
 | 
			
		||||
copy_dir = "0.1.3"
 | 
			
		||||
env_logger = "0.10.0"
 | 
			
		||||
log = { workspace = true }
 | 
			
		||||
handlebars = "4.3.7"
 | 
			
		||||
pulldown-cmark = { version = "0.9.3", default-features = false }
 | 
			
		||||
serde = { version = "1.0.183", features = ["derive"] }
 | 
			
		||||
tokio = { version = "1.32.0", features = ["full"] }
 | 
			
		||||
tower-http = { version = "0.4.3", features = ["fs"] }
 | 
			
		||||
tower-livereload = "0.8.0"
 | 
			
		||||
walkdir = "2.3.3"
 | 
			
		||||
 | 
			
		||||
treehouse-format = { workspace = true }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,74 +1,242 @@
 | 
			
		|||
use std::{
 | 
			
		||||
    ffi::OsStr,
 | 
			
		||||
    path::{Path, PathBuf},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
use anyhow::{bail, Context};
 | 
			
		||||
use axum::Router;
 | 
			
		||||
use codespan_reporting::{
 | 
			
		||||
    diagnostic::{Diagnostic, Label, LabelStyle, Severity},
 | 
			
		||||
    files::SimpleFile,
 | 
			
		||||
    files::{Files as _, SimpleFiles},
 | 
			
		||||
    term::termcolor::{ColorChoice, StandardStream},
 | 
			
		||||
};
 | 
			
		||||
use copy_dir::copy_dir;
 | 
			
		||||
use handlebars::Handlebars;
 | 
			
		||||
use log::{debug, info};
 | 
			
		||||
use serde::Serialize;
 | 
			
		||||
use tower_http::services::ServeDir;
 | 
			
		||||
use tower_livereload::LiveReloadLayer;
 | 
			
		||||
use treehouse_format::ast::Roots;
 | 
			
		||||
use walkdir::WalkDir;
 | 
			
		||||
 | 
			
		||||
use crate::html::tree::branches_to_html;
 | 
			
		||||
 | 
			
		||||
#[derive(Default)]
 | 
			
		||||
struct Generator {
 | 
			
		||||
    tree_files: Vec<PathBuf>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Files = SimpleFiles<String, String>;
 | 
			
		||||
type FileId = <Files as codespan_reporting::files::Files<'static>>::FileId;
 | 
			
		||||
 | 
			
		||||
pub struct Diagnosis {
 | 
			
		||||
    pub files: Files,
 | 
			
		||||
    pub diagnostics: Vec<Diagnostic<FileId>>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Generator {
 | 
			
		||||
    fn add_directory_rec(&mut self, directory: &Path) -> anyhow::Result<()> {
 | 
			
		||||
        for entry in WalkDir::new(directory) {
 | 
			
		||||
            let entry = entry?;
 | 
			
		||||
            if entry.path().extension() == Some(OsStr::new("tree")) {
 | 
			
		||||
                self.tree_files.push(entry.path().to_owned());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn register_template(
 | 
			
		||||
        handlebars: &mut Handlebars<'_>,
 | 
			
		||||
        diagnosis: &mut Diagnosis,
 | 
			
		||||
        name: &str,
 | 
			
		||||
        path: &Path,
 | 
			
		||||
    ) -> anyhow::Result<FileId> {
 | 
			
		||||
        let source = std::fs::read_to_string(path)
 | 
			
		||||
            .with_context(|| format!("cannot read template file {path:?}"))?;
 | 
			
		||||
        let file_id = diagnosis
 | 
			
		||||
            .files
 | 
			
		||||
            .add(path.to_string_lossy().into_owned(), source);
 | 
			
		||||
        let file = diagnosis
 | 
			
		||||
            .files
 | 
			
		||||
            .get(file_id)
 | 
			
		||||
            .expect("file was just added to the list");
 | 
			
		||||
        let source = file.source();
 | 
			
		||||
        if let Err(error) = handlebars.register_template_string(name, source) {
 | 
			
		||||
            Self::wrangle_handlebars_error_into_diagnostic(
 | 
			
		||||
                diagnosis,
 | 
			
		||||
                file_id,
 | 
			
		||||
                error.line_no,
 | 
			
		||||
                error.column_no,
 | 
			
		||||
                error.reason().to_string(),
 | 
			
		||||
            )?;
 | 
			
		||||
        }
 | 
			
		||||
        Ok(file_id)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn wrangle_handlebars_error_into_diagnostic(
 | 
			
		||||
        diagnosis: &mut Diagnosis,
 | 
			
		||||
        file_id: FileId,
 | 
			
		||||
        line: Option<usize>,
 | 
			
		||||
        column: Option<usize>,
 | 
			
		||||
        message: String,
 | 
			
		||||
    ) -> anyhow::Result<()> {
 | 
			
		||||
        if let (Some(line), Some(column)) = (line, column) {
 | 
			
		||||
            let line_range = diagnosis
 | 
			
		||||
                .files
 | 
			
		||||
                .line_range(file_id, line)
 | 
			
		||||
                .expect("file was added to the list");
 | 
			
		||||
            diagnosis.diagnostics.push(Diagnostic {
 | 
			
		||||
                severity: Severity::Error,
 | 
			
		||||
                code: Some("template".into()),
 | 
			
		||||
                message,
 | 
			
		||||
                labels: vec![Label {
 | 
			
		||||
                    style: LabelStyle::Primary,
 | 
			
		||||
                    file_id,
 | 
			
		||||
                    range: line_range.start + column..line_range.start + column + 1,
 | 
			
		||||
                    message: String::new(),
 | 
			
		||||
                }],
 | 
			
		||||
                notes: vec![],
 | 
			
		||||
            })
 | 
			
		||||
        } else {
 | 
			
		||||
            let file = diagnosis
 | 
			
		||||
                .files
 | 
			
		||||
                .get(file_id)
 | 
			
		||||
                .expect("file should already be in the list");
 | 
			
		||||
            bail!("template error in {}: {message}", file.name());
 | 
			
		||||
        }
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn generate_all_files(&self, dirs: &Dirs<'_>) -> anyhow::Result<Diagnosis> {
 | 
			
		||||
        let mut diagnosis = Diagnosis {
 | 
			
		||||
            files: Files::new(),
 | 
			
		||||
            diagnostics: vec![],
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        let mut handlebars = Handlebars::new();
 | 
			
		||||
        let tree_template = Self::register_template(
 | 
			
		||||
            &mut handlebars,
 | 
			
		||||
            &mut diagnosis,
 | 
			
		||||
            "tree",
 | 
			
		||||
            &dirs.template_dir.join("tree.hbs"),
 | 
			
		||||
        )?;
 | 
			
		||||
 | 
			
		||||
        for path in &self.tree_files {
 | 
			
		||||
            let utf8_filename = path.to_string_lossy();
 | 
			
		||||
            let target_file = path.strip_prefix(dirs.content_dir).unwrap_or(path);
 | 
			
		||||
            let target_path = if target_file == OsStr::new("index.tree") {
 | 
			
		||||
                dirs.target_dir.join("index.html")
 | 
			
		||||
            } else {
 | 
			
		||||
                dirs.target_dir.join(target_file).with_extension("html")
 | 
			
		||||
            };
 | 
			
		||||
            debug!("generating: {path:?} -> {target_path:?}");
 | 
			
		||||
 | 
			
		||||
            let source = match std::fs::read_to_string(path) {
 | 
			
		||||
                Ok(source) => source,
 | 
			
		||||
                Err(error) => {
 | 
			
		||||
                    diagnosis.diagnostics.push(Diagnostic {
 | 
			
		||||
                        severity: Severity::Error,
 | 
			
		||||
                        code: None,
 | 
			
		||||
                        message: format!("{utf8_filename}: cannot read file: {error}"),
 | 
			
		||||
                        labels: vec![],
 | 
			
		||||
                        notes: vec![],
 | 
			
		||||
                    });
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
            let file_id = diagnosis.files.add(utf8_filename.into_owned(), source);
 | 
			
		||||
            let source = diagnosis
 | 
			
		||||
                .files
 | 
			
		||||
                .get(file_id)
 | 
			
		||||
                .expect("file was just added to the list")
 | 
			
		||||
                .source();
 | 
			
		||||
 | 
			
		||||
            let parse_result = Roots::parse(&mut treehouse_format::pull::Parser {
 | 
			
		||||
                input: source,
 | 
			
		||||
                position: 0,
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            match parse_result {
 | 
			
		||||
                Ok(roots) => {
 | 
			
		||||
                    let mut tree = String::new();
 | 
			
		||||
                    branches_to_html(&mut tree, &roots.branches, source);
 | 
			
		||||
 | 
			
		||||
                    let template_data = TemplateData { tree };
 | 
			
		||||
                    let templated_html = match handlebars.render("tree", &template_data) {
 | 
			
		||||
                        Ok(html) => html,
 | 
			
		||||
                        Err(error) => {
 | 
			
		||||
                            Self::wrangle_handlebars_error_into_diagnostic(
 | 
			
		||||
                                &mut diagnosis,
 | 
			
		||||
                                tree_template,
 | 
			
		||||
                                error.line_no,
 | 
			
		||||
                                error.column_no,
 | 
			
		||||
                                error.desc,
 | 
			
		||||
                            )?;
 | 
			
		||||
                            continue;
 | 
			
		||||
                        }
 | 
			
		||||
                    };
 | 
			
		||||
 | 
			
		||||
                    std::fs::write(target_path, templated_html)?;
 | 
			
		||||
                }
 | 
			
		||||
                Err(error) => diagnosis.diagnostics.push(Diagnostic {
 | 
			
		||||
                    severity: Severity::Error,
 | 
			
		||||
                    code: Some("tree".into()),
 | 
			
		||||
                    message: error.kind.to_string(),
 | 
			
		||||
                    labels: vec![Label {
 | 
			
		||||
                        style: LabelStyle::Primary,
 | 
			
		||||
                        file_id,
 | 
			
		||||
                        range: error.range,
 | 
			
		||||
                        message: String::new(),
 | 
			
		||||
                    }],
 | 
			
		||||
                    notes: vec![],
 | 
			
		||||
                }),
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Ok(diagnosis)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone, Copy)]
 | 
			
		||||
pub struct Dirs<'a> {
 | 
			
		||||
    pub target_dir: &'a Path,
 | 
			
		||||
    pub static_dir: &'a Path,
 | 
			
		||||
    pub template_dir: &'a Path,
 | 
			
		||||
    pub content_dir: &'a Path,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Serialize)]
 | 
			
		||||
pub struct TemplateData {
 | 
			
		||||
    pub tree: String,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn regenerate() -> anyhow::Result<()> {
 | 
			
		||||
    let _ = std::fs::remove_dir_all("target/site");
 | 
			
		||||
    std::fs::create_dir_all("target/site")?;
 | 
			
		||||
pub fn regenerate(dirs: &Dirs<'_>) -> anyhow::Result<()> {
 | 
			
		||||
    info!("cleaning target directory");
 | 
			
		||||
    let _ = std::fs::remove_dir_all(dirs.target_dir);
 | 
			
		||||
    std::fs::create_dir_all(dirs.target_dir)?;
 | 
			
		||||
 | 
			
		||||
    copy_dir("static", "target/site/static")?;
 | 
			
		||||
    info!("copying static directory to target directory");
 | 
			
		||||
    copy_dir(dirs.static_dir, dirs.target_dir.join("static"))?;
 | 
			
		||||
 | 
			
		||||
    let mut handlebars = Handlebars::new();
 | 
			
		||||
    handlebars.register_template_file("template/index.hbs", "template/index.hbs")?;
 | 
			
		||||
    info!("generating standalone pages");
 | 
			
		||||
    let mut generator = Generator::default();
 | 
			
		||||
    generator.add_directory_rec(dirs.content_dir)?;
 | 
			
		||||
    let diagnosis = generator.generate_all_files(dirs)?;
 | 
			
		||||
 | 
			
		||||
    let root_file = std::fs::read_to_string("content/tree/index.tree")?;
 | 
			
		||||
    let parse_result = Roots::parse(&mut treehouse_format::pull::Parser {
 | 
			
		||||
        input: &root_file,
 | 
			
		||||
        position: 0,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    match parse_result {
 | 
			
		||||
        Ok(roots) => {
 | 
			
		||||
            let mut tree = String::new();
 | 
			
		||||
            branches_to_html(&mut tree, &roots.branches, &root_file);
 | 
			
		||||
 | 
			
		||||
            let index_html = handlebars.render("template/index.hbs", &TemplateData { tree })?;
 | 
			
		||||
 | 
			
		||||
            std::fs::write("target/site/index.html", index_html)?;
 | 
			
		||||
        }
 | 
			
		||||
        Err(error) => {
 | 
			
		||||
            let writer = StandardStream::stderr(ColorChoice::Auto);
 | 
			
		||||
            let config = codespan_reporting::term::Config::default();
 | 
			
		||||
            let files = SimpleFile::new("index.tree", &root_file);
 | 
			
		||||
            let diagnostic = Diagnostic {
 | 
			
		||||
                severity: Severity::Error,
 | 
			
		||||
                code: None,
 | 
			
		||||
                message: error.kind.to_string(),
 | 
			
		||||
                labels: vec![Label {
 | 
			
		||||
                    style: LabelStyle::Primary,
 | 
			
		||||
                    file_id: (),
 | 
			
		||||
                    range: error.range,
 | 
			
		||||
                    message: String::new(),
 | 
			
		||||
                }],
 | 
			
		||||
                notes: vec![],
 | 
			
		||||
            };
 | 
			
		||||
            codespan_reporting::term::emit(&mut writer.lock(), &config, &files, &diagnostic)?;
 | 
			
		||||
        }
 | 
			
		||||
    let writer = StandardStream::stderr(ColorChoice::Auto);
 | 
			
		||||
    let config = codespan_reporting::term::Config::default();
 | 
			
		||||
    for diagnostic in &diagnosis.diagnostics {
 | 
			
		||||
        codespan_reporting::term::emit(&mut writer.lock(), &config, &diagnosis.files, diagnostic)
 | 
			
		||||
            .context("could not emit diagnostic")?;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn regenerate_or_report_error() {
 | 
			
		||||
    eprintln!("regenerating");
 | 
			
		||||
pub fn regenerate_or_report_error(dirs: &Dirs<'_>) {
 | 
			
		||||
    info!("regenerating site content");
 | 
			
		||||
 | 
			
		||||
    match regenerate() {
 | 
			
		||||
    match regenerate(dirs) {
 | 
			
		||||
        Ok(_) => (),
 | 
			
		||||
        Err(error) => eprintln!("error: {error:?}"),
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -80,7 +248,7 @@ pub async fn web_server() -> anyhow::Result<()> {
 | 
			
		|||
    #[cfg(debug_assertions)]
 | 
			
		||||
    let app = app.layer(LiveReloadLayer::new());
 | 
			
		||||
 | 
			
		||||
    eprintln!("serving on port 8080");
 | 
			
		||||
    info!("serving on port 8080");
 | 
			
		||||
    Ok(axum::Server::bind(&([0, 0, 0, 0], 8080).into())
 | 
			
		||||
        .serve(app.into_make_service())
 | 
			
		||||
        .await?)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,11 @@
 | 
			
		|||
use std::path::Path;
 | 
			
		||||
 | 
			
		||||
use clap::Parser;
 | 
			
		||||
use cli::{
 | 
			
		||||
    regenerate::{self, regenerate_or_report_error},
 | 
			
		||||
    regenerate::{self, regenerate_or_report_error, Dirs},
 | 
			
		||||
    Command, ProgramArgs,
 | 
			
		||||
};
 | 
			
		||||
use log::{error, info};
 | 
			
		||||
 | 
			
		||||
mod cli;
 | 
			
		||||
mod html;
 | 
			
		||||
| 
						 | 
				
			
			@ -12,7 +15,18 @@ async fn fallible_main() -> anyhow::Result<()> {
 | 
			
		|||
 | 
			
		||||
    match args.command {
 | 
			
		||||
        Command::Regenerate(regenerate_args) => {
 | 
			
		||||
            regenerate_or_report_error();
 | 
			
		||||
            let dirs = Dirs {
 | 
			
		||||
                target_dir: Path::new("target/site"),
 | 
			
		||||
 | 
			
		||||
                // NOTE: These are intentionally left unconfigurable from within treehouse.toml
 | 
			
		||||
                // because this is is one of those things that should be consistent between sites.
 | 
			
		||||
                static_dir: Path::new("static"),
 | 
			
		||||
                template_dir: Path::new("template"),
 | 
			
		||||
                content_dir: Path::new("content"),
 | 
			
		||||
            };
 | 
			
		||||
            info!("regenerating using directories: {dirs:#?}");
 | 
			
		||||
 | 
			
		||||
            regenerate_or_report_error(&dirs);
 | 
			
		||||
 | 
			
		||||
            if regenerate_args.serve {
 | 
			
		||||
                regenerate::web_server().await?;
 | 
			
		||||
| 
						 | 
				
			
			@ -25,9 +39,13 @@ async fn fallible_main() -> anyhow::Result<()> {
 | 
			
		|||
 | 
			
		||||
#[tokio::main]
 | 
			
		||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
 | 
			
		||||
    env_logger::Builder::new()
 | 
			
		||||
        .filter_module("treehouse", log::LevelFilter::Debug)
 | 
			
		||||
        .init();
 | 
			
		||||
 | 
			
		||||
    match fallible_main().await {
 | 
			
		||||
        Ok(_) => (),
 | 
			
		||||
        Err(error) => eprintln!("fatal: {error:?}"),
 | 
			
		||||
        Err(error) => error!("fatal: {error:?}"),
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Ok(())
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,7 +10,7 @@ body {
 | 
			
		|||
 | 
			
		||||
body {
 | 
			
		||||
    background-color: rgb(255, 253, 246);
 | 
			
		||||
    color: #333;
 | 
			
		||||
    color: #55423e;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Set up typography */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue