Migrate to SQLite for Internal Launcher Data (#1300)

* initial migration

* barebones profiles

* Finish profiles

* Add back file watcher

* UI support progress

* Finish most of cache

* Fix options page

* Fix forge, finish modrinth auth

* Accounts, process cache

* Run SQLX prepare

* Finish

* Run lint + actions

* Fix version to be compat with windows

* fix lint

* actually fix lint

* actually fix lint again
This commit is contained in:
Geometrically
2024-07-24 11:03:19 -07:00
committed by GitHub
parent 90f74427d9
commit 49a20a303a
156 changed files with 9208 additions and 8547 deletions

View File

@@ -1,24 +1,24 @@
use crate::state::CacheBehaviour;
use crate::{
event::{
emit::{emit_profile, init_loading, loading_try_for_each_concurrent},
emit::{emit_profile, init_loading},
ProfilePayloadType,
},
pack::{self, install_from::generate_pack_from_version_id},
prelude::{ProfilePathId, ProjectPathId},
profile::get,
state::{ProfileInstallStage, Project},
LoadingBarType, State,
state::ProfileInstallStage,
LoadingBarType,
};
use futures::try_join;
/// Updates a managed modrinth pack to the version specified by new_version_id
#[tracing::instrument]
#[theseus_macros::debug_pin]
pub async fn update_managed_modrinth_version(
profile_path: &ProfilePathId,
profile_path: &String,
new_version_id: &String,
) -> crate::Result<()> {
let profile = get(profile_path, None).await?.ok_or_else(|| {
let profile = get(profile_path).await?.ok_or_else(|| {
crate::ErrorKind::UnmanagedProfileError(profile_path.to_string())
.as_error()
})?;
@@ -30,46 +30,29 @@ pub async fn update_managed_modrinth_version(
};
// Extract modrinth pack information, if appropriate
let linked_data = profile
.metadata
.linked_data
.as_ref()
.ok_or_else(unmanaged_err)?;
let project_id: &String =
linked_data.project_id.as_ref().ok_or_else(unmanaged_err)?;
let version_id =
linked_data.version_id.as_ref().ok_or_else(unmanaged_err)?;
let linked_data = profile.linked_data.as_ref().ok_or_else(unmanaged_err)?;
// Replace the pack with the new version
replace_managed_modrinth(
profile_path,
&profile,
project_id,
version_id,
&linked_data.project_id,
&linked_data.version_id,
Some(new_version_id),
true, // switching versions should ignore the lock
)
.await?;
emit_profile(
profile.uuid,
profile_path,
&profile.metadata.name,
ProfilePayloadType::Edited,
)
.await?;
emit_profile(profile_path, ProfilePayloadType::Edited).await?;
State::sync().await?;
Ok(())
}
/// Repair a managed modrinth pack by 'updating' it to the current version
#[tracing::instrument]
#[theseus_macros::debug_pin]
pub async fn repair_managed_modrinth(
profile_path: &ProfilePathId,
) -> crate::Result<()> {
let profile = get(profile_path, None).await?.ok_or_else(|| {
pub async fn repair_managed_modrinth(profile_path: &str) -> crate::Result<()> {
let profile = get(profile_path).await?.ok_or_else(|| {
crate::ErrorKind::UnmanagedProfileError(profile_path.to_string())
.as_error()
})?;
@@ -83,69 +66,44 @@ pub async fn repair_managed_modrinth(
// For repairing specifically, first we remove all installed projects (to ensure we do remove ones that aren't in the pack)
// We do a project removal followed by removing everything in the .mrpack, to ensure we only
// remove relevant projects and not things like save files
let projects_map = profile.projects.clone();
let stream = futures::stream::iter(
projects_map
.into_iter()
.map(Ok::<(ProjectPathId, Project), crate::Error>),
);
loading_try_for_each_concurrent(
stream,
None,
None,
0.0,
0,
None,
|(project_id, _)| {
let profile = profile.clone();
async move {
profile.remove_project(&project_id, Some(true)).await?;
Ok(())
}
},
)
.await?;
let state = crate::State::get().await?;
let projects_map = profile
.get_projects(
Some(CacheBehaviour::MustRevalidate),
&state.pool,
&state.api_semaphore,
)
.await?;
for (file, _) in projects_map {
crate::state::Profile::remove_project(&profile.path, &file).await?;
}
// Extract modrinth pack information, if appropriate
let linked_data = profile
.metadata
.linked_data
.as_ref()
.ok_or_else(unmanaged_err)?;
let project_id: &String =
linked_data.project_id.as_ref().ok_or_else(unmanaged_err)?;
let version_id =
linked_data.version_id.as_ref().ok_or_else(unmanaged_err)?;
let linked_data = profile.linked_data.as_ref().ok_or_else(unmanaged_err)?;
// Replace the pack with the same version
replace_managed_modrinth(
profile_path,
&profile,
project_id,
version_id,
&linked_data.project_id,
&linked_data.version_id,
None,
false, // do not ignore lock, as repairing can reset the lock
)
.await?;
emit_profile(
profile.uuid,
profile_path,
&profile.metadata.name,
ProfilePayloadType::Edited,
)
.await?;
emit_profile(profile_path, ProfilePayloadType::Edited).await?;
State::sync().await?;
Ok(())
}
/// Replace a managed modrinth pack with a new version
/// If new_version_id is None, the pack is 'reinstalled' in-place
#[tracing::instrument(skip(profile))]
#[theseus_macros::debug_pin]
async fn replace_managed_modrinth(
profile_path: &ProfilePathId,
profile_path: &str,
profile: &crate::state::Profile,
project_id: &String,
version_id: &String,
@@ -161,59 +119,63 @@ async fn replace_managed_modrinth(
// Fetch .mrpacks for both old and new versions
// TODO: this will need to be updated if we revert the hacky pack method we needed for compiler speed
let (old_pack_creator, new_pack_creator) =
if let Some(new_version_id) = new_version_id {
let shared_loading_bar = init_loading(
LoadingBarType::PackFileDownload {
profile_path: profile_path.get_full_path().await?,
pack_name: profile.metadata.name.clone(),
icon: None,
pack_version: version_id.clone(),
},
200.0, // These two downloads will share the same loading bar
"Downloading pack file",
)
.await?;
let (old_pack_creator, new_pack_creator) = if let Some(new_version_id) =
new_version_id
{
let shared_loading_bar = init_loading(
LoadingBarType::PackFileDownload {
profile_path: crate::api::profile::get_full_path(profile_path)
.await?
.to_string_lossy()
.to_string(),
pack_name: profile.name.clone(),
icon: None,
pack_version: version_id.clone(),
},
200.0, // These two downloads will share the same loading bar
"Downloading pack file",
)
.await?;
// download in parallel, then join.
try_join!(
generate_pack_from_version_id(
project_id.clone(),
version_id.clone(),
profile.metadata.name.clone(),
None,
profile_path.clone(),
Some(shared_loading_bar.clone())
),
generate_pack_from_version_id(
project_id.clone(),
new_version_id.clone(),
profile.metadata.name.clone(),
None,
profile_path.clone(),
Some(shared_loading_bar)
)
)?
} else {
// If new_version_id is None, we don't need to download the new pack, so we clone the old one
let mut old_pack_creator = generate_pack_from_version_id(
// download in parallel, then join.
try_join!(
generate_pack_from_version_id(
project_id.clone(),
version_id.clone(),
profile.metadata.name.clone(),
profile.name.clone(),
None,
profile_path.clone(),
profile_path.to_string(),
Some(shared_loading_bar.clone())
),
generate_pack_from_version_id(
project_id.clone(),
new_version_id.clone(),
profile.name.clone(),
None,
profile_path.to_string(),
Some(shared_loading_bar)
)
.await?;
old_pack_creator.description.existing_loading_bar = None;
(old_pack_creator.clone(), old_pack_creator)
};
)?
} else {
// If new_version_id is None, we don't need to download the new pack, so we clone the old one
let mut old_pack_creator = generate_pack_from_version_id(
project_id.clone(),
version_id.clone(),
profile.name.clone(),
None,
profile_path.to_string(),
None,
)
.await?;
old_pack_creator.description.existing_loading_bar = None;
(old_pack_creator.clone(), old_pack_creator)
};
// Removal - remove all files that were added by the old pack
// - remove all installed projects
// - remove all overrides
pack::install_mrpack::remove_all_related_files(
profile_path.clone(),
profile_path.to_string(),
old_pack_creator.file,
)
.await?;