fix(config): Make print-config not panic without a config (#5001)

This commit is contained in:
Dom Slee 2023-04-14 10:29:21 +10:00 committed by GitHub
parent b44f22e375
commit ce7f984932
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 307 additions and 117 deletions

View File

@ -1,5 +1,6 @@
use crate::configs::Palette; use crate::configs::Palette;
use crate::context::Context; use crate::context::Context;
use crate::serde_utils::{ValueDeserializer, ValueRef}; use crate::serde_utils::{ValueDeserializer, ValueRef};
use crate::utils; use crate::utils;
use nu_ansi_term::Color; use nu_ansi_term::Color;
@ -10,9 +11,9 @@ use serde::{
use std::borrow::Cow; use std::borrow::Cow;
use std::clone::Clone; use std::clone::Clone;
use std::collections::HashMap; use std::collections::HashMap;
use std::ffi::OsString;
use std::io::ErrorKind; use std::io::ErrorKind;
use std::env;
use toml::Value; use toml::Value;
/// Root config of a module. /// Root config of a module.
@ -120,25 +121,10 @@ pub struct StarshipConfig {
pub config: Option<toml::Table>, 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 { impl StarshipConfig {
/// Initialize the Config struct /// Initialize the Config struct
pub fn initialize() -> Self { pub fn initialize(config_file_path: &Option<OsString>) -> Self {
Self::config_from_file() Self::config_from_file(config_file_path)
.map(|config| Self { .map(|config| Self {
config: Some(config), config: Some(config),
}) })
@ -146,10 +132,30 @@ impl StarshipConfig {
} }
/// Create a config from a starship configuration file /// Create a config from a starship configuration file
fn config_from_file() -> Option<toml::Table> { fn config_from_file(config_file_path: &Option<OsString>) -> Option<toml::Table> {
let file_path = get_config_path()?; 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) => { Ok(content) => {
log::trace!("Config file content: \"\n{}\"", &content); log::trace!("Config file content: \"\n{}\"", &content);
Some(content) Some(content)
@ -164,17 +170,6 @@ impl StarshipConfig {
log::log!(level, "Unable to read config file content: {}", &e); log::log!(level, "Unable to read config file content: {}", &e);
None 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 // Test default behavior
assert!(get_palette(&palettes, None).is_none()); 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"
);
}
} }

View File

@ -1,6 +1,3 @@
use std::env;
use std::ffi::OsString;
use std::io::ErrorKind;
use std::process; use std::process;
use std::process::Stdio; use std::process::Stdio;
use std::str::FromStr; use std::str::FromStr;
@ -8,6 +5,7 @@ use std::str::FromStr;
use crate::config::ModuleConfig; use crate::config::ModuleConfig;
use crate::config::StarshipConfig; use crate::config::StarshipConfig;
use crate::configs::PROMPT_ORDER; use crate::configs::PROMPT_ORDER;
use crate::context::Context;
use crate::utils; use crate::utils;
use std::fs::File; use std::fs::File;
use std::io::Write; use std::io::Write;
@ -18,15 +16,15 @@ const STD_EDITOR: &str = "vi";
#[cfg(windows)] #[cfg(windows)]
const STD_EDITOR: &str = "notepad.exe"; const STD_EDITOR: &str = "notepad.exe";
pub fn update_configuration(name: &str, value: &str) { pub fn update_configuration(context: &Context, name: &str, value: &str) {
let mut doc = get_configuration_edit(); let mut doc = get_configuration_edit(context);
match handle_update_configuration(&mut doc, name, value) { match handle_update_configuration(&mut doc, name, value) {
Err(e) => { Err(e) => {
eprintln!("{e}"); eprintln!("{e}");
process::exit(1); 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(()) 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 { let config = if use_default {
// Get default config // Get default config
let default_config = crate::configs::FullConfig::default(); 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() toml::value::Value::try_from(default_config).unwrap()
} else { } else {
// Get config as toml::Value // Get config as toml::Value
let user_config = get_configuration(); let user_config = get_configuration(context);
// Convert into FullConfig and fill in default values // Convert into FullConfig and fill in default values
let user_config = crate::configs::FullConfig::load(&user_config); let user_config = crate::configs::FullConfig::load(&user_config);
// Convert back to Value because toml can't serialize FullConfig directly // 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(); let string_config = toml::to_string_pretty(&print_config).unwrap();
println!("{string_config}"); println!("{string_config}");
string_config
} }
fn extract_toml_paths(mut config: toml::Value, paths: &[String]) -> toml::Value { 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) toml::Value::Table(subset)
} }
pub fn toggle_configuration(name: &str, key: &str) { pub fn toggle_configuration(context: &Context, name: &str, key: &str) {
let mut doc = get_configuration_edit(); let mut doc = get_configuration_edit(context);
match handle_toggle_configuration(&mut doc, name, key) { match handle_toggle_configuration(&mut doc, name, key) {
Err(e) => { Err(e) => {
eprintln!("{e}"); eprintln!("{e}");
process::exit(1); 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(()) Ok(())
} }
pub fn get_configuration() -> toml::Table { pub fn get_configuration(context: &Context) -> toml::Table {
let starship_config = StarshipConfig::initialize(); let starship_config = StarshipConfig::initialize(&context.get_config_path_os());
starship_config starship_config.config.unwrap_or(toml::Table::new())
.config
.expect("Failed to load starship config")
} }
pub fn get_configuration_edit() -> Document { pub fn get_configuration_edit(context: &Context) -> Document {
let file_path = get_config_path(); let config_file_path = context.get_config_path_os();
let toml_content = match utils::read_file(file_path) { let toml_content = StarshipConfig::read_config_content_as_str(&config_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
}
};
toml_content toml_content
.unwrap_or_default() .unwrap_or_default()
@ -250,8 +232,11 @@ pub fn get_configuration_edit() -> Document {
.expect("Failed to load starship config") .expect("Failed to load starship config")
} }
pub fn write_configuration(doc: &Document) { pub fn write_configuration(context: &Context, doc: &Document) {
let config_path = get_config_path(); 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(); let config_str = doc.to_string();
@ -260,10 +245,16 @@ pub fn write_configuration(doc: &Document) {
.expect("Error writing starship config"); .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 // Argument currently only used for testing, but could be used to specify
// an editor override on the command line. // 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 editor_cmd = shell_words::split(&get_editor(editor_override))?;
let mut command = match utils::create_command(&editor_cmd[0]) { 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() 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)] #[cfg(test)]
mod tests { 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::*; use super::*;
// This is every possible permutation, 3² = 9. // This is every possible permutation, 3² = 9.
@ -379,13 +369,13 @@ mod tests {
#[test] #[test]
fn no_panic_when_editor_unparsable() { fn no_panic_when_editor_unparsable() {
let outcome = edit_configuration(Some("\"vim")); let outcome = edit_configuration(&Default::default(), Some("\"vim"));
assert!(outcome.is_err()); assert!(outcome.is_err());
} }
#[test] #[test]
fn no_panic_when_editor_not_found() { 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()); assert!(outcome.is_err());
} }
@ -581,4 +571,115 @@ mod tests {
.as_bool() .as_bool()
.unwrap()) .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,
))
}
} }

View File

@ -1,10 +1,11 @@
use crate::config::{ModuleConfig, StarshipConfig}; use crate::config::{ModuleConfig, StarshipConfig};
use crate::configs::StarshipRootConfig; use crate::configs::StarshipRootConfig;
use crate::context_env::Env;
use crate::module::Module; use crate::module::Module;
use crate::utils::{create_command, exec_timeout, read_file, CommandOutput, PathExt}; use crate::utils::{create_command, exec_timeout, read_file, CommandOutput, PathExt};
use crate::modules; use crate::modules;
use crate::utils::{self, home_dir}; use crate::utils;
use clap::Parser; use clap::Parser;
use gix::{ use gix::{
sec::{self as git_sec, trust::DefaultForLevel}, sec::{self as git_sec, trust::DefaultForLevel},
@ -60,8 +61,7 @@ pub struct Context<'a> {
pub width: usize, pub width: usize,
/// A HashMap of environment variable mocks /// A HashMap of environment variable mocks
#[cfg(test)] pub env: Env<'a>,
pub env: HashMap<&'a str, String>,
/// A HashMap of command mocks /// A HashMap of command mocks
#[cfg(test)] #[cfg(test)]
@ -107,7 +107,14 @@ impl<'a> Context<'a> {
.or_else(|| env::var("PWD").map(PathBuf::from).ok()) .or_else(|| env::var("PWD").map(PathBuf::from).ok())
.unwrap_or_else(|| path.clone()); .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 /// Create a new instance of Context for the provided directory
@ -117,8 +124,9 @@ impl<'a> Context<'a> {
target: Target, target: Target,
path: PathBuf, path: PathBuf,
logical_path: PathBuf, logical_path: PathBuf,
env: Env<'a>,
) -> Context<'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 // If the vector is zero-length, we should pretend that we didn't get a
// pipestatus at all (since this is the input `--pipestatus=""`) // pipestatus at all (since this is the input `--pipestatus=""`)
@ -162,11 +170,10 @@ impl<'a> Context<'a> {
shell, shell,
target, target,
width, width,
env,
#[cfg(test)] #[cfg(test)]
root_dir: tempfile::TempDir::new().unwrap(), root_dir: tempfile::TempDir::new().unwrap(),
#[cfg(test)] #[cfg(test)]
env: HashMap::new(),
#[cfg(test)]
cmd: HashMap::new(), cmd: HashMap::new(),
#[cfg(feature = "battery")] #[cfg(feature = "battery")]
battery_info_provider: &crate::modules::BatteryInfoProviderImpl, 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 // 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> { pub fn get_home(&self) -> Option<PathBuf> {
if cfg!(test) { home_dir(&self.env)
return self.get_env("HOME").map(PathBuf::from).or_else(home_dir);
}
home_dir()
} }
// Retrieves a environment variable from the os or from a table if in testing mode // 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] #[inline]
pub fn get_env<K: AsRef<str>>(&self, key: K) -> Option<String> { 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) // 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] #[inline]
pub fn get_env_os<K: AsRef<str>>(&self, key: K) -> Option<OsString> { 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 /// 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() 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)] #[derive(Debug)]
@ -907,6 +922,7 @@ mod tests {
Target::Main, Target::Main,
test_path.clone(), test_path.clone(),
test_path.clone(), test_path.clone(),
Default::default(),
); );
assert_ne!(context.current_dir, context.logical_dir); assert_ne!(context.current_dir, context.logical_dir);
@ -931,6 +947,7 @@ mod tests {
Target::Main, Target::Main,
test_path.clone(), test_path.clone(),
test_path.clone(), test_path.clone(),
Default::default(),
); );
let expected_current_dir = &test_path; let expected_current_dir = &test_path;
@ -952,6 +969,7 @@ mod tests {
Target::Main, Target::Main,
test_path.clone(), test_path.clone(),
test_path.clone(), test_path.clone(),
Default::default(),
); );
let expected_current_dir = home_dir() let expected_current_dir = home_dir()
@ -973,6 +991,7 @@ mod tests {
Target::Main, Target::Main,
test_path.clone(), test_path.clone(),
test_path, test_path,
Default::default(),
); );
let expected_path = Path::new(r"C:\"); let expected_path = Path::new(r"C:\");

48
src/context_env.rs Normal file
View 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)
}
}

View File

@ -11,6 +11,7 @@ pub mod config;
pub mod configs; pub mod configs;
pub mod configure; pub mod configure;
pub mod context; pub mod context;
pub mod context_env;
pub mod formatter; pub mod formatter;
pub mod init; pub mod init;
pub mod logger; pub mod logger;

View File

@ -10,7 +10,7 @@ use clap::{CommandFactory, Parser, Subcommand};
use clap_complete::{generate, Shell as CompletionShell}; use clap_complete::{generate, Shell as CompletionShell};
use rand::distributions::Alphanumeric; use rand::distributions::Alphanumeric;
use rand::Rng; use rand::Rng;
use starship::context::{Properties, Target}; use starship::context::{Context, Properties, Target};
use starship::module::ALL_MODULES; use starship::module::ALL_MODULES;
use starship::*; use starship::*;
@ -208,17 +208,22 @@ fn main() {
} }
Commands::Preset { name, list, output } => print::preset_command(name, output, list), Commands::Preset { name, list, output } => print::preset_command(name, output, list),
Commands::Config { name, value } => { Commands::Config { name, value } => {
let context = Context::default();
if let Some(name) = name { if let Some(name) = name {
if let Some(value) = value { 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}"); eprintln!("Could not edit configuration: {reason}");
std::process::exit(1); std::process::exit(1);
} }
} }
Commands::PrintConfig { default, name } => configure::print_configuration(default, &name), Commands::PrintConfig { default, name } => {
Commands::Toggle { name, value } => configure::toggle_configuration(&name, &value), configure::print_configuration(&Context::default(), default, &name);
}
Commands::Toggle { name, value } => {
configure::toggle_configuration(&Context::default(), &name, &value)
}
Commands::BugReport => bug_report::create(), Commands::BugReport => bug_report::create(),
Commands::Time => { Commands::Time => {
match SystemTime::now() match SystemTime::now()

View File

@ -386,6 +386,7 @@ fn git_status_wsl(context: &Context, conf: &GitStatusConfig) -> Option<String> {
use crate::utils::create_command; use crate::utils::create_command;
use nix::sys::utsname::uname; use nix::sys::utsname::uname;
use std::env; use std::env;
use std::ffi::OsString;
use std::io::ErrorKind; use std::io::ErrorKind;
let starship_exe = conf.windows_starship?; let starship_exe = conf.windows_starship?;
@ -454,7 +455,9 @@ fn git_status_wsl(context: &Context, conf: &GitStatusConfig) -> Option<String> {
.map(|mut c| { .map(|mut c| {
c.env( c.env(
"STARSHIP_CONFIG", "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) .env("WSLENV", wslenv)
.args(["module", "git_status", "--path", winpath]); .args(["module", "git_status", "--path", winpath]);

View File

@ -735,6 +735,7 @@ version = "12"
Target::Main, Target::Main,
dir.path().into(), dir.path().into(),
dir.path().into(), dir.path().into(),
Default::default(),
); );
assert_eq!( assert_eq!(
@ -756,6 +757,7 @@ version = "12"
Target::Main, Target::Main,
dir.path().into(), dir.path().into(),
dir.path().into(), dir.path().into(),
Default::default(),
); );
assert_eq!( assert_eq!(
@ -777,6 +779,7 @@ version = "12"
Target::Main, Target::Main,
dir.path().into(), dir.path().into(),
dir.path().into(), dir.path().into(),
Default::default(),
); );
assert_eq!( assert_eq!(
@ -800,6 +803,7 @@ version = "12"
Target::Main, Target::Main,
child_dir_path.clone(), child_dir_path.clone(),
child_dir_path, child_dir_path,
Default::default(),
); );
assert_eq!( assert_eq!(
@ -820,6 +824,7 @@ version = "12"
Target::Main, Target::Main,
dir.path().into(), dir.path().into(),
dir.path().into(), dir.path().into(),
Default::default(),
); );
assert_eq!(find_rust_toolchain_file(&context), None); assert_eq!(find_rust_toolchain_file(&context), None);
@ -838,6 +843,7 @@ version = "12"
Target::Main, Target::Main,
dir.path().into(), dir.path().into(),
dir.path().into(), dir.path().into(),
Default::default(),
); );
assert_eq!( assert_eq!(
@ -859,6 +865,7 @@ version = "12"
Target::Main, Target::Main,
dir.path().into(), dir.path().into(),
dir.path().into(), dir.path().into(),
Default::default(),
); );
assert_eq!( assert_eq!(
@ -882,6 +889,7 @@ version = "12"
Target::Main, Target::Main,
child_dir_path.clone(), child_dir_path.clone(),
child_dir_path, child_dir_path,
Default::default(),
); );
assert_eq!( assert_eq!(

View File

@ -43,6 +43,7 @@ pub fn default_context() -> Context<'static> {
Target::Main, Target::Main,
PathBuf::new(), PathBuf::new(),
PathBuf::new(), PathBuf::new(),
Default::default(),
); );
context.config = StarshipConfig { config: None }; context.config = StarshipConfig { config: None };
context context