rearrange things a bit
This commit is contained in:
parent
63dd2fa5ab
commit
27414d4254
1182
Cargo.lock
generated
1182
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -6,15 +6,15 @@ edition = "2021"
|
|||
[dependencies]
|
||||
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"
|
||||
handlebars = "4.3.7"
|
||||
pulldown-cmark = { version = "0.9.3", default-features = false }
|
||||
serde = { version = "1.0.183", features = ["derive"] }
|
||||
thiserror = "1.0.47"
|
||||
tokio = "1.32.0"
|
||||
tokio = { version = "1.32.0", features = ["full"] }
|
||||
tower-http = { version = "0.4.3", features = ["fs"] }
|
||||
tower-livereload = "0.8.0"
|
||||
treehouse-format = { workspace = true }
|
||||
watchexec = "2.3.0"
|
||||
|
||||
treehouse-format = { workspace = true }
|
||||
|
||||
|
|
22
crates/treehouse/src/cli/mod.rs
Normal file
22
crates/treehouse/src/cli/mod.rs
Normal file
|
@ -0,0 +1,22 @@
|
|||
pub mod regenerate;
|
||||
|
||||
use clap::{Args, Parser, Subcommand};
|
||||
|
||||
#[derive(Parser)]
|
||||
pub struct ProgramArgs {
|
||||
#[clap(subcommand)]
|
||||
pub command: Command,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
pub enum Command {
|
||||
/// Regenerate the website.
|
||||
Regenerate(#[clap(flatten)] RegenerateArgs),
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct RegenerateArgs {
|
||||
/// Start a web server serving the static files. Useful with `cargo watch`.
|
||||
#[clap(short, long)]
|
||||
pub serve: bool,
|
||||
}
|
87
crates/treehouse/src/cli/regenerate.rs
Normal file
87
crates/treehouse/src/cli/regenerate.rs
Normal file
|
@ -0,0 +1,87 @@
|
|||
use axum::Router;
|
||||
use codespan_reporting::{
|
||||
diagnostic::{Diagnostic, Label, LabelStyle, Severity},
|
||||
files::SimpleFile,
|
||||
term::termcolor::{ColorChoice, StandardStream},
|
||||
};
|
||||
use copy_dir::copy_dir;
|
||||
use handlebars::Handlebars;
|
||||
use serde::Serialize;
|
||||
use tower_http::services::ServeDir;
|
||||
use tower_livereload::LiveReloadLayer;
|
||||
use treehouse_format::ast::Roots;
|
||||
|
||||
use crate::html::tree::branches_to_html;
|
||||
|
||||
#[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")?;
|
||||
|
||||
copy_dir("static", "target/site/static")?;
|
||||
|
||||
let mut handlebars = Handlebars::new();
|
||||
handlebars.register_template_file("template/index.hbs", "template/index.hbs")?;
|
||||
|
||||
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)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn regenerate_or_report_error() {
|
||||
eprintln!("regenerating");
|
||||
|
||||
match regenerate() {
|
||||
Ok(_) => (),
|
||||
Err(error) => eprintln!("error: {error:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn web_server() -> anyhow::Result<()> {
|
||||
let app = Router::new().nest_service("/", ServeDir::new("target/site"));
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
let app = app.layer(LiveReloadLayer::new());
|
||||
|
||||
eprintln!("serving on port 8080");
|
||||
Ok(axum::Server::bind(&([0, 0, 0, 0], 8080).into())
|
||||
.serve(app.into_make_service())
|
||||
.await?)
|
||||
}
|
|
@ -1,95 +1,24 @@
|
|||
use clap::Parser;
|
||||
use cli::{
|
||||
regenerate::{self, regenerate_or_report_error},
|
||||
Command, ProgramArgs,
|
||||
};
|
||||
|
||||
mod cli;
|
||||
mod html;
|
||||
|
||||
use axum::Router;
|
||||
use codespan_reporting::{
|
||||
diagnostic::{Diagnostic, Label, LabelStyle, Severity},
|
||||
files::SimpleFile,
|
||||
term::termcolor::{ColorChoice, StandardStream},
|
||||
};
|
||||
use copy_dir::copy_dir;
|
||||
use handlebars::Handlebars;
|
||||
use html::tree::branches_to_html;
|
||||
use serde::Serialize;
|
||||
use tower_http::services::ServeDir;
|
||||
use tower_livereload::LiveReloadLayer;
|
||||
use treehouse_format::{ast::Roots, pull::Parser};
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct TemplateData {
|
||||
pub tree: String,
|
||||
}
|
||||
|
||||
fn regenerate() -> anyhow::Result<()> {
|
||||
let _ = std::fs::remove_dir_all("target/site");
|
||||
std::fs::create_dir_all("target/site")?;
|
||||
|
||||
copy_dir("static", "target/site/static")?;
|
||||
|
||||
let mut handlebars = Handlebars::new();
|
||||
handlebars.register_template_file("template/index.hbs", "template/index.hbs")?;
|
||||
|
||||
let root_file = std::fs::read_to_string("content/tree/root.tree")?;
|
||||
let parse_result = Roots::parse(&mut 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("root.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)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn regenerate_or_report_error() {
|
||||
eprintln!("regenerating");
|
||||
|
||||
match regenerate() {
|
||||
Ok(_) => (),
|
||||
Err(error) => eprintln!("error: {error:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
async fn web_server() -> anyhow::Result<()> {
|
||||
let app = Router::new().nest_service("/", ServeDir::new("target/site"));
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
let app = app.layer(LiveReloadLayer::new());
|
||||
|
||||
Ok(axum::Server::bind(&([0, 0, 0, 0], 8080).into())
|
||||
.serve(app.into_make_service())
|
||||
.await?)
|
||||
}
|
||||
|
||||
async fn fallible_main() -> anyhow::Result<()> {
|
||||
regenerate_or_report_error();
|
||||
let args = ProgramArgs::parse();
|
||||
|
||||
web_server().await?;
|
||||
match args.command {
|
||||
Command::Regenerate(regenerate_args) => {
|
||||
regenerate_or_report_error();
|
||||
|
||||
if regenerate_args.serve {
|
||||
regenerate::web_server().await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue