diff --git a/docs/config/README.md b/docs/config/README.md index 7dd33952..1c8c5422 100644 --- a/docs/config/README.md +++ b/docs/config/README.md @@ -187,6 +187,7 @@ $git_status\ $hg_branch\ $docker_context\ $package\ +$cmake\ $dotnet\ $elixir\ $elm\ @@ -425,6 +426,31 @@ error_symbol = "[➜](bold red) " vicmd_symbol = "[V](bold green) " ``` +## CMake + +The `cmake` module shows the currently installed version of CMake if: + +- The current directory contains a `CMakeLists.txt` file + +### Options + +| Option | Default | Description | +| ---------- | ---------------------------------- | -------------------------------------------- | +| `format` | `"via [$symbol$version]($style) "` | The format for the module. | +| `symbol` | `"🛆 "` | The symbol used before the version of cmake. | +| `style` | `"bold blue"` | The style for the module. | +| `disabled` | `false` | Disables the `cmake` module. | + +### Variables + +| Variable | Example | Description | +| -------- | --------- | ------------------------------------ | +| version | `v3.17.3` | The version of cmake | +| symbol | | Mirrors the value of option `symbol` | +| style\* | | Mirrors the value of option `style` | + +\*: This variable can only be used as a part of a style string + ## Command Duration The `cmd_duration` module shows how long the last command took to execute. diff --git a/src/configs/cmake.rs b/src/configs/cmake.rs new file mode 100644 index 00000000..5045786b --- /dev/null +++ b/src/configs/cmake.rs @@ -0,0 +1,22 @@ +use crate::config::{ModuleConfig, RootModuleConfig}; + +use starship_module_config_derive::ModuleConfig; + +#[derive(Clone, ModuleConfig)] +pub struct CMakeConfig<'a> { + pub format: &'a str, + pub symbol: &'a str, + pub style: &'a str, + pub disabled: bool, +} + +impl<'a> RootModuleConfig<'a> for CMakeConfig<'a> { + fn new() -> Self { + CMakeConfig { + format: "via [$symbol$version]($style) ", + symbol: "🛆 ", + style: "bold blue", + disabled: false, + } + } +} diff --git a/src/configs/mod.rs b/src/configs/mod.rs index e0a3f470..4b871288 100644 --- a/src/configs/mod.rs +++ b/src/configs/mod.rs @@ -1,6 +1,7 @@ pub mod aws; pub mod battery; pub mod character; +pub mod cmake; pub mod cmd_duration; pub mod conda; pub mod crystal; diff --git a/src/configs/starship_root.rs b/src/configs/starship_root.rs index 2c61547b..80393792 100644 --- a/src/configs/starship_root.rs +++ b/src/configs/starship_root.rs @@ -11,7 +11,7 @@ pub struct StarshipRootConfig<'a> { // List of default prompt order // NOTE: If this const value is changed then Default prompt order subheading inside // prompt heading of config docs needs to be updated according to changes made here. -pub const PROMPT_ORDER: [&str; 42] = [ +pub const PROMPT_ORDER: [&str; 43] = [ "username", "hostname", "singularity", @@ -26,6 +26,7 @@ pub const PROMPT_ORDER: [&str; 42] = [ "package", // ↓ Toolchain version modules ↓ // (Let's keep these sorted alphabetically) + "cmake", "dotnet", "elixir", "elm", diff --git a/src/module.rs b/src/module.rs index 9f429290..eda8ba99 100644 --- a/src/module.rs +++ b/src/module.rs @@ -12,6 +12,7 @@ pub const ALL_MODULES: &[&str] = &[ #[cfg(feature = "battery")] "battery", "character", + "cmake", "cmd_duration", "conda", "directory", diff --git a/src/modules/cmake.rs b/src/modules/cmake.rs new file mode 100644 index 00000000..90c09988 --- /dev/null +++ b/src/modules/cmake.rs @@ -0,0 +1,84 @@ +use super::{Context, Module, RootModuleConfig}; + +use crate::configs::cmake::CMakeConfig; +use crate::formatter::StringFormatter; +use crate::utils; + +/// Creates a module with the current CMake version +/// +/// Will display the CMake version if any of the following criteria are met: +/// - The current directory contains a `CMakeLists.txt` file +pub fn module<'a>(context: &'a Context) -> Option> { + let is_cmake_project = context + .try_begin_scan()? + .set_files(&["CMakeLists.txt"]) + .is_match(); + + if !is_cmake_project { + return None; + } + + let mut module = context.new_module("cmake"); + let config = CMakeConfig::try_load(module.config); + let parsed = StringFormatter::new(config.format).and_then(|formatter| { + formatter + .map_meta(|variable, _| match variable { + "symbol" => Some(config.symbol), + _ => None, + }) + .map_style(|variable| match variable { + "style" => Some(Ok(config.style)), + _ => None, + }) + .map(|variable| match variable { + "version" => utils::exec_cmd("cmake", &["--version"]) + .map(|output| format_cmake_version(&output.stdout)) + .flatten() + .map(Ok), + _ => None, + }) + .parse(None) + }); + + module.set_segments(match parsed { + Ok(segments) => segments, + Err(error) => { + log::warn!("Error in module `cmake`: \n{}", error); + return None; + } + }); + + Some(module) +} + +fn format_cmake_version(cmake_version: &str) -> Option { + let version = cmake_version.split_whitespace().nth(2)?; + Some(format!("v{}", version)) +} + +#[cfg(test)] +mod tests { + use crate::modules::utils::test::render_module; + use ansi_term::Color; + use std::fs::File; + use std::io; + + #[test] + fn folder_without_cmake_lists() -> io::Result<()> { + let dir = tempfile::tempdir()?; + let actual = render_module("cmake", dir.path(), None); + let expected = None; + assert_eq!(expected, actual); + dir.close() + } + + #[test] + fn folder_with_cmake_lists() -> io::Result<()> { + let dir = tempfile::tempdir()?; + File::create(dir.path().join("CMakeLists.txt"))?.sync_all()?; + let actual = render_module("cmake", dir.path(), None); + let expected = Some(format!("via {} ", Color::Blue.bold().paint("🛆 v3.17.3"))); + assert_eq!(expected, actual); + dir.close() + } +} diff --git a/src/modules/mod.rs b/src/modules/mod.rs index 135fc7ac..a7d059a9 100644 --- a/src/modules/mod.rs +++ b/src/modules/mod.rs @@ -1,6 +1,7 @@ // While adding out new module add out module to src/module.rs ALL_MODULES const array also. mod aws; mod character; +mod cmake; mod cmd_duration; mod conda; mod crystal; @@ -57,6 +58,7 @@ pub fn handle<'a>(module: &str, context: &'a Context) -> Option> { #[cfg(feature = "battery")] "battery" => battery::module(context), "character" => character::module(context), + "cmake" => cmake::module(context), "cmd_duration" => cmd_duration::module(context), "conda" => conda::module(context), "directory" => directory::module(context), @@ -109,6 +111,7 @@ pub fn description(module: &str) -> &'static str { "character" => { "A character (usually an arrow) beside where the text is entered in your terminal" } + "cmake" => "The currently installed version of CMake", "cmd_duration" => "How long the last command took to execute", "conda" => "The current conda environment, if $CONDA_DEFAULT_ENV is set", "crystal" => "The currently installed version of Crystal", diff --git a/src/utils.rs b/src/utils.rs index 8b3a9372..2ef3cef5 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -123,6 +123,15 @@ active boot switches: -d:release\n", stdout: String::from("0.6.0"), stderr: String::default(), }), + "cmake --version" => Some(CommandOutput { + stdout: String::from( + "\ +cmake version 3.17.3 + +CMake suite maintained and supported by Kitware (kitware.com/cmake).\n", + ), + stderr: String::default(), + }), "terraform version" => Some(CommandOutput { stdout: String::from("Terraform v0.12.14"), stderr: String::default(),