Skip to content

Commit

Permalink
ssg-parent: builder cmd and watch paths parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
mightyiam committed Nov 7, 2024
1 parent ecd6960 commit 3bc62a7
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 34 deletions.
18 changes: 16 additions & 2 deletions crates/cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,28 @@ async fn main() {

let cli = Cli::parse();

let parent = Parent::new(OUTPUT_DIR.clone()).post_build(tailwind::execute);
let parent = Parent::new(
OUTPUT_DIR.clone(),
"cargo",
["run", "--package", "builder", "--", OUTPUT_DIR.as_str()],
)
.post_build(tailwind::execute);

match cli.mode.unwrap_or_default() {
Mode::Build => {
parent.build().await.unwrap();
}
Mode::Dev { open } => {
let error = parent.dev(open).await;
let error = parent
.dev(
[Utf8PathBuf::from_iter([
env!("CARGO_MANIFEST_DIR"),
"..",
"builder",
])],
open,
)
.await;
panic!("{error}");
}
Mode::PrintOutputDir => print!("{}", OUTPUT_DIR.as_os_str().to_str().unwrap()),
Expand Down
18 changes: 10 additions & 8 deletions crates/reactive/src/driver/notify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,20 @@ pub use notify::{Error, Event, EventKind, Result};
pub struct FsChangeDriver<T> {
watcher: RecommendedWatcher,
sender: mpsc::Sender<Result<Event>>,
path: PathBuf,
paths: Vec<PathBuf>,
boo: PhantomData<fn(T) -> PathBuf>,
}

impl<T> Driver for FsChangeDriver<T>
where
PathBuf: From<T>,
{
type Args = T;
type Args = Vec<T>;
type ConstructionError = notify::Error;
type Input = ();
type Output = LocalBoxStream<'static, Result<Event>>;

fn new(path: Self::Args) -> Result<(Self, Self::Output)> {
fn new(paths: Self::Args) -> Result<(Self, Self::Output)> {
let (sender, receiver) = mpsc::channel::<Result<Event>>(1);

let mut sender_clone = sender.clone();
Expand All @@ -42,18 +42,20 @@ where
let fs_change_driver = Self {
watcher,
sender,
path: path.into(),
paths: paths.into_iter().map(Into::into).collect(),
boo: PhantomData,
};

Ok((fs_change_driver, receiver.boxed_local()))
}

fn init(mut self, _input: Self::Input) -> LocalBoxFuture<'static, ()> {
if let Err(error) = self.watcher.watch(&self.path, RecursiveMode::Recursive) {
block_on(self.sender.send(Err(error))).unwrap();
return pending().boxed_local();
};
for path in self.paths {
if let Err(error) = self.watcher.watch(&path, RecursiveMode::Recursive) {
block_on(self.sender.send(Err(error))).unwrap();
return pending().boxed_local();
};
}

async move {
let _watcher = self.watcher;
Expand Down
61 changes: 37 additions & 24 deletions crates/ssg-parent/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
#![warn(clippy::all, clippy::pedantic)]

use camino::Utf8PathBuf;
use std::{
ffi::{OsStr, OsString},
path::PathBuf,
};

use colored::Colorize;
use futures::{
channel::mpsc,
Expand All @@ -16,13 +20,16 @@ type PostBuildReturn =
#[derive(derive_more::Debug)]
#[must_use]
pub struct Parent {
#[debug(skip)]
builder_command: OsString,
#[debug(skip)]
builder_args: Vec<OsString>,
output_dir: camino::Utf8PathBuf,
builder: BuilderState,
#[debug("{}", match post_build { None => "None", Some(_) => "Some(function)" })]
post_build: Option<Box<dyn Fn() -> PostBuildReturn>>,
}

const BUILDER_CRATE_NAME: &str = "builder";
const LOCALHOST: &str = "localhost";

/// Error type returned from the reactive app
Expand Down Expand Up @@ -74,9 +81,18 @@ pub enum BuildError {
}

impl Parent {
pub fn new(output_dir: impl Into<camino::Utf8PathBuf>) -> Self {
pub fn new(
output_dir: impl Into<camino::Utf8PathBuf>,
builder_command: impl AsRef<OsStr> + 'static,
builder_args: impl IntoIterator<Item = impl AsRef<OsStr>>,
) -> Self {
Self {
output_dir: output_dir.into(),
builder_command: builder_command.as_ref().to_owned(),
builder_args: builder_args
.into_iter()
.map(|v| v.as_ref().to_owned())
.collect::<Vec<_>>(),
builder: BuilderState::default(),
post_build: None,
}
Expand Down Expand Up @@ -108,7 +124,11 @@ impl Parent {

/// Sets up a development environment that watches the file system,
/// recompiling the crate that when run describes the website on localhost when there are changes.
pub async fn dev(self, launch_browser: bool) -> DevError {
pub async fn dev(
self,
paths_to_watch: impl IntoIterator<Item = impl Into<PathBuf>>,
launch_browser: bool,
) -> DevError {
let Some(port) = portpicker::pick_unused_port() else {
return DevError::NoFreePort;
};
Expand All @@ -129,15 +149,12 @@ impl Parent {
let (open_browser_driver, browser_opened) =
reactive::driver::open_that::StaticOpenThatDriver::new(url.to_string());
let (eprintln_driver, ()) = reactive::driver::println::EprintlnDriver::new();
let (notify_driver, notify) =
match reactive::driver::notify::FsChangeDriver::new(Utf8PathBuf::from_iter([
env!("CARGO_MANIFEST_DIR"),
"..",
BUILDER_CRATE_NAME,
])) {
Ok(val) => val,
Err(e) => return e.into(),
};
let (notify_driver, notify) = match reactive::driver::notify::FsChangeDriver::new(
paths_to_watch.into_iter().map(Into::into).collect(),
) {
Ok(val) => val,
Err(e) => return e.into(),
};

let inputs = Inputs {
server_task,
Expand Down Expand Up @@ -178,17 +195,9 @@ impl Parent {
}

fn builder_command(&self) -> tokio::process::Command {
let mut cargo_run_builder = tokio::process::Command::new("cargo");

cargo_run_builder.args([
"run",
"--package",
BUILDER_CRATE_NAME,
"--",
self.output_dir.as_str(),
]);

cargo_run_builder
let mut command = tokio::process::Command::new(&self.builder_command);
command.args(&self.builder_args);
command
}

fn input_event(&mut self, input: InputEvent) -> Option<OutputEvent> {
Expand Down Expand Up @@ -404,12 +413,16 @@ impl Parent {

#[cfg(test)]
mod test {
use std::ffi::OsString;

use crate::{BuilderState, Parent};

#[test]
fn parent_debug() {
let parent_no_post_build = Parent {
output_dir: camino::Utf8PathBuf::from("path/to/there"),
builder_command: OsString::new(),
builder_args: vec![],
builder: BuilderState::default(),
post_build: None,
};
Expand Down

0 comments on commit 3bc62a7

Please sign in to comment.