implemented serve command and added async runtime

This commit is contained in:
2023-03-12 19:30:11 +01:00
parent fb147e5857
commit cc77e4ef9c
5 changed files with 1994 additions and 44 deletions

1908
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -11,8 +11,12 @@ license-file = "LICENSE.txt"
bytes = "1.4.0"
clap = { version = "4.1.8", features = ["derive"] }
colored = "2.0.0"
futures = "0.3.26"
home = "0.5.4"
live-server = "0.6.0"
notify = { version = "5.1.0", features = ["serde"] }
regex = "1.7.1"
reqwest = { version = "0.11.14", features = ["blocking"] }
text_io = "0.1.12"
tokio = { version = "1.26.0", features = ["full"] }
zip-extract = "0.1.1"

View File

@@ -1,3 +1,110 @@
pub fn serve() {
println!("serving the developement version")
use colored::Colorize;
use live_server::listen;
use notify::{
event::{self, ModifyKind},
Config, Event, EventKind, RecommendedWatcher, RecursiveMode, Watcher,
};
use std::{env, path::Path};
use tokio::sync::mpsc::{channel, Receiver};
use crate::app::{
builder::{
asciidoctor::{AsciiDoctorDocsBuilder, AsciiDoctorSlideBuilder},
Builder,
},
fs_util,
};
pub async fn serve() {
tokio::join!(watch_and_build(), start_server());
println!("stopping live server");
}
async fn watch_and_build() {
watch(Path::new("./docs"))
.await
.expect("something went wrong")
}
async fn start_server() {
println!("Serving at http://localhost:8080");
let Ok(()) = listen("localhost", 8080, "./dist").await else {
panic!("could not start server")
};
}
async fn watch(path: &Path) -> notify::Result<()> {
let (mut watcher, mut rx) = watcher()?;
watcher.watch(path.as_ref(), RecursiveMode::Recursive)?;
while let Some(res) = rx.recv().await {
match res {
Ok(event) => file_change(event),
Err(e) => println!("watch error: {:?}", e),
}
}
Ok(())
}
fn file_change(event: Event) {
match event.kind {
EventKind::Modify(ModifyKind::Data(_)) => {
build_file(event.paths).expect("building file failed");
()
}
_ => (),
}
}
fn build_file(paths: Vec<std::path::PathBuf>) -> Result<(), String> {
let invalid_path_message = "changed path is invalid";
let in_path = paths
.first()
.expect(invalid_path_message)
.to_str()
.expect(invalid_path_message)
.replace(&current_dir(), "")
.replace("/./", "./");
let out_path = in_path
.replace("./docs/", "./dist/")
.replace(".adoc", ".html");
println!("{} {}", "[Rebuilding]".green(), in_path);
if in_path.starts_with("./docs/slides") {
let slide_builder = AsciiDoctorSlideBuilder {};
slide_builder.build(&in_path, &out_path)
} else {
let doc_builder = AsciiDoctorDocsBuilder {};
doc_builder.build(&in_path, &out_path)
}
}
fn current_dir() -> String {
let err_message = "something went wrong";
return String::from(
env::current_dir()
.expect(err_message)
.to_str()
.expect(err_message),
);
}
fn watcher() -> notify::Result<(RecommendedWatcher, Receiver<notify::Result<Event>>)> {
let (tx, rx) = channel(1);
let watcher = RecommendedWatcher::new(
move |res| {
futures::executor::block_on(async {
tx.send(res).await.unwrap();
});
},
Config::default(),
)?;
Ok((watcher, rx))
}

View File

@@ -15,16 +15,16 @@ pub struct App;
impl App {
pub fn start(&self) {
pub async fn start(&self) {
let args = args();
Self::setup_environment_variables();
match args.command {
CommandArg::Build => build(),
CommandArg::Build => build().await,
CommandArg::Health => health(),
CommandArg::InstallReveal => install_reveal(),
CommandArg::Serve => serve()
}
CommandArg::InstallReveal => install_reveal().await,
CommandArg::Serve => serve().await
};
}
fn setup_environment_variables() {

View File

@@ -5,7 +5,8 @@ mod test;
use app::App;
fn main() {
#[tokio::main]
async fn main() {
let app = App::new();
app.start();
app.start().await;
}