mirror of
https://github.com/Llewellynvdm/starship.git
synced 2024-11-28 15:56:28 +00:00
feat(module): Add sudo
module (#3135)
* add feature - sudo module * add sudo module identifiers and entry point * fix test test_sudo_not_cached * add test test_sudo_cached * add `allow_windows` and `binary` options * rustfmt sudo_x_cached and rmv them on windows * add false `allow_windows` block windows test * add `doas` cached/not_cached tests * better description in `starship explain` * fix `test_doas_cached` with `-n` flag Co-authored-by: David Knaack <davidkna@users.noreply.github.com> * rmv `binary` alternatives and their tests * fix symbol and update config/README * fix all mocks to use `sudo -n true` * fix expected output in `test_sudo_cached` * proper checking for blocked sudo Co-authored-by: David Knaack <davidkna@users.noreply.github.com> * add `allow_windows = true` to non-windows tests * allow sudo_* tests to run on windows + fix parsed * rustfmt `blocks_windows` test Co-authored-by: David Knaack <davidkna@users.noreply.github.com>
This commit is contained in:
parent
c3e33ea1c7
commit
779e53cd66
@ -243,6 +243,7 @@ $openstack\
|
|||||||
$env_var\
|
$env_var\
|
||||||
$crystal\
|
$crystal\
|
||||||
$custom\
|
$custom\
|
||||||
|
$sudo\
|
||||||
$cmd_duration\
|
$cmd_duration\
|
||||||
$line_break\
|
$line_break\
|
||||||
$jobs\
|
$jobs\
|
||||||
@ -2947,6 +2948,58 @@ disabled = false
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Sudo
|
||||||
|
|
||||||
|
The `sudo` module displays if sudo credentials are currently cached.
|
||||||
|
The module will only be shown if credentials are cached.
|
||||||
|
|
||||||
|
::: tip
|
||||||
|
|
||||||
|
This module is disabled by default.
|
||||||
|
To enable it, set `disabled` to `false` in your configuration file.
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
| Option | Default | Description |
|
||||||
|
| -------------- | ----------------------- | ------------------------------------------------------------ |
|
||||||
|
| `format` | `[as $symbol]($style)"` | The format of the module |
|
||||||
|
| `symbol` | `"🧙 "` | The symbol displayed when credentials are cached |
|
||||||
|
| `style` | `"bold blue"` | The style for the module. |
|
||||||
|
| `allow_windows`| `false` | Since windows has no default sudo, default is disabled. |
|
||||||
|
| `disabled` | `true` | Disables the `sudo` module. |
|
||||||
|
|
||||||
|
### Variables
|
||||||
|
|
||||||
|
| Variable | Example | Description |
|
||||||
|
| --------- | ------- | ------------------------------------ |
|
||||||
|
| 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
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
```toml
|
||||||
|
|
||||||
|
# ~/.config/starship.toml
|
||||||
|
|
||||||
|
[sudo]
|
||||||
|
style = "bold green"
|
||||||
|
symbol = "👩💻 "
|
||||||
|
disabled = false
|
||||||
|
```
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# On windows
|
||||||
|
# $HOME\.starship\config.toml
|
||||||
|
|
||||||
|
[sudo]
|
||||||
|
allow_windows = true
|
||||||
|
disabled = false
|
||||||
|
```
|
||||||
|
|
||||||
## Swift
|
## Swift
|
||||||
|
|
||||||
By default the `swift` module shows the currently installed version of [Swift](https://swift.org/).
|
By default the `swift` module shows the currently installed version of [Swift](https://swift.org/).
|
||||||
|
@ -226,6 +226,9 @@ format = '\[[$symbol($version)]($style)\]'
|
|||||||
[scala]
|
[scala]
|
||||||
format = '\[[$symbol($version)]($style)\]'
|
format = '\[[$symbol($version)]($style)\]'
|
||||||
|
|
||||||
|
[sudo]
|
||||||
|
format = '\[[as $symbol]\]
|
||||||
|
|
||||||
[swift]
|
[swift]
|
||||||
format = '\[[$symbol($version)]($style)\]'
|
format = '\[[$symbol($version)]($style)\]'
|
||||||
|
|
||||||
@ -375,6 +378,9 @@ symbol = "rs "
|
|||||||
[scala]
|
[scala]
|
||||||
symbol = "scala "
|
symbol = "scala "
|
||||||
|
|
||||||
|
[sudo]
|
||||||
|
symbol = "sudo "
|
||||||
|
|
||||||
[swift]
|
[swift]
|
||||||
symbol = "swift "
|
symbol = "swift "
|
||||||
```
|
```
|
||||||
|
@ -61,6 +61,7 @@ pub mod shlvl;
|
|||||||
pub mod singularity;
|
pub mod singularity;
|
||||||
mod starship_root;
|
mod starship_root;
|
||||||
pub mod status;
|
pub mod status;
|
||||||
|
pub mod sudo;
|
||||||
pub mod swift;
|
pub mod swift;
|
||||||
pub mod terraform;
|
pub mod terraform;
|
||||||
pub mod time;
|
pub mod time;
|
||||||
@ -138,6 +139,7 @@ pub struct FullConfig<'a> {
|
|||||||
shlvl: shlvl::ShLvlConfig<'a>,
|
shlvl: shlvl::ShLvlConfig<'a>,
|
||||||
singularity: singularity::SingularityConfig<'a>,
|
singularity: singularity::SingularityConfig<'a>,
|
||||||
status: status::StatusConfig<'a>,
|
status: status::StatusConfig<'a>,
|
||||||
|
sudo: sudo::SudoConfig<'a>,
|
||||||
swift: swift::SwiftConfig<'a>,
|
swift: swift::SwiftConfig<'a>,
|
||||||
terraform: terraform::TerraformConfig<'a>,
|
terraform: terraform::TerraformConfig<'a>,
|
||||||
time: time::TimeConfig<'a>,
|
time: time::TimeConfig<'a>,
|
||||||
@ -214,6 +216,7 @@ impl<'a> Default for FullConfig<'a> {
|
|||||||
shlvl: Default::default(),
|
shlvl: Default::default(),
|
||||||
singularity: Default::default(),
|
singularity: Default::default(),
|
||||||
status: Default::default(),
|
status: Default::default(),
|
||||||
|
sudo: Default::default(),
|
||||||
swift: Default::default(),
|
swift: Default::default(),
|
||||||
terraform: Default::default(),
|
terraform: Default::default(),
|
||||||
time: Default::default(),
|
time: Default::default(),
|
||||||
|
@ -76,6 +76,7 @@ pub const PROMPT_ORDER: &[&str] = &[
|
|||||||
"env_var",
|
"env_var",
|
||||||
"crystal",
|
"crystal",
|
||||||
"custom",
|
"custom",
|
||||||
|
"sudo",
|
||||||
"cmd_duration",
|
"cmd_duration",
|
||||||
"line_break",
|
"line_break",
|
||||||
"jobs",
|
"jobs",
|
||||||
|
25
src/configs/sudo.rs
Normal file
25
src/configs/sudo.rs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
use crate::config::ModuleConfig;
|
||||||
|
|
||||||
|
use serde::Serialize;
|
||||||
|
use starship_module_config_derive::ModuleConfig;
|
||||||
|
|
||||||
|
#[derive(Clone, ModuleConfig, Serialize)]
|
||||||
|
pub struct SudoConfig<'a> {
|
||||||
|
pub format: &'a str,
|
||||||
|
pub symbol: &'a str,
|
||||||
|
pub style: &'a str,
|
||||||
|
pub allow_windows: bool,
|
||||||
|
pub disabled: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Default for SudoConfig<'a> {
|
||||||
|
fn default() -> Self {
|
||||||
|
SudoConfig {
|
||||||
|
format: "[as $symbol]($style)",
|
||||||
|
symbol: "🧙 ",
|
||||||
|
style: "bold blue",
|
||||||
|
allow_windows: false,
|
||||||
|
disabled: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -65,6 +65,7 @@ pub const ALL_MODULES: &[&str] = &[
|
|||||||
"shlvl",
|
"shlvl",
|
||||||
"singularity",
|
"singularity",
|
||||||
"status",
|
"status",
|
||||||
|
"sudo",
|
||||||
"swift",
|
"swift",
|
||||||
"terraform",
|
"terraform",
|
||||||
"time",
|
"time",
|
||||||
|
@ -55,6 +55,7 @@ mod shell;
|
|||||||
mod shlvl;
|
mod shlvl;
|
||||||
mod singularity;
|
mod singularity;
|
||||||
mod status;
|
mod status;
|
||||||
|
mod sudo;
|
||||||
mod swift;
|
mod swift;
|
||||||
mod terraform;
|
mod terraform;
|
||||||
mod time;
|
mod time;
|
||||||
@ -139,6 +140,7 @@ pub fn handle<'a>(module: &str, context: &'a Context) -> Option<Module<'a>> {
|
|||||||
"singularity" => singularity::module(context),
|
"singularity" => singularity::module(context),
|
||||||
"swift" => swift::module(context),
|
"swift" => swift::module(context),
|
||||||
"status" => status::module(context),
|
"status" => status::module(context),
|
||||||
|
"sudo" => sudo::module(context),
|
||||||
"terraform" => terraform::module(context),
|
"terraform" => terraform::module(context),
|
||||||
"time" => time::module(context),
|
"time" => time::module(context),
|
||||||
"crystal" => crystal::module(context),
|
"crystal" => crystal::module(context),
|
||||||
@ -226,6 +228,7 @@ pub fn description(module: &str) -> &'static str {
|
|||||||
"shlvl" => "The current value of SHLVL",
|
"shlvl" => "The current value of SHLVL",
|
||||||
"singularity" => "The currently used Singularity image",
|
"singularity" => "The currently used Singularity image",
|
||||||
"status" => "The status of the last command",
|
"status" => "The status of the last command",
|
||||||
|
"sudo" => "The sudo credentials are currently cached",
|
||||||
"swift" => "The currently installed version of Swift",
|
"swift" => "The currently installed version of Swift",
|
||||||
"terraform" => "The currently selected terraform workspace and version",
|
"terraform" => "The currently selected terraform workspace and version",
|
||||||
"time" => "The current local time",
|
"time" => "The current local time",
|
||||||
|
113
src/modules/sudo.rs
Normal file
113
src/modules/sudo.rs
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
use std::env;
|
||||||
|
|
||||||
|
use super::{Context, Module, RootModuleConfig};
|
||||||
|
|
||||||
|
use crate::configs::sudo::SudoConfig;
|
||||||
|
use crate::formatter::StringFormatter;
|
||||||
|
|
||||||
|
/// Creates a module with sudo credential cache status
|
||||||
|
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||||
|
let mut module = context.new_module("sudo");
|
||||||
|
let config = SudoConfig::try_load(module.config);
|
||||||
|
|
||||||
|
if config.disabled {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
if !config.allow_windows && env::consts::FAMILY == "windows" {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let is_sudo_cached = context.exec_cmd("sudo", &["-n", "true"]).is_some();
|
||||||
|
|
||||||
|
if !is_sudo_cached {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
})
|
||||||
|
.parse(None, Some(context))
|
||||||
|
});
|
||||||
|
|
||||||
|
module.set_segments(match parsed {
|
||||||
|
Ok(segments) => segments,
|
||||||
|
Err(error) => {
|
||||||
|
log::warn!("Error in module `sudo`:\n{}", error);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Some(module)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::{test::ModuleRenderer, utils::CommandOutput};
|
||||||
|
use ansi_term::Color;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_sudo_not_cached() {
|
||||||
|
let actual = ModuleRenderer::new("sudo")
|
||||||
|
.cmd("sudo -n true", None)
|
||||||
|
.config(toml::toml! {
|
||||||
|
[sudo]
|
||||||
|
disabled = false
|
||||||
|
allow_windows = true
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
let expected = None;
|
||||||
|
|
||||||
|
assert_eq!(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_sudo_cached() {
|
||||||
|
let actual = ModuleRenderer::new("sudo")
|
||||||
|
.cmd(
|
||||||
|
"sudo -n true",
|
||||||
|
Some(CommandOutput {
|
||||||
|
stdout: "".to_owned(),
|
||||||
|
stderr: "".to_owned(),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.config(toml::toml! {
|
||||||
|
[sudo]
|
||||||
|
disabled = false
|
||||||
|
allow_windows = true
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
let expected = Some(format!("{}", Color::Blue.bold().paint("as 🧙 ")));
|
||||||
|
|
||||||
|
assert_eq!(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(windows)]
|
||||||
|
fn test_allow_windows_disabled_blocks_windows() {
|
||||||
|
let actual = ModuleRenderer::new("sudo")
|
||||||
|
.cmd(
|
||||||
|
"sudo -n true",
|
||||||
|
Some(CommandOutput {
|
||||||
|
stdout: "".to_owned(),
|
||||||
|
stderr: "".to_owned(),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.config(toml::toml! {
|
||||||
|
[sudo]
|
||||||
|
disabled = false
|
||||||
|
allow_windows = false
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
let expected = None;
|
||||||
|
|
||||||
|
assert_eq!(expected, actual);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user