mirror of
https://github.com/modrinth/code.git
synced 2026-08-25 09:04:55 +00:00
feat: support supplementary environment variables for hooks in App (#5916)
* feat: Implement launcher supplementary environmental variables, and env var substitution in hooks * lint fix, prettier reformat * descriptions added for each environment variable for hook settings * alphabetize language keys --------- Co-authored-by: Prospector <6166773+Prospector@users.noreply.github.com>
This commit is contained in:
@@ -79,15 +79,95 @@ async fn run_credentials(
|
||||
.into());
|
||||
}
|
||||
|
||||
let pre_launch_hooks = context
|
||||
let pre_launch_hook = context
|
||||
.launch_overrides
|
||||
.hooks
|
||||
.pre_launch
|
||||
.as_ref()
|
||||
.or(settings.hooks.pre_launch.as_ref())
|
||||
.filter(|hook_command| !hook_command.is_empty());
|
||||
if let Some(hook) = pre_launch_hooks {
|
||||
let mut cmd = shlex::split(hook)
|
||||
|
||||
let java_args = context
|
||||
.launch_overrides
|
||||
.extra_launch_args
|
||||
.clone()
|
||||
.unwrap_or(settings.extra_launch_args);
|
||||
|
||||
let wrapper = context
|
||||
.launch_overrides
|
||||
.hooks
|
||||
.wrapper
|
||||
.clone()
|
||||
.or(settings.hooks.wrapper)
|
||||
.filter(|hook_command| !hook_command.is_empty());
|
||||
|
||||
let env_args = context
|
||||
.launch_overrides
|
||||
.custom_env_vars
|
||||
.clone()
|
||||
.unwrap_or(settings.custom_env_vars);
|
||||
|
||||
let post_exit_hook = context
|
||||
.launch_overrides
|
||||
.hooks
|
||||
.post_exit
|
||||
.clone()
|
||||
.or(settings.hooks.post_exit)
|
||||
.filter(|hook_command| !hook_command.is_empty());
|
||||
|
||||
let memory = context.launch_overrides.memory.unwrap_or(settings.memory);
|
||||
let resolution = context
|
||||
.launch_overrides
|
||||
.game_resolution
|
||||
.unwrap_or(settings.game_resolution);
|
||||
let has_hook_commands = pre_launch_hook.is_some()
|
||||
|| wrapper.is_some()
|
||||
|| post_exit_hook.is_some();
|
||||
let full_path = if has_hook_commands {
|
||||
Some(crate::util::io::canonicalize(
|
||||
state
|
||||
.directories
|
||||
.instances_dir()
|
||||
.join(&context.instance.path),
|
||||
)?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let hook_environment = if has_hook_commands {
|
||||
let full_path = full_path
|
||||
.as_ref()
|
||||
.expect("hooked launches always resolve their instance path");
|
||||
let java_version =
|
||||
crate::launcher::resolve_java_for_launch(&context).await?;
|
||||
|
||||
Some(crate::launcher::hooks::HookEnvironment::from_current_env(
|
||||
&env_args,
|
||||
crate::launcher::hooks::HookVariables {
|
||||
instance_name: context.instance.name.clone(),
|
||||
instance_id: context.instance.path.clone(),
|
||||
instance_dir: full_path.to_string_lossy().to_string(),
|
||||
java_path: java_version.path.clone(),
|
||||
java_args: crate::launcher::hooks::build_hook_java_args(
|
||||
&java_args,
|
||||
memory,
|
||||
&java_version,
|
||||
),
|
||||
},
|
||||
))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let launch_env_args = hook_environment
|
||||
.as_ref()
|
||||
.map_or_else(|| env_args.clone(), |env| env.injected_envs());
|
||||
|
||||
if let (Some(hook), Some(hook_environment), Some(full_path)) = (
|
||||
pre_launch_hook,
|
||||
hook_environment.as_ref(),
|
||||
full_path.as_ref(),
|
||||
) {
|
||||
let expanded_hook = hook_environment.expand(hook);
|
||||
let mut cmd = shlex::split(&expanded_hook)
|
||||
.ok_or_else(|| {
|
||||
crate::ErrorKind::LauncherError(format!(
|
||||
"Invalid pre-launch command: {hook}",
|
||||
@@ -96,17 +176,12 @@ async fn run_credentials(
|
||||
.into_iter();
|
||||
|
||||
if let Some(command) = cmd.next() {
|
||||
let full_path = crate::util::io::canonicalize(
|
||||
state
|
||||
.directories
|
||||
.instances_dir()
|
||||
.join(&context.instance.path),
|
||||
)?;
|
||||
let result = Command::new(command)
|
||||
.args(cmd)
|
||||
.current_dir(&full_path)
|
||||
.envs(launch_env_args.iter().cloned())
|
||||
.current_dir(full_path)
|
||||
.spawn()
|
||||
.map_err(|e| IOError::with_path(e, &full_path))?
|
||||
.map_err(|e| IOError::with_path(e, full_path))?
|
||||
.wait()
|
||||
.await
|
||||
.map_err(IOError::from)?;
|
||||
@@ -121,34 +196,19 @@ async fn run_credentials(
|
||||
}
|
||||
}
|
||||
|
||||
let java_args = context
|
||||
.launch_overrides
|
||||
.extra_launch_args
|
||||
.clone()
|
||||
.unwrap_or(settings.extra_launch_args);
|
||||
let wrapper = context
|
||||
.launch_overrides
|
||||
.hooks
|
||||
.wrapper
|
||||
.clone()
|
||||
.or(settings.hooks.wrapper)
|
||||
let wrapper = wrapper
|
||||
.map(|hook| {
|
||||
hook_environment
|
||||
.as_ref()
|
||||
.map_or(hook.clone(), |env| env.expand(&hook))
|
||||
})
|
||||
.filter(|hook_command| !hook_command.is_empty());
|
||||
let memory = context.launch_overrides.memory.unwrap_or(settings.memory);
|
||||
let resolution = context
|
||||
.launch_overrides
|
||||
.game_resolution
|
||||
.unwrap_or(settings.game_resolution);
|
||||
let env_args = context
|
||||
.launch_overrides
|
||||
.custom_env_vars
|
||||
.clone()
|
||||
.unwrap_or(settings.custom_env_vars);
|
||||
let post_exit_hook = context
|
||||
.launch_overrides
|
||||
.hooks
|
||||
.post_exit
|
||||
.clone()
|
||||
.or(settings.hooks.post_exit)
|
||||
let post_exit_hook = post_exit_hook
|
||||
.map(|hook| {
|
||||
hook_environment
|
||||
.as_ref()
|
||||
.map_or(hook.clone(), |env| env.expand(&hook))
|
||||
})
|
||||
.filter(|hook_command| !hook_command.is_empty());
|
||||
|
||||
let mut mc_set_options: Vec<(String, String)> = vec![];
|
||||
@@ -210,7 +270,7 @@ async fn run_credentials(
|
||||
crate::minecraft_skins::flush_pending_skin_change().await?;
|
||||
crate::launcher::launch_minecraft(
|
||||
&java_args,
|
||||
&env_args,
|
||||
&launch_env_args,
|
||||
&mc_set_options,
|
||||
&wrapper,
|
||||
&memory,
|
||||
|
||||
Reference in New Issue
Block a user