Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(hostname): add detect_env_vars as option #5196

Merged
merged 9 commits into from Sep 16, 2023
8 changes: 8 additions & 0 deletions .github/config-schema.json
Expand Up @@ -784,6 +784,7 @@
},
"hostname": {
"default": {
"detect_env_vars": [],
"disabled": false,
"format": "[$ssh_symbol$hostname]($style) in ",
"ssh_only": true,
Expand Down Expand Up @@ -3699,6 +3700,13 @@
"default": ".",
"type": "string"
},
"detect_env_vars": {
"default": [],
"type": "array",
"items": {
"type": "string"
}
},
"format": {
"default": "[$ssh_symbol$hostname]($style) in ",
"type": "string"
Expand Down
37 changes: 28 additions & 9 deletions docs/config/README.md
Expand Up @@ -2200,16 +2200,22 @@ format = 'via [⎈ $version](bold white) '

The `hostname` module shows the system hostname.

::: warning

The `detect_env_vars` is only used, if `ssh_only` is set to `false` or there
is an environment variable `SSH_CONNECTION` set.

mickimnet marked this conversation as resolved.
Show resolved Hide resolved
### Options

| Option | Default | Description |
| ------------ | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `ssh_only` | `true` | Only show hostname when connected to an SSH session. |
| `ssh_symbol` | `'🌐 '` | A format string representing the symbol when connected to SSH session. |
| `trim_at` | `'.'` | String that the hostname is cut off at, after the first match. `'.'` will stop after the first dot. `''` will disable any truncation |
| `format` | `'[$ssh_symbol$hostname]($style) in '` | The format for the module. |
| `style` | `'bold dimmed green'` | The style for the module. |
| `disabled` | `false` | Disables the `hostname` module. |
| Option | Default | Description |
| ----------------- | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `ssh_only` | `true` | Only show hostname when connected to an SSH session. |
| `ssh_symbol` | `'🌐 '` | A format string representing the symbol when connected to SSH session. |
| `trim_at` | `'.'` | String that the hostname is cut off at, after the first match. `'.'` will stop after the first dot. `''` will disable any truncation. |
| `detect_env_vars` | `[]` | Which environment variable(s) should trigger this module. |
| `format` | `'[$ssh_symbol$hostname]($style) in '` | The format for the module. |
| `style` | `'bold dimmed green'` | The style for the module. |
| `disabled` | `false` | Disables the `hostname` module. |

### Variables

Expand All @@ -2221,7 +2227,9 @@ The `hostname` module shows the system hostname.

*: This variable can only be used as a part of a style string

### Example
### Examples

#### Always show the hostname

```toml
# ~/.config/starship.toml
Expand All @@ -2233,6 +2241,17 @@ trim_at = '.companyname.com'
disabled = false
```

#### Hide the hostname in remote tmux sessions

```toml
# ~/.config/starship.toml

[hostname]
ssh_only = false
detect_env_vars = ['!TMUX', 'SSH_CONNECTION']
disabled = false
```

## Java

The `java` module shows the currently installed version of [Java](https://www.oracle.com/java/).
Expand Down
2 changes: 2 additions & 0 deletions src/configs/hostname.rs
Expand Up @@ -11,6 +11,7 @@ pub struct HostnameConfig<'a> {
pub ssh_only: bool,
pub ssh_symbol: &'a str,
pub trim_at: &'a str,
pub detect_env_vars: Vec<&'a str>,
pub format: &'a str,
pub style: &'a str,
pub disabled: bool,
Expand All @@ -22,6 +23,7 @@ impl<'a> Default for HostnameConfig<'a> {
ssh_only: true,
ssh_symbol: "🌐 ",
trim_at: ".",
detect_env_vars: vec![],
format: "[$ssh_symbol$hostname]($style) in ",
style: "green dimmed bold",
disabled: false,
Expand Down
26 changes: 25 additions & 1 deletion src/context.rs
Expand Up @@ -235,8 +235,32 @@ impl<'a> Context<'a> {
disabled == Some(true)
}

/// Returns true when a negated environment variable is defined in `env_vars` and is present
fn has_negated_env_var(&self, env_vars: &'a [&'a str]) -> bool {
env_vars
.iter()
.filter_map(|env_var| env_var.strip_prefix('!'))
.any(|env_var| self.get_env(env_var).is_some())
}

/// Returns true if 'detect_env_vars' is empty,
/// or if at least one environment variable is set and no negated environment variable is set
pub fn detect_env_vars(&'a self, env_vars: &'a [&'a str]) -> bool {
env_vars.is_empty() || (env_vars.iter().any(|e| self.get_env(e).is_some()))
if env_vars.is_empty() {
return true;
}

if self.has_negated_env_var(env_vars) {
return false;
}

// Returns true if at least one environment variable is set
let mut iter = env_vars
.iter()
.filter(|env_var| !env_var.starts_with('!'))
.peekable();

iter.peek().is_none() || iter.any(|env_var| self.get_env(env_var).is_some())
}

// returns a new ScanDir struct with reference to current dir_files of context
Expand Down
78 changes: 74 additions & 4 deletions src/modules/hostname.rs
Expand Up @@ -8,14 +8,18 @@ use crate::formatter::StringFormatter;
/// Creates a module with the system hostname
///
/// Will display the hostname if all of the following criteria are met:
/// - hostname.disabled is absent or false
/// - `hostname.disabled` is absent or false
/// - `hostname.ssh_only` is false OR the user is currently connected as an SSH session (`$SSH_CONNECTION`)
/// - `hostname.ssh_only` is false AND `hostname.detect_env_vars` is either empty or contains a defined environment variable
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
let mut module = context.new_module("hostname");
let config: HostnameConfig = HostnameConfig::try_load(module.config);

let ssh_connection = context.get_env("SSH_CONNECTION");
if config.ssh_only && ssh_connection.is_none() {

if (config.ssh_only && ssh_connection.is_none())
|| !context.detect_env_vars(&config.detect_env_vars)
{
return None;
}

Expand Down Expand Up @@ -96,17 +100,82 @@ mod tests {
}

#[test]
fn ssh_only_false_no_ssh() {
fn ssh_only_false_with_empty_detect_env_vars() {
let hostname = get_hostname!();
let actual = ModuleRenderer::new("hostname")
.config(toml::toml! {
[hostname]
ssh_only = false
trim_at = ""
detect_env_vars = []
})
.collect();

let expected = Some(format!("{} in ", style().paint(hostname)));
assert_eq!(expected, actual);
}

#[test]
fn ssh_only_false_with_matching_negated_env_var() {
let actual = ModuleRenderer::new("hostname")
.config(toml::toml! {
[hostname]
ssh_only = false
trim_at = ""
detect_env_vars = ["!NEGATED"]
})
.env("NEGATED", "true")
.collect();
let expected = None;

assert_eq!(expected, actual);
}

#[test]
fn ssh_only_false_with_only_negated_env_vars() {
let hostname = get_hostname!();
let actual = ModuleRenderer::new("hostname")
.config(toml::toml! {
[hostname]
ssh_only = false
trim_at = ""
detect_env_vars = ["!NEGATED_ONE", "!NEGATED_TWO", "!NEGATED_THREE"]
})
.collect();

let expected = Some(format!("{} in ", style().paint(hostname)));
println!("{}", expected.as_ref().unwrap());
assert_eq!(expected, actual);
}

#[test]
fn ssh_only_false_with_matching_env_var() {
let hostname = get_hostname!();
let actual = ModuleRenderer::new("hostname")
.config(toml::toml! {
[hostname]
ssh_only = false
trim_at = ""
detect_env_vars = ["FORCE_HOSTNAME"]
})
.env("FORCE_HOSTNAME", "true")
.collect();

let expected = Some(format!("{} in ", style().paint(hostname)));
assert_eq!(expected, actual);
}

#[test]
fn ssh_only_false_without_matching_env_vars() {
let actual = ModuleRenderer::new("hostname")
.config(toml::toml! {
[hostname]
ssh_only = false
trim_at = ""
detect_env_vars = ["FORCE_HOSTNAME", "!NEGATED"]
})
.collect();
let expected = None;

assert_eq!(expected, actual);
}

Expand All @@ -121,6 +190,7 @@ mod tests {
})
.collect();
let expected = Some(format!("{} in ", style().paint(hostname)));

assert_eq!(expected, actual);
}

Expand Down