diff --git a/README.md b/README.md index 27cbb4dd..e3f9d499 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,7 @@ The prompt shows information you need while you're working, while staying sleek - Current Python version (`🐍`) - Current Go version (`🐹`) - Nix-shell environment detection +- Print an environment variable - Current version of package in current directory (`📦`) - npm (Node.js) - cargo (Rust) diff --git a/docs/config/README.md b/docs/config/README.md index d21df11b..c1d296ae 100644 --- a/docs/config/README.md +++ b/docs/config/README.md @@ -84,7 +84,6 @@ prompt_order = [ "username", "hostname", "directory", - "aws", "git_branch", "git_state", "git_status", @@ -96,6 +95,8 @@ prompt_order = [ "golang", "java", "nix_shell", + "aws", + "env_var", "cmd_duration", "line_break", "jobs", @@ -309,6 +310,36 @@ it would have been `nixpkgs/pkgs`. truncation_length = 8 ``` +## Environment Variable + +The `env_var` module displays the current value of a selected environment variable. +The module will be shown only if any of the following conditions are met: + +- The `variable` configuration option matches an existing environment variable +- The `variable` configuration option is not defined, but the `default` configuration option is + +### Options + +| Variable | Default | Description | +| ---------- | ---------------- | ---------------------------------------------------------------------------- | +| `symbol` | | The symbol used before displaying the variable value. | +| `variable` | | The environment variable to be displayed. | +| `default` | | The default value to be displayed when the selected variable is not defined. | +| `prefix` | `""` | Prefix to display immediately before the variable value. | +| `suffix` | `""` | Suffix to display immediately after the variable value. | +| `style` | `"dimmed black"` | The style for the module. | +| `disabled` | `false` | Disables the `env_var` module. | + +### Example + +```toml +# ~/.config/starship.toml + +[env_var] +variable = "SHELL" +default = "unknown shell" +``` + ## Git Branch The `git_branch` module shows the active branch of the repo in your current directory. diff --git a/src/module.rs b/src/module.rs index 47c5eabf..7ebfa53e 100644 --- a/src/module.rs +++ b/src/module.rs @@ -12,6 +12,7 @@ pub const ALL_MODULES: &[&str] = &[ "character", "cmd_duration", "directory", + "env_var", "git_branch", "git_state", "git_status", diff --git a/src/modules/env_var.rs b/src/modules/env_var.rs new file mode 100644 index 00000000..bb46456a --- /dev/null +++ b/src/modules/env_var.rs @@ -0,0 +1,43 @@ +use ansi_term::Color; +use std::env; + +use super::{Context, Module}; + +/// Creates a module with the value of the chosen environment variable +/// +/// Will display the environment variable's value if all of the following criteria are met: +/// - env_var.disabled is absent or false +/// - env_var.variable is defined +/// - a variable named as the value of env_var.variable is defined +pub fn module<'a>(context: &'a Context) -> Option> { + let mut module = context.new_module("env_var"); + let module_style = module + .config_value_style("style") + .unwrap_or_else(|| Color::Black.bold().dimmed()); + + let env_name = module.config_value_str("variable")?; + + let default_value = module.config_value_str("default"); + + let env_value = get_env_value(env_name, default_value)?; + + let prefix = module.config_value_str("prefix").unwrap_or("").to_owned(); + let suffix = module.config_value_str("suffix").unwrap_or("").to_owned(); + + module.set_style(module_style); + module.get_prefix().set_value("with "); + module.new_segment_if_config_exists("symbol"); + module.new_segment("env_var", &format!("{}{}{}", prefix, env_value, suffix)); + + Some(module) +} + +fn get_env_value(name: &str, default: Option<&str>) -> Option { + match env::var_os(name) { + Some(os_value) => match os_value.into_string() { + Ok(value) => Some(value), + Err(_error) => None, + }, + None => default.map(|value| value.to_owned()), + } +} diff --git a/src/modules/mod.rs b/src/modules/mod.rs index c1618252..82d3614a 100644 --- a/src/modules/mod.rs +++ b/src/modules/mod.rs @@ -3,6 +3,7 @@ mod aws; mod character; mod cmd_duration; mod directory; +mod env_var; mod git_branch; mod git_state; mod git_status; @@ -30,6 +31,7 @@ pub fn handle<'a>(module: &str, context: &'a Context) -> Option> { match module { "aws" => aws::module(context), "directory" => directory::module(context), + "env_var" => env_var::module(context), "character" => character::module(context), "nodejs" => nodejs::module(context), "rust" => rust::module(context), diff --git a/src/print.rs b/src/print.rs index 1c7e4670..18fe5ea1 100644 --- a/src/print.rs +++ b/src/print.rs @@ -15,7 +15,6 @@ const DEFAULT_PROMPT_ORDER: &[&str] = &[ "username", "hostname", "directory", - "aws", "git_branch", "git_state", "git_status", @@ -27,6 +26,8 @@ const DEFAULT_PROMPT_ORDER: &[&str] = &[ "golang", "java", "nix_shell", + "aws", + "env_var", "cmd_duration", "line_break", "jobs", diff --git a/tests/testsuite/env_var.rs b/tests/testsuite/env_var.rs new file mode 100644 index 00000000..2464c615 --- /dev/null +++ b/tests/testsuite/env_var.rs @@ -0,0 +1,141 @@ +use ansi_term::{Color, Style}; +use std::io; + +use crate::common; +use crate::common::TestCommand; + +const TEST_VAR_VALUE: &str = "astronauts"; + +#[test] +fn empty_config() -> io::Result<()> { + let output = common::render_module("env_var") + .env_clear() + .use_config(toml::toml! { + [env_var] + }) + .output()?; + let expected = ""; + let actual = String::from_utf8(output.stdout).unwrap(); + assert_eq!(expected, actual); + Ok(()) +} + +#[test] +fn defined_variable() -> io::Result<()> { + let output = common::render_module("env_var") + .env_clear() + .use_config(toml::toml! { + [env_var] + variable = "TEST_VAR" + }) + .env("TEST_VAR", TEST_VAR_VALUE) + .output()?; + let expected = format!("with {} ", style().paint(TEST_VAR_VALUE)); + let actual = String::from_utf8(output.stdout).unwrap(); + assert_eq!(expected, actual); + Ok(()) +} + +#[test] +fn undefined_variable() -> io::Result<()> { + let output = common::render_module("env_var") + .env_clear() + .use_config(toml::toml! { + [env_var] + variable = "TEST_VAR" + }) + .output()?; + let expected = ""; + let actual = String::from_utf8(output.stdout).unwrap(); + assert_eq!(expected, actual); + Ok(()) +} + +#[test] +fn default_has_no_effect() -> io::Result<()> { + let output = common::render_module("env_var") + .env_clear() + .use_config(toml::toml! { + [env_var] + variable = "TEST_VAR" + default = "N/A" + }) + .env("TEST_VAR", TEST_VAR_VALUE) + .output()?; + let expected = format!("with {} ", style().paint(TEST_VAR_VALUE)); + let actual = String::from_utf8(output.stdout).unwrap(); + assert_eq!(expected, actual); + Ok(()) +} + +#[test] +fn default_takes_effect() -> io::Result<()> { + let output = common::render_module("env_var") + .env_clear() + .use_config(toml::toml! { + [env_var] + variable = "UNDEFINED_TEST_VAR" + default = "N/A" + }) + .output()?; + let expected = format!("with {} ", style().paint("N/A")); + let actual = String::from_utf8(output.stdout).unwrap(); + assert_eq!(expected, actual); + Ok(()) +} + +#[test] +fn symbol() -> io::Result<()> { + let output = common::render_module("env_var") + .env_clear() + .use_config(toml::toml! { + [env_var] + symbol = "■ " + variable = "TEST_VAR" + }) + .env("TEST_VAR", TEST_VAR_VALUE) + .output()?; + let expected = format!("with {} ", style().paint(format!("■ {}", TEST_VAR_VALUE))); + let actual = String::from_utf8(output.stdout).unwrap(); + assert_eq!(expected, actual); + Ok(()) +} + +#[test] +fn prefix() -> io::Result<()> { + let output = common::render_module("env_var") + .env_clear() + .use_config(toml::toml! { + [env_var] + variable = "TEST_VAR" + prefix = "_" + }) + .env("TEST_VAR", TEST_VAR_VALUE) + .output()?; + let expected = format!("with {} ", style().paint(format!("_{}", TEST_VAR_VALUE))); + let actual = String::from_utf8(output.stdout).unwrap(); + assert_eq!(expected, actual); + Ok(()) +} + +#[test] +fn suffix() -> io::Result<()> { + let output = common::render_module("env_var") + .env_clear() + .use_config(toml::toml! { + [env_var] + variable = "TEST_VAR" + suffix = "_" + }) + .env("TEST_VAR", TEST_VAR_VALUE) + .output()?; + let expected = format!("with {} ", style().paint(format!("{}_", TEST_VAR_VALUE))); + let actual = String::from_utf8(output.stdout).unwrap(); + assert_eq!(expected, actual); + Ok(()) +} + +fn style() -> Style { + // default style + Color::Black.bold().dimmed() +} diff --git a/tests/testsuite/main.rs b/tests/testsuite/main.rs index 89f573f9..5506e221 100644 --- a/tests/testsuite/main.rs +++ b/tests/testsuite/main.rs @@ -4,6 +4,7 @@ mod cmd_duration; mod common; mod configuration; mod directory; +mod env_var; mod git_branch; mod git_state; mod git_status;