use super::Provider;
use crate::nixpacks::{
app::App,
environment::Environment,
nix::pkg::Pkg,
plan::{
phase::{Phase, StartPhase},
BuildPlan,
},
};
use anyhow::Result;
use regex::Regex;
const DEFAULT_JDK_PKG_NAME: &str = "jdk8";
pub struct ClojureProvider {}
impl Provider for ClojureProvider {
fn name(&self) -> &str {
"clojure"
}
fn detect(&self, app: &App, _env: &Environment) -> Result<bool> {
Ok(app.includes_file("project.clj"))
}
fn get_build_plan(&self, app: &App, env: &Environment) -> Result<Option<BuildPlan>> {
let setup = Phase::setup(Some(vec![
Pkg::new("leiningen"),
ClojureProvider::get_nix_jdk_package(app, env)?,
]));
let has_lein_ring_plugin = app
.read_file("project.clj")?
.to_lowercase()
.contains("[lein-ring ");
let build_cmd = if has_lein_ring_plugin {
"lein ring uberjar"
} else {
"lein uberjar"
};
let move_file_cmd = "if [ -f /app/target/default+uberjar/*standalone.jar ]; then mv /app/target/default+uberjar/*standalone.jar /app/target/*standalone.jar; fi";
let mut build = Phase::build(Some(format!("{build_cmd}; {move_file_cmd}")));
build.depends_on_phase("setup");
let start = StartPhase::new("bash -c \"java $JAVA_OPTS -jar /app/target/*standalone.jar\"");
let plan = BuildPlan::new(&vec![setup, build], Some(start));
Ok(Some(plan))
}
}
impl ClojureProvider {
fn get_custom_version(app: &App, env: &Environment) -> Result<String> {
let mut custom_version = env.get_config_variable("JDK_VERSION");
if custom_version.is_none() && app.includes_file(".jdk-version") {
custom_version = Some(app.read_file(".jdk-version")?);
}
match custom_version {
Some(v) => Ok(v),
None => Ok(DEFAULT_JDK_PKG_NAME.to_string()),
}
}
fn parse_custom_version(custom_version: &str) -> Result<String> {
let jdk_regex = Regex::new(r"^([0-9][0-9]?|latest)$")?;
let matches = jdk_regex.captures(custom_version.trim());
if matches.is_none() {
return Ok(DEFAULT_JDK_PKG_NAME.to_string());
}
let matches = matches.unwrap();
let matched_value = matches.get(0);
let value = match matched_value {
Some(m) => m.as_str(),
None => "_",
};
Ok(value.to_string())
}
pub fn get_nix_jdk_package(app: &App, env: &Environment) -> Result<Pkg> {
let custom_version = ClojureProvider::get_custom_version(app, env)?;
let parsed_version = ClojureProvider::parse_custom_version(&custom_version)?;
let pkg_name = match parsed_version.as_str() {
"latest" => "jdk",
"11" => "jdk11",
_ => DEFAULT_JDK_PKG_NAME, };
Ok(Pkg::new(pkg_name))
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::nixpacks::{app::App, environment::Environment, nix::pkg::Pkg};
use std::collections::BTreeMap;
#[test]
fn test_no_version() -> Result<()> {
assert_eq!(
ClojureProvider::get_nix_jdk_package(
&App::new("./examples/clojure")?,
&Environment::default()
)?,
Pkg::new(DEFAULT_JDK_PKG_NAME)
);
Ok(())
}
#[test]
fn test_custom_version() -> Result<()> {
assert_eq!(
ClojureProvider::get_nix_jdk_package(
&App::new("./examples/clojure-jdk11")?,
&Environment::default()
)?,
Pkg::new("jdk11")
);
Ok(())
}
#[test]
fn test_custom_latest_version() -> Result<()> {
assert_eq!(
ClojureProvider::get_nix_jdk_package(
&App::new("./examples/clojure-jdk-latest")?,
&Environment::default()
)?,
Pkg::new("jdk")
);
Ok(())
}
#[test]
fn test_latest_version_from_environment_variable() -> Result<()> {
assert_eq!(
ClojureProvider::get_nix_jdk_package(
&App::new("./examples/clojure-jdk-latest")?,
&Environment::new(BTreeMap::from([(
"NIXPACKS_JDK_VERSION".to_string(),
"latest".to_string()
)]))
)?,
Pkg::new("jdk")
);
Ok(())
}
#[test]
fn test_version_from_environment_variable() -> Result<()> {
assert_eq!(
ClojureProvider::get_nix_jdk_package(
&App::new("./examples/clojure")?,
&Environment::new(BTreeMap::from([(
"NIXPACKS_JDK_VERSION".to_string(),
"11".to_string()
)]))
)?,
Pkg::new("jdk11")
);
Ok(())
}
}