|
|
|
@ -15,6 +15,7 @@
@@ -15,6 +15,7 @@
|
|
|
|
|
#include <ranges> |
|
|
|
|
#include <stack> |
|
|
|
|
#include <map> |
|
|
|
|
#include <thread> |
|
|
|
|
|
|
|
|
|
#include <json.hpp> |
|
|
|
|
#include <date.h> |
|
|
|
@ -98,6 +99,9 @@ class builder {
@@ -98,6 +99,9 @@ class builder {
|
|
|
|
|
std::map<std::string, std::string> properties; |
|
|
|
|
templater *templr; |
|
|
|
|
|
|
|
|
|
std::map<fs::path, time_t> last_build; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const std::set<std::string> apply_templates_exts {"md","html", "txt", "markdown", "xml", "atom", "rss"}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -438,6 +442,7 @@ class builder {
@@ -438,6 +442,7 @@ class builder {
|
|
|
|
|
{new rss_feed_plugin{}, new microblog_plugin{}}); |
|
|
|
|
|
|
|
|
|
add_default_templates(); |
|
|
|
|
update_file_dates(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
~builder() {delete templr;} |
|
|
|
@ -463,11 +468,13 @@ class builder {
@@ -463,11 +468,13 @@ class builder {
|
|
|
|
|
void |
|
|
|
|
write_build(std::map<fs::path, blog_item> &compile_jobs)
|
|
|
|
|
{ |
|
|
|
|
time_t now = to_time_t(std::chrono::system_clock::now()); |
|
|
|
|
|
|
|
|
|
// make directory structure
|
|
|
|
|
for (auto &e: compile_jobs) { |
|
|
|
|
if (job_type::MAKE_DIR & e.second.type) { |
|
|
|
|
fs::create_directories(e.first); |
|
|
|
|
last_build[e.second.src] = now; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -477,6 +484,7 @@ class builder {
@@ -477,6 +484,7 @@ class builder {
|
|
|
|
|
auto dest = e.first; |
|
|
|
|
if (job_type::COPY_FILE & e.second.type) { |
|
|
|
|
fs::copy(src, dest, fs::copy_options::update_existing);
|
|
|
|
|
last_build[e.second.src] = now; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (job_type::DELETE_FILE & e.second.type) { |
|
|
|
@ -497,17 +505,17 @@ class builder {
@@ -497,17 +505,17 @@ class builder {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (auto &e: compile_jobs) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (auto &e: compile_jobs) { |
|
|
|
|
if ((job_type::MARKDOWN | job_type::TEMPLATE) & e.second.type) { |
|
|
|
|
write_file(e.first.string(), e.second.properties.at("body")); |
|
|
|
|
last_build[e.second.src] = now; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
build()
|
|
|
|
|
{ |
|
|
|
@ -560,7 +568,58 @@ class builder {
@@ -560,7 +568,58 @@ class builder {
|
|
|
|
|
// stage 2 build
|
|
|
|
|
|
|
|
|
|
write_build(compile_jobs); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void update_file_dates() { |
|
|
|
|
for (auto e = fs::recursive_directory_iterator(properties.at("source_root")); |
|
|
|
|
e != fs::recursive_directory_iterator(); |
|
|
|
|
++e) |
|
|
|
|
{ |
|
|
|
|
// skip hidden files
|
|
|
|
|
std::string filename = e->path().filename().string(); |
|
|
|
|
if (filename.length() > 0 && filename.at(0) == '.') { |
|
|
|
|
e.disable_recursion_pending(); |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
time_t last_modification = to_time_t(fs::last_write_time(e->path())); |
|
|
|
|
last_build[e->path()] = last_modification;
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void rebuild_if_newer() { |
|
|
|
|
bool rebuild = false; |
|
|
|
|
// for (auto &e: fs::directory_iterator(properties.at("source_root"))) {
|
|
|
|
|
for (auto e = fs::recursive_directory_iterator(properties.at("source_root")); |
|
|
|
|
e != fs::recursive_directory_iterator(); |
|
|
|
|
++e) |
|
|
|
|
{ |
|
|
|
|
// skip hidden files
|
|
|
|
|
std::string filename = e->path().filename().string(); |
|
|
|
|
if (filename.length() > 0 && filename.at(0) == '.') { |
|
|
|
|
e.disable_recursion_pending(); |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (this->last_build.count(e->path())) { |
|
|
|
|
|
|
|
|
|
time_t last_modification = to_time_t(fs::last_write_time(e->path())); |
|
|
|
|
|
|
|
|
|
if (std::difftime(last_modification, last_build.at(e->path())) > 0) { |
|
|
|
|
rebuild = true; |
|
|
|
|
spdlog::info("Rebuilding with updated file: {}", e->path().string()); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} else { |
|
|
|
|
rebuild = true; |
|
|
|
|
spdlog::info("Rebuilding with new file: {}", e->path().string()); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (rebuild) |
|
|
|
|
build(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void dump_stgen_json() { |
|
|
|
@ -771,9 +830,9 @@ int main(int argc, char **argv) {
@@ -771,9 +830,9 @@ int main(int argc, char **argv) {
|
|
|
|
|
* compiled in rather than fork and exec'd |
|
|
|
|
*/ |
|
|
|
|
while (continue_running) { |
|
|
|
|
b.build(); |
|
|
|
|
spdlog::info("Built site."); |
|
|
|
|
sleep(5); |
|
|
|
|
b.rebuild_if_newer(); |
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(200)); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
s.stop_serving(); |
|
|
|
|
}
|
|
|
|
|