implemented serve command and added async runtime
This commit is contained in:
1908
Cargo.lock
generated
1908
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -11,8 +11,12 @@ license-file = "LICENSE.txt"
|
|||||||
bytes = "1.4.0"
|
bytes = "1.4.0"
|
||||||
clap = { version = "4.1.8", features = ["derive"] }
|
clap = { version = "4.1.8", features = ["derive"] }
|
||||||
colored = "2.0.0"
|
colored = "2.0.0"
|
||||||
|
futures = "0.3.26"
|
||||||
home = "0.5.4"
|
home = "0.5.4"
|
||||||
|
live-server = "0.6.0"
|
||||||
|
notify = { version = "5.1.0", features = ["serde"] }
|
||||||
regex = "1.7.1"
|
regex = "1.7.1"
|
||||||
reqwest = { version = "0.11.14", features = ["blocking"] }
|
reqwest = { version = "0.11.14", features = ["blocking"] }
|
||||||
text_io = "0.1.12"
|
text_io = "0.1.12"
|
||||||
|
tokio = { version = "1.26.0", features = ["full"] }
|
||||||
zip-extract = "0.1.1"
|
zip-extract = "0.1.1"
|
||||||
|
|||||||
@@ -1,3 +1,110 @@
|
|||||||
pub fn serve() {
|
use colored::Colorize;
|
||||||
println!("serving the developement version")
|
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(¤t_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))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,16 +15,16 @@ pub struct App;
|
|||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
|
|
||||||
pub fn start(&self) {
|
pub async fn start(&self) {
|
||||||
let args = args();
|
let args = args();
|
||||||
Self::setup_environment_variables();
|
Self::setup_environment_variables();
|
||||||
|
|
||||||
match args.command {
|
match args.command {
|
||||||
CommandArg::Build => build(),
|
CommandArg::Build => build().await,
|
||||||
CommandArg::Health => health(),
|
CommandArg::Health => health(),
|
||||||
CommandArg::InstallReveal => install_reveal(),
|
CommandArg::InstallReveal => install_reveal().await,
|
||||||
CommandArg::Serve => serve()
|
CommandArg::Serve => serve().await
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_environment_variables() {
|
fn setup_environment_variables() {
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ mod test;
|
|||||||
|
|
||||||
use app::App;
|
use app::App;
|
||||||
|
|
||||||
fn main() {
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
let app = App::new();
|
let app = App::new();
|
||||||
app.start();
|
app.start().await;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user