use crate::*;
use std::convert::{AsRef};
use std::fs;
use std::io;
use std::path::{Path, PathBuf};
pub fn metabuild() {
let java_home = paths::java_home().unwrap();
println!("cargo:rerun-if-env-changed=JAVA_HOME");
println!("cargo:rustc-env=JAVA_HOME={}", java_home.display());
env::set_var("JAVA_HOME", &java_home);
let profile = env::var("PROFILE").expect("${PROFILE} is not set or is invalid Unicode");
let package_name = env::var("CARGO_PKG_NAME").expect("${CARGO_PKG_NAME} is not set or is invalid Unicode");
let out_dir = env::var_path("OUT_DIR").expect("${OUT_DIR} is not set or is invalid Unicode");
let debug_info = match profile.as_str() {
"debug" => Some(javac::DebugInfo::ALL),
"release" => Some(javac::DebugInfo::NONE), _custom => None,
};
let mut files = Vec::new();
find_java_srcs(Path::new("."), &mut files).unwrap_or_else(|err| panic!("Failed to enumerate/read Java source code: {}", err));
let entry_point = if files.iter().find(|p| p.file_name() == Some(std::ffi::OsStr::new("Main.java"))).is_some() { Some(String::from("Main")) } else { None };
let out_java = out_dir.join("java");
let out_classes = out_java.join("classes");
let out_sources = out_java.join("source" );
let out_headers = out_java.join("headers");
let out_jars = out_java.join("jars");
let mut path;
let out_jar = if entry_point.is_none() {
&out_jars
} else {
path = out_dir.clone();
let ok =
path.file_name().and_then(|s| s.to_str()).map_or(false, |n| n == "out") && path.pop() &&
path.file_name().and_then(|s| s.to_str()).map_or(false, |n| n.starts_with(&package_name)) && path.pop() &&
path.file_name().and_then(|s| s.to_str()).map_or(false, |n| n == "build") && path.pop();
if ok {
&path
} else {
println!("cargo:warning=Expected OUT_DIR {:?} to end with build/{}-.../out", out_dir, package_name);
&out_jars
}
}.join(format!("{}.jar", package_name));
let _ = fs::create_dir_all(&out_java);
let _ = fs::create_dir(&out_classes);
let _ = fs::create_dir(&out_sources);
let _ = fs::create_dir(&out_headers);
let _ = fs::create_dir(&out_jars);
javac::Compile {
java_home: Some(java_home.clone()),
debug_info,
out_classes: Some(out_classes.clone()),
out_sources: Some(out_sources),
out_headers: Some(out_headers),
files,
..javac::Compile::default()
}.exec().unwrap();
jar::Archive {
entry_point,
java_home: Some(java_home.as_ref()),
jar_file: Some(out_jar.as_ref()),
files: &[(out_classes.as_ref(), &[".".as_ref()][..])][..],
..jar::Archive::default()
}.create().unwrap();
println!("cargo:rustc-env=JERK_BUILD_JAR={}", out_jar.display());
}
fn find_java_srcs(path: &Path, files: &mut Vec<PathBuf>) -> io::Result<()> {
println!("cargo:rerun-if-changed={}", path.display()); for entry in fs::read_dir(path)? {
let entry = entry?;
let path = entry.path();
let name = entry.file_name();
let name_lossy = name.to_string_lossy();
const DOT_JAVA : &'static str = ".java";
if path.is_dir() {
find_java_srcs(&path, files)?;
} else if name_lossy.get(name_lossy.len().saturating_sub(DOT_JAVA.len())..).map(|ext| ext.eq_ignore_ascii_case(DOT_JAVA)).unwrap_or(false) {
println!("cargo:rerun-if-changed={}", path.display()); files.push(path);
}
}
Ok(())
}