summaryrefslogtreecommitdiffstats
path: root/src/modules/kotlin.rs
diff options
context:
space:
mode:
authorNicola Corti <corti.nico@gmail.com>2020-12-26 15:26:50 +0100
committerGitHub <noreply@github.com>2020-12-26 15:26:50 +0100
commit208251adefcfdba3604821daca848b76e78ff0eb (patch)
tree07a5d5a9a664b23710d72ded1b44d7e7a62f6fe0 /src/modules/kotlin.rs
parent53a08712eb2de5d507655d423cc78e7130a32dd1 (diff)
feat(kotlin): Add the kotlin module (#2026)
Add a module to show the currently installed Kotlin version if a .kt/.kts file is found in the current folder
Diffstat (limited to 'src/modules/kotlin.rs')
-rw-r--r--src/modules/kotlin.rs174
1 files changed, 174 insertions, 0 deletions
diff --git a/src/modules/kotlin.rs b/src/modules/kotlin.rs
new file mode 100644
index 000000000..31d979b44
--- /dev/null
+++ b/src/modules/kotlin.rs
@@ -0,0 +1,174 @@
+use super::{Context, Module, RootModuleConfig};
+
+use crate::configs::kotlin::KotlinConfig;
+use crate::formatter::StringFormatter;
+use crate::utils;
+
+use regex::Regex;
+const KOTLIN_VERSION_PATTERN: &str = "(?P<version>[\\d\\.]+[\\d\\.]+[\\d\\.]+)";
+
+/// Creates a module with the current Kotlin version
+///
+/// Will display the Kotlin version if any of the following criteria are met:
+/// - Current directory contains a file with a `.kt` or `.kts` extension
+pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
+ let is_kotlin_project = context
+ .try_begin_scan()?
+ .set_extensions(&["kt", "kts"])
+ .is_match();
+
+ if !is_kotlin_project {
+ return None;
+ }
+
+ let mut module = context.new_module("kotlin");
+ let config = KotlinConfig::try_load(module.config);
+ let kotlin_version = format_kotlin_version(&get_kotlin_version(&config.kotlin_binary)?)?;
+ let parsed = StringFormatter::new(config.format).and_then(|formatter| {
+ formatter
+ .map_meta(|var, _| match var {
+ "symbol" => Some(config.symbol),
+ _ => None,
+ })
+ .map_style(|variable| match variable {
+ "style" => Some(Ok(config.style)),
+ _ => None,
+ })
+ .map(|variable| match variable {
+ "version" => Some(Ok(&kotlin_version)),
+ _ => None,
+ })
+ .parse(None)
+ });
+
+ module.set_segments(match parsed {
+ Ok(segments) => segments,
+ Err(error) => {
+ log::warn!("Error in module `kotlin`:\n{}", error);
+ return None;
+ }
+ });
+
+ Some(module)
+}
+
+fn get_kotlin_version(kotlin_binary: &str) -> Option<String> {
+ match utils::exec_cmd(kotlin_binary, &["-version"]) {
+ Some(output) => {
+ if output.stdout.is_empty() {
+ Some(output.stderr)
+ } else {
+ Some(output.stdout)
+ }
+ }
+ None => None,
+ }
+}
+
+fn format_kotlin_version(kotlin_stdout: &str) -> Option<String> {
+ // kotlin -version output looks like this:
+ // Kotlin version 1.4.21-release-411 (JRE 14.0.1+7)
+
+ // kotlinc -version output looks like this:
+ // info: kotlinc-jvm 1.4.21 (JRE 14.0.1+7)
+ let re = Regex::new(KOTLIN_VERSION_PATTERN).ok()?;
+ let captures = re.captures(kotlin_stdout)?;
+ let version = &captures["version"];
+ Some(format!("v{}", version))
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use crate::test::ModuleRenderer;
+ use ansi_term::Color;
+ use std::fs::File;
+ use std::io;
+
+ #[test]
+ fn folder_without_kotlin_files() -> io::Result<()> {
+ let dir = tempfile::tempdir()?;
+ let actual = ModuleRenderer::new("kotlin").path(dir.path()).collect();
+ let expected = None;
+ assert_eq!(expected, actual);
+ dir.close()
+ }
+
+ #[test]
+ fn folder_with_kotlin_file() -> io::Result<()> {
+ let dir = tempfile::tempdir()?;
+ File::create(dir.path().join("main.kt"))?.sync_all()?;
+ let actual = ModuleRenderer::new("kotlin").path(dir.path()).collect();
+ let expected = Some(format!("via {} ", Color::Blue.bold().paint("🅺 v1.4.21")));
+ assert_eq!(expected, actual);
+ dir.close()
+ }
+
+ #[test]
+ fn folder_with_kotlin_script_file() -> io::Result<()> {
+ let dir = tempfile::tempdir()?;
+ File::create(dir.path().join("main.kts"))?.sync_all()?;
+ let actual = ModuleRenderer::new("kotlin").path(dir.path()).collect();
+ let expected = Some(format!("via {} ", Color::Blue.bold().paint("🅺 v1.4.21")));
+ assert_eq!(expected, actual);
+ dir.close()
+ }
+
+ #[test]
+ fn kotlin_binary_is_kotlin_runtime() -> io::Result<()> {
+ let dir = tempfile::tempdir()?;
+ File::create(dir.path().join("main.kt"))?.sync_all()?;
+
+ let config = toml::toml! {
+ [kotlin]
+ kotlin_binary = "kotlin"
+ };
+
+ let actual = ModuleRenderer::new("kotlin")
+ .path(dir.path())
+ .config(config)
+ .collect();
+
+ let expected = Some(format!("via {} ", Color::Blue.bold().paint("🅺 v1.4.21")));
+ assert_eq!(expected, actual);
+ dir.close()
+ }
+
+ #[test]
+ fn kotlin_binary_is_kotlin_compiler() -> io::Result<()> {
+ let dir = tempfile::tempdir()?;
+ File::create(dir.path().join("main.kt"))?.sync_all()?;
+
+ let config = toml::toml! {
+ [kotlin]
+ kotlin_binary = "kotlinc"
+ };
+
+ let actual = ModuleRenderer::new("kotlin")
+ .path(dir.path())
+ .config(config)
+ .collect();
+
+ let expected = Some(format!("via {} ", Color::Blue.bold().paint("🅺 v1.4.21")));
+ assert_eq!(expected, actual);
+ dir.close()
+ }
+
+ #[test]
+ fn test_format_kotlin_version_from_runtime() {
+ let kotlin_input = "Kotlin version 1.4.21-release-411 (JRE 14.0.1+7)";
+ assert_eq!(
+ format_kotlin_version(kotlin_input),
+ Some("v1.4.21".to_string())
+ );
+ }
+
+ #[test]
+ fn test_format_kotlin_version_from_compiler() {
+ let kotlin_input = "info: kotlinc-jvm 1.4.21 (JRE 14.0.1+7)";
+ assert_eq!(
+ format_kotlin_version(kotlin_input),
+ Some("v1.4.21".to_string())
+ );
+ }
+}