fix: align rendering process with bds2

This commit is contained in:
2026-07-24 06:22:45 +02:00
parent 28119c15b7
commit 473c48937d
15 changed files with 1022 additions and 581 deletions

View File

@@ -149,6 +149,7 @@ impl BdsApp {
);
let mut render_task_ids = Vec::new();
let mut tasks = Vec::new();
let prepared_generation = Arc::new(std::sync::OnceLock::new());
for section in sections {
let label = t(self.ui_locale, generation_section_label_key(section));
@@ -173,6 +174,7 @@ impl BdsApp {
let task_data_dir = data_dir.clone();
let task_group_id = group_id.clone();
let task_validation = validation.clone();
let task_prepared_generation = Arc::clone(&prepared_generation);
let locale = self.ui_locale;
tasks.push(Task::perform(
async move {
@@ -185,6 +187,7 @@ impl BdsApp {
task_id,
section,
task_validation,
task_prepared_generation,
force,
locale,
page_work,
@@ -494,6 +497,9 @@ fn run_site_generation_section(
task_id: TaskId,
section: engine::generation::GenerationSection,
validation: Option<engine::validate_site::SiteValidationReport>,
prepared_generation: Arc<
std::sync::OnceLock<Result<Arc<engine::generation::PreparedSiteGeneration>, String>>,
>,
force: bool,
locale: UiLocale,
expected_pages: usize,
@@ -511,23 +517,33 @@ fn run_site_generation_section(
)),
);
let db = Database::open(&db_path).map_err(|error| error.to_string())?;
let metadata = engine::meta::read_project_json(&data_dir).map_err(|error| error.to_string())?;
let posts = bds_core::db::queries::post::list_posts_by_project(db.conn(), &project_id)
.map_err(|error| error.to_string())?;
let mut sources = Vec::new();
for post in posts
.into_iter()
.filter(engine::generation::has_published_snapshot)
{
if task_manager.is_cancelled(task_id) {
return Err("cancelled".to_string());
}
if let Some(source) = engine::generation::load_published_post_source(&data_dir, post)
.map_err(|error| error.to_string())?
{
sources.push(source);
}
}
let prepared = prepared_generation
.get_or_init(|| {
let metadata =
engine::meta::read_project_json(&data_dir).map_err(|error| error.to_string())?;
let posts = bds_core::db::queries::post::list_posts_by_project(db.conn(), &project_id)
.map_err(|error| error.to_string())?;
let sources = posts
.into_iter()
.filter(engine::generation::has_published_snapshot)
.map(|post| engine::generation::load_published_post_source(&data_dir, post))
.collect::<Result<Vec<_>, _>>()
.map_err(|error| error.to_string())?
.into_iter()
.flatten()
.collect::<Vec<_>>();
engine::generation::prepare_site_generation(
db.conn(),
&data_dir,
&project_id,
&metadata,
&sources,
)
.map(Arc::new)
.map_err(|error| error.to_string())
})
.as_ref()
.map_err(Clone::clone)?;
let output_dir = data_dir.join("html");
std::fs::create_dir_all(&output_dir).map_err(|error| error.to_string())?;
let render_manager = Arc::clone(&task_manager);
@@ -558,38 +574,26 @@ fn run_site_generation_section(
};
let is_cancelled = move || cancel_manager.is_cancelled(task_id);
match validation {
Some(validation) => engine::generation::apply_validation_section_with_progress(
Some(validation) => engine::generation::apply_validation_prepared_section_with_progress(
db.conn(),
&output_dir,
&project_id,
&metadata,
&sources,
prepared,
&validation,
section,
on_page,
on_rendered,
&on_rendered,
is_cancelled,
),
None if force => engine::generation::render_site_section_forced_with_progress(
None => engine::generation::render_prepared_site_section_with_progress(
db.conn(),
&output_dir,
&project_id,
&metadata,
&sources,
prepared,
section,
force,
&on_rendered,
on_page,
on_rendered,
is_cancelled,
),
None => engine::generation::render_site_section_with_progress(
db.conn(),
&output_dir,
&project_id,
&metadata,
&sources,
section,
on_page,
on_rendered,
is_cancelled,
),
}

View File

@@ -112,33 +112,6 @@ fn close_btn_style(_theme: &Theme, status: button::Status) -> button::Style {
}
}
#[cfg(test)]
mod progress_tests {
use super::*;
#[test]
fn group_progress_includes_pending_tasks_as_zero_like_bds2() {
let complete = TaskSnapshot {
id: 1,
label: String::new(),
group_id: None,
group_name: None,
status: String::new(),
progress: Some(1.0),
message: None,
is_cancellable: false,
};
let pending = TaskSnapshot {
id: 2,
progress: None,
is_cancellable: true,
..complete.clone()
};
assert_eq!(group_progress(&[&complete, &pending]), Some(0.5));
}
}
#[expect(
clippy::too_many_arguments,
reason = "arguments are independent panel state slices"
@@ -459,3 +432,30 @@ fn post_link_button(locale: UiLocale, link: &ResolvedPostLink) -> Element<'stati
.style(tab_inactive)
.into()
}
#[cfg(test)]
mod progress_tests {
use super::*;
#[test]
fn group_progress_includes_pending_tasks_as_zero_like_bds2() {
let complete = TaskSnapshot {
id: 1,
label: String::new(),
group_id: None,
group_name: None,
status: String::new(),
progress: Some(1.0),
message: None,
is_cancellable: false,
};
let pending = TaskSnapshot {
id: 2,
progress: None,
is_cancellable: true,
..complete.clone()
};
assert_eq!(group_progress(&[&complete, &pending]), Some(0.5));
}
}