use super::{Loading, STORAGE_DIR, action::StorageAction, git::Git};
use crate::action::UiAction;
use std::sync::atomic::{AtomicUsize, Ordering::Relaxed};
static DONE: AtomicUsize = AtomicUsize::new(0);
static TOTAL: AtomicUsize = AtomicUsize::new(0);
pub(crate) fn progress() -> Option<(usize, usize)> {
let total = TOTAL.load(Relaxed);
(super::loading() == Loading::Migrating && total > 0).then(|| (DONE.load(Relaxed), total))
}
pub(super) fn run(git: &mut Git) {
let pending = gled_migrate::pending(&STORAGE_DIR);
if pending.is_empty() {
return;
}
tracing::info!("Migrating {} asset files", pending.len());
DONE.store(0, Relaxed);
TOTAL.store(pending.len(), Relaxed);
Loading::Migrating.set();
let migration = gled_migrate::migrate(&STORAGE_DIR, &pending, |progress| {
tracing::debug!("{} ({}/{})", progress.task, progress.done, progress.total);
DONE.store(progress.done, Relaxed);
});
for error in migration.errors {
tracing::error!("Could not migrate {error}");
UiAction::Error(format!("Could not migrate {error}")).enqueue();
}
if !migration.missing_pictures.is_empty() {
let pictures: Vec<String> = migration
.missing_pictures
.iter()
.map(|path| path.display().to_string())
.collect();
let message = format!(
"These pictures are neither in the asset repository nor on this machine, so \
they stay missing: {}",
pictures.join(", ")
);
tracing::warn!("{message}");
UiAction::Error(message).enqueue();
}
let wrote_any = !migration.written.is_empty();
for file in migration.written {
if let Err(err) = git.write_asset(&file.path, file.contents) {
UiAction::Error(format!("Could not write migrated asset: {err}")).enqueue();
}
}
if wrote_any {
super::files::write_storage_version_file(git);
}
StorageAction::CountStagedFiles.enqueue();
TOTAL.store(0, Relaxed);
}