rochacbruno / marmite

Markdown makes sites - A Static Site Generator for Blogs
https://rochacbruno.github.io/marmite/
GNU Affero General Public License v3.0
340 stars 19 forks source link

[feat:] Add Watch Feature to Monitor Input Folder for Changes #60

Closed SkySingh04 closed 1 week ago

SkySingh04 commented 1 week ago

Description

This PR introduces the --watch flag to the marmite project, allowing it to monitor the input_folder for any changes and rebuild the site when changes are detected. This feature was inspired by similar implementations in static site generators like Zola and Cobalt.

Key features added:

Changes

  1. Added --watch flag support to enable file system monitoring for changes.
  2. Wrapped input_folder in an Arc to share it across threads, ensuring thread safety.
  3. Introduced a file watcher (hotwatch) that triggers site regeneration when changes are detected in input_folder.
  4. Modified the function to build the site on-the-fly when a change is detected.

Known Issues:

Currently, there are still some lifetime errors due to Rust's ownership system, specifically around borrowing input_folder. The error:

[E0373] closure may outlive the current function, but it borrows `input_folder`, which is owned by the current function.

Next Steps:

Feel free to review the implementation so far, and I’ll continue working on the remaining issues!

Checklist:

Related Issue : #34

rochacbruno commented 1 week ago

That's great @SkySingh04

There was a major refactor on the weekend, so now the code is better separated in modules.

The bad part is that you gonna need to rebase / resolve conflicts.

The good part is that you can now rely on site::generate(...) as the only function will need to respawn on changes.

rochacbruno commented 1 week ago

It looks like some tipe of Locking mechanism will be required

[2024-10-23T10:02:30Z INFO  marmite::site] Site generated at: /tmp/site/
[2024-10-23T10:02:30Z INFO  marmite::site] Watching for changes in folder: example
[2024-10-23T10:02:35Z INFO  marmite::site] Change detected. Rebuilding site...
[2024-10-23T10:02:35Z ERROR marmite::site] Error: Duplicate slug found: 'what-is-marmite-static-site-generator' - try setting any of `title`, `slug` as a unique text, or leave both empty so filename will be assumed.

The thread sleeps for one sec, and then another suddenly tries to rebuild using the shared site_data

I guess that, before rebuilding it is going to be needed to cleanup the site_data.posts and site_data.pages to an empty Vec::new()

Then apply some Mutex on the site_data

Initially

let site_data = Arc::new(Mutex::new(Data::new(config_str)));
let site_data_clone = Arc::clone(&site_data);

Then on the closure

let mut site_data = site_data.lock().unwrap();  // lock to prevent race condition.
site_data.posts = Vec::new();
site_data.pages = Vec::new();
collect_content(&content_dir, &mut site_data);
detect_slug_collision(&site_data);

// Sort posts by date (newest first)
site_data.posts.sort_by(|a, b| b.date.cmp(&a.date));
// Sort pages on title
site_data.pages.sort_by(|a, b| a.title.cmp(&b.title));

This change will probably spawn some adjusts on other places to get site_date.site out of the Arc.

BTW:

I added a justfile

cargo install just
just check # check for linting errors
just fix  # attempt to fix clippy problems
SkySingh04 commented 1 week ago

@rochacbruno Your requested changes have been made

rochacbruno commented 1 week ago

@SkySingh04 that's great, I executed cargo fmt and I will merge it and then the compatibility with --serve can come in another PR, is that ok?

rochacbruno commented 1 week ago

For the --serve to work I think I know what should be done, the loop with sleep must be replaced with a server::start when --serve is true.

SkySingh04 commented 1 week ago

Sure @rochacbruno , I can raise a PR for that as well ✅