From b685bb2954ac08a524e7af4f18bc8bf34bd7b366 Mon Sep 17 00:00:00 2001 From: Barnaby Keene Date: Sun, 5 Apr 2020 20:42:55 +0100 Subject: [PATCH] feat: add docker context module (#996) * feat: add docker context module Adds a simple module that checks for a Docker config file and if present, reads the `currentContext` value out and displays on the prompt with a whale. * feat: add `only_with_compose_yml` option to docker_context When enabled, will only show the docker context name if there's a docker-compose.yml file in the current directory. * Update src/modules/docker_context.rs Co-Authored-By: Thomas O'Donnell * Update src/modules/docker_context.rs Co-Authored-By: Thomas O'Donnell * rename `only_with_compose_yml` configuration key to a more generic `only_with_files` * Update src/modules/docker_context.rs Co-Authored-By: Thomas O'Donnell * re-order configuration table * Update docs/config/README.md Co-Authored-By: Thomas O'Donnell * Update src/configs/docker_context.rs Co-Authored-By: Thomas O'Donnell Co-authored-by: Thomas O'Donnell --- docs/config/README.md | 25 ++++++++++++++++++ src/configs/docker_context.rs | 25 ++++++++++++++++++ src/configs/mod.rs | 1 + src/configs/starship_root.rs | 1 + src/module.rs | 1 + src/modules/docker_context.rs | 48 +++++++++++++++++++++++++++++++++++ src/modules/mod.rs | 3 +++ 7 files changed, 104 insertions(+) create mode 100644 src/configs/docker_context.rs create mode 100644 src/modules/docker_context.rs diff --git a/docs/config/README.md b/docs/config/README.md index 3de40b5ee..8c0131fb0 100644 --- a/docs/config/README.md +++ b/docs/config/README.md @@ -100,6 +100,7 @@ prompt_order = [ "git_state", "git_status", "hg_branch", + "docker_context", "package", "dotnet", "elixir", @@ -405,6 +406,30 @@ a single character. For `fish_style_pwd_dir_length = 2`, it would be `/bu/th/ci/ truncation_length = 8 ``` +## Docker Context + +The `docker_context` module shows the currently active +[Docker context](https://docs.docker.com/engine/context/working-with-contexts/) if it's not set to +`default`. + +### Options + +| Variable | Default | Description | +| ----------------- | ------------- | ---------------------------------------------------------------------------- | +| `symbol` | `"🐳 "` | The symbol used before displaying the Docker context . | +| `only_with_files` | `false` | Only show when there's a `docker-compose.yml` or `Dockerfile` in the current directory. | +| `style` | `"bold blue"` | The style for the module. | +| `disabled` | `true` | Disables the `docker_context` module. | + +### Example + +```toml +# ~/.config/starship.toml + +[docker_context] +symbol = "🐋 " +``` + ## Dotnet The `dotnet` module shows the relevant version of the .NET Core SDK for the current directory. If diff --git a/src/configs/docker_context.rs b/src/configs/docker_context.rs new file mode 100644 index 000000000..79be04294 --- /dev/null +++ b/src/configs/docker_context.rs @@ -0,0 +1,25 @@ +use crate::config::{ModuleConfig, RootModuleConfig, SegmentConfig}; + +use ansi_term::{Color, Style}; +use starship_module_config_derive::ModuleConfig; + +#[derive(Clone, ModuleConfig)] +pub struct DockerContextConfig<'a> { + pub symbol: SegmentConfig<'a>, + pub context: SegmentConfig<'a>, + pub style: Style, + pub only_with_files: bool, + pub disabled: bool, +} + +impl<'a> RootModuleConfig<'a> for DockerContextConfig<'a> { + fn new() -> Self { + DockerContextConfig { + symbol: SegmentConfig::new("🐳 "), + context: SegmentConfig::default(), + style: Color::Blue.bold(), + only_with_files: true, + disabled: false, + } + } +} diff --git a/src/configs/mod.rs b/src/configs/mod.rs index d6110bca4..54f1455a5 100644 --- a/src/configs/mod.rs +++ b/src/configs/mod.rs @@ -5,6 +5,7 @@ pub mod cmd_duration; pub mod conda; pub mod crystal; pub mod directory; +pub mod docker_context; pub mod dotnet; pub mod elixir; pub mod elm; diff --git a/src/configs/starship_root.rs b/src/configs/starship_root.rs index c15642544..113f96551 100644 --- a/src/configs/starship_root.rs +++ b/src/configs/starship_root.rs @@ -27,6 +27,7 @@ impl<'a> RootModuleConfig<'a> for StarshipRootConfig<'a> { "git_state", "git_status", "hg_branch", + "docker_context", "package", // ↓ Toolchain version modules ↓ // (Let's keep these sorted alphabetically) diff --git a/src/module.rs b/src/module.rs index 90bca641f..7fc2c72e5 100644 --- a/src/module.rs +++ b/src/module.rs @@ -17,6 +17,7 @@ pub const ALL_MODULES: &[&str] = &[ "cmd_duration", "conda", "directory", + "docker_context", "dotnet", "elixir", "elm", diff --git a/src/modules/docker_context.rs b/src/modules/docker_context.rs new file mode 100644 index 000000000..6cf0e2d94 --- /dev/null +++ b/src/modules/docker_context.rs @@ -0,0 +1,48 @@ +use dirs::home_dir; + +use super::{Context, Module, RootModuleConfig}; + +use crate::configs::docker_context::DockerContextConfig; +use crate::utils; + +const DOCKER_CONFIG_FILE: &str = ".docker/config.json"; + +/// Creates a module with the currently active Docker context +/// +/// Will display the Docker context if the following criteria are met: +/// - There is a file named `$HOME/.docker/config.json` +/// - The file is JSON and contains a field named `currentContext` +/// - The value of `currentContext` is not `default` +pub fn module<'a>(context: &'a Context) -> Option> { + let mut module = context.new_module("docker_context"); + let config: DockerContextConfig = DockerContextConfig::try_load(module.config); + + if config.only_with_files + && !context + .try_begin_scan()? + .set_files(&["docker-compose.yml", "Dockerfile"]) + .is_match() + { + return None; + } + + let config_path = home_dir()?.join(DOCKER_CONFIG_FILE); + let json = utils::read_file(config_path).ok()?; + let parsed_json = serde_json::from_str(&json).ok()?; + + match parsed_json { + serde_json::Value::Object(root) => { + let current_context = root.get("currentContext")?; + match current_context { + serde_json::Value::String(ctx) => { + module.set_style(config.style); + module.create_segment("symbol", &config.symbol); + module.create_segment("context", &config.context.with_value(&ctx)); + Some(module) + } + _ => None, + } + } + _ => None, + } +} diff --git a/src/modules/mod.rs b/src/modules/mod.rs index 167f7b639..fba3ded50 100644 --- a/src/modules/mod.rs +++ b/src/modules/mod.rs @@ -5,6 +5,7 @@ mod cmd_duration; mod conda; mod crystal; mod directory; +mod docker_context; mod dotnet; mod elixir; mod elm; @@ -54,6 +55,7 @@ pub fn handle<'a>(module: &str, context: &'a Context) -> Option> { "cmd_duration" => cmd_duration::module(context), "conda" => conda::module(context), "directory" => directory::module(context), + "docker_context" => docker_context::module(context), "dotnet" => dotnet::module(context), "elixir" => elixir::module(context), "elm" => elm::module(context), @@ -101,6 +103,7 @@ pub fn description(module: &str) -> &'static str { "cmd_duration" => "How long the last command took to execute", "conda" => "The current conda environment, if $CONDA_DEFAULT_ENV is set", "directory" => "The current working directory", + "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", "git_branch" => "The active branch of the repo in your current directory",