feat(git_mob): add new git_mob module

This commit is contained in:
twobiers 2023-12-22 13:47:29 +01:00
parent 9af6670cd2
commit 0077d40465
No known key found for this signature in database
GPG Key ID: 38191C4EC96D0F36
8 changed files with 281 additions and 0 deletions

View File

@ -622,6 +622,20 @@
}
]
},
"git_mob": {
"default": {
"disabled": true,
"format": "[$symbol $initials \\($count\\)]($style)",
"separator": ",",
"style": "green bold",
"symbol": "👥"
},
"allOf": [
{
"$ref": "#/definitions/GitMobConfig"
}
]
},
"git_state": {
"default": {
"am": "AM",
@ -3379,6 +3393,32 @@
},
"additionalProperties": false
},
"GitMobConfig": {
"type": "object",
"properties": {
"format": {
"default": "[$symbol $initials \\($count\\)]($style)",
"type": "string"
},
"style": {
"default": "green bold",
"type": "string"
},
"symbol": {
"default": "👥",
"type": "string"
},
"disabled": {
"default": true,
"type": "boolean"
},
"separator": {
"default": ",",
"type": "string"
}
},
"additionalProperties": false
},
"GitStateConfig": {
"type": "object",
"properties": {

View File

@ -279,6 +279,7 @@ $git_branch\
$git_commit\
$git_state\
$git_metrics\
$git_mob\
$git_status\
$hg_branch\
$pijul_channel\
@ -1939,6 +1940,44 @@ added_style = 'bold blue'
format = '[+$added]($added_style)/[-$deleted]($deleted_style) '
```
## Git Mob
The `git_mob` module will show the configured Co-Author initials.
::: tip
This module is disabled by default.
To enable it, set `disabled` to `false` in your configuration file.
:::
### Options
| Option | Default | Description |
| ----------- | -------------------------------------------- | --------------------------------- |
| `disabled` | `true` | Disables the `git_mob` module. |
| `format` | `'[$symbol $initials \\($count\\)]($style)'` | The format for the module. |
| `separator` | `','` | Separator for multiple Co-Authors |
| `style` | `'green bold'` | Style for the module |
| `symbol` | `'👥 '` | Symbol to display |
### Variables
| Variable | Example | Description |
| -------- | ------- | ------------------------------------------------------------- |
| initials | `ab,ce` | The Co-Author initials separated using the provided separator |
| count | `2` | The count of configured Co-Authors |
### Example
```toml
# ~/.config/starship.toml
[git_mob]
disabled = false
separator = ","
```
## Git Status
The `git_status` module shows symbols representing the state of the repo in your

28
src/configs/git_mob.rs Normal file
View File

@ -0,0 +1,28 @@
use serde::{Deserialize, Serialize};
#[derive(Clone, Deserialize, Serialize)]
#[cfg_attr(
feature = "config-schema",
derive(schemars::JsonSchema),
schemars(deny_unknown_fields)
)]
#[serde(default)]
pub struct GitMobConfig<'a> {
pub format: &'a str,
pub style: &'a str,
pub symbol: &'a str,
pub disabled: bool,
pub separator: &'a str,
}
impl<'a> Default for GitMobConfig<'a> {
fn default() -> Self {
GitMobConfig {
format: "[$symbol $initials \\($count\\)]($style)",
style: "green bold",
symbol: "👥",
disabled: true,
separator: ",",
}
}
}

View File

@ -34,6 +34,7 @@ pub mod gcloud;
pub mod git_branch;
pub mod git_commit;
pub mod git_metrics;
pub mod git_mob;
pub mod git_state;
pub mod git_status;
pub mod go;
@ -174,6 +175,8 @@ pub struct FullConfig<'a> {
#[serde(borrow)]
git_metrics: git_metrics::GitMetricsConfig<'a>,
#[serde(borrow)]
git_mob: git_mob::GitMobConfig<'a>,
#[serde(borrow)]
git_state: git_state::GitStateConfig<'a>,
#[serde(borrow)]
git_status: git_status::GitStatusConfig<'a>,

View File

@ -45,6 +45,7 @@ pub const PROMPT_ORDER: &[&str] = &[
"git_commit",
"git_state",
"git_metrics",
"git_mob",
"git_status",
"hg_branch",
"pijul_channel",

View File

@ -41,6 +41,7 @@ pub const ALL_MODULES: &[&str] = &[
"git_branch",
"git_commit",
"git_metrics",
"git_mob",
"git_state",
"git_status",
"golang",

166
src/modules/git_mob.rs Normal file
View File

@ -0,0 +1,166 @@
use super::{Context, Module, ModuleConfig};
use crate::configs::git_mob::GitMobConfig;
use crate::formatter::StringFormatter;
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
let mut module = context.new_module("git_mob");
let config: GitMobConfig = GitMobConfig::try_load(module.config);
if config.disabled {
return None;
};
let mob_authors = parse_git_mob_authors(
&context
.exec_cmd("git", &["mob-print", "--initials"])?
.stdout,
);
let parsed = StringFormatter::new(config.format).and_then(|formatter| {
formatter
.map_meta(|var, _| match var {
"separator" => Some(config.separator),
"symbol" => Some(config.symbol),
_ => None,
})
.map_style(|variable| match variable {
"style" => Some(Ok(config.style)),
_ => None,
})
.map(|variable| match variable {
"initials" => Some(Ok(mob_authors.join(config.separator))),
"count" => Some(Ok(mob_authors.len().to_string())),
_ => None,
})
.parse(None, Some(context))
});
module.set_segments(match parsed {
Ok(segments) => segments,
Err(error) => {
log::warn!("Error in module `git_mob`:\n{}", error);
return None;
}
});
Some(module)
}
fn parse_git_mob_authors(git_mob_stdout: &str) -> Vec<String> {
return git_mob_stdout.split(',').map(|s| s.to_owned()).collect();
}
#[cfg(test)]
mod tests {
use crate::test::{fixture_repo, FixtureProvider, ModuleRenderer};
use crate::utils::CommandOutput;
use nu_ansi_term::Color;
use std::io;
#[test]
fn nothing_on_empty_dir() -> io::Result<()> {
let repo_dir = tempfile::tempdir()?;
let actual = ModuleRenderer::new("git_mob")
.path(repo_dir.path())
.config(toml::toml! {
[git_mob]
enabled = true
})
.collect();
let expected = None;
assert_eq!(expected, actual);
repo_dir.close()
}
#[test]
fn nothing_on_disabled() -> io::Result<()> {
let repo_dir = fixture_repo(FixtureProvider::Git)?;
let actual = ModuleRenderer::new("git_mob")
.path(repo_dir.path())
.config(toml::toml! {
[git_mob]
disabled = true
})
.collect();
let expected = None;
assert_eq!(expected, actual);
repo_dir.close()
}
#[test]
fn nothing_on_not_existing_cmd() -> io::Result<()> {
let repo_dir = tempfile::tempdir()?;
let actual = ModuleRenderer::new("git_mob")
.path(repo_dir.path())
.config(toml::toml! {
[git_mob]
disabled = false
})
.cmd("git mob-print --initials", None)
.collect();
let expected = None;
assert_eq!(expected, actual);
repo_dir.close()
}
#[test]
fn initials_and_count() -> io::Result<()> {
let repo_dir = tempfile::tempdir()?;
let actual = ModuleRenderer::new("git_mob")
.path(repo_dir.path())
.config(toml::toml! {
[git_mob]
disabled = false
})
.cmd(
"git mob-print --initials",
Some(CommandOutput {
stdout: String::from("ab,ca,de"),
stderr: String::default(),
}),
)
.collect();
let expected = Some(format!("{}", Color::Green.bold().paint("👥 ab,ca,de (3)")));
assert_eq!(expected, actual);
repo_dir.close()
}
#[test]
fn initials_with_custom_separator() -> io::Result<()> {
let repo_dir = tempfile::tempdir()?;
let actual = ModuleRenderer::new("git_mob")
.path(repo_dir.path())
.config(toml::toml! {
[git_mob]
disabled = false
separator = "|"
})
.cmd(
"git mob-print --initials",
Some(CommandOutput {
stdout: String::from("ab,ca,de"),
stderr: String::default(),
}),
)
.collect();
let expected = Some(format!("{}", Color::Green.bold().paint("👥 ab|ca|de (3)")));
assert_eq!(expected, actual);
repo_dir.close()
}
}

View File

@ -31,6 +31,7 @@ mod gcloud;
mod git_branch;
mod git_commit;
mod git_metrics;
mod git_mob;
mod git_state;
mod git_status;
mod golang;
@ -138,6 +139,7 @@ pub fn handle<'a>(module: &str, context: &'a Context) -> Option<Module<'a>> {
"git_branch" => git_branch::module(context),
"git_commit" => git_commit::module(context),
"git_metrics" => git_metrics::module(context),
"git_mob" => git_mob::module(context),
"git_state" => git_state::module(context),
"git_status" => git_status::module(context),
"golang" => golang::module(context),
@ -256,6 +258,7 @@ pub fn description(module: &str) -> &'static str {
"git_branch" => "The active branch of the repo in your current directory",
"git_commit" => "The active commit (and tag if any) of the repo in your current directory",
"git_metrics" => "The currently added/deleted lines in your repo",
"git_mob" => "Current configured Co-Authors using the git-mob tool",
"git_state" => "The current git operation, and it's progress",
"git_status" => "Symbol representing the state of the repo",
"golang" => "The currently installed version of Golang",