feat(username): add detect_env_vars as option (#5833)

* Added the option "detect_env_vars" to the `username` module

with the same functionality as in the `hostname` module.

* Fixed logic error and added test to catch it

* build(deps): update dependency vitepress to ^1.0.0-rc.45

* build(deps): update rust crate shadow-rs to 0.27.1

* Added the option "detect_env_vars" to the `username` module

with the same functionality as in the `hostname` module.

* Fixed logic error and added test to catch it

* Removed unused gix import

* Removed unused gix import, again

* Removed unused gix import. Next try

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This commit is contained in:
Mick Hohmann 2024-03-20 22:47:32 +01:00 committed by GitHub
parent aef1a3f275
commit b8a812b932
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 117 additions and 10 deletions

View File

@ -1717,6 +1717,7 @@
},
"username": {
"default": {
"detect_env_vars": [],
"disabled": false,
"format": "[$user]($style) in ",
"show_always": false,
@ -5878,6 +5879,13 @@
"UsernameConfig": {
"type": "object",
"properties": {
"detect_env_vars": {
"default": [],
"type": "array",
"items": {
"type": "string"
}
},
"format": {
"default": "[$user]($style) in ",
"type": "string"

View File

@ -4357,6 +4357,7 @@ The module will be shown if any of the following conditions are met:
- The current user isn't the same as the one that is logged in
- The user is currently connected as an SSH session
- The variable `show_always` is set to true
- The array `detect_env_vars` contains at least the name of one environment variable, that is set
::: tip
@ -4368,13 +4369,14 @@ these variables, one workaround is to set one of them with a dummy value.
### Options
| Option | Default | Description |
| ------------- | ----------------------- | ------------------------------------------- |
| `style_root` | `'bold red'` | The style used when the user is root/admin. |
| `style_user` | `'bold yellow'` | The style used for non-root users. |
| `format` | `'[$user]($style) in '` | The format for the module. |
| `show_always` | `false` | Always shows the `username` module. |
| `disabled` | `false` | Disables the `username` module. |
| Option | Default | Description |
| ----------------- | ----------------------- | --------------------------------------------------------- |
| `style_root` | `'bold red'` | The style used when the user is root/admin. |
| `style_user` | `'bold yellow'` | The style used for non-root users. |
| `detect_env_vars` | `[]` | Which environment variable(s) should trigger this module. |
| `format` | `'[$user]($style) in '` | The format for the module. |
| `show_always` | `false` | Always shows the `username` module. |
| `disabled` | `false` | Disables the `username` module. |
### Variables
@ -4385,6 +4387,8 @@ these variables, one workaround is to set one of them with a dummy value.
### Example
#### Always show the hostname
```toml
# ~/.config/starship.toml
@ -4396,6 +4400,17 @@ disabled = false
show_always = true
```
#### Hide the hostname in remote tmux sessions
```toml
# ~/.config/starship.toml
[hostname]
ssh_only = false
detect_env_vars = ['!TMUX', 'SSH_CONNECTION']
disabled = false
```
## Vagrant
The `vagrant` module shows the currently installed version of [Vagrant](https://www.vagrantup.com/).

View File

@ -8,6 +8,7 @@ use serde::{Deserialize, Serialize};
)]
#[serde(default)]
pub struct UsernameConfig<'a> {
pub detect_env_vars: Vec<&'a str>,
pub format: &'a str,
pub style_root: &'a str,
pub style_user: &'a str,
@ -18,6 +19,7 @@ pub struct UsernameConfig<'a> {
impl<'a> Default for UsernameConfig<'a> {
fn default() -> Self {
UsernameConfig {
detect_env_vars: vec![],
format: "[$user]($style) in ",
style_root: "red bold",
style_user: "yellow bold",

View File

@ -15,23 +15,29 @@ const USERNAME_ENV_VAR: &str = "USERNAME";
/// - The current user is root (UID = 0) [1]
/// - The current user isn't the same as the one that is logged in (`$LOGNAME` != `$USER`) [2]
/// - The user is currently connected as an SSH session (`$SSH_CONNECTION`) [3]
/// - The option `username.detect_env_vars` is set with a not negated environment variable [4]
/// Does not display the username:
/// - If the option `username.detect_env_vars` is set with a negated environment variable [A]
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
let mut username = context.get_env(USERNAME_ENV_VAR)?;
let mut module = context.new_module("username");
let config: UsernameConfig = UsernameConfig::try_load(module.config);
let has_detected_env_var = context.detect_env_vars(&config.detect_env_vars);
let is_root = is_root_user();
if cfg!(target_os = "windows") && is_root {
username = "Administrator".to_string();
}
let show_username = config.show_always
|| is_root // [1]
|| !is_login_user(context, &username) // [2]
|| is_ssh_session(context); // [3]
|| is_ssh_session(context) // [3]
|| ( !config.detect_env_vars.is_empty() && has_detected_env_var ); // [4]
if !show_username {
return None;
if !show_username || !has_detected_env_var {
return None; // [A]
}
let parsed = StringFormatter::new(config.format).and_then(|formatter| {
@ -109,11 +115,69 @@ fn is_ssh_session(context: &Context) -> bool {
#[cfg(test)]
mod tests {
use gix::config::key;
use crate::test::ModuleRenderer;
// TODO: Add tests for if root user (UID == 0)
// Requires mocking
#[test]
fn ssh_with_empty_detect_env_vars() {
let actual = ModuleRenderer::new("username")
.env(super::USERNAME_ENV_VAR, "astronaut")
.env("SSH_CONNECTION", "192.168.223.17 36673 192.168.223.229 22")
// Test output should not change when run by root/non-root user
.config(toml::toml! {
[username]
style_root = ""
style_user = ""
detect_env_vars = []
})
.collect();
let expected = Some("astronaut in ");
assert_eq!(expected, actual.as_deref());
}
#[test]
fn ssh_with_matching_detect_env_vars() {
let actual = ModuleRenderer::new("username")
.env(super::USERNAME_ENV_VAR, "astronaut")
.env("SSH_CONNECTION", "192.168.223.17 36673 192.168.223.229 22")
.env("FORCE_USERNAME", "true")
// Test output should not change when run by root/non-root user
.config(toml::toml! {
[username]
style_root = ""
style_user = ""
detect_env_vars = ["FORCE_USERNAME"]
})
.collect();
let expected = Some("astronaut in ");
assert_eq!(expected, actual.as_deref());
}
#[test]
fn ssh_with_matching_negated_detect_env_vars() {
let actual = ModuleRenderer::new("username")
.env(super::USERNAME_ENV_VAR, "astronaut")
.env("SSH_CONNECTION", "192.168.223.17 36673 192.168.223.229 22")
.env("NEGATED", "true")
// Test output should not change when run by root/non-root user
.config(toml::toml! {
[username]
style_root = ""
style_user = ""
detect_env_vars = ["!NEGATED"]
})
.collect();
let expected = None;
assert_eq!(expected, actual.as_deref());
}
#[test]
fn no_env_variables() {
let actual = ModuleRenderer::new("username").collect();
@ -241,4 +305,22 @@ mod tests {
assert_eq!(expected, actual.as_deref());
}
#[test]
fn show_always_false() {
let actual = ModuleRenderer::new("username")
.env(super::USERNAME_ENV_VAR, "astronaut")
// Test output should not change when run by root/non-root user
.config(toml::toml! {
[username]
show_always = false
style_root = ""
style_user = ""
})
.collect();
let expected = None;
assert_eq!(expected, actual.as_deref());
}
}