From fa1267f12f60510d6214476e3d059edcb861f0c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Da=20Fonseca?= Date: Sat, 2 Nov 2019 12:08:54 +0100 Subject: [PATCH] feat: Add configuration to set how much AWS profile info is shown (#556) --- docs/config/README.md | 12 ++-- src/configs/aws.rs | 20 ++++++ src/modules/aws.rs | 89 ++++++++++++++++----------- tests/testsuite/aws.rs | 136 ++++++++++++++++++++++++++++++++++++++--- 4 files changed, 210 insertions(+), 47 deletions(-) diff --git a/docs/config/README.md b/docs/config/README.md index 897e8697..eab725b0 100644 --- a/docs/config/README.md +++ b/docs/config/README.md @@ -123,11 +123,12 @@ The `aws` module shows the current AWS region and profile. This is based on ### Options -| Variable | Default | Description | -| ---------- | --------------- | ---------------------------------------------------------- | -| `symbol` | `"☁️ "` | The symbol used before displaying the current AWS profile. | -| `style` | `"bold yellow"` | The style for the module. | -| `disabled` | `false` | Disables the `AWS` module. | +| Variable | Default | Description | +| ----------------- | --------------- | ----------------------------------------------------------------------------| +| `symbol` | `"☁️ "` | The symbol used before displaying the current AWS profile. | +| `style` | `"bold yellow"` | The style for the module. | +| `disabled` | `false` | Disables the `AWS` module. | +| `displayed_items` | `all` | Choose which item to display. Possible values: [`all`, `profile`, `region`] | ### Example @@ -137,6 +138,7 @@ The `aws` module shows the current AWS region and profile. This is based on [aws] style = "bold blue" symbol = "🅰 " +displayed_items = "region" ``` ## Battery diff --git a/src/configs/aws.rs b/src/configs/aws.rs index a4dc4ca7..54dca305 100644 --- a/src/configs/aws.rs +++ b/src/configs/aws.rs @@ -3,6 +3,13 @@ use crate::config::{ModuleConfig, RootModuleConfig, SegmentConfig}; use ansi_term::{Color, Style}; use starship_module_config_derive::ModuleConfig; +#[derive(Clone, PartialEq)] +pub enum AwsItems { + All, + Region, + Profile, +} + #[derive(Clone, ModuleConfig)] pub struct AwsConfig<'a> { pub symbol: SegmentConfig<'a>, @@ -10,6 +17,7 @@ pub struct AwsConfig<'a> { pub region: SegmentConfig<'a>, pub style: Style, pub disabled: bool, + pub displayed_items: AwsItems, } impl<'a> RootModuleConfig<'a> for AwsConfig<'a> { @@ -20,6 +28,18 @@ impl<'a> RootModuleConfig<'a> for AwsConfig<'a> { region: SegmentConfig::default(), style: Color::Yellow.bold(), disabled: false, + displayed_items: AwsItems::All, + } + } +} + +impl<'a> ModuleConfig<'a> for AwsItems { + fn from_config(config: &toml::Value) -> Option { + match config.as_str()? { + "all" => Some(AwsItems::All), + "region" => Some(AwsItems::Region), + "profile" => Some(AwsItems::Profile), + _ => None, } } } diff --git a/src/modules/aws.rs b/src/modules/aws.rs index 9225c0fe..ceb36c85 100644 --- a/src/modules/aws.rs +++ b/src/modules/aws.rs @@ -8,9 +8,12 @@ use dirs::home_dir; use super::{Context, Module, RootModuleConfig}; -use crate::configs::aws::AwsConfig; +use crate::configs::aws::{AwsConfig, AwsItems}; -fn get_aws_region_from_config(aws_profile: &Option) -> Option { +type Profile = String; +type Region = String; + +fn get_aws_region_from_config(aws_profile: Option<&str>) -> Option { let config_location = env::var("AWS_CONFIG_FILE") .ok() .and_then(|path| PathBuf::from_str(&path).ok()) @@ -44,43 +47,38 @@ fn get_aws_region_from_config(aws_profile: &Option) -> Option { Some(region.to_string()) } -fn get_aws_region() -> Option<(String, String)> { - env::var("AWS_DEFAULT_REGION") - .ok() - .map(|region| (String::new(), region)) - .or_else(|| { - let aws_profile = env::var("AWS_PROFILE").ok(); - let aws_region = get_aws_region_from_config(&aws_profile); +fn get_aws_profile_and_region() -> (Option, Option) { + match ( + env::var("AWS_PROFILE").ok(), + env::var("AWS_REGION").ok(), + env::var("AWS_DEFAULT_REGION").ok(), + ) { + (Some(p), Some(_), Some(dr)) => (Some(p), Some(dr)), + (Some(p), Some(r), None) => (Some(p), Some(r)), + (None, Some(r), None) => (None, Some(r)), + (Some(p), None, Some(dr)) => (Some(p), Some(dr)), + (Some(ref p), None, None) => (Some(p.to_owned()), get_aws_region_from_config(Some(p))), + (None, None, Some(dr)) => (None, Some(dr)), + (None, Some(_), Some(dr)) => (None, Some(dr)), + (None, None, None) => (None, get_aws_region_from_config(None)), + } +} - if aws_profile.is_none() && aws_region.is_none() { - None - } else { - Some(( - aws_profile.unwrap_or_default(), - aws_region.unwrap_or_default(), - )) - } - }) - .or_else(|| { - env::var("AWS_REGION") - .ok() - .map(|region| (String::new(), region)) - }) +fn get_aws_region() -> Option { + match ( + env::var("AWS_REGION").ok(), + env::var("AWS_DEFAULT_REGION").ok(), + ) { + (Some(r), None) => Some(r), + (None, Some(dr)) => Some(dr), + (Some(_), Some(dr)) => Some(dr), + (None, None) => get_aws_region_from_config(None), + } } pub fn module<'a>(context: &'a Context) -> Option> { const AWS_PREFIX: &str = "on "; - let (aws_profile, aws_region) = get_aws_region()?; - if aws_profile.is_empty() && aws_region.is_empty() { - return None; - } - let aws_region = if aws_profile.is_empty() || aws_region.is_empty() { - aws_region - } else { - format!("({})", aws_region) - }; - let mut module = context.new_module("aws"); let config: AwsConfig = AwsConfig::try_load(module.config); @@ -89,8 +87,29 @@ pub fn module<'a>(context: &'a Context) -> Option> { module.get_prefix().set_value(AWS_PREFIX); module.create_segment("symbol", &config.symbol); - module.create_segment("profile", &config.profile.with_value(&aws_profile)); - module.create_segment("region", &config.profile.with_value(&aws_region)); + match config.displayed_items { + AwsItems::All => { + let (aws_profile, aws_region) = get_aws_profile_and_region(); + + let aws_segment = match (&aws_profile, &aws_region) { + (None, None) => return None, + (Some(p), Some(r)) => format!("{}({})", p, r), + (Some(p), None) => p.to_string(), + (None, Some(r)) => r.to_string(), + }; + module.create_segment("all", &config.region.with_value(&aws_segment)); + } + AwsItems::Profile => { + let aws_profile = env::var("AWS_PROFILE").ok()?; + + module.create_segment("profile", &config.profile.with_value(&aws_profile)); + } + AwsItems::Region => { + let aws_region = get_aws_region()?; + + module.create_segment("region", &config.region.with_value(&aws_region)); + } + }; Some(module) } diff --git a/tests/testsuite/aws.rs b/tests/testsuite/aws.rs index 12da2392..766d16d1 100644 --- a/tests/testsuite/aws.rs +++ b/tests/testsuite/aws.rs @@ -4,12 +4,11 @@ use std::io::{self, Write}; use ansi_term::Color; use tempfile; -use crate::common; +use crate::common::{self, TestCommand}; #[test] fn no_region_set() -> io::Result<()> { let output = common::render_module("aws") - .env_clear() .env("PATH", env!("PATH")) .output()?; let expected = ""; @@ -21,7 +20,6 @@ fn no_region_set() -> io::Result<()> { #[test] fn region_set() -> io::Result<()> { let output = common::render_module("aws") - .env_clear() .env("AWS_REGION", "ap-northeast-2") .output()?; let expected = format!("on {} ", Color::Yellow.bold().paint("☁️ ap-northeast-2")); @@ -33,7 +31,6 @@ fn region_set() -> io::Result<()> { #[test] fn default_region_set() -> io::Result<()> { let output = common::render_module("aws") - .env_clear() .env("AWS_REGION", "ap-northeast-2") .env("AWS_DEFAULT_REGION", "ap-northeast-1") .output()?; @@ -46,7 +43,6 @@ fn default_region_set() -> io::Result<()> { #[test] fn profile_set() -> io::Result<()> { let output = common::render_module("aws") - .env_clear() .env("AWS_PROFILE", "astronauts") .output()?; let expected = format!("on {} ", Color::Yellow.bold().paint("☁️ astronauts")); @@ -55,6 +51,21 @@ fn profile_set() -> io::Result<()> { Ok(()) } +#[test] +fn profile_and_region_set() -> io::Result<()> { + let output = common::render_module("aws") + .env("AWS_PROFILE", "astronauts") + .env("AWS_REGION", "ap-northeast-2") + .output()?; + let expected = format!( + "on {} ", + Color::Yellow.bold().paint("☁️ astronauts(ap-northeast-2)") + ); + let actual = String::from_utf8(output.stdout).unwrap(); + assert_eq!(expected, actual); + Ok(()) +} + #[test] fn default_profile_set() -> io::Result<()> { let dir = tempfile::tempdir()?; @@ -72,7 +83,6 @@ region = us-east-2 )?; let output = common::render_module("aws") - .env_clear() .env("AWS_CONFIG_FILE", config_path.to_string_lossy().as_ref()) .output()?; let expected = format!("on {} ", Color::Yellow.bold().paint("☁️ us-east-1")); @@ -98,9 +108,11 @@ region = us-east-2 )?; let output = common::render_module("aws") - .env_clear() .env("AWS_CONFIG_FILE", config_path.to_string_lossy().as_ref()) .env("AWS_PROFILE", "astronauts") + .use_config(toml::toml! { + [aws] + }) .output()?; let expected = format!( "on {} ", @@ -110,3 +122,113 @@ region = us-east-2 assert_eq!(expected, actual); Ok(()) } + +#[test] +fn profile_and_region_set_with_display_all() -> io::Result<()> { + let output = common::render_module("aws") + .env("AWS_PROFILE", "astronauts") + .env("AWS_REGION", "ap-northeast-1") + .use_config(toml::toml! { + [aws] + displayed_items = "all" + }) + .output()?; + let expected = format!( + "on {} ", + Color::Yellow.bold().paint("☁️ astronauts(ap-northeast-1)") + ); + let actual = String::from_utf8(output.stdout).unwrap(); + assert_eq!(expected, actual); + Ok(()) +} + +#[test] +fn profile_set_with_display_all() -> io::Result<()> { + let output = common::render_module("aws") + .env("AWS_PROFILE", "astronauts") + .use_config(toml::toml! { + [aws] + displayed_items = "all" + }) + .output()?; + let expected = format!("on {} ", Color::Yellow.bold().paint("☁️ astronauts")); + let actual = String::from_utf8(output.stdout).unwrap(); + assert_eq!(expected, actual); + Ok(()) +} + +#[test] +fn region_set_with_display_all() -> io::Result<()> { + let output = common::render_module("aws") + .env("AWS_REGION", "ap-northeast-1") + .use_config(toml::toml! { + [aws] + displayed_items = "all" + }) + .output()?; + let expected = format!("on {} ", Color::Yellow.bold().paint("☁️ ap-northeast-1")); + let actual = String::from_utf8(output.stdout).unwrap(); + assert_eq!(expected, actual); + Ok(()) +} + +#[test] +fn profile_and_region_set_with_display_region() -> io::Result<()> { + let output = common::render_module("aws") + .env("AWS_PROFILE", "astronauts") + .env("AWS_DEFAULT_REGION", "ap-northeast-1") + .use_config(toml::toml! { + [aws] + displayed_items = "region" + }) + .output()?; + let expected = format!("on {} ", Color::Yellow.bold().paint("☁️ ap-northeast-1")); + let actual = String::from_utf8(output.stdout).unwrap(); + assert_eq!(expected, actual); + Ok(()) +} + +#[test] +fn profile_and_region_set_with_display_profile() -> io::Result<()> { + let output = common::render_module("aws") + .env("AWS_PROFILE", "astronauts") + .env("AWS_REGION", "ap-northeast-1") + .use_config(toml::toml! { + [aws] + displayed_items = "profile" + }) + .output()?; + let expected = format!("on {} ", Color::Yellow.bold().paint("☁️ astronauts")); + let actual = String::from_utf8(output.stdout).unwrap(); + assert_eq!(expected, actual); + Ok(()) +} + +#[test] +fn region_set_with_display_profile() -> io::Result<()> { + let output = common::render_module("aws") + .env("AWS_REGION", "ap-northeast-1") + .use_config(toml::toml! { + [aws] + displayed_items = "profile" + }) + .output()?; + let expected = ""; + let actual = String::from_utf8(output.stdout).unwrap(); + assert_eq!(expected, actual); + Ok(()) +} + +#[test] +fn region_not_set_with_display_region() -> io::Result<()> { + let output = common::render_module("aws") + .use_config(toml::toml! { + [aws] + displayed_items = "region" + }) + .output()?; + let expected = ""; + let actual = String::from_utf8(output.stdout).unwrap(); + assert_eq!(expected, actual); + Ok(()) +}