From 48f913ec2309c8fa1f3c012e5aa33f7df0f6e0ad Mon Sep 17 00:00:00 2001 From: Milo <50248166+Milo123459@users.noreply.github.com> Date: Mon, 3 May 2021 20:50:29 +0100 Subject: [PATCH] feat(vlang): create module (#2577) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add V module * Format * Fix tests * fix typo * Update src/configs/v.rs Co-authored-by: Dario Vladović * Update docs/config/README.md Co-authored-by: Dario Vladović * Update docs/config/README.md Co-authored-by: Dario Vladović * Update docs/config/README.md Co-authored-by: Dario Vladović * Use blue bold * v -> vlang * change docs * More vlang fixes * add package support for v * Update docs/config/README.md Co-authored-by: Dario Vladović * use regex * Update src/configs/mod.rs Co-authored-by: David Knaack * apply patch * fix Co-authored-by: Dario Vladović Co-authored-by: David Knaack --- docs/config/README.md | 37 +++++++++++++++ src/configs/mod.rs | 3 ++ src/configs/starship_root.rs | 1 + src/configs/v.rs | 29 ++++++++++++ src/module.rs | 1 + src/modules/mod.rs | 3 ++ src/modules/package.rs | 24 ++++++++++ src/modules/vlang.rs | 92 ++++++++++++++++++++++++++++++++++++ src/utils.rs | 4 ++ 9 files changed, 194 insertions(+) create mode 100644 src/configs/v.rs create mode 100644 src/modules/vlang.rs diff --git a/docs/config/README.md b/docs/config/README.md index b6ff3281..86e20616 100644 --- a/docs/config/README.md +++ b/docs/config/README.md @@ -223,6 +223,7 @@ $rust\ $scala\ $swift\ $terraform\ +$vlang\ $vagrant\ $zig\ $nix_shell\ @@ -2022,6 +2023,7 @@ package, and shows its current version. The module currently supports `npm`, `ca - [**helm**](https://helm.sh/docs/helm/helm_package/) - The `helm` chart version is extracted from the `Chart.yaml` present - [**maven**](https://maven.apache.org/) - The `maven` package version is extracted from the `pom.xml` present - [**meson**](https://mesonbuild.com/) - The `meson` package version is extracted from the `meson.build` present +- [**vlang**](https://vlang.io) - The `vlang` package version is extracted from the `v.mod` present > ⚠️ The version being shown is that of the package whose source code is in your > current directory, not your package manager. @@ -2839,6 +2841,41 @@ By default the module will be shown if any of the following conditions are met: format = "via [⍱ $version](bold white) " ``` +## VLang + +The `vlang` module shows you your currently installed version of V. +By default the module will be shown if any of the following conditions are met: +- The current directory contains a file with `.v` extension +- The current directory contains a `v.mod` file + +### Options + +| Option | Default | Description | +| ------------------- | ------------------------------------------------- | ----------------------------------------------- | +| `format` | `"via [$symbol($version )]($style)"` | The format for the module. | +| `symbol` | `"V "` | A format string representing the symbol of V | +| `detect_extensions` | `["v"]` | Which extensions should trigger this module. | +| `detect_files` | `["v.mod"]` | Which filenames should trigger this module. | +| `detect_folders` | `[]` | Which folders should trigger this module. | +| `style` | `"blue bold"` | The style for the module. | +| `disabled` | `false` | Disables the `vlang` module. | + +### Variables + +| Variable | Example | Description | +| -------- | -------- | ------------------------------------ | +| version | `v0.2` | The version of `v` | +| symbol | | Mirrors the value of option `symbol` | +| style\* | | Mirrors the value of option `style` | + +### Example + +```toml +# ~/.config/starship.toml +[v] +format = "via [V $version](blue bold) " +``` + ## VCSH The `vcsh` module displays the current active [VCSH](https://github.com/RichiH/vcsh) repository. diff --git a/src/configs/mod.rs b/src/configs/mod.rs index a7663fac..08fbbfa0 100644 --- a/src/configs/mod.rs +++ b/src/configs/mod.rs @@ -59,6 +59,7 @@ pub mod swift; pub mod terraform; pub mod time; pub mod username; +pub mod v; pub mod vagrant; pub mod vcsh; pub mod zig; @@ -128,6 +129,7 @@ pub struct FullConfig<'a> { terraform: terraform::TerraformConfig<'a>, time: time::TimeConfig<'a>, username: username::UsernameConfig<'a>, + vlang: v::VLangConfig<'a>, vagrant: vagrant::VagrantConfig<'a>, zig: zig::ZigConfig<'a>, custom: IndexMap>, @@ -196,6 +198,7 @@ impl<'a> Default for FullConfig<'a> { time: Default::default(), username: Default::default(), vagrant: Default::default(), + vlang: Default::default(), zig: Default::default(), custom: Default::default(), } diff --git a/src/configs/starship_root.rs b/src/configs/starship_root.rs index 50c206c0..f8cc2c62 100644 --- a/src/configs/starship_root.rs +++ b/src/configs/starship_root.rs @@ -58,6 +58,7 @@ pub const PROMPT_ORDER: &[&str] = &[ "scala", "swift", "terraform", + "vlang", "vagrant", "zig", // ↑ Toolchain version modules ↑ diff --git a/src/configs/v.rs b/src/configs/v.rs new file mode 100644 index 00000000..dc8624c6 --- /dev/null +++ b/src/configs/v.rs @@ -0,0 +1,29 @@ +use crate::config::ModuleConfig; + +use serde::Serialize; +use starship_module_config_derive::ModuleConfig; + +#[derive(Clone, ModuleConfig, Serialize)] +pub struct VLangConfig<'a> { + pub format: &'a str, + pub symbol: &'a str, + pub style: &'a str, + pub disabled: bool, + pub detect_extensions: Vec<&'a str>, + pub detect_files: Vec<&'a str>, + pub detect_folders: Vec<&'a str>, +} + +impl<'a> Default for VLangConfig<'a> { + fn default() -> Self { + VLangConfig { + format: "via [$symbol($version )]($style)", + symbol: "V ", + style: "blue bold", + disabled: false, + detect_extensions: vec!["v"], + detect_files: vec!["v.mod"], + detect_folders: vec![], + } + } +} diff --git a/src/module.rs b/src/module.rs index cee9f357..860ca04c 100644 --- a/src/module.rs +++ b/src/module.rs @@ -67,6 +67,7 @@ pub const ALL_MODULES: &[&str] = &[ "username", "vcsh", "vagrant", + "vlang", "zig", ]; diff --git a/src/modules/mod.rs b/src/modules/mod.rs index 1d5eac0e..b255a7f2 100644 --- a/src/modules/mod.rs +++ b/src/modules/mod.rs @@ -57,6 +57,7 @@ mod username; mod utils; mod vagrant; mod vcsh; +mod vlang; mod zig; #[cfg(feature = "battery")] @@ -130,6 +131,7 @@ pub fn handle<'a>(module: &str, context: &'a Context) -> Option> { "time" => time::module(context), "crystal" => crystal::module(context), "username" => username::module(context), + "vlang" => vlang::module(context), "vagrant" => vagrant::module(context), "vcsh" => vcsh::module(context), "zig" => zig::module(context), @@ -210,6 +212,7 @@ pub fn description(module: &str) -> &'static str { "terraform" => "The currently selected terraform workspace and version", "time" => "The current local time", "username" => "The active user's username", + "vlang" => "The currently installed version of V", "vagrant" => "The currently installed version of Vagrant", "vcsh" => "The currently active VCSH repository", "zig" => "The currently installed version of Zig", diff --git a/src/modules/package.rs b/src/modules/package.rs index bd7372ca..1f95a7e0 100644 --- a/src/modules/package.rs +++ b/src/modules/package.rs @@ -54,6 +54,13 @@ fn extract_cargo_version(file_contents: &str) -> Option { Some(formatted_version) } +fn extract_vlang_version(file_contents: &str) -> Option { + let re = Regex::new(r"(?m)^\s*version\s*:\s*'(?P[^']+)'").unwrap(); + let caps = re.captures(file_contents)?; + let formatted_version = format_version(&caps["version"]); + Some(formatted_version) +} + fn extract_package_version(file_contents: &str, display_private: bool) -> Option { let package_json: json::Value = json::from_str(file_contents).ok()?; @@ -198,6 +205,8 @@ fn get_package_version(base_dir: &Path, config: &PackageConfig) -> Option io::Result<()> { + let config_name = "v.mod"; + let config_content = " + Module { + name: 'starship', + author: 'matchai', + version: '1.2.3' + }"; + let project_dir = create_project_dir()?; + fill_config(&project_dir, config_name, Some(&config_content))?; + expect_output(&project_dir, Some("v1.2.3"), None); + project_dir.close() + } + fn create_project_dir() -> io::Result { tempfile::tempdir() } diff --git a/src/modules/vlang.rs b/src/modules/vlang.rs new file mode 100644 index 00000000..0d7d0e7b --- /dev/null +++ b/src/modules/vlang.rs @@ -0,0 +1,92 @@ +use super::{Context, Module, RootModuleConfig}; + +use crate::configs::v::VLangConfig; +use crate::formatter::StringFormatter; + +/// Creates a module with the current V version +pub fn module<'a>(context: &'a Context) -> Option> { + let mut module = context.new_module("vlang"); + let config = VLangConfig::try_load(module.config); + let is_v_project = context + .try_begin_scan()? + .set_extensions(&config.detect_extensions) + .is_match(); + + if !is_v_project { + return None; + } + + let parsed = StringFormatter::new(config.format).and_then(|formatter| { + formatter + .map_meta(|var, _| match var { + "symbol" => Some(config.symbol), + _ => None, + }) + .map_style(|variable| match variable { + "style" => Some(Ok(config.style)), + _ => None, + }) + .map(|variable| match variable { + "version" => context + .exec_cmd("v", &["version"]) + .and_then(|output| parse_v_version(output.stdout.trim())) + .map(Ok), + _ => None, + }) + .parse(None) + }); + + module.set_segments(match parsed { + Ok(segments) => segments, + Err(error) => { + log::warn!("Error in module `vlang`:\n{}", error); + return None; + } + }); + + Some(module) +} + +fn parse_v_version(v_version: &str) -> Option { + let version = v_version + // split into ["V", "0.2", "30c0659"] + .split_whitespace() + // return "0.2" + .nth(1)?; + + Some(format!("v{}", version)) +} + +#[cfg(test)] +mod tests { + use super::parse_v_version; + use crate::test::ModuleRenderer; + use ansi_term::Color; + use std::fs::File; + use std::io; + + #[test] + fn test_parse_v_version() { + const OUTPUT: &str = "V 0.2 30c0659\n"; + assert_eq!(parse_v_version(OUTPUT.trim()), Some("v0.2".to_string())) + } + + #[test] + fn folder_without_v_files() -> io::Result<()> { + let dir = tempfile::tempdir()?; + let actual = ModuleRenderer::new("vlang").path(dir.path()).collect(); + let expected = None; + assert_eq!(expected, actual); + dir.close() + } + + #[test] + fn folder_with_v_files() -> io::Result<()> { + let dir = tempfile::tempdir()?; + File::create(dir.path().join("hello.v"))?.sync_all()?; + let actual = ModuleRenderer::new("vlang").path(dir.path()).collect(); + let expected = Some(format!("via {}", Color::Blue.bold().paint("V v0.2 "))); + assert_eq!(expected, actual); + dir.close() + } +} diff --git a/src/utils.rs b/src/utils.rs index 32fd342f..7ef829a3 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -188,6 +188,10 @@ Target: x86_64-apple-darwin19.4.0\n", stdout: String::from("Vagrant 2.2.10\n"), stderr: String::default(), }), + "v version" => Some(CommandOutput { + stdout: String::from("V 0.2 30c0659"), + stderr: String::default() + }), "zig version" => Some(CommandOutput { stdout: String::from("0.6.0\n"), stderr: String::default(),