mirror of
https://github.com/modrinth/code.git
synced 2026-08-30 11:36:05 +00:00
fix: show "inspecting modpack"
Shows when determining external files for modpacks which have many overrides/over gb of content files.
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
use crate::State;
|
||||
use crate::data::ModLoader;
|
||||
use crate::event::LoadingBarType;
|
||||
use crate::event::emit::{emit_loading, init_loading};
|
||||
use crate::install::{
|
||||
InstallErrorContext, InstallPhaseDetails, InstallPhaseId, InstallProgress,
|
||||
InstallProgressReporter,
|
||||
@@ -18,7 +20,7 @@ use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use std::future::Future;
|
||||
|
||||
use std::path::PathBuf;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::pin::Pin;
|
||||
|
||||
#[derive(Serialize, Deserialize, Eq, PartialEq)]
|
||||
@@ -153,6 +155,17 @@ pub struct CreatePack {
|
||||
|
||||
const MAX_LOCAL_FILE_HASH_LOOKUP_SIZE: u64 = 1024 * 1024 * 1024;
|
||||
|
||||
pub(crate) fn get_local_pack_instance(path: &Path) -> CreatePackInstance {
|
||||
CreatePackInstance {
|
||||
name: path
|
||||
.file_stem()
|
||||
.unwrap_or_default()
|
||||
.to_string_lossy()
|
||||
.to_string(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct CreatePackDescription {
|
||||
pub icon: Option<PathBuf>,
|
||||
@@ -182,11 +195,23 @@ pub async fn get_instance_from_pack(
|
||||
..Default::default()
|
||||
}),
|
||||
CreatePackLocation::FromFile { path } => {
|
||||
let file_name = path
|
||||
.file_stem()
|
||||
.unwrap_or_default()
|
||||
.to_string_lossy()
|
||||
.to_string();
|
||||
let mut instance = get_local_pack_instance(&path);
|
||||
let inspection = init_loading(
|
||||
LoadingBarType::PackImport {
|
||||
pack_name: instance.name.clone(),
|
||||
},
|
||||
100.0,
|
||||
"Inspecting modpack",
|
||||
)
|
||||
.await
|
||||
.ok();
|
||||
if let Some(inspection) = &inspection {
|
||||
let _ = emit_loading(
|
||||
inspection,
|
||||
1.0,
|
||||
Some("Reading local modpack"),
|
||||
);
|
||||
}
|
||||
|
||||
let is_known_file = if tokio::fs::metadata(&path).await?.len()
|
||||
<= MAX_LOCAL_FILE_HASH_LOOKUP_SIZE
|
||||
@@ -214,6 +239,13 @@ pub async fn get_instance_from_pack(
|
||||
} else {
|
||||
false
|
||||
};
|
||||
if let Some(inspection) = &inspection {
|
||||
let _ = emit_loading(
|
||||
inspection,
|
||||
39.0,
|
||||
Some("Inspecting modpack files"),
|
||||
);
|
||||
}
|
||||
|
||||
let external_files_in_modpack =
|
||||
super::install_mrpack::get_external_files_from_mrpack(
|
||||
@@ -221,12 +253,9 @@ pub async fn get_instance_from_pack(
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(CreatePackInstance {
|
||||
name: file_name,
|
||||
unknown_file: !is_known_file,
|
||||
external_files_in_modpack,
|
||||
..Default::default()
|
||||
})
|
||||
instance.unknown_file = !is_known_file;
|
||||
instance.external_files_in_modpack = external_files_in_modpack;
|
||||
Ok(instance)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,6 +157,9 @@ pub enum LoadingBarType {
|
||||
pack_id: Option<String>,
|
||||
pack_version: Option<String>,
|
||||
},
|
||||
PackImport {
|
||||
pack_name: String,
|
||||
},
|
||||
MinecraftDownload {
|
||||
instance_id: String,
|
||||
instance_name: String,
|
||||
|
||||
@@ -16,6 +16,7 @@ use crate::ErrorKind;
|
||||
use crate::api::pack::install_from::{
|
||||
CreatePackLocation, generate_pack_from_file,
|
||||
generate_pack_from_version_id_with_reporter, get_instance_from_pack,
|
||||
get_local_pack_instance,
|
||||
};
|
||||
use crate::api::pack::install_mrpack::install_zipped_mrpack_files_with_reporter;
|
||||
use crate::event::InstancePayloadType;
|
||||
@@ -163,16 +164,6 @@ pub async fn retry_job(job_id: Uuid) -> crate::Result<InstallJobSnapshot> {
|
||||
job.state.progress.phase = InstallPhaseId::PreparingInstance;
|
||||
job.state.progress.progress = None;
|
||||
job.state.progress.details = InstallPhaseDetails::Empty;
|
||||
if let Err(error) = prepare_initial_instance(&mut job.state, &state).await {
|
||||
if let Err(cleanup_error) =
|
||||
recovery::apply_cleanup(&job.state, &state).await
|
||||
{
|
||||
tracing::error!(
|
||||
"Error cleaning up install job {job_id} retry preparation: {cleanup_error}"
|
||||
);
|
||||
}
|
||||
return Err(error);
|
||||
}
|
||||
job.state.record_event(InstallJobEventKind::JobQueued {
|
||||
kind: job.state.request.kind(),
|
||||
});
|
||||
@@ -197,6 +188,42 @@ pub async fn retry_job(job_id: Uuid) -> crate::Result<InstallJobSnapshot> {
|
||||
return Err(error);
|
||||
}
|
||||
};
|
||||
emit_install_job(&record.snapshot()).await?;
|
||||
|
||||
if let Err(error) = prepare_initial_instance(&mut job.state, &state).await {
|
||||
let error_view = install_error_view(
|
||||
job.state.progress.phase,
|
||||
&error,
|
||||
job.state.context.clone(),
|
||||
);
|
||||
if let Err(terminal_error) =
|
||||
terminalize_failed_job(job_id, job.state, error_view, &state).await
|
||||
{
|
||||
tracing::error!(
|
||||
"Failed to terminalize retried install job {job_id}: {terminal_error}"
|
||||
);
|
||||
}
|
||||
return Err(error);
|
||||
}
|
||||
let record = match store::update_state(job_id, &job.state, &state).await {
|
||||
Ok(record) => record,
|
||||
Err(error) => {
|
||||
let error_view = install_error_view(
|
||||
job.state.progress.phase,
|
||||
&error,
|
||||
job.state.context.clone(),
|
||||
);
|
||||
if let Err(terminal_error) =
|
||||
terminalize_failed_job(job_id, job.state, error_view, &state)
|
||||
.await
|
||||
{
|
||||
tracing::error!(
|
||||
"Failed to terminalize retried install job {job_id}: {terminal_error}"
|
||||
);
|
||||
}
|
||||
return Err(error);
|
||||
}
|
||||
};
|
||||
if let Err(error) =
|
||||
lock_existing_instance_if_needed(&job.state, &state).await
|
||||
{
|
||||
@@ -337,31 +364,39 @@ async fn start(request: InstallRequest) -> crate::Result<InstallJobSnapshot> {
|
||||
let state = State::get().await?;
|
||||
let id = Uuid::new_v4();
|
||||
let mut job_state = InstallJobState::new(request);
|
||||
set_initial_display(&mut job_state);
|
||||
let record =
|
||||
store::insert(id, &job_state, InstallJobStatus::Queued, &state).await?;
|
||||
emit_install_job(&record.snapshot()).await?;
|
||||
|
||||
if let Err(error) = prepare_initial_instance(&mut job_state, &state).await {
|
||||
if let Err(cleanup_error) =
|
||||
recovery::apply_cleanup(&job_state, &state).await
|
||||
let error_view = install_error_view(
|
||||
job_state.progress.phase,
|
||||
&error,
|
||||
job_state.context.clone(),
|
||||
);
|
||||
if let Err(terminal_error) =
|
||||
terminalize_failed_job(id, job_state, error_view, &state).await
|
||||
{
|
||||
tracing::error!(
|
||||
"Error cleaning up install job preparation: {cleanup_error}"
|
||||
"Failed to terminalize install job {id} after setup error: {terminal_error}"
|
||||
);
|
||||
}
|
||||
return Err(error);
|
||||
}
|
||||
let record = match store::insert(
|
||||
id,
|
||||
&job_state,
|
||||
InstallJobStatus::Queued,
|
||||
&state,
|
||||
)
|
||||
.await
|
||||
{
|
||||
let record = match store::update_state(id, &job_state, &state).await {
|
||||
Ok(record) => record,
|
||||
Err(error) => {
|
||||
if let Err(cleanup_error) =
|
||||
recovery::apply_cleanup(&job_state, &state).await
|
||||
let error_view = install_error_view(
|
||||
job_state.progress.phase,
|
||||
&error,
|
||||
job_state.context.clone(),
|
||||
);
|
||||
if let Err(terminal_error) =
|
||||
terminalize_failed_job(id, job_state, error_view, &state).await
|
||||
{
|
||||
tracing::error!(
|
||||
"Error cleaning up untracked install job {id}: {cleanup_error}"
|
||||
"Failed to terminalize install job {id} after setup error: {terminal_error}"
|
||||
);
|
||||
}
|
||||
return Err(error);
|
||||
@@ -422,7 +457,12 @@ async fn prepare_initial_instance(
|
||||
location,
|
||||
post_install_edit,
|
||||
} => {
|
||||
let preview = get_instance_from_pack(location).await?;
|
||||
let preview = match location {
|
||||
CreatePackLocation::FromFile { path } => {
|
||||
get_local_pack_instance(&path)
|
||||
}
|
||||
location => get_instance_from_pack(location).await?,
|
||||
};
|
||||
let name = post_install_edit
|
||||
.as_ref()
|
||||
.and_then(|edit| edit.name.clone())
|
||||
@@ -1443,6 +1483,26 @@ fn set_display(
|
||||
job_state.display = Some(InstallJobDisplay { title, icon });
|
||||
}
|
||||
|
||||
fn set_initial_display(job_state: &mut InstallJobState) {
|
||||
let display = match &job_state.request {
|
||||
InstallRequest::CreateModpackInstance { location, .. } => {
|
||||
match location {
|
||||
CreatePackLocation::FromVersionId {
|
||||
title, icon_url, ..
|
||||
} => Some((title.clone(), icon_url.clone())),
|
||||
CreatePackLocation::FromFile { path } => {
|
||||
Some((get_local_pack_instance(path).name, None))
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
|
||||
if let Some((title, icon)) = display {
|
||||
set_display(job_state, title, icon);
|
||||
}
|
||||
}
|
||||
|
||||
fn install_error_view(
|
||||
phase: InstallPhaseId,
|
||||
error: &crate::Error,
|
||||
|
||||
Reference in New Issue
Block a user