From 71f03ec3e948e7e8871657bcb19ea65aafea57e8 Mon Sep 17 00:00:00 2001 From: Kuba Clark Date: Fri, 20 Sep 2019 01:02:53 +0200 Subject: [PATCH] feat: Add Java Module (#314) Implements a Java module which shows basic Java information when inside a Java project. --- .github/workflows/continuous-integration.yml | 5 + Cargo.lock | 42 +++----- README.md | 1 + docs/config/README.md | 26 +++++ src/module.rs | 1 + src/modules/java.rs | 105 +++++++++++++++++++ src/modules/mod.rs | 2 + src/print.rs | 1 + tests/Dockerfile | 17 +++ tests/testsuite/java.rs | 26 +++++ tests/testsuite/main.rs | 1 + 11 files changed, 198 insertions(+), 29 deletions(-) create mode 100644 src/modules/java.rs create mode 100644 tests/testsuite/java.rs diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index f4f8de9e..e1b3773d 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -70,6 +70,11 @@ jobs: - uses: actions/setup-python@master with: python-version: "3.6.9" + + # Install Java at a fixed version + - uses: actions/setup-java@master + with: + java-version: '12.0.2' # Run the ignored tests that expect the above setup - uses: actions/checkout@master diff --git a/Cargo.lock b/Cargo.lock index 8791e419..7d461894 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,10 +2,10 @@ # It is not intended for manual editing. [[package]] name = "aho-corasick" -version = "0.7.3" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -255,7 +255,7 @@ dependencies = [ "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -408,7 +408,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "memchr" -version = "2.2.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -638,23 +638,19 @@ dependencies = [ [[package]] name = "regex" -version = "1.1.6" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "aho-corasick 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex-syntax" -version = "0.6.6" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "remove_dir_all" @@ -844,11 +840,6 @@ name = "typenum" version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "ucd-util" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "unicode-bidi" version = "0.3.4" @@ -899,11 +890,6 @@ dependencies = [ "percent-encoding 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "utf8-ranges" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "vcpkg" version = "0.2.6" @@ -961,7 +947,7 @@ dependencies = [ ] [metadata] -"checksum aho-corasick 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e6f484ae0c99fec2e858eb6134949117399f222608d84cadb3f58c1f97c2364c" +"checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "checksum ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" "checksum argon2rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3f67b0b6a86dae6e67ff4ca2b6201396074996379fba2b92ff649126f37cb392" @@ -1008,7 +994,7 @@ dependencies = [ "checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" "checksum mach 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "86dd2487cdfea56def77b88438a2c915fb45113c5319bfe7e14306ca4cd0b0e1" "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" -"checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39" +"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" "checksum memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce6075db033bbbb7ee5a0bbd3a3186bbae616f57fb001c485c7ff77955f8177f" "checksum nix 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0d10caafde29a846a82ae0af70414e4643e072993441033b2c93217957e2f867" "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" @@ -1038,8 +1024,8 @@ dependencies = [ "checksum redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)" = "12229c14a0f65c4f1cb046a3b52047cdd9da1f4b30f8a39c5063c8bae515e252" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" "checksum redox_users 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3fe5204c3a17e97dde73f285d49be585df59ed84b50a872baf416e73b62c3828" -"checksum regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8f0a0bcab2fd7d1d7c54fa9eae6f43eddeb9ce2e7352f8518a814a4f65d60c58" -"checksum regex-syntax 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "dcfd8681eebe297b81d98498869d4aae052137651ad7b96822f09ceb690d0a96" +"checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd" +"checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716" "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" "checksum rustc-demangle 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "ccc78bfd5acd7bf3e89cffcf899e5cb1a52d6fafa8dec2739ad70c9577a57288" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" @@ -1062,7 +1048,6 @@ dependencies = [ "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" "checksum toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c7aabe75941d914b72bf3e5d3932ed92ce0664d49d8432305a8b547c37227724" "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" -"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" "checksum unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "141339a08b982d942be2ca06ff8b076563cbe223d1befd5450716790d44e2426" "checksum unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1967f4cdfc355b37fd76d2a954fb2ed3871034eb4f26d60537d88795cfc332a9" @@ -1070,7 +1055,6 @@ dependencies = [ "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum uom 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "347fe3ff20637a62ab9749a5c90d167302bcbdab77ec961dda7f62a5ca6d368a" "checksum url 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "77ddaf52e65c6b81c56b7e957c0b1970f7937f21c5c6774c4e56fcb4e20b48c6" -"checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737" "checksum vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "def296d3eb3b12371b2c7d0e83bfe1403e4db2d7a0bba324a12b21c4ee13143d" "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" diff --git a/README.md b/README.md index b251dd0e..99cda40d 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,7 @@ The prompt shows information you need while you're working, while staying sleek - Prompt character turns red if the last command exits with non-zero code - Current username if not the same as the logged-in user +- Current Java version(`☕`) - Current Node.js version(`⬢`) - Current Rust version (`🦀`) - Current Ruby version (`💎`) diff --git a/docs/config/README.md b/docs/config/README.md index 427720f6..7aae0099 100644 --- a/docs/config/README.md +++ b/docs/config/README.md @@ -93,6 +93,7 @@ prompt_order = [ "rust", "python", "golang", + "java", "nix_shell", "cmd_duration", "line_break", @@ -493,6 +494,31 @@ impure_msg = "impure shell" pure_msg = "pure shell" ``` +## Java + +The `java` module shows the currently installed version of Java. +The module will be shown if any of the following conditions are met: + +- The current directory contains a `pom.xml` or `build.gradle` file +- The current directory contains a file with the `.java`, `.class` or `.jar` extension + +### Options + +| Variable | Default | Description | +| ---------- | -------------- | -------------------------------------------------------- | +| `symbol` | `"☕ "` | The symbol used before displaying the version of Java. | +| `style` | `"dimmed red"` | The style for the module. | +| `disabled` | `false` | Disables the `java` module. | + +### Example + +```toml +# ~/.config/starship.toml + +[java] +symbol = "🌟 " +``` + ## NodeJS diff --git a/src/module.rs b/src/module.rs index 6a55a0c8..62483486 100644 --- a/src/module.rs +++ b/src/module.rs @@ -16,6 +16,7 @@ pub const ALL_MODULES: &[&str] = &[ "git_status", "golang", "hostname", + "java", "jobs", "line_break", "nix_shell", diff --git a/src/modules/java.rs b/src/modules/java.rs new file mode 100644 index 00000000..9bd9c736 --- /dev/null +++ b/src/modules/java.rs @@ -0,0 +1,105 @@ +use std::process::Command; + +use ansi_term::Color; + +use super::{Context, Module}; + +/// Creates a module with the current Java version +/// +/// Will display the Java version if any of the following criteria are met: +/// - Current directory contains a file with a `.java`, `.class` or `.jar` extension +/// - Current directory contains a `pom.xml` or `build.gradle` file +pub fn module<'a>(context: &'a Context) -> Option> { + let is_java_project = context + .try_begin_scan()? + .set_files(&["pom.xml", "build.gradle"]) + .set_extensions(&["java", "class", "jar"]) + .is_match(); + + if !is_java_project { + return None; + } + + match get_java_version() { + Some(java_version) => { + const JAVA_CHAR: &str = "☕ "; + + let mut module = context.new_module("java"); + let module_style = module + .config_value_style("style") + .unwrap_or_else(|| Color::Red.dimmed()); + module.set_style(module_style); + + let formatted_version = format_java_version(java_version)?; + module.new_segment("symbol", JAVA_CHAR); + module.new_segment("version", &formatted_version); + + Some(module) + } + None => None, + } +} + +fn get_java_version() -> Option { + let java_command = match std::env::var("JAVA_HOME") { + Ok(java_home) => format!("{}/bin/java", java_home), + Err(_) => String::from("java"), + }; + + match Command::new(java_command).arg("-Xinternalversion").output() { + Ok(output) => Some(String::from_utf8(output.stdout).unwrap()), + Err(_) => None, + } +} + +/// Extract the java version from `java_stdout`. +/// The expected format is similar to: "JRE (1.8.0_222-b10)". +/// Some Java vendors don't follow this format: "JRE (Zulu 8.40.0.25-CA-linux64)"). +fn format_java_version(java_stdout: String) -> Option { + let start = java_stdout.find("JRE (")? + "JRE (".len(); + let end = start + + (java_stdout[start..].find(|c| match c { + '0'..='9' | '.' => false, + _ => true, + })?); + + if start == end { + None + } else { + Some(format!("v{}", &java_stdout[start..end])) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_format_java_version_openjdk() { + let java_8 = String::from("OpenJDK 64-Bit Server VM (25.222-b10) for linux-amd64 JRE (1.8.0_222-b10), built on Jul 11 2019 10:18:43 by \"openjdk\" with gcc 4.4.7 20120313 (Red Hat 4.4.7-23)"); + let java_11 = String::from("OpenJDK 64-Bit Server VM (11.0.4+11-post-Ubuntu-1ubuntu219.04) for linux-amd64 JRE (11.0.4+11-post-Ubuntu-1ubuntu219.04), built on Jul 18 2019 18:21:46 by \"build\" with gcc 8.3.0"); + assert_eq!(format_java_version(java_11), Some(String::from("v11.0.4"))); + assert_eq!(format_java_version(java_8), Some(String::from("v1.8.0"))); + } + + #[test] + fn test_format_java_version_oracle() { + let java_8 = String::from("Java HotSpot(TM) Client VM (25.65-b01) for linux-arm-vfp-hflt JRE (1.8.0_65-b17), built on Oct 6 2015 16:19:04 by \"java_re\" with gcc 4.7.2 20120910 (prerelease)"); + assert_eq!(format_java_version(java_8), Some(String::from("v1.8.0"))); + } + + #[test] + fn test_format_java_version_redhat() { + let java_8 = String::from("OpenJDK 64-Bit Server VM (25.222-b10) for linux-amd64 JRE (1.8.0_222-b10), built on Jul 11 2019 20:48:53 by \"root\" with gcc 7.3.1 20180303 (Red Hat 7.3.1-5)"); + let java_12 = String::from("OpenJDK 64-Bit Server VM (12.0.2+10) for linux-amd64 JRE (12.0.2+10), built on Jul 18 2019 14:41:47 by \"jenkins\" with gcc 7.3.1 20180303 (Red Hat 7.3.1-5)"); + assert_eq!(format_java_version(java_8), Some(String::from("v1.8.0"))); + assert_eq!(format_java_version(java_12), Some(String::from("v12.0.2"))); + } + + #[test] + fn test_format_java_version_zulu() { + // Not currently supported + let java_8 = String::from("OpenJDK 64-Bit Server VM (25.222-b10) for linux-amd64 JRE (Zulu 8.40.0.25-CA-linux64) (1.8.0_222-b10), built on Jul 11 2019 11:36:39 by \"zulu_re\" with gcc 4.4.7 20120313 (Red Hat 4.4.7-3)"); + assert_eq!(format_java_version(java_8), None); + } +} diff --git a/src/modules/mod.rs b/src/modules/mod.rs index 34f1cc12..40590618 100644 --- a/src/modules/mod.rs +++ b/src/modules/mod.rs @@ -7,6 +7,7 @@ mod git_state; mod git_status; mod golang; mod hostname; +mod java; mod jobs; mod line_break; mod nix_shell; @@ -42,6 +43,7 @@ pub fn handle<'a>(module: &str, context: &'a Context) -> Option> { #[cfg(feature = "battery")] "battery" => battery::module(context), "cmd_duration" => cmd_duration::module(context), + "java" => java::module(context), "jobs" => jobs::module(context), "nix_shell" => nix_shell::module(context), "hostname" => hostname::module(context), diff --git a/src/print.rs b/src/print.rs index 6faf13ce..12e98fb2 100644 --- a/src/print.rs +++ b/src/print.rs @@ -24,6 +24,7 @@ const DEFAULT_PROMPT_ORDER: &[&str] = &[ "rust", "python", "golang", + "java", "nix_shell", "cmd_duration", "line_break", diff --git a/tests/Dockerfile b/tests/Dockerfile index f7fcae66..58d54462 100644 --- a/tests/Dockerfile +++ b/tests/Dockerfile @@ -48,6 +48,23 @@ RUN curl https://pyenv.run | bash \ # Check that Python was correctly installed RUN python --version +# Install Java. +ENV JAVA_HOME /home/nonroot/java +ENV PATH $JAVA_HOME/bin:$PATH +ENV JAVA_URL https://download.java.net/java/GA/jdk12.0.2/e482c34c86bd4bf8b56c0b35558996b9/10/GPL/openjdk-12.0.2_linux-x64_bin.tar.gz + +RUN mkdir -p "$JAVA_HOME"; \ +RUN set -eux; \ + curl -fL -o $JAVA_HOME/openjdk.tgz "$JAVA_URL"; \ + tar --extract \ + --file $JAVA_HOME/openjdk.tgz \ + --directory "$JAVA_HOME" \ + --strip-components 1 \ + --no-same-owner \ + ; \ +RUN java -version; \ + javac -version + # Create blank project RUN USER=nonroot cargo new --bin /src/starship WORKDIR /src/starship diff --git a/tests/testsuite/java.rs b/tests/testsuite/java.rs new file mode 100644 index 00000000..9cced9d0 --- /dev/null +++ b/tests/testsuite/java.rs @@ -0,0 +1,26 @@ +use std::fs::File; +use std::io; + +use ansi_term::Color; + +use crate::common; + +// When these tests run in the CI, they use Azul's Zulu Java distribution. +// The version format returned by this java package is irregular and not supported (yet). + +//#[test] +//#[ignore] +//fn folder_with_pom() -> io::Result<()> { +// let dir = common::new_tempdir()?; +// File::create(dir.path().join("pom.xml"))?; +// +// let output = common::render_module("java") +// .arg("--path") +// .arg(dir.path()) +// .output()?; +// let actual = String::from_utf8(output.stdout).unwrap(); +// +// let expected = format!("via {} ", Color::Red.dimmed().paint("☕ ")); +// assert_eq!(expected, actual); +// Ok(()) +//} diff --git a/tests/testsuite/main.rs b/tests/testsuite/main.rs index f92a702c..d299ca61 100644 --- a/tests/testsuite/main.rs +++ b/tests/testsuite/main.rs @@ -8,6 +8,7 @@ mod git_state; mod git_status; mod golang; mod hostname; +mod java; mod jobs; mod line_break; mod modules;