use std::collections::BTreeMap;
use std::path::{Path, PathBuf};
use yog_ids::Format;
use yog_script_build::{JvmBuild, build_jar};
use crate::diagnostics;
use crate::project::manifest::{SOURCES_DIR, YogToml};
const PACKAGE_ROOT: &str = "yogscript";
const WORK_DIR: &str = "scripts";
const JAVAC: &str = "javac";
const JDK_BIN: &str = "bin";
pub fn jars(
root: &Path,
meta: &YogToml,
build_dir: &Path,
) -> Result<Vec<(String, Vec<u8>)>, String> {
let sources = sources(root)?;
if sources.is_empty() {
return Ok(Vec::new());
}
let home = yog_home::Home::locate()?;
let resolver = yog_home::targets::Resolver::new(&home)?;
let api = resolver.java_api_jar().ok_or(
"Yog Script needs the loader SDK's java-api jar: `./build.sh build api` in the SDK",
)?;
let package = format!("{PACKAGE_ROOT}.{}", yog_ids::mod_lib_name(&meta.id));
let mut out = Vec::new();
for (mc, java) in versions(&resolver)? {
let javac = resolver.jdk(java).map_or_else(
|| PathBuf::from(JAVAC),
|jdk| {
jdk.join(JDK_BIN)
.join(format!("{JAVAC}{}", std::env::consts::EXE_SUFFIX))
},
);
let work = build_dir.join(WORK_DIR).join(&mc);
let jar = build_dir
.join(WORK_DIR)
.join(format!("{mc}-{}.jar", meta.id));
let b = JvmBuild {
javac: &javac,
release: java,
classpath: std::slice::from_ref(&api),
package: &package,
work: &work,
to_server: meta.to_server,
};
if let Err(problems) = build_jar(&sources, &b, &jar) {
diagnostics::report_all(&problems);
problems.iter().for_each(|d| yog_logging::error!("{d}"));
return Err(format!("the Yog Script didn't build for {mc}"));
}
let bytes = std::fs::read(&jar).map_err(|e| format!("{}: {e}", jar.display()))?;
out.push((
format!("{}/{mc}/{}.jar", yog_ids::archive::SCRIPTS, meta.id),
bytes,
));
yog_logging::info!("scripts for {mc} (Java {java})");
}
Ok(out)
}
fn sources(root: &Path) -> Result<Vec<(String, String)>, String> {
crate::files::of(&root.join(SOURCES_DIR), Format::Script)
.into_iter()
.map(|f| {
let text = std::fs::read_to_string(&f).map_err(|e| format!("{}: {e}", f.display()))?;
Ok((crate::shown_path(root, &f), text))
})
.collect()
}
fn versions(resolver: &yog_home::targets::Resolver) -> Result<BTreeMap<String, u32>, String> {
let mut out = BTreeMap::new();
for t in resolver.targets()? {
if let (Some(mc), Some(java)) = (t.variant.clone(), t.java()) {
out.insert(mc, java);
}
}
if out.is_empty() {
return Err("no game version to build the Yog Script for: no loader SDK".into());
}
Ok(out)
}