mirror of
https://github.com/Llewellynvdm/starship.git
synced 2024-12-25 03:16:01 +00:00
fix(config): Make print-config not panic without a config (#5001)
This commit is contained in:
parent
b44f22e375
commit
ce7f984932
@ -1,5 +1,6 @@
|
||||
use crate::configs::Palette;
|
||||
use crate::context::Context;
|
||||
|
||||
use crate::serde_utils::{ValueDeserializer, ValueRef};
|
||||
use crate::utils;
|
||||
use nu_ansi_term::Color;
|
||||
@ -10,9 +11,9 @@ use serde::{
|
||||
use std::borrow::Cow;
|
||||
use std::clone::Clone;
|
||||
use std::collections::HashMap;
|
||||
use std::ffi::OsString;
|
||||
use std::io::ErrorKind;
|
||||
|
||||
use std::env;
|
||||
use toml::Value;
|
||||
|
||||
/// Root config of a module.
|
||||
@ -120,25 +121,10 @@ pub struct StarshipConfig {
|
||||
pub config: Option<toml::Table>,
|
||||
}
|
||||
|
||||
pub fn get_config_path() -> Option<String> {
|
||||
if let Ok(path) = env::var("STARSHIP_CONFIG") {
|
||||
// Use $STARSHIP_CONFIG as the config path if available
|
||||
log::debug!("STARSHIP_CONFIG is set: {}", &path);
|
||||
Some(path)
|
||||
} else {
|
||||
// Default to using ~/.config/starship.toml
|
||||
log::debug!("STARSHIP_CONFIG is not set");
|
||||
let config_path = utils::home_dir()?.join(".config/starship.toml");
|
||||
let config_path_str = config_path.to_str()?.to_owned();
|
||||
log::debug!("Using default config path: {}", config_path_str);
|
||||
Some(config_path_str)
|
||||
}
|
||||
}
|
||||
|
||||
impl StarshipConfig {
|
||||
/// Initialize the Config struct
|
||||
pub fn initialize() -> Self {
|
||||
Self::config_from_file()
|
||||
pub fn initialize(config_file_path: &Option<OsString>) -> Self {
|
||||
Self::config_from_file(config_file_path)
|
||||
.map(|config| Self {
|
||||
config: Some(config),
|
||||
})
|
||||
@ -146,10 +132,30 @@ impl StarshipConfig {
|
||||
}
|
||||
|
||||
/// Create a config from a starship configuration file
|
||||
fn config_from_file() -> Option<toml::Table> {
|
||||
let file_path = get_config_path()?;
|
||||
fn config_from_file(config_file_path: &Option<OsString>) -> Option<toml::Table> {
|
||||
let toml_content = Self::read_config_content_as_str(config_file_path)?;
|
||||
|
||||
let toml_content = match utils::read_file(file_path) {
|
||||
match toml::from_str(&toml_content) {
|
||||
Ok(parsed) => {
|
||||
log::debug!("Config parsed: {:?}", &parsed);
|
||||
Some(parsed)
|
||||
}
|
||||
Err(error) => {
|
||||
log::error!("Unable to parse the config file: {}", error);
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_config_content_as_str(config_file_path: &Option<OsString>) -> Option<String> {
|
||||
if config_file_path.is_none() {
|
||||
log::debug!(
|
||||
"Unable to determine `config_file_path`. Perhaps `utils::home_dir` is not defined on your platform?"
|
||||
);
|
||||
return None;
|
||||
}
|
||||
let config_file_path = config_file_path.as_ref().unwrap();
|
||||
match utils::read_file(config_file_path) {
|
||||
Ok(content) => {
|
||||
log::trace!("Config file content: \"\n{}\"", &content);
|
||||
Some(content)
|
||||
@ -164,17 +170,6 @@ impl StarshipConfig {
|
||||
log::log!(level, "Unable to read config file content: {}", &e);
|
||||
None
|
||||
}
|
||||
}?;
|
||||
|
||||
match toml::from_str(&toml_content) {
|
||||
Ok(parsed) => {
|
||||
log::debug!("Config parsed: {:?}", &parsed);
|
||||
Some(parsed)
|
||||
}
|
||||
Err(error) => {
|
||||
log::error!("Unable to parse the config file: {}", error);
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -921,4 +916,13 @@ mod tests {
|
||||
// Test default behavior
|
||||
assert!(get_palette(&palettes, None).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_config_no_config_file_path_provided() {
|
||||
assert_eq!(
|
||||
None,
|
||||
StarshipConfig::read_config_content_as_str(&None),
|
||||
"if the platform doesn't have utils::home_dir(), it should return None"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
203
src/configure.rs
203
src/configure.rs
@ -1,6 +1,3 @@
|
||||
use std::env;
|
||||
use std::ffi::OsString;
|
||||
use std::io::ErrorKind;
|
||||
use std::process;
|
||||
use std::process::Stdio;
|
||||
use std::str::FromStr;
|
||||
@ -8,6 +5,7 @@ use std::str::FromStr;
|
||||
use crate::config::ModuleConfig;
|
||||
use crate::config::StarshipConfig;
|
||||
use crate::configs::PROMPT_ORDER;
|
||||
use crate::context::Context;
|
||||
use crate::utils;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
@ -18,15 +16,15 @@ const STD_EDITOR: &str = "vi";
|
||||
#[cfg(windows)]
|
||||
const STD_EDITOR: &str = "notepad.exe";
|
||||
|
||||
pub fn update_configuration(name: &str, value: &str) {
|
||||
let mut doc = get_configuration_edit();
|
||||
pub fn update_configuration(context: &Context, name: &str, value: &str) {
|
||||
let mut doc = get_configuration_edit(context);
|
||||
|
||||
match handle_update_configuration(&mut doc, name, value) {
|
||||
Err(e) => {
|
||||
eprintln!("{e}");
|
||||
process::exit(1);
|
||||
}
|
||||
_ => write_configuration(&doc),
|
||||
_ => write_configuration(context, &doc),
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,7 +69,7 @@ fn handle_update_configuration(doc: &mut Document, name: &str, value: &str) -> R
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn print_configuration(use_default: bool, paths: &[String]) {
|
||||
pub fn print_configuration(context: &Context, use_default: bool, paths: &[String]) -> String {
|
||||
let config = if use_default {
|
||||
// Get default config
|
||||
let default_config = crate::configs::FullConfig::default();
|
||||
@ -79,7 +77,7 @@ pub fn print_configuration(use_default: bool, paths: &[String]) {
|
||||
toml::value::Value::try_from(default_config).unwrap()
|
||||
} else {
|
||||
// Get config as toml::Value
|
||||
let user_config = get_configuration();
|
||||
let user_config = get_configuration(context);
|
||||
// Convert into FullConfig and fill in default values
|
||||
let user_config = crate::configs::FullConfig::load(&user_config);
|
||||
// Convert back to Value because toml can't serialize FullConfig directly
|
||||
@ -124,6 +122,7 @@ pub fn print_configuration(use_default: bool, paths: &[String]) {
|
||||
let string_config = toml::to_string_pretty(&print_config).unwrap();
|
||||
|
||||
println!("{string_config}");
|
||||
string_config
|
||||
}
|
||||
|
||||
fn extract_toml_paths(mut config: toml::Value, paths: &[String]) -> toml::Value {
|
||||
@ -176,15 +175,15 @@ fn extract_toml_paths(mut config: toml::Value, paths: &[String]) -> toml::Value
|
||||
toml::Value::Table(subset)
|
||||
}
|
||||
|
||||
pub fn toggle_configuration(name: &str, key: &str) {
|
||||
let mut doc = get_configuration_edit();
|
||||
pub fn toggle_configuration(context: &Context, name: &str, key: &str) {
|
||||
let mut doc = get_configuration_edit(context);
|
||||
|
||||
match handle_toggle_configuration(&mut doc, name, key) {
|
||||
Err(e) => {
|
||||
eprintln!("{e}");
|
||||
process::exit(1);
|
||||
}
|
||||
_ => write_configuration(&doc),
|
||||
_ => write_configuration(context, &doc),
|
||||
}
|
||||
}
|
||||
|
||||
@ -217,32 +216,15 @@ fn handle_toggle_configuration(doc: &mut Document, name: &str, key: &str) -> Res
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_configuration() -> toml::Table {
|
||||
let starship_config = StarshipConfig::initialize();
|
||||
pub fn get_configuration(context: &Context) -> toml::Table {
|
||||
let starship_config = StarshipConfig::initialize(&context.get_config_path_os());
|
||||
|
||||
starship_config
|
||||
.config
|
||||
.expect("Failed to load starship config")
|
||||
starship_config.config.unwrap_or(toml::Table::new())
|
||||
}
|
||||
|
||||
pub fn get_configuration_edit() -> Document {
|
||||
let file_path = get_config_path();
|
||||
let toml_content = match utils::read_file(file_path) {
|
||||
Ok(content) => {
|
||||
log::trace!("Config file content: \"\n{}\"", &content);
|
||||
Some(content)
|
||||
}
|
||||
Err(e) => {
|
||||
let level = if e.kind() == ErrorKind::NotFound {
|
||||
log::Level::Debug
|
||||
} else {
|
||||
log::Level::Error
|
||||
};
|
||||
|
||||
log::log!(level, "Unable to read config file content: {}", &e);
|
||||
None
|
||||
}
|
||||
};
|
||||
pub fn get_configuration_edit(context: &Context) -> Document {
|
||||
let config_file_path = context.get_config_path_os();
|
||||
let toml_content = StarshipConfig::read_config_content_as_str(&config_file_path);
|
||||
|
||||
toml_content
|
||||
.unwrap_or_default()
|
||||
@ -250,8 +232,11 @@ pub fn get_configuration_edit() -> Document {
|
||||
.expect("Failed to load starship config")
|
||||
}
|
||||
|
||||
pub fn write_configuration(doc: &Document) {
|
||||
let config_path = get_config_path();
|
||||
pub fn write_configuration(context: &Context, doc: &Document) {
|
||||
let config_path = context.get_config_path_os().unwrap_or_else(|| {
|
||||
eprintln!("config path required to write configuration");
|
||||
process::exit(1);
|
||||
});
|
||||
|
||||
let config_str = doc.to_string();
|
||||
|
||||
@ -260,10 +245,16 @@ pub fn write_configuration(doc: &Document) {
|
||||
.expect("Error writing starship config");
|
||||
}
|
||||
|
||||
pub fn edit_configuration(editor_override: Option<&str>) -> Result<(), Box<dyn std::error::Error>> {
|
||||
pub fn edit_configuration(
|
||||
context: &Context,
|
||||
editor_override: Option<&str>,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Argument currently only used for testing, but could be used to specify
|
||||
// an editor override on the command line.
|
||||
let config_path = get_config_path();
|
||||
let config_path = context.get_config_path_os().unwrap_or_else(|| {
|
||||
eprintln!("config path required to edit configuration");
|
||||
process::exit(1);
|
||||
});
|
||||
|
||||
let editor_cmd = shell_words::split(&get_editor(editor_override))?;
|
||||
let mut command = match utils::create_command(&editor_cmd[0]) {
|
||||
@ -313,19 +304,18 @@ fn get_editor_internal(visual: Option<String>, editor: Option<String>) -> String
|
||||
STD_EDITOR.into()
|
||||
}
|
||||
|
||||
fn get_config_path() -> OsString {
|
||||
if let Some(config_path) = env::var_os("STARSHIP_CONFIG") {
|
||||
return config_path;
|
||||
}
|
||||
utils::home_dir()
|
||||
.expect("couldn't find home directory")
|
||||
.join(".config")
|
||||
.join("starship.toml")
|
||||
.into()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::{fs::create_dir, io};
|
||||
|
||||
use tempfile::TempDir;
|
||||
use toml_edit::Item;
|
||||
|
||||
use crate::{
|
||||
context::{Shell, Target},
|
||||
context_env::Env,
|
||||
};
|
||||
|
||||
use super::*;
|
||||
|
||||
// This is every possible permutation, 3² = 9.
|
||||
@ -379,13 +369,13 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn no_panic_when_editor_unparsable() {
|
||||
let outcome = edit_configuration(Some("\"vim"));
|
||||
let outcome = edit_configuration(&Default::default(), Some("\"vim"));
|
||||
assert!(outcome.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_panic_when_editor_not_found() {
|
||||
let outcome = edit_configuration(Some("this_editor_does_not_exist"));
|
||||
let outcome = edit_configuration(&Default::default(), Some("this_editor_does_not_exist"));
|
||||
assert!(outcome.is_err());
|
||||
}
|
||||
|
||||
@ -581,4 +571,115 @@ mod tests {
|
||||
.as_bool()
|
||||
.unwrap())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn write_and_get_configuration_test() -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let context = setup_config(&dir, true, StarshipConfigEnvScenario::NotSpecified)?;
|
||||
let mut doc = get_configuration_edit(&context);
|
||||
doc["directory"]["format"] = Item::Value("myformat".into());
|
||||
write_configuration(&context, &doc);
|
||||
let doc_reloaded = get_configuration_edit(&context);
|
||||
assert_eq!(
|
||||
"myformat",
|
||||
doc_reloaded["directory"]["format"].as_str().unwrap()
|
||||
);
|
||||
dir.close()
|
||||
}
|
||||
|
||||
const PRINT_CONFIG_DEFAULT: &str = "[custom]";
|
||||
const PRINT_CONFIG_HOME: &str = "[custom.home]";
|
||||
const PRINT_CONFIG_ENV: &str = "[custom.STARSHIP_CONFIG]";
|
||||
|
||||
#[test]
|
||||
fn print_configuration_scenarios() -> io::Result<()> {
|
||||
run_print_configuration_test(
|
||||
"~/.config/starship.toml, no STARSHIP_CONFIG uses home",
|
||||
true,
|
||||
StarshipConfigEnvScenario::NotSpecified,
|
||||
PRINT_CONFIG_HOME,
|
||||
)?;
|
||||
run_print_configuration_test(
|
||||
"no ~/.config/starship.toml, no STARSHIP_CONFIG uses default",
|
||||
false,
|
||||
StarshipConfigEnvScenario::NotSpecified,
|
||||
PRINT_CONFIG_DEFAULT,
|
||||
)?;
|
||||
run_print_configuration_test(
|
||||
"~/.config/starship.toml, STARSHIP_CONFIG nonexisting file uses default",
|
||||
true,
|
||||
StarshipConfigEnvScenario::NonExistingFile,
|
||||
PRINT_CONFIG_DEFAULT,
|
||||
)?;
|
||||
run_print_configuration_test(
|
||||
"~/.config/starship.toml, STARSHIP_CONFIG existing file uses STARSHIP_CONFIG file",
|
||||
true,
|
||||
StarshipConfigEnvScenario::ExistingFile,
|
||||
PRINT_CONFIG_ENV,
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
enum StarshipConfigEnvScenario {
|
||||
NotSpecified,
|
||||
NonExistingFile,
|
||||
ExistingFile,
|
||||
}
|
||||
|
||||
fn run_print_configuration_test(
|
||||
message: &str,
|
||||
home_file_exists: bool,
|
||||
starship_config_env_scenario: StarshipConfigEnvScenario,
|
||||
expected_first_line: &str,
|
||||
) -> io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let context = setup_config(&dir, home_file_exists, starship_config_env_scenario)?;
|
||||
let config = print_configuration(&context, false, &["custom".to_string()]);
|
||||
let first_line = config.split('\n').next().unwrap();
|
||||
assert_eq!(expected_first_line, first_line, "{message}");
|
||||
dir.close()
|
||||
}
|
||||
|
||||
fn setup_config(
|
||||
dir: &TempDir,
|
||||
home_file_exists: bool,
|
||||
starship_config_env_scenario: StarshipConfigEnvScenario,
|
||||
) -> io::Result<Context> {
|
||||
let config_path = dir.path().to_path_buf().join(".config");
|
||||
create_dir(&config_path)?;
|
||||
let home_starship_toml = config_path.join("starship.toml");
|
||||
let env_toml = dir.path().join("env.toml");
|
||||
if home_file_exists {
|
||||
let mut home_file = File::create(home_starship_toml)?;
|
||||
home_file.write_all(PRINT_CONFIG_HOME.as_bytes())?;
|
||||
}
|
||||
|
||||
let env_starship_config = match starship_config_env_scenario {
|
||||
StarshipConfigEnvScenario::NotSpecified => None,
|
||||
StarshipConfigEnvScenario::NonExistingFile => Some(env_toml),
|
||||
StarshipConfigEnvScenario::ExistingFile => {
|
||||
let mut env_toml_file = File::create(&env_toml)?;
|
||||
env_toml_file.write_all(PRINT_CONFIG_ENV.as_bytes())?;
|
||||
Some(env_toml)
|
||||
}
|
||||
};
|
||||
|
||||
let mut env = Env::default();
|
||||
if let Some(v) = env_starship_config {
|
||||
env.insert("STARSHIP_CONFIG", v.to_string_lossy().to_string());
|
||||
}
|
||||
env.insert(
|
||||
"HOME",
|
||||
dir.path().to_path_buf().to_string_lossy().to_string(),
|
||||
);
|
||||
|
||||
Ok(Context::new_with_shell_and_path(
|
||||
Default::default(),
|
||||
Shell::Unknown,
|
||||
Target::Main,
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
env,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
use crate::config::{ModuleConfig, StarshipConfig};
|
||||
use crate::configs::StarshipRootConfig;
|
||||
use crate::context_env::Env;
|
||||
use crate::module::Module;
|
||||
use crate::utils::{create_command, exec_timeout, read_file, CommandOutput, PathExt};
|
||||
|
||||
use crate::modules;
|
||||
use crate::utils::{self, home_dir};
|
||||
use crate::utils;
|
||||
use clap::Parser;
|
||||
use gix::{
|
||||
sec::{self as git_sec, trust::DefaultForLevel},
|
||||
@ -60,8 +61,7 @@ pub struct Context<'a> {
|
||||
pub width: usize,
|
||||
|
||||
/// A HashMap of environment variable mocks
|
||||
#[cfg(test)]
|
||||
pub env: HashMap<&'a str, String>,
|
||||
pub env: Env<'a>,
|
||||
|
||||
/// A HashMap of command mocks
|
||||
#[cfg(test)]
|
||||
@ -107,7 +107,14 @@ impl<'a> Context<'a> {
|
||||
.or_else(|| env::var("PWD").map(PathBuf::from).ok())
|
||||
.unwrap_or_else(|| path.clone());
|
||||
|
||||
Context::new_with_shell_and_path(arguments, shell, target, path, logical_path)
|
||||
Context::new_with_shell_and_path(
|
||||
arguments,
|
||||
shell,
|
||||
target,
|
||||
path,
|
||||
logical_path,
|
||||
Default::default(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Create a new instance of Context for the provided directory
|
||||
@ -117,8 +124,9 @@ impl<'a> Context<'a> {
|
||||
target: Target,
|
||||
path: PathBuf,
|
||||
logical_path: PathBuf,
|
||||
env: Env<'a>,
|
||||
) -> Context<'a> {
|
||||
let config = StarshipConfig::initialize();
|
||||
let config = StarshipConfig::initialize(&get_config_path_os(&env));
|
||||
|
||||
// If the vector is zero-length, we should pretend that we didn't get a
|
||||
// pipestatus at all (since this is the input `--pipestatus=""`)
|
||||
@ -162,11 +170,10 @@ impl<'a> Context<'a> {
|
||||
shell,
|
||||
target,
|
||||
width,
|
||||
env,
|
||||
#[cfg(test)]
|
||||
root_dir: tempfile::TempDir::new().unwrap(),
|
||||
#[cfg(test)]
|
||||
env: HashMap::new(),
|
||||
#[cfg(test)]
|
||||
cmd: HashMap::new(),
|
||||
#[cfg(feature = "battery")]
|
||||
battery_info_provider: &crate::modules::BatteryInfoProviderImpl,
|
||||
@ -177,37 +184,19 @@ impl<'a> Context<'a> {
|
||||
|
||||
// Tries to retrieve home directory from a table in testing mode or else retrieves it from the os
|
||||
pub fn get_home(&self) -> Option<PathBuf> {
|
||||
if cfg!(test) {
|
||||
return self.get_env("HOME").map(PathBuf::from).or_else(home_dir);
|
||||
}
|
||||
|
||||
home_dir()
|
||||
home_dir(&self.env)
|
||||
}
|
||||
|
||||
// Retrieves a environment variable from the os or from a table if in testing mode
|
||||
#[cfg(test)]
|
||||
pub fn get_env<K: AsRef<str>>(&self, key: K) -> Option<String> {
|
||||
self.env
|
||||
.get(key.as_ref())
|
||||
.map(std::string::ToString::to_string)
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
#[inline]
|
||||
pub fn get_env<K: AsRef<str>>(&self, key: K) -> Option<String> {
|
||||
env::var(key.as_ref()).ok()
|
||||
self.env.get_env(key)
|
||||
}
|
||||
|
||||
// Retrieves a environment variable from the os or from a table if in testing mode (os version)
|
||||
#[cfg(test)]
|
||||
pub fn get_env_os<K: AsRef<str>>(&self, key: K) -> Option<OsString> {
|
||||
self.env.get(key.as_ref()).map(OsString::from)
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
#[inline]
|
||||
pub fn get_env_os<K: AsRef<str>>(&self, key: K) -> Option<OsString> {
|
||||
env::var_os(key.as_ref())
|
||||
self.env.get_env_os(key)
|
||||
}
|
||||
|
||||
/// Convert a `~` in a path to the home directory
|
||||
@ -401,6 +390,32 @@ impl<'a> Context<'a> {
|
||||
|
||||
read_file(self.current_dir.join(file_name)).ok()
|
||||
}
|
||||
|
||||
pub fn get_config_path_os(&self) -> Option<OsString> {
|
||||
get_config_path_os(&self.env)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Context<'_> {
|
||||
fn default() -> Self {
|
||||
Context::new(Default::default(), Target::Main)
|
||||
}
|
||||
}
|
||||
|
||||
fn home_dir(env: &Env) -> Option<PathBuf> {
|
||||
if cfg!(test) {
|
||||
if let Some(home) = env.get_env("HOME") {
|
||||
return Some(PathBuf::from(home));
|
||||
}
|
||||
}
|
||||
utils::home_dir()
|
||||
}
|
||||
|
||||
fn get_config_path_os(env: &Env) -> Option<OsString> {
|
||||
if let Some(config_path) = env.get_env_os("STARSHIP_CONFIG") {
|
||||
return Some(config_path);
|
||||
}
|
||||
Some(home_dir(env)?.join(".config").join("starship.toml").into())
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -907,6 +922,7 @@ mod tests {
|
||||
Target::Main,
|
||||
test_path.clone(),
|
||||
test_path.clone(),
|
||||
Default::default(),
|
||||
);
|
||||
|
||||
assert_ne!(context.current_dir, context.logical_dir);
|
||||
@ -931,6 +947,7 @@ mod tests {
|
||||
Target::Main,
|
||||
test_path.clone(),
|
||||
test_path.clone(),
|
||||
Default::default(),
|
||||
);
|
||||
|
||||
let expected_current_dir = &test_path;
|
||||
@ -952,6 +969,7 @@ mod tests {
|
||||
Target::Main,
|
||||
test_path.clone(),
|
||||
test_path.clone(),
|
||||
Default::default(),
|
||||
);
|
||||
|
||||
let expected_current_dir = home_dir()
|
||||
@ -973,6 +991,7 @@ mod tests {
|
||||
Target::Main,
|
||||
test_path.clone(),
|
||||
test_path,
|
||||
Default::default(),
|
||||
);
|
||||
|
||||
let expected_path = Path::new(r"C:\");
|
||||
|
48
src/context_env.rs
Normal file
48
src/context_env.rs
Normal file
@ -0,0 +1,48 @@
|
||||
#[cfg(test)]
|
||||
use std::collections::HashMap;
|
||||
#[cfg(not(test))]
|
||||
use std::env;
|
||||
use std::ffi::OsString;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Env<'a> {
|
||||
/// A HashMap of environment variable mocks
|
||||
#[cfg(test)]
|
||||
pub env: HashMap<&'a str, String>,
|
||||
|
||||
#[cfg(not(test))]
|
||||
_marker: std::marker::PhantomData<&'a ()>,
|
||||
}
|
||||
|
||||
impl<'a> Env<'a> {
|
||||
// Retrieves a environment variable from the os or from a table if in testing mode
|
||||
#[cfg(test)]
|
||||
pub fn get_env<K: AsRef<str>>(&self, key: K) -> Option<String> {
|
||||
self.env
|
||||
.get(key.as_ref())
|
||||
.map(std::string::ToString::to_string)
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
#[inline]
|
||||
pub fn get_env<K: AsRef<str>>(&self, key: K) -> Option<String> {
|
||||
env::var(key.as_ref()).ok()
|
||||
}
|
||||
|
||||
// Retrieves a environment variable from the os or from a table if in testing mode (os version)
|
||||
#[cfg(test)]
|
||||
pub fn get_env_os<K: AsRef<str>>(&self, key: K) -> Option<OsString> {
|
||||
self.env.get(key.as_ref()).map(OsString::from)
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
#[inline]
|
||||
pub fn get_env_os<K: AsRef<str>>(&self, key: K) -> Option<OsString> {
|
||||
env::var_os(key.as_ref())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub fn insert(&mut self, k: &'a str, v: String) -> Option<String> {
|
||||
self.env.insert(k, v)
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ pub mod config;
|
||||
pub mod configs;
|
||||
pub mod configure;
|
||||
pub mod context;
|
||||
pub mod context_env;
|
||||
pub mod formatter;
|
||||
pub mod init;
|
||||
pub mod logger;
|
||||
|
15
src/main.rs
15
src/main.rs
@ -10,7 +10,7 @@ use clap::{CommandFactory, Parser, Subcommand};
|
||||
use clap_complete::{generate, Shell as CompletionShell};
|
||||
use rand::distributions::Alphanumeric;
|
||||
use rand::Rng;
|
||||
use starship::context::{Properties, Target};
|
||||
use starship::context::{Context, Properties, Target};
|
||||
use starship::module::ALL_MODULES;
|
||||
use starship::*;
|
||||
|
||||
@ -208,17 +208,22 @@ fn main() {
|
||||
}
|
||||
Commands::Preset { name, list, output } => print::preset_command(name, output, list),
|
||||
Commands::Config { name, value } => {
|
||||
let context = Context::default();
|
||||
if let Some(name) = name {
|
||||
if let Some(value) = value {
|
||||
configure::update_configuration(&name, &value)
|
||||
configure::update_configuration(&context, &name, &value)
|
||||
}
|
||||
} else if let Err(reason) = configure::edit_configuration(None) {
|
||||
} else if let Err(reason) = configure::edit_configuration(&context, None) {
|
||||
eprintln!("Could not edit configuration: {reason}");
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
Commands::PrintConfig { default, name } => configure::print_configuration(default, &name),
|
||||
Commands::Toggle { name, value } => configure::toggle_configuration(&name, &value),
|
||||
Commands::PrintConfig { default, name } => {
|
||||
configure::print_configuration(&Context::default(), default, &name);
|
||||
}
|
||||
Commands::Toggle { name, value } => {
|
||||
configure::toggle_configuration(&Context::default(), &name, &value)
|
||||
}
|
||||
Commands::BugReport => bug_report::create(),
|
||||
Commands::Time => {
|
||||
match SystemTime::now()
|
||||
|
@ -386,6 +386,7 @@ fn git_status_wsl(context: &Context, conf: &GitStatusConfig) -> Option<String> {
|
||||
use crate::utils::create_command;
|
||||
use nix::sys::utsname::uname;
|
||||
use std::env;
|
||||
use std::ffi::OsString;
|
||||
use std::io::ErrorKind;
|
||||
|
||||
let starship_exe = conf.windows_starship?;
|
||||
@ -454,7 +455,9 @@ fn git_status_wsl(context: &Context, conf: &GitStatusConfig) -> Option<String> {
|
||||
.map(|mut c| {
|
||||
c.env(
|
||||
"STARSHIP_CONFIG",
|
||||
crate::config::get_config_path().unwrap_or_else(|| "/dev/null".to_string()),
|
||||
context
|
||||
.get_config_path_os()
|
||||
.unwrap_or_else(|| OsString::from("/dev/null")),
|
||||
)
|
||||
.env("WSLENV", wslenv)
|
||||
.args(["module", "git_status", "--path", winpath]);
|
||||
|
@ -735,6 +735,7 @@ version = "12"
|
||||
Target::Main,
|
||||
dir.path().into(),
|
||||
dir.path().into(),
|
||||
Default::default(),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
@ -756,6 +757,7 @@ version = "12"
|
||||
Target::Main,
|
||||
dir.path().into(),
|
||||
dir.path().into(),
|
||||
Default::default(),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
@ -777,6 +779,7 @@ version = "12"
|
||||
Target::Main,
|
||||
dir.path().into(),
|
||||
dir.path().into(),
|
||||
Default::default(),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
@ -800,6 +803,7 @@ version = "12"
|
||||
Target::Main,
|
||||
child_dir_path.clone(),
|
||||
child_dir_path,
|
||||
Default::default(),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
@ -820,6 +824,7 @@ version = "12"
|
||||
Target::Main,
|
||||
dir.path().into(),
|
||||
dir.path().into(),
|
||||
Default::default(),
|
||||
);
|
||||
|
||||
assert_eq!(find_rust_toolchain_file(&context), None);
|
||||
@ -838,6 +843,7 @@ version = "12"
|
||||
Target::Main,
|
||||
dir.path().into(),
|
||||
dir.path().into(),
|
||||
Default::default(),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
@ -859,6 +865,7 @@ version = "12"
|
||||
Target::Main,
|
||||
dir.path().into(),
|
||||
dir.path().into(),
|
||||
Default::default(),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
@ -882,6 +889,7 @@ version = "12"
|
||||
Target::Main,
|
||||
child_dir_path.clone(),
|
||||
child_dir_path,
|
||||
Default::default(),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
|
@ -43,6 +43,7 @@ pub fn default_context() -> Context<'static> {
|
||||
Target::Main,
|
||||
PathBuf::new(),
|
||||
PathBuf::new(),
|
||||
Default::default(),
|
||||
);
|
||||
context.config = StarshipConfig { config: None };
|
||||
context
|
||||
|
Loading…
Reference in New Issue
Block a user