diff --git a/.github/config-schema.json b/.github/config-schema.json index 5a3247f7..99d164f7 100644 --- a/.github/config-schema.json +++ b/.github/config-schema.json @@ -767,6 +767,9 @@ "kubernetes": { "default": { "context_aliases": {}, + "detect_extensions": [], + "detect_files": [], + "detect_folders": [], "disabled": true, "format": "[$symbol$context( \\($namespace\\))]($style) in ", "style": "cyan bold", @@ -3323,6 +3326,27 @@ "additionalProperties": { "type": "string" } + }, + "detect_extensions": { + "default": [], + "type": "array", + "items": { + "type": "string" + } + }, + "detect_files": { + "default": [], + "type": "array", + "items": { + "type": "string" + } + }, + "detect_folders": { + "default": [], + "type": "array", + "items": { + "type": "string" + } } } }, diff --git a/docs/config/README.md b/docs/config/README.md index e8347891..7316b86d 100644 --- a/docs/config/README.md +++ b/docs/config/README.md @@ -2084,18 +2084,25 @@ If the `$KUBECONFIG` env var is set the module will use that if not it will use This module is disabled by default. To enable it, set `disabled` to `false` in your configuration file. +When the module is enabled it will always be active, unless any of +`detect_extensions`, `detect_files` or `detect_folders` have been st in which +case the module will only be active in directories that match those conditions. + ::: ### Options -| Option | Default | Description | -| ----------------- | -------------------------------------------------- | --------------------------------------------------------------------- | -| `symbol` | `"☸ "` | A format string representing the symbol displayed before the Cluster. | -| `format` | `'[$symbol$context( \($namespace\))]($style) in '` | The format for the module. | -| `style` | `"cyan bold"` | The style for the module. | -| `context_aliases` | | Table of context aliases to display. | -| `user_aliases` | | Table of user aliases to display. | -| `disabled` | `true` | Disables the `kubernetes` module. | +| Option | Default | Description | +| ------------------- | -------------------------------------------------- | --------------------------------------------------------------------- | +| `symbol` | `"☸ "` | A format string representing the symbol displayed before the Cluster. | +| `format` | `'[$symbol$context( \($namespace\))]($style) in '` | The format for the module. | +| `style` | `"cyan bold"` | The style for the module. | +| `context_aliases` | | Table of context aliases to display. | +| `user_aliases` | | Table of user aliases to display. | +| `detect_extensions` | `[]` | Which extensions should trigger this module. | +| `detect_files` | `[]` | Which filenames should trigger this module. | +| `detect_folders` | `[]` | Which folders should trigger this modules. | +| `disabled` | `true` | Disables the `kubernetes` module. | ### Variables @@ -2127,6 +2134,16 @@ disabled = false "root/.*" = "root" ``` +Only show the module in directories that contain a `k8s` file. + +```toml +# ~/.config/starship.toml + +[kubernetes] +disabled = false +detect_files = ['k8s'] +``` + #### Regex Matching Additional to simple aliasing, `context_aliases` and `user_aliases` also supports diff --git a/src/configs/kubernetes.rs b/src/configs/kubernetes.rs index 8e7362ea..fde9add5 100644 --- a/src/configs/kubernetes.rs +++ b/src/configs/kubernetes.rs @@ -11,6 +11,9 @@ pub struct KubernetesConfig<'a> { pub disabled: bool, pub context_aliases: HashMap, pub user_aliases: HashMap, + pub detect_extensions: Vec<&'a str>, + pub detect_files: Vec<&'a str>, + pub detect_folders: Vec<&'a str>, } impl<'a> Default for KubernetesConfig<'a> { @@ -22,6 +25,9 @@ impl<'a> Default for KubernetesConfig<'a> { disabled: true, context_aliases: HashMap::new(), user_aliases: HashMap::new(), + detect_extensions: vec![], + detect_files: vec![], + detect_folders: vec![], } } } diff --git a/src/modules/kubernetes.rs b/src/modules/kubernetes.rs index d5aa48b4..a8449a20 100644 --- a/src/modules/kubernetes.rs +++ b/src/modules/kubernetes.rs @@ -119,6 +119,23 @@ pub fn module<'a>(context: &'a Context) -> Option> { return None; }; + // If we have some config for doing the directory scan then we use it but if we don't then we + // assume we should treat it like the module is enabled to preserve backward compatability. + let have_scan_config = !(config.detect_files.is_empty() + && config.detect_folders.is_empty() + && config.detect_extensions.is_empty()); + + let is_kube_project = context + .try_begin_scan()? + .set_files(&config.detect_files) + .set_folders(&config.detect_folders) + .set_extensions(&config.detect_extensions) + .is_match(); + + if have_scan_config && !is_kube_project { + return None; + } + let default_config_file = context.get_home()?.join(".kube").join("config"); let kube_cfg = context @@ -197,7 +214,7 @@ mod tests { use crate::test::ModuleRenderer; use ansi_term::Color; use std::env; - use std::fs::File; + use std::fs::{create_dir, File}; use std::io::{self, Write}; #[test] @@ -234,6 +251,128 @@ users: [] dir.close() } + #[test] + fn test_none_when_no_detected_files_or_folders() -> io::Result<()> { + let dir = tempfile::tempdir()?; + + let filename = dir.path().join("config"); + + let mut file = File::create(&filename)?; + file.write_all( + b" +apiVersion: v1 +clusters: [] +contexts: + - context: + cluster: test_cluster + user: test_user + name: test_context +current-context: test_context +kind: Config +preferences: {} +users: [] +", + )?; + file.sync_all()?; + + let actual = ModuleRenderer::new("kubernetes") + .path(dir.path()) + .env("KUBECONFIG", filename.to_string_lossy().as_ref()) + .config(toml::toml! { + [kubernetes] + disabled = false + detect_files = ["k8s.ext"] + detect_extensions = ["k8s"] + detect_folders = ["k8s_folder"] + }) + .collect(); + + assert_eq!(None, actual); + + dir.close() + } + + #[test] + fn test_with_detected_files_and_folder() -> io::Result<()> { + let dir = tempfile::tempdir()?; + + let filename = dir.path().join("config"); + + let mut file = File::create(&filename)?; + file.write_all( + b" +apiVersion: v1 +clusters: [] +contexts: + - context: + cluster: test_cluster + user: test_user + name: test_context +current-context: test_context +kind: Config +preferences: {} +users: [] +", + )?; + file.sync_all()?; + + let dir_with_file = tempfile::tempdir()?; + File::create(dir_with_file.path().join("k8s.ext"))?.sync_all()?; + + let actual_file = ModuleRenderer::new("kubernetes") + .path(dir_with_file.path()) + .env("KUBECONFIG", filename.to_string_lossy().as_ref()) + .config(toml::toml! { + [kubernetes] + disabled = false + detect_files = ["k8s.ext"] + detect_extensions = ["k8s"] + detect_folders = ["k8s_folder"] + }) + .collect(); + + let dir_with_ext = tempfile::tempdir()?; + File::create(dir_with_ext.path().join("test.k8s"))?.sync_all()?; + + let actual_ext = ModuleRenderer::new("kubernetes") + .path(dir_with_ext.path()) + .env("KUBECONFIG", filename.to_string_lossy().as_ref()) + .config(toml::toml! { + [kubernetes] + disabled = false + detect_files = ["k8s.ext"] + detect_extensions = ["k8s"] + detect_folders = ["k8s_folder"] + }) + .collect(); + + let dir_with_dir = tempfile::tempdir()?; + create_dir(dir_with_dir.path().join("k8s_folder"))?; + + let actual_dir = ModuleRenderer::new("kubernetes") + .path(dir_with_dir.path()) + .env("KUBECONFIG", filename.to_string_lossy().as_ref()) + .config(toml::toml! { + [kubernetes] + disabled = false + detect_files = ["k8s.ext"] + detect_extensions = ["k8s"] + detect_folders = ["k8s_folder"] + }) + .collect(); + + let expected = Some(format!( + "{} in ", + Color::Cyan.bold().paint("☸ test_context") + )); + + assert_eq!(expected, actual_file); + assert_eq!(expected, actual_ext); + assert_eq!(expected, actual_dir); + + dir.close() + } + fn base_test_ctx_alias(ctx_name: &str, config: toml::Value, expected: &str) -> io::Result<()> { let dir = tempfile::tempdir()?;