diff options
author | wdullaer <wdullaer@users.noreply.github.com> | 2019-12-09 08:42:51 +0700 |
---|---|---|
committer | Matan Kushner <hello@matchai.me> | 2019-12-08 20:42:51 -0500 |
commit | 44b37a7baca4d9e50a524c51f9ea305f0b5f60fa (patch) | |
tree | 2e215b996415ddf16eb7e7c165eb4c5b64d1d9c5 /src | |
parent | f458a5e8c91bd6fd5b7df905f0b65e0e35034072 (diff) |
feat: Implement terraform module with workspace and version (#644)
Diffstat (limited to 'src')
-rw-r--r-- | src/configs/mod.rs | 1 | ||||
-rw-r--r-- | src/configs/starship_root.rs | 1 | ||||
-rw-r--r-- | src/configs/terraform.rs | 27 | ||||
-rw-r--r-- | src/module.rs | 1 | ||||
-rw-r--r-- | src/modules/mod.rs | 2 | ||||
-rw-r--r-- | src/modules/terraform.rs | 125 |
6 files changed, 157 insertions, 0 deletions
diff --git a/src/configs/mod.rs b/src/configs/mod.rs index c840f3bba..dcf0337f4 100644 --- a/src/configs/mod.rs +++ b/src/configs/mod.rs @@ -25,6 +25,7 @@ pub mod python; pub mod ruby; pub mod rust; mod starship_root; +pub mod terraform; pub mod time; pub mod username; diff --git a/src/configs/starship_root.rs b/src/configs/starship_root.rs index 293dcb17c..00a647354 100644 --- a/src/configs/starship_root.rs +++ b/src/configs/starship_root.rs @@ -36,6 +36,7 @@ impl<'a> RootModuleConfig<'a> for StarshipRootConfig<'a> { "python", "ruby", "rust", + "terraform", // ↑ Toolchain version modules ↑ "nix_shell", "conda", diff --git a/src/configs/terraform.rs b/src/configs/terraform.rs new file mode 100644 index 000000000..3d427e5c4 --- /dev/null +++ b/src/configs/terraform.rs @@ -0,0 +1,27 @@ +use crate::config::{ModuleConfig, RootModuleConfig, SegmentConfig}; + +use ansi_term::{Color, Style}; +use starship_module_config_derive::ModuleConfig; + +#[derive(Clone, ModuleConfig)] +pub struct TerraformConfig<'a> { + pub symbol: SegmentConfig<'a>, + pub workspace: SegmentConfig<'a>, + pub version: SegmentConfig<'a>, + pub style: Style, + pub disabled: bool, + pub show_version: bool, +} + +impl<'a> RootModuleConfig<'a> for TerraformConfig<'a> { + fn new() -> Self { + TerraformConfig { + symbol: SegmentConfig::new("💠 "), + workspace: SegmentConfig::default(), + version: SegmentConfig::default(), + style: Color::Fixed(105).bold(), + disabled: false, + show_version: false, + } + } +} diff --git a/src/module.rs b/src/module.rs index 71b25627f..873c2e1ad 100644 --- a/src/module.rs +++ b/src/module.rs @@ -36,6 +36,7 @@ pub const ALL_MODULES: &[&str] = &[ "ruby", "rust", "php", + "terraform", "time", "username", ]; diff --git a/src/modules/mod.rs b/src/modules/mod.rs index 42951324b..a95ea4fd3 100644 --- a/src/modules/mod.rs +++ b/src/modules/mod.rs @@ -25,6 +25,7 @@ mod php; mod python; mod ruby; mod rust; +mod terraform; mod time; mod username; mod utils; @@ -68,6 +69,7 @@ pub fn handle<'a>(module: &str, context: &'a Context) -> Option<Module<'a>> { "python" => python::module(context), "ruby" => ruby::module(context), "rust" => rust::module(context), + "terraform" => terraform::module(context), "time" => time::module(context), "username" => username::module(context), _ => { diff --git a/src/modules/terraform.rs b/src/modules/terraform.rs new file mode 100644 index 000000000..60d0b46c9 --- /dev/null +++ b/src/modules/terraform.rs @@ -0,0 +1,125 @@ +use super::{Context, Module, RootModuleConfig}; + +use crate::configs::terraform::TerraformConfig; +use crate::utils; +use std::env; +use std::io; +use std::path::PathBuf; + +/// Creates a module with the current Terraform version and workspace +/// +/// Will display the Terraform version and workspace if any of the following criteria are met: +/// - Current directory contains a `.terraform` directory +/// - Current directory contains a file with the `.tf` extension +pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> { + let is_terraform_project = context + .try_begin_scan()? + .set_folders(&[".terraform"]) + .set_extensions(&["tf"]) + .is_match(); + + if !is_terraform_project { + return None; + } + + let mut module = context.new_module("terraform"); + let config: TerraformConfig = TerraformConfig::try_load(module.config); + + module.set_style(config.style); + module.create_segment("symbol", &config.symbol); + + if config.show_version { + let terraform_version = + format_terraform_version(&utils::exec_cmd("terraform", &["version"])?.stdout.as_str())?; + module.create_segment("version", &config.version.with_value(&terraform_version)); + } + + let terraform_workspace = &get_terraform_workspace(&context.current_dir)?; + module.create_segment( + "workspace", + &config.workspace.with_value(&terraform_workspace), + ); + + Some(module) +} + +// Determines the currently selected workspace (see https://github.com/hashicorp/terraform/blob/master/command/meta.go for the original implementation) +fn get_terraform_workspace(cwd: &PathBuf) -> Option<String> { + // Workspace can be explicitly overwritten by an env var + let workspace_override = env::var("TF_WORKSPACE"); + if workspace_override.is_ok() { + return workspace_override.ok(); + } + + // Data directory containing current workspace can be overwritten by an env var + let datadir = match env::var("TF_DATA_DIR") { + Ok(s) => PathBuf::from(s), + Err(_) => cwd.join(".terraform"), + }; + match utils::read_file(datadir.join("environment")) { + Err(ref e) if e.kind() == io::ErrorKind::NotFound => Some("default".to_string()), + Ok(s) => Some(s), + _ => None, + } +} + +fn format_terraform_version(version: &str) -> Option<String> { + // `terraform version` output looks like this + // Terraform v0.12.14 + // With potential extra output if it detects you are not running the latest version + Some( + version + .lines() + .next()? + .trim_start_matches("Terraform ") + .trim() + .to_owned() + + " ", + ) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_format_terraform_version_release() { + let input = "Terraform v0.12.14"; + assert_eq!( + format_terraform_version(input), + Some("v0.12.14 ".to_string()) + ); + } + + #[test] + fn test_format_terraform_version_prerelease() { + let input = "Terraform v0.12.14-rc1"; + assert_eq!( + format_terraform_version(input), + Some("v0.12.14-rc1 ".to_string()) + ); + } + + #[test] + fn test_format_terraform_version_development() { + let input = "Terraform v0.12.14-dev (cca89f74)"; + assert_eq!( + format_terraform_version(input), + Some("v0.12.14-dev (cca89f74) ".to_string()) + ); + } + + #[test] + fn test_format_terraform_version_multiline() { + let input = "Terraform v0.12.13 + +Your version of Terraform is out of date! The latest version +is 0.12.14. You can update by downloading from www.terraform.io/downloads.html + +"; + assert_eq!( + format_terraform_version(input), + Some("v0.12.13 ".to_string()) + ); + } +} |