-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
public final class JavaInfo { | ||
private static final String[] CHECKED_PROPERTIES = new String[] { | ||
"os.arch", | ||
"java.version", | ||
"java.vendor" | ||
}; | ||
|
||
public static void main(String[] args) { | ||
int returnCode = 0; | ||
|
||
for (String key : CHECKED_PROPERTIES) { | ||
String property = System.getProperty(key); | ||
|
||
if (property != null) { | ||
System.out.println(key + "=" + property); | ||
} else { | ||
returnCode = 1; | ||
} | ||
} | ||
|
||
System.exit(returnCode); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
javac -target 7 -source 7 -Xlint:deprecation -Xlint:unchecked JavaInfo.java |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
use std::{collections::HashMap, path::Path, process::Command}; | ||
|
||
use super::{extract_java_majorminor_version, JavaInstallation, JAVA_BIN}; | ||
|
||
pub fn check_java(path: &Path) -> Option<JavaInstallation> { | ||
Check warning on line 5 in src/api/tools/java/check.rs GitHub Actions / clippyfunction `check_java` is never used
|
||
let Ok(path) = std::fs::canonicalize(path) else { | ||
return None; | ||
}; | ||
|
||
let java = if path.file_name()?.to_str()? != JAVA_BIN { | ||
path.join(JAVA_BIN) | ||
} else { | ||
path.clone() | ||
}; | ||
Check warning on line 14 in src/api/tools/java/check.rs GitHub Actions / clippyunnecessary `!=` operation
|
||
|
||
if !java.exists() { | ||
return None; | ||
}; | ||
|
||
let tempdir = tempfile::tempdir().ok()?.into_path(); | ||
let file_path = tempdir.join("JavaInfo.class"); | ||
std::fs::write(&file_path, include_bytes!("../../../../res/java/JavaInfo.class")).ok()?; | ||
|
||
let output = Command::new(&java) | ||
.arg("-cp") | ||
.arg(file_path.parent().unwrap()) | ||
.arg("JavaInfo") | ||
.output() | ||
.ok()?; | ||
|
||
let stdout = String::from_utf8_lossy(&output.stdout); | ||
|
||
let mut info = HashMap::new(); | ||
|
||
for line in stdout.lines() { | ||
let Some((key, value)) = line.split_once('=') else { | ||
continue; | ||
}; | ||
|
||
info.insert(key.to_owned(), value.to_owned()); | ||
} | ||
|
||
Some(JavaInstallation { | ||
path, | ||
version: extract_java_majorminor_version(info.get("java.version")?).ok()?.1, | ||
architecture: info.get("os.arch")?.clone(), | ||
vendor: info.get("java.vendor")?.clone(), | ||
}) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
use std::collections::HashMap; | ||
use std::env; | ||
use std::path::PathBuf; | ||
use std::collections::HashSet; | ||
|
||
enum JavaLocation { | ||
Path(&'static str), | ||
PathSubpathAndWildcard(&'static str, Vec<&'static str>), | ||
PathWildcard(&'static str, Vec<&'static str>), | ||
} | ||
|
||
fn env_paths() -> HashSet<PathBuf> { | ||
let paths = | ||
env::var("PATH").map(|x| env::split_paths(&x).collect::<HashSet<_>>()); | ||
paths.unwrap_or_else(|_| HashSet::new()) | ||
} | ||
|
||
pub(super) fn collect_possible_java_paths() -> HashSet<PathBuf> { | ||
Check warning on line 18 in src/api/tools/java/find.rs GitHub Actions / clippyfunction `collect_possible_java_paths` is never used
|
||
let locations = &get_possible_java_locations()[env::consts::OS]; | ||
|
||
let mut paths = HashSet::new(); | ||
|
||
paths.extend(env_paths()); | ||
|
||
for loc in locations { | ||
match loc { | ||
JavaLocation::Path(path) => { | ||
paths.insert(path.into()); | ||
} | ||
JavaLocation::PathWildcard(base, extras) => { | ||
if let Ok(entries) = PathBuf::from(base).read_dir() { | ||
for entry in entries.flatten() { | ||
for extra in extras { | ||
paths.insert(entry.path().join(extra)); | ||
} | ||
} | ||
} | ||
} | ||
JavaLocation::PathSubpathAndWildcard(base, extras) => { | ||
paths.insert(base.into()); | ||
for extra in extras { | ||
paths.insert(PathBuf::from(base).join(extra)); | ||
} | ||
if let Ok(entries) = PathBuf::from(base).read_dir() { | ||
for entry in entries.flatten() { | ||
for extra in extras { | ||
paths.insert(entry.path().join(extra)); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
paths | ||
} | ||
|
||
fn get_possible_java_locations() -> HashMap<&'static str, Vec<JavaLocation>> { | ||
Check warning on line 58 in src/api/tools/java/find.rs GitHub Actions / clippyfunction `get_possible_java_locations` is never used
|
||
HashMap::from([ | ||
("windows", vec![ | ||
JavaLocation::PathWildcard(r"C:/Program Files/Java", vec!["bin"]), | ||
JavaLocation::PathWildcard(r"C:/Program Files (x86)/Java", vec!["bin"]), | ||
JavaLocation::PathWildcard(r"C:\Program Files\Eclipse Adoptium", vec!["bin"]), | ||
JavaLocation::PathWildcard(r"C:\Program Files (x86)\Eclipse Adoptium", vec!["bin"]), | ||
]), | ||
("macos", vec![ | ||
JavaLocation::Path(r"/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/MacOS/itms/java"), | ||
JavaLocation::Path(r"/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home"), | ||
JavaLocation::Path(r"/System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands"), | ||
JavaLocation::PathWildcard(r"/Library/Java/JavaVirtualMachines/", vec![r"Contents/Home/bin"]), | ||
]), | ||
("linux", vec![ | ||
JavaLocation::PathSubpathAndWildcard(r"/usr", vec!["jre/bin", "bin"]), | ||
JavaLocation::PathSubpathAndWildcard(r"/usr/java", vec!["jre/bin", "bin"]), | ||
JavaLocation::PathSubpathAndWildcard(r"/usr/lib/jvm", vec!["jre/bin", "bin"]), | ||
JavaLocation::PathSubpathAndWildcard(r"/usr/lib64/jvm", vec!["jre/bin", "bin"]), | ||
JavaLocation::PathSubpathAndWildcard(r"/opt/jdk", vec!["jre/bin", "bin"]), | ||
JavaLocation::PathSubpathAndWildcard(r"/opt/jdks", vec!["jre/bin", "bin"]), | ||
]) | ||
]) | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
use std::path::PathBuf; | ||
|
||
use anyhow::{anyhow, Result}; | ||
|
||
use super::JavaVersion; | ||
|
||
pub struct JavaInstallation { | ||
Check warning on line 7 in src/api/tools/java/installation.rs GitHub Actions / clippystruct `JavaInstallation` is never constructed
|
||
pub path: PathBuf, | ||
pub version: JavaVersion, | ||
pub architecture: String, | ||
pub vendor: String, | ||
} | ||
|
||
/// 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) | ||
Check warning on line 16 in src/api/tools/java/installation.rs GitHub Actions / clippyitem in documentation is missing backticks
|
||
/// "20" -> (1, 20) | ||
pub fn extract_java_majorminor_version( | ||
Check warning on line 18 in src/api/tools/java/installation.rs GitHub Actions / clippyfunction `extract_java_majorminor_version` is never used
|
||
version: &str, | ||
) -> Result<(u32, u32)> { | ||
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(|| anyhow!("Invalid JRE version"))? | ||
.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)) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,15 @@ | ||
pub const JAVA_BIN: &str = "java"; | ||
pub type JavaVersion = u32; | ||
|
||
mod installation; | ||
mod find; | ||
mod check; | ||
pub use installation::*; | ||
pub use find::*; | ||
Check warning on line 8 in src/api/tools/java/mod.rs GitHub Actions / clippyglob import doesn't reexport anything with visibility `pub` because no imported item is public enough
|
||
pub use check::*; | ||
|
||
pub fn get_java_installations() -> Vec<JavaInstallation> { | ||
Check warning on line 11 in src/api/tools/java/mod.rs GitHub Actions / clippyfunction `get_java_installations` is never used
|
||
let paths = collect_possible_java_paths(); | ||
|
||
paths.into_iter().filter_map(|path| check_java(&path)).collect() | ||
} |