You've already forked AstralRinth
Jre api (#66)
* basic push * actual push * JRE detection, and autosetting * removed a println, retrying CI/CD * new game version compare; preset java 7 and 8 using our jre * 1.8 mislabeled * working JRE changes * fixed bugs with JRE setup * fixed bugs with JRE setup * manual merge * prettier * fixes + jre 17 * clippy, prettier * typo * forgot to hook up a function * pr fix + comment fix * added loader_version * take 2
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
use dunce::canonicalize;
|
||||
use lazy_static::lazy_static;
|
||||
use regex::Regex;
|
||||
use std::collections::HashSet;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
use std::{collections::HashSet, path::Path};
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
use winreg::{
|
||||
@@ -12,7 +13,7 @@ use winreg::{
|
||||
RegKey,
|
||||
};
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Clone)]
|
||||
pub struct JavaVersion {
|
||||
pub path: String,
|
||||
pub version: String,
|
||||
@@ -35,11 +36,8 @@ pub fn get_all_jre() -> Result<Vec<JavaVersion>, JREError> {
|
||||
let Ok(java_subpaths) = std::fs::read_dir(java_path) else {continue };
|
||||
for java_subpath in java_subpaths {
|
||||
let path = java_subpath?.path();
|
||||
if let Some(j) =
|
||||
check_java_at_filepath(PathBuf::from(path).join("bin"))
|
||||
{
|
||||
if let Some(j) = check_java_at_filepath(&path.join("bin")) {
|
||||
jres.insert(j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -90,10 +88,9 @@ pub fn get_all_jre_winregkey(
|
||||
subkey.get_value(subkey_value);
|
||||
let Ok(path) = path else {continue};
|
||||
if let Some(j) =
|
||||
check_java_at_filepath(PathBuf::from(path).join("bin"))
|
||||
check_java_at_filepath(&PathBuf::from(path).join("bin"))
|
||||
{
|
||||
jres.insert(j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -118,12 +115,23 @@ pub fn get_all_jre() -> Result<Vec<JavaVersion>, JREError> {
|
||||
r"/System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands",
|
||||
];
|
||||
for path in java_paths {
|
||||
if let Some(j) = check_java_at_filepath(PathBuf::from(path).join("bin"))
|
||||
if let Some(j) =
|
||||
check_java_at_filepath(&PathBuf::from(path).join("bin"))
|
||||
{
|
||||
jres.insert(j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Iterate over JavaVirtualMachines/(something)/Contents/Home/bin
|
||||
let base_path = PathBuf::from("/Library/Java/JavaVirtualMachines/");
|
||||
if base_path.is_dir() {
|
||||
for entry in std::fs::read_dir(base_path)? {
|
||||
let entry = entry?.path().join("Contents/Home/bin");
|
||||
if let Some(j) = check_java_at_filepath(entry.as_path()) {
|
||||
jres.insert(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(jres.into_iter().collect())
|
||||
}
|
||||
|
||||
@@ -149,29 +157,29 @@ pub fn get_all_jre() -> Result<Vec<JavaVersion>, JREError> {
|
||||
];
|
||||
for path in java_paths {
|
||||
if let Some(j) =
|
||||
check_java_at_filepath(PathBuf::from(path).join("jre").join("bin"))
|
||||
check_java_at_filepath(&PathBuf::from(path).join("jre").join("bin"))
|
||||
{
|
||||
jres.insert(j);
|
||||
break;
|
||||
}
|
||||
if let Some(j) = check_java_at_filepath(PathBuf::from(path).join("bin"))
|
||||
if let Some(j) =
|
||||
check_java_at_filepath(&PathBuf::from(path).join("bin"))
|
||||
{
|
||||
jres.insert(j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Ok(jres.into_iter().collect())
|
||||
}
|
||||
|
||||
// Gets all JREs from the PATH env variable
|
||||
#[tracing::instrument]
|
||||
pub fn get_all_jre_path() -> Result<HashSet<JavaVersion>, JREError> {
|
||||
fn get_all_jre_path() -> Result<HashSet<JavaVersion>, JREError> {
|
||||
// Iterate over values in PATH variable, where accessible JREs are referenced
|
||||
let paths = env::var("PATH")?;
|
||||
let paths = env::split_paths(&paths);
|
||||
|
||||
let mut jres = HashSet::new();
|
||||
for path in paths {
|
||||
if let Some(j) = check_java_at_filepath(path) {
|
||||
if let Some(j) = check_java_at_filepath(&path) {
|
||||
jres.insert(j);
|
||||
}
|
||||
}
|
||||
@@ -189,14 +197,19 @@ const JAVA_BIN: &str = "java";
|
||||
// For example filepath 'path', attempt to resolve it and get a Java version at this path
|
||||
// If no such path exists, or no such valid java at this path exists, returns None
|
||||
#[tracing::instrument]
|
||||
pub fn check_java_at_filepath(path: PathBuf) -> Option<JavaVersion> {
|
||||
pub fn check_java_at_filepath(path: &Path) -> Option<JavaVersion> {
|
||||
// Attempt to canonicalize the potential java filepath
|
||||
// If it fails, this path does not exist and None is returned (no Java here)
|
||||
let Ok(path) = canonicalize(path) else { return None };
|
||||
let Some(path_str) = path.to_str() else { return None };
|
||||
|
||||
// Checks for existence of Java at this filepath
|
||||
let java = path.join(JAVA_BIN);
|
||||
// Adds JAVA_BIN to the end of the path if it is not already there
|
||||
let java = if path.file_name()?.to_str()? != JAVA_BIN {
|
||||
path.join(JAVA_BIN)
|
||||
} else {
|
||||
path
|
||||
};
|
||||
|
||||
if !java.exists() {
|
||||
return None;
|
||||
};
|
||||
@@ -216,7 +229,8 @@ pub fn check_java_at_filepath(path: PathBuf) -> Option<JavaVersion> {
|
||||
// Extract version info from it
|
||||
if let Some(captures) = JAVA_VERSION_CAPTURE.captures(&stderr) {
|
||||
if let Some(version) = captures.get(1) {
|
||||
let path = path_str.to_string();
|
||||
let Some(path) = java.to_str() else { return None };
|
||||
let path = path.to_string();
|
||||
return Some(JavaVersion {
|
||||
path,
|
||||
version: version.as_str().to_string(),
|
||||
@@ -226,6 +240,38 @@ pub fn check_java_at_filepath(path: PathBuf) -> Option<JavaVersion> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Extract major/minor version from a java version string
|
||||
/// Gets the minor version or an error, and assumes 1 for major version if it could not find
|
||||
/// "1.8.0_361" -> (1, 8)
|
||||
/// "20" -> (1, 20)
|
||||
pub fn extract_java_majorminor_version(
|
||||
version: &str,
|
||||
) -> Result<(u32, u32), JREError> {
|
||||
let mut split = version.split('.');
|
||||
let major_opt = split.next();
|
||||
|
||||
let mut major;
|
||||
// Try minor. If doesn't exist, in format like "20" so use major
|
||||
let mut minor = if let Some(minor) = split.next() {
|
||||
major = major_opt.unwrap_or("1").parse::<u32>()?;
|
||||
minor.parse::<u32>()?
|
||||
} else {
|
||||
// Formatted like "20", only one value means that is minor version
|
||||
major = 1;
|
||||
major_opt
|
||||
.ok_or_else(|| JREError::InvalidJREVersion(version.to_string()))?
|
||||
.parse::<u32>()?
|
||||
};
|
||||
|
||||
// Java start should always be 1. If more than 1, it is formatted like "17.0.1.2" and starts with minor version
|
||||
if major > 1 {
|
||||
minor = major;
|
||||
major = 1;
|
||||
}
|
||||
|
||||
Ok((major, minor))
|
||||
}
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
pub enum JREError {
|
||||
#[error("Command error : {0}")]
|
||||
@@ -233,4 +279,32 @@ pub enum JREError {
|
||||
|
||||
#[error("Env error: {0}")]
|
||||
EnvError(#[from] env::VarError),
|
||||
|
||||
#[error("No JRE found for required version: {0}")]
|
||||
NoJREFound(String),
|
||||
|
||||
#[error("Invalid JRE version string: {0}")]
|
||||
InvalidJREVersion(String),
|
||||
|
||||
#[error("Parsing error: {0}")]
|
||||
ParseError(#[from] std::num::ParseIntError),
|
||||
|
||||
#[error("No stored tag for Minecraft Version {0}")]
|
||||
NoMinecraftVersionFound(String),
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::extract_java_majorminor_version;
|
||||
|
||||
#[test]
|
||||
pub fn java_version_parsing() {
|
||||
assert_eq!(extract_java_majorminor_version("1.8").unwrap(), (1, 8));
|
||||
assert_eq!(extract_java_majorminor_version("17.0.6").unwrap(), (1, 17));
|
||||
assert_eq!(extract_java_majorminor_version("20").unwrap(), (1, 20));
|
||||
assert_eq!(
|
||||
extract_java_majorminor_version("1.8.0_361").unwrap(),
|
||||
(1, 8)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user