use std::error::Error;
use std::path::{Path,PathBuf};
use glob::glob;
use crate::config;
use crate::config::{Config,Key};
use crate::build;
use crate::build::{PACKAGE_NAME,Artifact};
use crate::platform;
use crate::platform::{PluginError,whiley};
use crate::jvm;
pub static STANDARD_DEFAULT : &'static str = "ES6";
static BUILD_JAVASCRIPT_TARGET : Key = Key::new(&["build","js","target"]);
static BUILD_JAVASCRIPT_STANDARD : Key = Key::new(&["build","js","standard"]);
static BUILD_JAVASCRIPT_INCLUDES : Key = Key::new(&["build","js","includes"]);
static MAVEN_DEPS : &'static [&str] = &[
whiley::MAVEN_DEPS[0], whiley::MAVEN_DEPS[1], "org.whiley:wyjs:0.10.5",
];
pub struct JavaScriptPlatform {
name: String,
source: String,
target: String,
standard: String,
includes: Vec<String>,
whileypath: Vec<String>
}
impl JavaScriptPlatform {
fn match_includes(&self) -> Vec<String> {
let mut matches = Vec::new();
matches.push(self.name.clone());
matches
}
fn match_natives(&self) -> Vec<String> {
let mut matches = Vec::new();
for i in &self.includes {
for entry in glob(&i).expect("invalid pattern for key \"build.js.includes\"") {
match entry {
Ok(path) => {
matches.push(path.to_str().unwrap().to_string());
}
Err(e) => println!("{:?}", e)
}
}
}
matches
}
fn target_path(&self) -> PathBuf {
let mut bin = PathBuf::from(&self.target);
let mut name = self.name.clone();
name.push_str(".js");
bin.push(&name);
bin
}
}
impl platform::JavaInstance for JavaScriptPlatform {
fn name(&self) -> &'static str {
"js"
}
fn dependencies(&self) -> &'static [&'static str] {
MAVEN_DEPS
}
fn arguments(&self) -> Vec<String> {
let mut args = Vec::new();
args.push("wyjs.Main".to_string());
args.push("-o".to_string());
args.push(self.name.clone());
let mut source = String::new();
source.push_str("--wyildir=");
source.push_str(self.source.as_str());
args.push(source);
let mut target = String::new();
target.push_str("--jsdir=");
target.push_str(self.target.as_str());
args.push(target);
args.push("-s".to_string());
args.push(self.standard.clone());
let mut whileypath = String::new();
if self.whileypath.len() > 0 {
whileypath.push_str("--whileypath=");
whileypath.push_str(self.whileypath.get(0).unwrap());
for e in &self.whileypath[1..] {
whileypath.push_str(jvm::classpath_sep());
whileypath.push_str(e);
}
args.push(whileypath);
}
args.append(&mut self.match_includes());
args
}
fn manifest(&self) -> Vec<build::Artifact> {
let mut artifacts = Vec::new();
if self.target != whiley::TARGET_DEFAULT {
artifacts.push(Artifact::BinaryFolder(PathBuf::from(&self.target)));
}
let bin = self.target_path();
artifacts.push(Artifact::BinaryFile(bin,false));
for s in self.match_natives() {
artifacts.push(Artifact::SourceFile(PathBuf::from(&s)));
}
artifacts
}
fn process(&self, output: &str) -> Result<Vec<build::Marker>,Box<dyn Error>> {
if output.len() > 0 {
Err(Box::new(PluginError{name:"wyjs".to_string(),message: output.to_string()}))
} else {
Ok(Vec::new())
}
}
}
pub struct Descriptor {}
impl platform::Descriptor for Descriptor {
fn apply<'a>(&self, config: &'a Config, whileyhome: &Path) -> Result<platform::Instance,config::Error> {
let name = config.get_string(&PACKAGE_NAME)?;
let source = config.get_string(&whiley::BUILD_WHILEY_TARGET).unwrap_or(whiley::TARGET_DEFAULT.to_string());
let target = config.get_string(&BUILD_JAVASCRIPT_TARGET).unwrap_or(whiley::TARGET_DEFAULT.to_string());
let standard = config.get_string(&BUILD_JAVASCRIPT_STANDARD).unwrap_or(STANDARD_DEFAULT.to_string());
let includes = config.get_string_array(&BUILD_JAVASCRIPT_INCLUDES).unwrap_or(Vec::new());
let mut whileypath = Vec::new();
for s in config.find_keys(&whiley::DEPENDENCIES).unwrap_or(Vec::new()) {
let a = [&whiley::TMP,s.as_str()];
let k = Key::new(&a);
let d = config.get_string(&k)?;
let mut pb = PathBuf::new();
pb.push(whileyhome);
pb.push("repository");
pb.push(format!("{}-v{}.zip",&s,&d));
let arg = pb.into_os_string().into_string().unwrap();
whileypath.push(arg);
}
let instance = Box::new(JavaScriptPlatform{name,source,target,standard,includes,whileypath});
Ok(platform::Instance::Java(instance))
}
}
pub const DESCRIPTOR : Descriptor = Descriptor{};