mirror of
https://github.com/starship/starship.git
synced 2024-12-15 20:00:45 +01:00
Merge branch 'master' into conditional-style
This commit is contained in:
commit
ba15c18c15
@ -41,7 +41,7 @@
|
||||
"plugins": [
|
||||
"https://github.com/dprint/dprint-plugin-typescript/releases/download/0.78.0/plugin.wasm",
|
||||
"https://github.com/dprint/dprint-plugin-json/releases/download/0.16.0/plugin.wasm",
|
||||
"https://github.com/dprint/dprint-plugin-markdown/releases/download/0.14.1/plugin.wasm",
|
||||
"https://github.com/dprint/dprint-plugin-markdown/releases/download/0.14.2/plugin.wasm",
|
||||
"https://github.com/dprint/dprint-plugin-toml/releases/download/0.5.4/plugin.wasm"
|
||||
]
|
||||
}
|
||||
|
35
Cargo.lock
generated
35
Cargo.lock
generated
@ -575,9 +575,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.3"
|
||||
version = "0.10.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506"
|
||||
checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
|
||||
dependencies = [
|
||||
"block-buffer 0.10.2",
|
||||
"crypto-common",
|
||||
@ -1031,9 +1031,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "git-features"
|
||||
version = "0.24.0"
|
||||
version = "0.24.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d795b325f589a50a00d834ffe278b1cc1c11a667016ac71941bce13a260c4ba9"
|
||||
checksum = "d7bdbe755d2129bc609437b6b18af1116f146128dda6070c15c0aa50201ac17c"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"crossbeam-channel",
|
||||
@ -1046,7 +1046,7 @@ dependencies = [
|
||||
"parking_lot",
|
||||
"prodash",
|
||||
"quick-error",
|
||||
"sha1 0.10.1",
|
||||
"sha1 0.10.5",
|
||||
"sha1_smol",
|
||||
"walkdir",
|
||||
]
|
||||
@ -2101,7 +2101,7 @@ checksum = "57959b91f0a133f89a68be874a5c88ed689c19cd729ecdb5d762ebf16c64d662"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"pest",
|
||||
"sha1 0.10.1",
|
||||
"sha1 0.10.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2268,9 +2268,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "prodash"
|
||||
version = "21.0.0"
|
||||
version = "21.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d27f6a3ef883aaea624a6ad91c88452e5df05430a79fd880c12673a7bc1648d6"
|
||||
checksum = "7e13d7bd38cdab08b3a8b780cedcc54238c84fdca4084eb188807b308bcf11e6"
|
||||
dependencies = [
|
||||
"bytesize",
|
||||
"human_format",
|
||||
@ -2632,17 +2632,6 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha-1"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"cpufeatures",
|
||||
"digest 0.10.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha1"
|
||||
version = "0.6.1"
|
||||
@ -2654,13 +2643,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sha1"
|
||||
version = "0.10.1"
|
||||
version = "0.10.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c77f4e7f65455545c2153c1253d25056825e77ee2533f0e41deb65a93a34852f"
|
||||
checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"cpufeatures",
|
||||
"digest 0.10.3",
|
||||
"digest 0.10.6",
|
||||
"sha1-asm",
|
||||
]
|
||||
|
||||
@ -2817,7 +2806,7 @@ dependencies = [
|
||||
"semver 1.0.14",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha-1",
|
||||
"sha1 0.10.5",
|
||||
"shadow-rs",
|
||||
"shell-words",
|
||||
"starship-battery",
|
||||
|
@ -48,7 +48,7 @@ clap_complete = "4.0.6"
|
||||
dirs-next = "2.0.0"
|
||||
dunce = "1.0.3"
|
||||
gethostname = "0.4.0"
|
||||
git-features = { version = "0.24.0", optional = true }
|
||||
git-features = { version = "0.24.1", optional = true }
|
||||
# default feature restriction addresses https://github.com/starship/starship/issues/4251
|
||||
git-repository = { version = "0.29.0", default-features = false, features = ["max-performance-safe"] }
|
||||
indexmap = { version = "1.9.2", features = ["serde"] }
|
||||
@ -73,7 +73,7 @@ rust-ini = "0.18.0"
|
||||
semver = "1.0.14"
|
||||
serde = { version = "1.0.147", features = ["derive"] }
|
||||
serde_json = "1.0.89"
|
||||
sha-1 = "0.10.0"
|
||||
sha1 = "0.10.5"
|
||||
shadow-rs = { version = "0.18.0", default-features = false }
|
||||
# battery is optional (on by default) because the crate doesn't currently build for Termux
|
||||
# see: https://github.com/svartalf/rust-battery/issues/33
|
||||
|
@ -439,7 +439,7 @@ Enterprise_Naming_Scheme-voidstars = 'void**'
|
||||
|
||||
## Azure
|
||||
|
||||
The `azure` module shows the current Azure Subscription. This is based on showing the name of the default subscription, as defined in the `~/.azure/azureProfile.json` file.
|
||||
The `azure` module shows the current Azure Subscription. This is based on showing the name of the default subscription or the username, as defined in the `~/.azure/azureProfile.json` file.
|
||||
|
||||
### Options
|
||||
|
||||
@ -450,7 +450,9 @@ The `azure` module shows the current Azure Subscription. This is based on showin
|
||||
| `style` | `'blue bold'` | The style used in the format. |
|
||||
| `disabled` | `true` | Disables the `azure` module. |
|
||||
|
||||
### Example
|
||||
### Examples
|
||||
|
||||
#### Display Subscription Name
|
||||
|
||||
```toml
|
||||
# ~/.config/starship.toml
|
||||
@ -462,6 +464,18 @@ symbol = 'ﴃ '
|
||||
style = 'blue bold'
|
||||
```
|
||||
|
||||
#### Display Username
|
||||
|
||||
```toml
|
||||
# ~/.config/starship.toml
|
||||
|
||||
[azure]
|
||||
disabled = false
|
||||
format = "on [$symbol($username)]($style) "
|
||||
symbol = "ﴃ "
|
||||
style = "blue bold"
|
||||
```
|
||||
|
||||
## Battery
|
||||
|
||||
The `battery` module shows how charged the device's battery is and its current charging status.
|
||||
|
@ -63,7 +63,7 @@ fn get_creds<'a>(context: &Context, config: &'a OnceCell<Option<Ini>>) -> Option
|
||||
// Get the section for a given profile name in the config file.
|
||||
fn get_profile_config<'a>(
|
||||
config: &'a Ini,
|
||||
profile: &Option<Profile>,
|
||||
profile: Option<&Profile>,
|
||||
) -> Option<&'a ini::Properties> {
|
||||
match profile {
|
||||
Some(profile) => config.section(Some(format!("profile {profile}"))),
|
||||
@ -74,11 +74,11 @@ fn get_profile_config<'a>(
|
||||
// Get the section for a given profile name in the credentials file.
|
||||
fn get_profile_creds<'a>(
|
||||
config: &'a Ini,
|
||||
profile: &Option<Profile>,
|
||||
profile: Option<&Profile>,
|
||||
) -> Option<&'a ini::Properties> {
|
||||
match profile {
|
||||
None => config.section(Some("default")),
|
||||
_ => config.section(profile.as_ref()),
|
||||
_ => config.section(profile),
|
||||
}
|
||||
}
|
||||
|
||||
@ -88,7 +88,7 @@ fn get_aws_region_from_config(
|
||||
aws_config: &AwsConfigFile,
|
||||
) -> Option<Region> {
|
||||
let config = get_config(context, aws_config)?;
|
||||
let section = get_profile_config(config, aws_profile)?;
|
||||
let section = get_profile_config(config, aws_profile.as_ref())?;
|
||||
|
||||
section.get("region").map(std::borrow::ToOwned::to_owned)
|
||||
}
|
||||
@ -118,7 +118,7 @@ fn get_aws_profile_and_region(
|
||||
|
||||
fn get_credentials_duration(
|
||||
context: &Context,
|
||||
aws_profile: &Option<String>,
|
||||
aws_profile: Option<&Profile>,
|
||||
aws_creds: &AwsCredsFile,
|
||||
) -> Option<i64> {
|
||||
let expiration_env_vars = ["AWS_SESSION_EXPIRATION", "AWSUME_EXPIRATION"];
|
||||
@ -150,18 +150,35 @@ fn alias_name(name: Option<String>, aliases: &HashMap<String, &str>) -> Option<S
|
||||
|
||||
fn has_credential_process_or_sso(
|
||||
context: &Context,
|
||||
aws_profile: &Option<Profile>,
|
||||
aws_profile: Option<&Profile>,
|
||||
aws_config: &AwsConfigFile,
|
||||
aws_creds: &AwsCredsFile,
|
||||
) -> Option<bool> {
|
||||
let config = get_config(context, aws_config)?;
|
||||
let credentials = get_creds(context, aws_creds);
|
||||
|
||||
let section = get_profile_config(config, aws_profile)?;
|
||||
Some(section.contains_key("credential_process") || section.contains_key("sso_start_url"))
|
||||
let empty_section = ini::Properties::new();
|
||||
// We use the aws_profile here because `get_profile_config()` treats None
|
||||
// as "special" and falls back to the "[default]"; otherwise this tries
|
||||
// to look up "[profile default]" which doesn't exist
|
||||
let config_section = get_profile_config(config, aws_profile).or(Some(&empty_section))?;
|
||||
|
||||
let credential_section = match credentials {
|
||||
Some(credentials) => get_profile_creds(credentials, aws_profile),
|
||||
None => None,
|
||||
};
|
||||
|
||||
Some(
|
||||
config_section.contains_key("credential_process")
|
||||
|| config_section.contains_key("sso_start_url")
|
||||
|| credential_section?.contains_key("credential_process")
|
||||
|| credential_section?.contains_key("sso_start_url"),
|
||||
)
|
||||
}
|
||||
|
||||
fn has_defined_credentials(
|
||||
context: &Context,
|
||||
aws_profile: &Option<Profile>,
|
||||
aws_profile: Option<&Profile>,
|
||||
aws_creds: &AwsCredsFile,
|
||||
) -> Option<bool> {
|
||||
let valid_env_vars = [
|
||||
@ -197,14 +214,15 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
|
||||
// only display if credential_process is defined or has valid credentials
|
||||
if !config.force_display
|
||||
&& !has_credential_process_or_sso(context, &aws_profile, &aws_config).unwrap_or(false)
|
||||
&& !has_defined_credentials(context, &aws_profile, &aws_creds).unwrap_or(false)
|
||||
&& !has_credential_process_or_sso(context, aws_profile.as_ref(), &aws_config, &aws_creds)
|
||||
.unwrap_or(false)
|
||||
&& !has_defined_credentials(context, aws_profile.as_ref(), &aws_creds).unwrap_or(false)
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
let duration = {
|
||||
get_credentials_duration(context, &aws_profile, &aws_creds).map(|duration| {
|
||||
get_credentials_duration(context, aws_profile.as_ref(), &aws_creds).map(|duration| {
|
||||
if duration > 0 {
|
||||
render_time((duration * 1000) as u128, false)
|
||||
} else {
|
||||
@ -899,6 +917,44 @@ credential_process = /opt/bin/awscreds-retriever
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn credential_process_set_in_credentials() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let config_path = dir.path().join("config");
|
||||
let credential_path = dir.path().join("credentials");
|
||||
let mut file = File::create(&config_path)?;
|
||||
|
||||
file.write_all(
|
||||
"[default]
|
||||
region = ap-northeast-2
|
||||
"
|
||||
.as_bytes(),
|
||||
)?;
|
||||
|
||||
let mut file = File::create(&credential_path)?;
|
||||
|
||||
file.write_all(
|
||||
"[default]
|
||||
credential_process = /opt/bin/awscreds-for-tests
|
||||
"
|
||||
.as_bytes(),
|
||||
)?;
|
||||
let actual = ModuleRenderer::new("aws")
|
||||
.env("AWS_CONFIG_FILE", config_path.to_string_lossy().as_ref())
|
||||
.env(
|
||||
"AWS_CREDENTIALS_FILE",
|
||||
credential_path.to_string_lossy().as_ref(),
|
||||
)
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"on {}",
|
||||
Color::Yellow.bold().paint("☁️ (ap-northeast-2) ")
|
||||
));
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sso_set() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
|
@ -1,15 +1,32 @@
|
||||
use std::fs::File;
|
||||
use std::io::{BufReader, Read};
|
||||
use std::path::{Path, PathBuf};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use super::{Context, Module, ModuleConfig};
|
||||
|
||||
type JValue = serde_json::Value;
|
||||
|
||||
use crate::configs::azure::AzureConfig;
|
||||
use crate::formatter::StringFormatter;
|
||||
|
||||
type SubscriptionName = String;
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct AzureProfile {
|
||||
installation_id: String,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
subscriptions: Vec<Subscription>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
struct User {
|
||||
name: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct Subscription {
|
||||
name: String,
|
||||
user: User,
|
||||
is_default: bool,
|
||||
}
|
||||
|
||||
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
let mut module = context.new_module("azure");
|
||||
@ -19,11 +36,14 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
return None;
|
||||
};
|
||||
|
||||
let subscription_name: Option<SubscriptionName> = get_azure_subscription_name(context);
|
||||
if subscription_name.is_none() {
|
||||
log::info!("Could not find Azure subscription name");
|
||||
let subscription: Option<Subscription> = get_azure_profile_info(context);
|
||||
|
||||
if subscription.is_none() {
|
||||
log::info!("Could not find Subscriptions in azureProfile.json");
|
||||
return None;
|
||||
};
|
||||
}
|
||||
|
||||
let subscription = subscription.unwrap();
|
||||
|
||||
let parsed = StringFormatter::new(config.format).and_then(|formatter| {
|
||||
formatter
|
||||
@ -36,7 +56,8 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
_ => None,
|
||||
})
|
||||
.map(|variable| match variable {
|
||||
"subscription" => Some(Ok(subscription_name.as_ref().unwrap())),
|
||||
"subscription" => Some(Ok(&subscription.name)),
|
||||
"username" => Some(Ok(&subscription.user.name)),
|
||||
_ => None,
|
||||
})
|
||||
.parse(None, Some(context))
|
||||
@ -53,24 +74,24 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
Some(module)
|
||||
}
|
||||
|
||||
fn get_azure_subscription_name(context: &Context) -> Option<SubscriptionName> {
|
||||
fn get_azure_profile_info(context: &Context) -> Option<Subscription> {
|
||||
let mut config_path = get_config_file_location(context)?;
|
||||
config_path.push("azureProfile.json");
|
||||
|
||||
let parsed_json = parse_json(&config_path)?;
|
||||
let azure_profile = load_azure_profile(&config_path)?;
|
||||
azure_profile
|
||||
.subscriptions
|
||||
.into_iter()
|
||||
.find(|s| s.is_default)
|
||||
}
|
||||
|
||||
let subscriptions = parsed_json.get("subscriptions")?.as_array()?;
|
||||
let subscription_name = subscriptions.iter().find_map(|s| {
|
||||
if s.get("isDefault")? == true {
|
||||
Some(s.get("name")?.as_str()?.to_string())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
if subscription_name.is_some() {
|
||||
subscription_name
|
||||
fn load_azure_profile(config_path: &PathBuf) -> Option<AzureProfile> {
|
||||
let json_data = fs::read_to_string(config_path).ok()?;
|
||||
let sanitized_json_data = json_data.strip_prefix('\u{feff}').unwrap_or(&json_data);
|
||||
if let Ok(azure_profile) = serde_json::from_str::<AzureProfile>(sanitized_json_data) {
|
||||
Some(azure_profile)
|
||||
} else {
|
||||
log::info!("Could not find subscription name");
|
||||
log::info!("Failed to parse azure profile.");
|
||||
None
|
||||
}
|
||||
}
|
||||
@ -86,27 +107,9 @@ fn get_config_file_location(context: &Context) -> Option<PathBuf> {
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_json(json_file_path: &Path) -> Option<JValue> {
|
||||
let mut buffer: Vec<u8> = Vec::new();
|
||||
|
||||
let json_file = File::open(json_file_path).ok()?;
|
||||
let mut reader = BufReader::new(json_file);
|
||||
reader.read_to_end(&mut buffer).ok()?;
|
||||
|
||||
let bytes = buffer.as_mut_slice();
|
||||
let decodedbuffer = bytes.strip_prefix(&[239, 187, 191]).unwrap_or(bytes);
|
||||
|
||||
if let Ok(parsed_json) = serde_json::from_slice(decodedbuffer) {
|
||||
Some(parsed_json)
|
||||
} else {
|
||||
log::info!("Failed to parse json");
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::modules::azure::parse_json;
|
||||
use crate::modules::azure::load_azure_profile;
|
||||
use crate::test::ModuleRenderer;
|
||||
use ini::Ini;
|
||||
use nu_ansi_term::Color;
|
||||
@ -154,6 +157,7 @@ mod tests {
|
||||
"name": "user@domain.com",
|
||||
"type": "user"
|
||||
},
|
||||
"isDefault": false,
|
||||
"tenantId": "a4e1bb4b-5330-2d50-339d-b9674d3a87bc",
|
||||
"environmentName": "AzureCloud",
|
||||
"homeTenantId": "a4e1bb4b-5330-2d50-339d-b9674d3a87bc",
|
||||
@ -194,6 +198,424 @@ mod tests {
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn user_name_set_correctly() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
|
||||
let azure_profile_contents = r#"{
|
||||
"installationId": "3deacd2a-b9db-77e1-aa42-23e2f8dfffc3",
|
||||
"subscriptions": [
|
||||
{
|
||||
"id": "f568c543-d12e-de0b-3d85-69843598b565",
|
||||
"name": "Subscription 2",
|
||||
"state": "Enabled",
|
||||
"user": {
|
||||
"name": "user@domain.com",
|
||||
"type": "user"
|
||||
},
|
||||
"isDefault": false,
|
||||
"tenantId": "0e8a15ec-b0f5-d355-7062-8ece54c59aee",
|
||||
"environmentName": "AzureCloud",
|
||||
"homeTenantId": "0e8a15ec-b0f5-d355-7062-8ece54c59aee",
|
||||
"managedByTenants": []
|
||||
},
|
||||
{
|
||||
"id": "d4442d26-ea6d-46c4-07cb-4f70b8ae5465",
|
||||
"name": "Subscription 3",
|
||||
"state": "Enabled",
|
||||
"user": {
|
||||
"name": "user@domain.com",
|
||||
"type": "user"
|
||||
},
|
||||
"isDefault": false,
|
||||
"tenantId": "a4e1bb4b-5330-2d50-339d-b9674d3a87bc",
|
||||
"environmentName": "AzureCloud",
|
||||
"homeTenantId": "a4e1bb4b-5330-2d50-339d-b9674d3a87bc",
|
||||
"managedByTenants": []
|
||||
},
|
||||
{
|
||||
"id": "f3935dc9-92b5-9a93-da7b-42c325d86939",
|
||||
"name": "Subscription 1",
|
||||
"state": "Enabled",
|
||||
"user": {
|
||||
"name": "user@domain.com",
|
||||
"type": "user"
|
||||
},
|
||||
"isDefault": true,
|
||||
"tenantId": "f0273a19-7779-e40a-00a1-53b8331b3bb6",
|
||||
"environmentName": "AzureCloud",
|
||||
"homeTenantId": "f0273a19-7779-e40a-00a1-53b8331b3bb6",
|
||||
"managedByTenants": []
|
||||
}
|
||||
]
|
||||
}
|
||||
"#;
|
||||
|
||||
generate_test_config(&dir, azure_profile_contents)?;
|
||||
let dir_path = &dir.path().to_string_lossy();
|
||||
let actual = ModuleRenderer::new("azure")
|
||||
.config(toml::toml! {
|
||||
[azure]
|
||||
format = "on [$symbol($username)]($style)"
|
||||
disabled = false
|
||||
})
|
||||
.env("AZURE_CONFIG_DIR", dir_path.as_ref())
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"on {}",
|
||||
Color::Blue.bold().paint("ﴃ user@domain.com")
|
||||
));
|
||||
assert_eq!(actual, expected);
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn subscription_name_empty() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
|
||||
let azure_profile_contents = r#"{
|
||||
"installationId": "3deacd2a-b9db-77e1-aa42-23e2f8dfffc3",
|
||||
"subscriptions": [
|
||||
{
|
||||
"id": "f568c543-d12e-de0b-3d85-69843598b565",
|
||||
"name": "Subscription 2",
|
||||
"state": "Enabled",
|
||||
"user": {
|
||||
"name": "user@domain.com",
|
||||
"type": "user"
|
||||
},
|
||||
"isDefault": false,
|
||||
"tenantId": "0e8a15ec-b0f5-d355-7062-8ece54c59aee",
|
||||
"environmentName": "AzureCloud",
|
||||
"homeTenantId": "0e8a15ec-b0f5-d355-7062-8ece54c59aee",
|
||||
"managedByTenants": []
|
||||
},
|
||||
{
|
||||
"id": "d4442d26-ea6d-46c4-07cb-4f70b8ae5465",
|
||||
"name": "Subscription 3",
|
||||
"state": "Enabled",
|
||||
"user": {
|
||||
"name": "user@domain.com",
|
||||
"type": "user"
|
||||
},
|
||||
"isDefault": false,
|
||||
"tenantId": "a4e1bb4b-5330-2d50-339d-b9674d3a87bc",
|
||||
"environmentName": "AzureCloud",
|
||||
"homeTenantId": "a4e1bb4b-5330-2d50-339d-b9674d3a87bc",
|
||||
"managedByTenants": []
|
||||
},
|
||||
{
|
||||
"id": "f3935dc9-92b5-9a93-da7b-42c325d86939",
|
||||
"name": "",
|
||||
"state": "Enabled",
|
||||
"user": {
|
||||
"name": "user@domain.com",
|
||||
"type": "user"
|
||||
},
|
||||
"isDefault": true,
|
||||
"tenantId": "f0273a19-7779-e40a-00a1-53b8331b3bb6",
|
||||
"environmentName": "AzureCloud",
|
||||
"homeTenantId": "f0273a19-7779-e40a-00a1-53b8331b3bb6",
|
||||
"managedByTenants": []
|
||||
}
|
||||
]
|
||||
}
|
||||
"#;
|
||||
|
||||
generate_test_config(&dir, azure_profile_contents)?;
|
||||
let dir_path = &dir.path().to_string_lossy();
|
||||
let actual = ModuleRenderer::new("azure")
|
||||
.config(toml::toml! {
|
||||
[azure]
|
||||
format = "on [$symbol($subscription:$username)]($style)"
|
||||
disabled = false
|
||||
})
|
||||
.env("AZURE_CONFIG_DIR", dir_path.as_ref())
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"on {}",
|
||||
Color::Blue.bold().paint("ﴃ :user@domain.com")
|
||||
));
|
||||
assert_eq!(actual, expected);
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn user_name_empty() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
|
||||
let azure_profile_contents = r#"{
|
||||
"installationId": "3deacd2a-b9db-77e1-aa42-23e2f8dfffc3",
|
||||
"subscriptions": [
|
||||
{
|
||||
"id": "f568c543-d12e-de0b-3d85-69843598b565",
|
||||
"name": "Subscription 2",
|
||||
"state": "Enabled",
|
||||
"user": {
|
||||
"name": "user@domain.com",
|
||||
"type": "user"
|
||||
},
|
||||
"isDefault": false,
|
||||
"tenantId": "0e8a15ec-b0f5-d355-7062-8ece54c59aee",
|
||||
"environmentName": "AzureCloud",
|
||||
"homeTenantId": "0e8a15ec-b0f5-d355-7062-8ece54c59aee",
|
||||
"managedByTenants": []
|
||||
},
|
||||
{
|
||||
"id": "d4442d26-ea6d-46c4-07cb-4f70b8ae5465",
|
||||
"name": "Subscription 3",
|
||||
"state": "Enabled",
|
||||
"user": {
|
||||
"name": "user@domain.com",
|
||||
"type": "user"
|
||||
},
|
||||
"isDefault": false,
|
||||
"tenantId": "a4e1bb4b-5330-2d50-339d-b9674d3a87bc",
|
||||
"environmentName": "AzureCloud",
|
||||
"homeTenantId": "a4e1bb4b-5330-2d50-339d-b9674d3a87bc",
|
||||
"managedByTenants": []
|
||||
},
|
||||
{
|
||||
"id": "f3935dc9-92b5-9a93-da7b-42c325d86939",
|
||||
"name": "Subscription 1",
|
||||
"state": "Enabled",
|
||||
"user": {
|
||||
"name": "",
|
||||
"type": "user"
|
||||
},
|
||||
"isDefault": true,
|
||||
"tenantId": "f0273a19-7779-e40a-00a1-53b8331b3bb6",
|
||||
"environmentName": "AzureCloud",
|
||||
"homeTenantId": "f0273a19-7779-e40a-00a1-53b8331b3bb6",
|
||||
"managedByTenants": []
|
||||
}
|
||||
]
|
||||
}
|
||||
"#;
|
||||
|
||||
generate_test_config(&dir, azure_profile_contents)?;
|
||||
let dir_path = &dir.path().to_string_lossy();
|
||||
let actual = ModuleRenderer::new("azure")
|
||||
.config(toml::toml! {
|
||||
[azure]
|
||||
format = "on [$symbol($subscription:$username)]($style)"
|
||||
disabled = false
|
||||
})
|
||||
.env("AZURE_CONFIG_DIR", dir_path.as_ref())
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"on {}",
|
||||
Color::Blue.bold().paint("ﴃ Subscription 1:")
|
||||
));
|
||||
assert_eq!(actual, expected);
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn user_name_missing_from_profile() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
|
||||
let azure_profile_contents = r#"{
|
||||
"installationId": "3deacd2a-b9db-77e1-aa42-23e2f8dfffc3",
|
||||
"subscriptions": [
|
||||
{
|
||||
"id": "f568c543-d12e-de0b-3d85-69843598b565",
|
||||
"name": "Subscription 2",
|
||||
"state": "Enabled",
|
||||
"user": {
|
||||
"type": "user"
|
||||
},
|
||||
"isDefault": false,
|
||||
"tenantId": "0e8a15ec-b0f5-d355-7062-8ece54c59aee",
|
||||
"environmentName": "AzureCloud",
|
||||
"homeTenantId": "0e8a15ec-b0f5-d355-7062-8ece54c59aee",
|
||||
"managedByTenants": []
|
||||
},
|
||||
{
|
||||
"id": "d4442d26-ea6d-46c4-07cb-4f70b8ae5465",
|
||||
"name": "Subscription 3",
|
||||
"state": "Enabled",
|
||||
"user": {
|
||||
"name": "user@domain.com",
|
||||
"type": "user"
|
||||
},
|
||||
"isDefault": false,
|
||||
"tenantId": "a4e1bb4b-5330-2d50-339d-b9674d3a87bc",
|
||||
"environmentName": "AzureCloud",
|
||||
"homeTenantId": "a4e1bb4b-5330-2d50-339d-b9674d3a87bc",
|
||||
"managedByTenants": []
|
||||
},
|
||||
{
|
||||
"id": "f3935dc9-92b5-9a93-da7b-42c325d86939",
|
||||
"name": "Subscription 1",
|
||||
"state": "Enabled",
|
||||
"user": {
|
||||
"name": "",
|
||||
"type": "user"
|
||||
},
|
||||
"isDefault": true,
|
||||
"tenantId": "f0273a19-7779-e40a-00a1-53b8331b3bb6",
|
||||
"environmentName": "AzureCloud",
|
||||
"homeTenantId": "f0273a19-7779-e40a-00a1-53b8331b3bb6",
|
||||
"managedByTenants": []
|
||||
}
|
||||
]
|
||||
}
|
||||
"#;
|
||||
|
||||
generate_test_config(&dir, azure_profile_contents)?;
|
||||
let dir_path = &dir.path().to_string_lossy();
|
||||
let actual = ModuleRenderer::new("azure")
|
||||
.config(toml::toml! {
|
||||
[azure]
|
||||
format = "on [$symbol($subscription:$username)]($style)"
|
||||
disabled = false
|
||||
})
|
||||
.env("AZURE_CONFIG_DIR", dir_path.as_ref())
|
||||
.collect();
|
||||
let expected = None;
|
||||
assert_eq!(actual, expected);
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn subscription_name_missing_from_profile() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
|
||||
let azure_profile_contents = r#"{
|
||||
"installationId": "3deacd2a-b9db-77e1-aa42-23e2f8dfffc3",
|
||||
"subscriptions": [
|
||||
{
|
||||
"id": "f568c543-d12e-de0b-3d85-69843598b565",
|
||||
"name": "Subscription 2",
|
||||
"state": "Enabled",
|
||||
"user": {
|
||||
"name": "user@domain.com",
|
||||
"type": "user"
|
||||
},
|
||||
"isDefault": false,
|
||||
"tenantId": "0e8a15ec-b0f5-d355-7062-8ece54c59aee",
|
||||
"environmentName": "AzureCloud",
|
||||
"homeTenantId": "0e8a15ec-b0f5-d355-7062-8ece54c59aee",
|
||||
"managedByTenants": []
|
||||
},
|
||||
{
|
||||
"id": "d4442d26-ea6d-46c4-07cb-4f70b8ae5465",
|
||||
"name": "Subscription 3",
|
||||
"state": "Enabled",
|
||||
"user": {
|
||||
"name": "user@domain.com",
|
||||
"type": "user"
|
||||
},
|
||||
"isDefault": false,
|
||||
"tenantId": "a4e1bb4b-5330-2d50-339d-b9674d3a87bc",
|
||||
"environmentName": "AzureCloud",
|
||||
"homeTenantId": "a4e1bb4b-5330-2d50-339d-b9674d3a87bc",
|
||||
"managedByTenants": []
|
||||
},
|
||||
{
|
||||
"id": "f3935dc9-92b5-9a93-da7b-42c325d86939",
|
||||
"state": "Enabled",
|
||||
"user": {
|
||||
"name": "user@domain.com",
|
||||
"type": "user"
|
||||
},
|
||||
"isDefault": true,
|
||||
"tenantId": "f0273a19-7779-e40a-00a1-53b8331b3bb6",
|
||||
"environmentName": "AzureCloud",
|
||||
"homeTenantId": "f0273a19-7779-e40a-00a1-53b8331b3bb6",
|
||||
"managedByTenants": []
|
||||
}
|
||||
]
|
||||
}
|
||||
"#;
|
||||
|
||||
generate_test_config(&dir, azure_profile_contents)?;
|
||||
let dir_path = &dir.path().to_string_lossy();
|
||||
let actual = ModuleRenderer::new("azure")
|
||||
.config(toml::toml! {
|
||||
[azure]
|
||||
format = "on [$symbol($subscription:$username)]($style)"
|
||||
disabled = false
|
||||
})
|
||||
.env("AZURE_CONFIG_DIR", dir_path.as_ref())
|
||||
.collect();
|
||||
let expected = None;
|
||||
assert_eq!(actual, expected);
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn subscription_name_and_username_found() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
|
||||
let azure_profile_contents = r#"{
|
||||
"installationId": "3deacd2a-b9db-77e1-aa42-23e2f8dfffc3",
|
||||
"subscriptions": [
|
||||
{
|
||||
"id": "f568c543-d12e-de0b-3d85-69843598b565",
|
||||
"name": "Subscription 2",
|
||||
"state": "Enabled",
|
||||
"user": {
|
||||
"name": "user@domain.com",
|
||||
"type": "user"
|
||||
},
|
||||
"isDefault": false,
|
||||
"tenantId": "0e8a15ec-b0f5-d355-7062-8ece54c59aee",
|
||||
"environmentName": "AzureCloud",
|
||||
"homeTenantId": "0e8a15ec-b0f5-d355-7062-8ece54c59aee",
|
||||
"managedByTenants": []
|
||||
},
|
||||
{
|
||||
"id": "d4442d26-ea6d-46c4-07cb-4f70b8ae5465",
|
||||
"name": "Subscription 3",
|
||||
"state": "Enabled",
|
||||
"user": {
|
||||
"name": "user@domain.com",
|
||||
"type": "user"
|
||||
},
|
||||
"isDefault": false,
|
||||
"tenantId": "a4e1bb4b-5330-2d50-339d-b9674d3a87bc",
|
||||
"environmentName": "AzureCloud",
|
||||
"homeTenantId": "a4e1bb4b-5330-2d50-339d-b9674d3a87bc",
|
||||
"managedByTenants": []
|
||||
},
|
||||
{
|
||||
"id": "f3935dc9-92b5-9a93-da7b-42c325d86939",
|
||||
"name": "Subscription 1",
|
||||
"state": "Enabled",
|
||||
"user": {
|
||||
"name": "user@domain.com",
|
||||
"type": "user"
|
||||
},
|
||||
"isDefault": true,
|
||||
"tenantId": "f0273a19-7779-e40a-00a1-53b8331b3bb6",
|
||||
"environmentName": "AzureCloud",
|
||||
"homeTenantId": "f0273a19-7779-e40a-00a1-53b8331b3bb6",
|
||||
"managedByTenants": []
|
||||
}
|
||||
]
|
||||
}
|
||||
"#;
|
||||
|
||||
generate_test_config(&dir, azure_profile_contents)?;
|
||||
let dir_path = &dir.path().to_string_lossy();
|
||||
let actual = ModuleRenderer::new("azure")
|
||||
.config(toml::toml! {
|
||||
[azure]
|
||||
format = "on [$symbol($subscription:$username)]($style)"
|
||||
disabled = false
|
||||
})
|
||||
.env("AZURE_CONFIG_DIR", dir_path.as_ref())
|
||||
.collect();
|
||||
let expected = Some(format!(
|
||||
"on {}",
|
||||
Color::Blue.bold().paint("ﴃ Subscription 1:user@domain.com")
|
||||
));
|
||||
assert_eq!(actual, expected);
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn subscription_azure_profile_empty() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
@ -203,6 +625,7 @@ mod tests {
|
||||
.with_section(Some("AzureCloud"))
|
||||
.set("subscription", "f3935dc9-92b5-9a93-da7b-42c325d86939");
|
||||
|
||||
//let azure_profile_contents = "\u{feff}{\"installationId\": \"2652263e-40f8-11ed-ae3b-367ddada549c\", \"subscriptions\": []}";
|
||||
let azure_profile_contents = r#"{
|
||||
"installationId": "3deacd2a-b9db-77e1-aa42-23e2f8dfffc3",
|
||||
"subscriptions": []
|
||||
@ -223,6 +646,48 @@ mod tests {
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn azure_profile_with_leading_char() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
|
||||
let bom = vec![239, 187, 191];
|
||||
let mut bom_str = String::from_utf8(bom).unwrap();
|
||||
|
||||
let json_str =
|
||||
r#"{"installationId": "3deacd2a-b9db-77e1-aa42-23e2f8dfffc3", "subscriptions": []}"#;
|
||||
|
||||
bom_str.push_str(json_str);
|
||||
|
||||
let dir_path_no_bom = save_string_to_file(&dir, bom_str, String::from("bom.json"))?;
|
||||
let sanitized_json = load_azure_profile(&dir_path_no_bom).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
sanitized_json.installation_id,
|
||||
"3deacd2a-b9db-77e1-aa42-23e2f8dfffc3"
|
||||
);
|
||||
assert!(sanitized_json.subscriptions.is_empty());
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn azure_profile_without_leading_char() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
|
||||
let json_str =
|
||||
r#"{"installationId": "3deacd2a-b9db-77e1-aa42-23e2f8dfffc3", "subscriptions": []}"#;
|
||||
|
||||
let dir_path_no_bom =
|
||||
save_string_to_file(&dir, json_str.to_string(), String::from("bom.json"))?;
|
||||
let sanitized_json = load_azure_profile(&dir_path_no_bom).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
sanitized_json.installation_id,
|
||||
"3deacd2a-b9db-77e1-aa42-23e2f8dfffc3"
|
||||
);
|
||||
assert!(sanitized_json.subscriptions.is_empty());
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn files_missing() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
@ -237,22 +702,6 @@ mod tests {
|
||||
dir.close()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn json_parsing() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
|
||||
let bom = vec![239, 187, 191];
|
||||
let mut bom_str = String::from_utf8(bom).unwrap();
|
||||
let json_str = r#"{"testKey": "testValue"}"#;
|
||||
bom_str.push_str(json_str);
|
||||
|
||||
let dir_path_no_bom = save_string_to_file(&dir, bom_str, String::from("bom.json"))?;
|
||||
let parsed_json = parse_json(&dir_path_no_bom).unwrap();
|
||||
|
||||
assert_eq!(parsed_json.get("testKey").unwrap(), "testValue");
|
||||
dir.close()
|
||||
}
|
||||
|
||||
fn save_string_to_file(
|
||||
dir: &TempDir,
|
||||
contents: String,
|
||||
|
@ -48,13 +48,14 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||
}
|
||||
});
|
||||
|
||||
Some(undistract_me(module, &config, elapsed))
|
||||
Some(undistract_me(module, &config, context, elapsed))
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "notify"))]
|
||||
fn undistract_me<'a, 'b>(
|
||||
module: Module<'a>,
|
||||
_config: &'b CmdDurationConfig,
|
||||
_context: &'a Context,
|
||||
_elapsed: u128,
|
||||
) -> Module<'a> {
|
||||
module
|
||||
@ -64,12 +65,24 @@ fn undistract_me<'a, 'b>(
|
||||
fn undistract_me<'a, 'b>(
|
||||
module: Module<'a>,
|
||||
config: &'b CmdDurationConfig,
|
||||
context: &'a Context,
|
||||
elapsed: u128,
|
||||
) -> Module<'a> {
|
||||
use notify_rust::{Notification, Timeout};
|
||||
use nu_ansi_term::{unstyle, AnsiStrings};
|
||||
|
||||
if config.show_notifications && config.min_time_to_notify as u128 <= elapsed {
|
||||
if cfg!(target_os = "linux") {
|
||||
let in_graphical_session = ["DISPLAY", "WAYLAND_DISPLAY", "MIR_SOCKET"]
|
||||
.iter()
|
||||
.find_map(|&var| context.get_env(var).filter(|val| !val.is_empty()))
|
||||
.is_some();
|
||||
|
||||
if !in_graphical_session {
|
||||
return module;
|
||||
};
|
||||
}
|
||||
|
||||
let body = format!(
|
||||
"Command execution {}",
|
||||
unstyle(&AnsiStrings(&module.ansi_strings()))
|
||||
|
Loading…
Reference in New Issue
Block a user