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]
|
[dependencies]
|
||||||
anyhow = "1.0.75"
|
anyhow = "1.0.75"
|
||||||
axum = "0.6.20"
|
axum = "0.6.20"
|
||||||
|
clap = { version = "4.3.22", features = ["derive"] }
|
||||||
codespan-reporting = "0.11.1"
|
codespan-reporting = "0.11.1"
|
||||||
copy_dir = "0.1.3"
|
copy_dir = "0.1.3"
|
||||||
handlebars = "4.3.7"
|
handlebars = "4.3.7"
|
||||||
pulldown-cmark = { version = "0.9.3", default-features = false }
|
pulldown-cmark = { version = "0.9.3", default-features = false }
|
||||||
serde = { version = "1.0.183", features = ["derive"] }
|
serde = { version = "1.0.183", features = ["derive"] }
|
||||||
thiserror = "1.0.47"
|
tokio = { version = "1.32.0", features = ["full"] }
|
||||||
tokio = "1.32.0"
|
|
||||||
tower-http = { version = "0.4.3", features = ["fs"] }
|
tower-http = { version = "0.4.3", features = ["fs"] }
|
||||||
tower-livereload = "0.8.0"
|
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;
|
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<()> {
|
async fn fallible_main() -> anyhow::Result<()> {
|
||||||
|
let args = ProgramArgs::parse();
|
||||||
|
|
||||||
|
match args.command {
|
||||||
|
Command::Regenerate(regenerate_args) => {
|
||||||
regenerate_or_report_error();
|
regenerate_or_report_error();
|
||||||
|
|
||||||
web_server().await?;
|
if regenerate_args.serve {
|
||||||
|
regenerate::web_server().await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue