use std::path::{Path, PathBuf};
use std::process::Command;
use jni::JavaVM;
use crate::test_jvm::{jdk, start};
pub struct Shared {
pub jdk: PathBuf,
pub classes: PathBuf,
pub mixin: Option<String>,
pub vm: JavaVM,
}
static SHARED: yog_sync::OnceLock<Option<Shared>> = yog_sync::OnceLock::new();
pub fn shared() -> Option<&'static Shared> {
SHARED
.get_or_init(|| {
let jdk = jdk()?;
let classes =
std::env::temp_dir().join(format!("yog-jvm-tests-{}", std::process::id()));
std::fs::create_dir_all(&classes).ok()?;
let mixin = mixin_classpath();
let cp = match &mixin {
Some(jars) => format!("{}:{jars}", classes.display()),
None => classes.display().to_string(),
};
let vm = start(&jdk, Path::new(&cp));
Some(Shared {
jdk,
classes,
mixin,
vm,
})
})
.as_ref()
}
impl Shared {
pub fn compile(&self, sources: &[PathBuf]) -> bool {
static COMPILING: yog_sync::Mutex<()> = yog_sync::Mutex::new(());
let _one = COMPILING.lock();
let cp = match &self.mixin {
Some(jars) => format!("{}:{jars}", self.classes.display()),
None => self.classes.display().to_string(),
};
Command::new(self.jdk.join("bin/javac"))
.arg("-proc:none")
.arg("-cp")
.arg(cp)
.arg("-d")
.arg(&self.classes)
.args(sources)
.status()
.is_ok_and(|s| s.success())
}
}
fn mixin_classpath() -> Option<String> {
if let Ok(cp) = std::env::var("YOG_MIXIN_CP") {
return Some(cp);
}
let cache = PathBuf::from(std::env::var_os("HOME")?).join(".gradle/caches/modules-2/files-2.1");
let newest = |group: &str, artifact: &str| -> Option<PathBuf> {
let mut jars: Vec<PathBuf> = std::fs::read_dir(cache.join(group).join(artifact))
.ok()?
.flatten()
.flat_map(|v| std::fs::read_dir(v.path()).into_iter().flatten().flatten())
.flat_map(|h| std::fs::read_dir(h.path()).into_iter().flatten().flatten())
.map(|f| f.path())
.filter(|p| {
let name = p.file_name().and_then(|n| n.to_str()).unwrap_or_default();
name.starts_with(artifact)
&& name.ends_with(".jar")
&& !name.contains("sources")
&& !name.contains("processor")
})
.collect();
jars.sort();
jars.pop()
};
let jars = [
newest("org.spongepowered", "mixin")?,
newest("org.ow2.asm", "asm")?,
newest("org.ow2.asm", "asm-tree")?,
newest("io.github.llamalad7", "mixinextras-common")?,
];
Some(
jars.iter()
.map(|j| j.display().to_string())
.collect::<Vec<_>>()
.join(":"),
)
}