Add live CLI progress for long-running jobs
This commit is contained in:
@@ -182,18 +182,31 @@ pub fn generate_starter_site_forced(
|
||||
posts: &[PublishedPostSource],
|
||||
language: &str,
|
||||
) -> EngineResult<GenerationReport> {
|
||||
generate_starter_site_with_progress_mode(
|
||||
generate_starter_site_forced_with_progress(
|
||||
conn,
|
||||
output_dir,
|
||||
project_id,
|
||||
metadata,
|
||||
posts,
|
||||
language,
|
||||
true,
|
||||
|_current, _total, _path| {},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn generate_starter_site_forced_with_progress(
|
||||
conn: &Connection,
|
||||
output_dir: &Path,
|
||||
project_id: &str,
|
||||
metadata: &ProjectMetadata,
|
||||
posts: &[PublishedPostSource],
|
||||
language: &str,
|
||||
on_page: impl FnMut(usize, usize, &str),
|
||||
) -> EngineResult<GenerationReport> {
|
||||
generate_starter_site_with_progress_mode(
|
||||
conn, output_dir, project_id, metadata, posts, language, true, on_page,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn generate_starter_site_with_progress(
|
||||
conn: &Connection,
|
||||
output_dir: &Path,
|
||||
@@ -224,8 +237,17 @@ fn generate_starter_site_with_progress_mode(
|
||||
) -> EngineResult<GenerationReport> {
|
||||
let data_dir = project_data_dir(output_dir);
|
||||
let prepared = prepare_site_generation(conn, &data_dir, project_id, metadata, posts)?;
|
||||
let total_pages = GenerationSection::ALL
|
||||
.into_iter()
|
||||
.map(|section| prepared_section_page_count(&prepared, None, section))
|
||||
.sum();
|
||||
let mut current_page = 0;
|
||||
let mut report = GenerationReport::default();
|
||||
for section in GenerationSection::ALL {
|
||||
let mut on_section_page = |_current, _total, path: &str| {
|
||||
current_page += 1;
|
||||
on_page(current_page, total_pages, path);
|
||||
};
|
||||
report.append(render_prepared_site_section_with_progress(
|
||||
conn,
|
||||
output_dir,
|
||||
@@ -234,7 +256,7 @@ fn generate_starter_site_with_progress_mode(
|
||||
section,
|
||||
force,
|
||||
&|_| {},
|
||||
&mut on_page,
|
||||
&mut on_section_page,
|
||||
|| false,
|
||||
)?);
|
||||
}
|
||||
@@ -446,25 +468,61 @@ pub fn apply_validation_sections(
|
||||
posts: &[PublishedPostSource],
|
||||
validation: &SiteValidationReport,
|
||||
sections: &[GenerationSection],
|
||||
) -> EngineResult<GenerationReport> {
|
||||
apply_validation_sections_with_progress(
|
||||
conn,
|
||||
output_dir,
|
||||
project_id,
|
||||
metadata,
|
||||
posts,
|
||||
validation,
|
||||
sections,
|
||||
|_current, _total, _url| {},
|
||||
)
|
||||
}
|
||||
|
||||
#[expect(
|
||||
clippy::too_many_arguments,
|
||||
reason = "validation application adds progress to the existing generation context"
|
||||
)]
|
||||
pub fn apply_validation_sections_with_progress(
|
||||
conn: &Connection,
|
||||
output_dir: &Path,
|
||||
project_id: &str,
|
||||
metadata: &ProjectMetadata,
|
||||
posts: &[PublishedPostSource],
|
||||
validation: &SiteValidationReport,
|
||||
sections: &[GenerationSection],
|
||||
mut on_page: impl FnMut(usize, usize, &str),
|
||||
) -> EngineResult<GenerationReport> {
|
||||
if sections.is_empty() {
|
||||
return Ok(GenerationReport::default());
|
||||
}
|
||||
|
||||
let data_dir = project_data_dir(output_dir);
|
||||
let prepared = prepare_site_generation(conn, &data_dir, project_id, metadata, posts)?;
|
||||
let total_pages = sections
|
||||
.iter()
|
||||
.map(|section| prepared_section_page_count(&prepared, Some(validation), *section))
|
||||
.sum();
|
||||
let mut current_page = 0;
|
||||
let mut report = GenerationReport::default();
|
||||
|
||||
for section in sections {
|
||||
report.append(apply_validation_section_with_progress(
|
||||
let mut on_section_page = |_current, _total, url: &str| {
|
||||
current_page += 1;
|
||||
on_page(current_page, total_pages, url);
|
||||
};
|
||||
report.append(apply_validation_prepared_section_with_progress(
|
||||
conn,
|
||||
output_dir,
|
||||
project_id,
|
||||
metadata,
|
||||
posts,
|
||||
&prepared,
|
||||
validation,
|
||||
*section,
|
||||
|_current, _total, _url| {},
|
||||
|_| {},
|
||||
|| false,
|
||||
&mut on_section_page,
|
||||
&|_| {},
|
||||
&mut || false,
|
||||
)?);
|
||||
}
|
||||
report.append(build_site_search_index(
|
||||
|
||||
@@ -45,12 +45,33 @@ pub fn rebuild_incremental(
|
||||
data_dir: &Path,
|
||||
project_id: &str,
|
||||
) -> EngineResult<IncrementalRebuildReport> {
|
||||
let report = super::metadata_diff::compute_metadata_diff(conn, data_dir, project_id)?;
|
||||
rebuild_incremental_with_progress(conn, data_dir, project_id, |_| true)
|
||||
}
|
||||
|
||||
pub fn rebuild_incremental_with_progress(
|
||||
conn: &Connection,
|
||||
data_dir: &Path,
|
||||
project_id: &str,
|
||||
mut on_progress: impl FnMut(f32) -> bool,
|
||||
) -> EngineResult<IncrementalRebuildReport> {
|
||||
let report = super::metadata_diff::compute_metadata_diff_with_progress(
|
||||
conn,
|
||||
data_dir,
|
||||
project_id,
|
||||
|current, total| on_progress(0.5 * current as f32 / total.max(1) as f32),
|
||||
)?;
|
||||
if !report.errors.is_empty() {
|
||||
return Err(crate::engine::EngineError::Validation(
|
||||
report.errors.join("; "),
|
||||
));
|
||||
}
|
||||
let orphans = report
|
||||
.orphans
|
||||
.iter()
|
||||
.filter(|orphan| orphan.reason == "file_without_db_entry")
|
||||
.collect::<Vec<_>>();
|
||||
let total = report.diffs.len() + orphans.len();
|
||||
let mut current = 0;
|
||||
for item in &report.diffs {
|
||||
super::metadata_diff::repair_metadata_diff_item(
|
||||
conn,
|
||||
@@ -59,20 +80,27 @@ pub fn rebuild_incremental(
|
||||
super::metadata_diff::RepairDirection::FileToDatabase,
|
||||
item,
|
||||
)?;
|
||||
current += 1;
|
||||
if !on_progress(0.5 + 0.5 * current as f32 / total.max(1) as f32) {
|
||||
return Err(crate::engine::EngineError::Cancelled);
|
||||
}
|
||||
}
|
||||
let mut result = IncrementalRebuildReport {
|
||||
differences_applied: report.diffs.len(),
|
||||
..Default::default()
|
||||
};
|
||||
for orphan in report
|
||||
.orphans
|
||||
.iter()
|
||||
.filter(|orphan| orphan.reason == "file_without_db_entry")
|
||||
{
|
||||
for orphan in orphans {
|
||||
match super::metadata_diff::import_orphan_file(conn, data_dir, project_id, orphan) {
|
||||
Ok(()) => result.orphans_imported += 1,
|
||||
Err(_) => result.orphans_failed += 1,
|
||||
}
|
||||
current += 1;
|
||||
if !on_progress(0.5 + 0.5 * current as f32 / total.max(1) as f32) {
|
||||
return Err(crate::engine::EngineError::Cancelled);
|
||||
}
|
||||
}
|
||||
if total == 0 && !on_progress(1.0) {
|
||||
return Err(crate::engine::EngineError::Cancelled);
|
||||
}
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user