From 8c17f7b97c1f59ac65f20aa4cc866bb19f1b9fc6 Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Mon, 27 Apr 2020 12:09:42 +0200 Subject: [PATCH] feat(erlang): Add Erlang module (#1129) --- docs/config/README.md | 24 +++++++++++ src/configs/erlang.rs | 23 +++++++++++ src/configs/mod.rs | 1 + src/configs/starship_root.rs | 1 + src/module.rs | 1 + src/modules/erlang.rs | 79 ++++++++++++++++++++++++++++++++++++ src/modules/mod.rs | 3 ++ src/utils.rs | 4 ++ 8 files changed, 136 insertions(+) create mode 100644 src/configs/erlang.rs create mode 100644 src/modules/erlang.rs diff --git a/docs/config/README.md b/docs/config/README.md index 8b7498d6..64fefd1c 100644 --- a/docs/config/README.md +++ b/docs/config/README.md @@ -105,6 +105,7 @@ prompt_order = [ "dotnet", "elixir", "elm", + "erlang", "golang", "haskell", "java", @@ -521,6 +522,29 @@ The module will be shown if any of the following conditions are met: symbol = " " ``` +## Erlang + +The `erlang` module shows the currently installed version of Erlang/OTP. +The module will be shown if any of the following conditions are met: + +- The current directory contains a `rebar.config` file. +- The current directory contains a `erlang.mk` file. + +### Options + +| Variable | Default | Description | +| ---------- | ------- | --------------------------------------------------------------- | +| `symbol` | `"🖧 "` | The symbol used before displaying the version of Erlang. | +| `disabled` | `false` | Disables the `erlang` module. | + +### Example + +```toml +# ~/.config/starship.toml + +[erlang] +symbol = "e " +``` ## Environment Variable The `env_var` module displays the current value of a selected environment variable. diff --git a/src/configs/erlang.rs b/src/configs/erlang.rs new file mode 100644 index 00000000..bad77580 --- /dev/null +++ b/src/configs/erlang.rs @@ -0,0 +1,23 @@ +use crate::config::{ModuleConfig, RootModuleConfig, SegmentConfig}; + +use ansi_term::{Color, Style}; +use starship_module_config_derive::ModuleConfig; + +#[derive(Clone, ModuleConfig)] +pub struct ErlangConfig<'a> { + pub symbol: SegmentConfig<'a>, + pub version: SegmentConfig<'a>, + pub style: Style, + pub disabled: bool, +} + +impl<'a> RootModuleConfig<'a> for ErlangConfig<'a> { + fn new() -> Self { + ErlangConfig { + symbol: SegmentConfig::new("🖧 "), + version: SegmentConfig::default(), + style: Color::Red.bold(), + disabled: false, + } + } +} diff --git a/src/configs/mod.rs b/src/configs/mod.rs index fcbbd7f3..26abbe0c 100644 --- a/src/configs/mod.rs +++ b/src/configs/mod.rs @@ -11,6 +11,7 @@ pub mod dotnet; pub mod elixir; pub mod elm; pub mod env_var; +pub mod erlang; pub mod git_branch; pub mod git_commit; pub mod git_state; diff --git a/src/configs/starship_root.rs b/src/configs/starship_root.rs index 948e73dd..edcc3147 100644 --- a/src/configs/starship_root.rs +++ b/src/configs/starship_root.rs @@ -34,6 +34,7 @@ impl<'a> RootModuleConfig<'a> for StarshipRootConfig<'a> { "dotnet", "elixir", "elm", + "erlang", "golang", "haskell", "java", diff --git a/src/module.rs b/src/module.rs index 486ad8a4..bf08427a 100644 --- a/src/module.rs +++ b/src/module.rs @@ -21,6 +21,7 @@ pub const ALL_MODULES: &[&str] = &[ "dotnet", "elixir", "elm", + "erlang", "env_var", "git_branch", "git_commit", diff --git a/src/modules/erlang.rs b/src/modules/erlang.rs new file mode 100644 index 00000000..505d34eb --- /dev/null +++ b/src/modules/erlang.rs @@ -0,0 +1,79 @@ +use super::{Context, Module, RootModuleConfig}; + +use crate::configs::erlang::ErlangConfig; + +/// Create a module with the current Erlang version +/// +/// Will display the Erlang version if any of the following criteria are met: +/// - Current directory contains a rebar.config file +/// - Current directory contains a erlang.mk file +pub fn module<'a>(context: &'a Context) -> Option> { + let is_erlang_project = context + .try_begin_scan()? + .set_files(&["rebar.config", "erlang.mk"]) + .is_match(); + + if !is_erlang_project { + return None; + } + + let erlang_version = get_erlang_version()?; + + let mut module = context.new_module("erlang"); + let config = ErlangConfig::try_load(module.config); + module.set_style(config.style); + + module.create_segment("symbol", &config.symbol); + module.create_segment("version", &config.version.with_value(&erlang_version)); + + Some(module) +} + +fn get_erlang_version() -> Option { + use crate::utils; + + Some(utils::exec_cmd( + "erl", + &[ + "-noshell", + "-eval", + "Fn=filename:join([code:root_dir(),\"releases\",erlang:system_info(otp_release),\"OTP_VERSION\"]),\ + {ok,Content}=file:read_file(Fn),\ + io:format(\"~s\",[Content]),\ + halt(0)." + ] + )?.stdout.trim().to_string()) +} + +#[cfg(test)] +mod tests { + use crate::modules::utils::test::render_module; + use ansi_term::Color; + use std::fs::File; + use std::io; + + #[test] + fn test_without_config() -> io::Result<()> { + let dir = tempfile::tempdir()?; + + let expected = None; + let output = render_module("erlang", dir.path()); + + assert_eq!(output, expected); + + dir.close() + } + + #[test] + fn test_with_config() -> io::Result<()> { + let dir = tempfile::tempdir()?; + File::create(dir.path().join("rebar.config"))?.sync_all()?; + + let expected = Some(format!("via {} ", Color::Red.bold().paint("🖧 22.1.3"))); + let output = render_module("erlang", dir.path()); + + assert_eq!(output, expected); + + dir.close() + } +} diff --git a/src/modules/mod.rs b/src/modules/mod.rs index 5c94cb41..1e4ac6f4 100644 --- a/src/modules/mod.rs +++ b/src/modules/mod.rs @@ -11,6 +11,7 @@ mod dotnet; mod elixir; mod elm; mod env_var; +mod erlang; mod git_branch; mod git_commit; mod git_state; @@ -60,6 +61,7 @@ pub fn handle<'a>(module: &str, context: &'a Context) -> Option> { "dotnet" => dotnet::module(context), "elixir" => elixir::module(context), "elm" => elm::module(context), + "erlang" => erlang::module(context), "env_var" => env_var::module(context), "git_branch" => git_branch::module(context), "git_commit" => git_commit::module(context), @@ -108,6 +110,7 @@ pub fn description(module: &str) -> &'static str { "docker_context" => "The current docker context", "dotnet" => "The relevant version of the .NET Core SDK for the current directory", "env_var" => "Displays the current value of a selected environment variable", + "erlang" => "Current OTP version", "git_branch" => "The active branch of the repo in your current directory", "git_commit" => "The active commit of the repo in your current directory", "git_state" => "The current git operation, and it's progress", diff --git a/src/utils.rs b/src/utils.rs index c3ec138b..37444fab 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -86,6 +86,10 @@ Elixir 1.10 (compiled with Erlang/OTP 22)", ), stderr: String::default(), }), + s if s.starts_with("erl") => Some(CommandOutput { + stdout: String::from("22.1.3"), + stderr: String::default(), + }), // If we don't have a mocked command fall back to executing the command _ => internal_exec_cmd(&cmd, &args), }