aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src-tauri
diff options
context:
space:
mode:
Diffstat (limited to 'src-tauri')
-rw-r--r--src-tauri/src/core/java/detection.rs82
-rw-r--r--src-tauri/src/core/java/persistence.rs2
-rw-r--r--src-tauri/src/core/java/priority.rs2
-rw-r--r--src-tauri/src/core/java/validation.rs2
4 files changed, 76 insertions, 12 deletions
diff --git a/src-tauri/src/core/java/detection.rs b/src-tauri/src/core/java/detection.rs
index 95e7803..08dcebb 100644
--- a/src-tauri/src/core/java/detection.rs
+++ b/src-tauri/src/core/java/detection.rs
@@ -1,4 +1,5 @@
use std::io::Read;
+use std::path::Path;
use std::path::PathBuf;
use std::process::{Command, Stdio};
use std::time::Duration;
@@ -6,25 +7,78 @@ use std::time::Duration;
#[cfg(target_os = "windows")]
use std::os::windows::process::CommandExt;
-use super::strip_unc_prefix;
+use crate::core::java::strip_unc_prefix;
const WHICH_TIMEOUT: Duration = Duration::from_secs(2);
+/// Scans a directory for Java installations, filtering out symlinks
+///
+/// # Arguments
+/// * `base_dir` - Base directory to scan (e.g., mise or SDKMAN java dir)
+/// * `should_skip` - Predicate to determine if an entry should be skipped
+///
+/// # Returns
+/// First valid Java installation found, or `None`
+fn scan_java_dir<F>(base_dir: &Path, should_skip: F) -> Option<PathBuf>
+where
+ F: Fn(&std::fs::DirEntry) -> bool,
+{
+ std::fs::read_dir(base_dir)
+ .ok()?
+ .flatten()
+ .filter(|entry| {
+ let path = entry.path();
+ // Only consider real directories, not symlinks
+ path.is_dir() && !path.is_symlink() && !should_skip(entry)
+ })
+ .find_map(|entry| {
+ let java_path = entry.path().join("bin/java");
+ if java_path.exists() && java_path.is_file() {
+ Some(java_path)
+ } else {
+ None
+ }
+ })
+}
+
/// Finds Java installation from SDKMAN! if available
///
-/// Checks the standard SDKMAN! installation path:
-/// `~/.sdkman/candidates/java/current/bin/java`
+/// Scans the SDKMAN! candidates directory and returns the first valid Java installation found.
+/// Skips the 'current' symlink to avoid duplicates.
+///
+/// Path: `~/.sdkman/candidates/java/`
///
/// # Returns
-/// `Some(PathBuf)` if SDKMAN! Java is found and exists, `None` otherwise
+/// `Some(PathBuf)` pointing to `bin/java` if found, `None` otherwise
pub fn find_sdkman_java() -> Option<PathBuf> {
let home = std::env::var("HOME").ok()?;
- let sdkman_path = PathBuf::from(&home).join(".sdkman/candidates/java/current/bin/java");
- if sdkman_path.exists() {
- Some(sdkman_path)
- } else {
- None
+ let sdkman_base = PathBuf::from(&home).join(".sdkman/candidates/java/");
+
+ if !sdkman_base.exists() {
+ return None;
}
+
+ scan_java_dir(&sdkman_base, |entry| entry.file_name() == "current")
+}
+
+/// Finds Java installation from mise if available
+///
+/// Scans the mise Java installation directory and returns the first valid installation found.
+/// Skips version alias symlinks (e.g., `21`, `21.0`, `latest`, `lts`) to avoid duplicates.
+///
+/// Path: `~/.local/share/mise/installs/java/`
+///
+/// # Returns
+/// `Some(PathBuf)` pointing to `bin/java` if found, `None` otherwise
+pub fn find_mise_java() -> Option<PathBuf> {
+ let home = std::env::var("HOME").ok()?;
+ let mise_base = PathBuf::from(&home).join(".local/share/mise/installs/java/");
+
+ if !mise_base.exists() {
+ return None;
+ }
+
+ scan_java_dir(&mise_base, |_| false) // mise: no additional filtering needed
}
/// Runs `which` (Unix) or `where` (Windows) command to find Java in PATH with timeout
@@ -150,6 +204,11 @@ pub fn get_java_candidates() -> Vec<PathBuf> {
if let Some(sdkman_java) = find_sdkman_java() {
candidates.push(sdkman_java);
}
+
+ // Check common mise java candidates
+ if let Some(mise_java) = find_mise_java() {
+ candidates.push(mise_java);
+ }
}
#[cfg(target_os = "macos")]
@@ -196,6 +255,11 @@ pub fn get_java_candidates() -> Vec<PathBuf> {
if let Some(sdkman_java) = find_sdkman_java() {
candidates.push(sdkman_java);
}
+
+ // Check common mise java candidates
+ if let Some(mise_java) = find_mise_java() {
+ candidates.push(mise_java);
+ }
}
#[cfg(target_os = "windows")]
diff --git a/src-tauri/src/core/java/persistence.rs b/src-tauri/src/core/java/persistence.rs
index d5b446c..6720696 100644
--- a/src-tauri/src/core/java/persistence.rs
+++ b/src-tauri/src/core/java/persistence.rs
@@ -1,4 +1,4 @@
-use super::error::JavaError;
+use crate::core::java::error::JavaError;
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use tauri::{AppHandle, Manager};
diff --git a/src-tauri/src/core/java/priority.rs b/src-tauri/src/core/java/priority.rs
index e456680..b2e9fb4 100644
--- a/src-tauri/src/core/java/priority.rs
+++ b/src-tauri/src/core/java/priority.rs
@@ -1,8 +1,8 @@
use tauri::AppHandle;
-use super::JavaInstallation;
use crate::core::java::persistence;
use crate::core::java::validation;
+use crate::core::java::JavaInstallation;
pub async fn resolve_java_for_launch(
app_handle: &AppHandle,
diff --git a/src-tauri/src/core/java/validation.rs b/src-tauri/src/core/java/validation.rs
index 48782f6..b56ad59 100644
--- a/src-tauri/src/core/java/validation.rs
+++ b/src-tauri/src/core/java/validation.rs
@@ -5,7 +5,7 @@ use std::process::Command;
#[cfg(target_os = "windows")]
use std::os::windows::process::CommandExt;
-use super::JavaInstallation;
+use crate::core::java::JavaInstallation;
pub async fn check_java_installation(path: &PathBuf) -> Option<JavaInstallation> {
let path = path.clone();