Path migration part 3: $nu paths (#13368)

# Description
Part 3 of replacing `std::path` types with `nu_path` types added in
#13115. This PR targets the paths listed in `$nu`. That is, the home,
config, data, and cache directories.
This commit is contained in:
Ian Manske 2024-08-01 08:16:31 +00:00 committed by GitHub
parent ca73d85c09
commit ae5fed41ed
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 90 additions and 92 deletions

View file

@ -67,7 +67,7 @@ impl Command for History {
} else { } else {
let history_reader: Option<Box<dyn ReedlineHistory>> = match history.file_format { let history_reader: Option<Box<dyn ReedlineHistory>> = match history.file_format {
HistoryFileFormat::Sqlite => { HistoryFileFormat::Sqlite => {
SqliteBackedHistory::with_file(history_path.clone(), None, None) SqliteBackedHistory::with_file(history_path.clone().into(), None, None)
.map(|inner| { .map(|inner| {
let boxed: Box<dyn ReedlineHistory> = Box::new(inner); let boxed: Box<dyn ReedlineHistory> = Box::new(inner);
boxed boxed
@ -77,7 +77,7 @@ impl Command for History {
HistoryFileFormat::PlainText => FileBackedHistory::with_file( HistoryFileFormat::PlainText => FileBackedHistory::with_file(
history.max_size as usize, history.max_size as usize,
history_path.clone(), history_path.clone().into(),
) )
.map(|inner| { .map(|inner| {
let boxed: Box<dyn ReedlineHistory> = Box::new(inner); let boxed: Box<dyn ReedlineHistory> = Box::new(inner);

View file

@ -176,7 +176,7 @@ pub fn complete_item(
} }
Some(Component::Normal(home)) if home.to_string_lossy() == "~" => { Some(Component::Normal(home)) if home.to_string_lossy() == "~" => {
components.next(); components.next();
cwd = home_dir().unwrap_or(cwd_pathbuf); cwd = home_dir().map(Into::into).unwrap_or(cwd_pathbuf);
prefix_len = 1; prefix_len = 1;
original_cwd = OriginalCwd::Home; original_cwd = OriginalCwd::Home;
} }

View file

@ -192,7 +192,8 @@ pub fn add_plugin_file(
} else if let Some(mut plugin_path) = nu_path::config_dir() { } else if let Some(mut plugin_path) = nu_path::config_dir() {
// Path to store plugins signatures // Path to store plugins signatures
plugin_path.push(storage_path); plugin_path.push(storage_path);
let mut plugin_path = canonicalize_with(&plugin_path, &cwd).unwrap_or(plugin_path); let mut plugin_path =
canonicalize_with(&plugin_path, &cwd).unwrap_or(plugin_path.into());
plugin_path.push(PLUGIN_FILE); plugin_path.push(PLUGIN_FILE);
let plugin_path = canonicalize_with(&plugin_path, &cwd).unwrap_or(plugin_path); let plugin_path = canonicalize_with(&plugin_path, &cwd).unwrap_or(plugin_path);
engine_state.plugin_path = Some(plugin_path); engine_state.plugin_path = Some(plugin_path);
@ -247,7 +248,7 @@ pub(crate) fn get_history_path(storage_path: &str, mode: HistoryFileFormat) -> O
HistoryFileFormat::PlainText => HISTORY_FILE_TXT, HistoryFileFormat::PlainText => HISTORY_FILE_TXT,
HistoryFileFormat::Sqlite => HISTORY_FILE_SQLITE, HistoryFileFormat::Sqlite => HISTORY_FILE_SQLITE,
}); });
history_path history_path.into()
}) })
} }

View file

@ -3,21 +3,26 @@ use nu_protocol::{
engine::{EngineState, Stack}, engine::{EngineState, Stack},
Range, ShellError, Span, Value, Range, ShellError, Span, Value,
}; };
use std::{ops::Bound, path::PathBuf}; use std::ops::Bound;
pub fn get_init_cwd() -> PathBuf { pub fn get_init_cwd() -> AbsolutePathBuf {
std::env::current_dir().unwrap_or_else(|_| { std::env::current_dir()
std::env::var("PWD") .ok()
.map(Into::into) .and_then(|path| AbsolutePathBuf::try_from(path).ok())
.unwrap_or_else(|_| nu_path::home_dir().unwrap_or_default()) .or_else(|| {
}) std::env::var("PWD")
.ok()
.and_then(|path| AbsolutePathBuf::try_from(path).ok())
})
.or_else(nu_path::home_dir)
.expect("Failed to get current working directory")
} }
pub fn get_guaranteed_cwd(engine_state: &EngineState, stack: &Stack) -> PathBuf { pub fn get_guaranteed_cwd(engine_state: &EngineState, stack: &Stack) -> AbsolutePathBuf {
engine_state engine_state
.cwd(Some(stack)) .cwd(Some(stack))
.map(AbsolutePathBuf::into_std_path_buf) .ok()
.unwrap_or(crate::util::get_init_cwd()) .unwrap_or_else(get_init_cwd)
} }
type MakeRangeError = fn(&str, Span) -> ShellError; type MakeRangeError = fn(&str, Span) -> ShellError;

View file

@ -1,6 +1,5 @@
use nu_cmd_base::util::get_init_cwd; use nu_cmd_base::util::get_init_cwd;
use nu_engine::command_prelude::*; use nu_engine::command_prelude::*;
use nu_path::AbsolutePathBuf;
use nu_utils::filesystem::{have_permission, PermissionResult}; use nu_utils::filesystem::{have_permission, PermissionResult};
#[derive(Clone)] #[derive(Clone)]
@ -46,8 +45,8 @@ impl Command for Cd {
// user can use `cd` to recover PWD to a good state. // user can use `cd` to recover PWD to a good state.
let cwd = engine_state let cwd = engine_state
.cwd(Some(stack)) .cwd(Some(stack))
.map(AbsolutePathBuf::into_std_path_buf) .ok()
.unwrap_or(get_init_cwd()); .unwrap_or_else(get_init_cwd);
let path_val = { let path_val = {
if let Some(path) = path_val { if let Some(path) = path_val {
@ -66,7 +65,7 @@ impl Command for Cd {
if let Some(oldpwd) = stack.get_env_var(engine_state, "OLDPWD") { if let Some(oldpwd) = stack.get_env_var(engine_state, "OLDPWD") {
oldpwd.to_path()? oldpwd.to_path()?
} else { } else {
cwd cwd.into()
} }
} else { } else {
// Trim whitespace from the end of path. // Trim whitespace from the end of path.

View file

@ -135,12 +135,9 @@ fn rm(
let home: Option<String> = nu_path::home_dir().map(|path| { let home: Option<String> = nu_path::home_dir().map(|path| {
{ {
if path.exists() { if path.exists() {
match nu_path::canonicalize_with(&path, &currentdir_path) { nu_path::canonicalize_with(&path, &currentdir_path).unwrap_or(path.into())
Ok(canon_path) => canon_path,
Err(_) => path,
}
} else { } else {
path path.into()
} }
} }
.to_string_lossy() .to_string_lossy()

View file

@ -1,4 +1,5 @@
use super::helpers; #[cfg(windows)]
use omnipath::WinPathExt;
use std::path::{Component, Path, PathBuf}; use std::path::{Component, Path, PathBuf};
/// Normalize the path, expanding occurrences of n-dots. /// Normalize the path, expanding occurrences of n-dots.
@ -63,7 +64,18 @@ pub fn expand_dots(path: impl AsRef<Path>) -> PathBuf {
} }
} }
helpers::simiplified(&result) simiplified(&result)
}
#[cfg(windows)]
fn simiplified(path: &std::path::Path) -> PathBuf {
path.to_winuser_path()
.unwrap_or_else(|_| path.to_path_buf())
}
#[cfg(not(windows))]
fn simiplified(path: &std::path::Path) -> PathBuf {
path.to_path_buf()
} }
#[cfg(test)] #[cfg(test)]

View file

@ -1,8 +1,9 @@
#[cfg(windows)]
use omnipath::WinPathExt;
use std::io; use std::io;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use super::dots::{expand_dots, expand_ndots}; use super::dots::{expand_dots, expand_ndots};
use super::helpers;
use super::tilde::expand_tilde; use super::tilde::expand_tilde;
// Join a path relative to another path. Paths starting with tilde are considered as absolute. // Join a path relative to another path. Paths starting with tilde are considered as absolute.
@ -30,8 +31,17 @@ where
fn canonicalize(path: impl AsRef<Path>) -> io::Result<PathBuf> { fn canonicalize(path: impl AsRef<Path>) -> io::Result<PathBuf> {
let path = expand_tilde(path); let path = expand_tilde(path);
let path = expand_ndots(path); let path = expand_ndots(path);
canonicalize_path(&path)
}
helpers::canonicalize(&path) #[cfg(windows)]
fn canonicalize_path(path: &std::path::Path) -> std::io::Result<std::path::PathBuf> {
path.canonicalize()?.to_winuser_path()
}
#[cfg(not(windows))]
fn canonicalize_path(path: &std::path::Path) -> std::io::Result<std::path::PathBuf> {
path.canonicalize()
} }
/// Resolve all symbolic links and all components (tilde, ., .., ...+) and return the path in its /// Resolve all symbolic links and all components (tilde, ., .., ...+) and return the path in its

View file

@ -1,59 +1,32 @@
#[cfg(windows)] use crate::AbsolutePathBuf;
use omnipath::WinPathExt;
use std::path::PathBuf;
pub fn home_dir() -> Option<PathBuf> { pub fn home_dir() -> Option<AbsolutePathBuf> {
dirs::home_dir() dirs::home_dir().and_then(|home| AbsolutePathBuf::try_from(home).ok())
} }
/// Return the data directory for the current platform or XDG_DATA_HOME if specified. /// Return the data directory for the current platform or XDG_DATA_HOME if specified.
pub fn data_dir() -> Option<PathBuf> { pub fn data_dir() -> Option<AbsolutePathBuf> {
match std::env::var("XDG_DATA_HOME").map(PathBuf::from) { std::env::var("XDG_DATA_HOME")
Ok(xdg_data) if xdg_data.is_absolute() => Some(canonicalize(&xdg_data).unwrap_or(xdg_data)), .ok()
_ => get_canonicalized_path(dirs::data_dir()), .and_then(|path| AbsolutePathBuf::try_from(path).ok())
} .or_else(|| dirs::data_dir().and_then(|path| AbsolutePathBuf::try_from(path).ok()))
.map(|path| path.canonicalize().map(Into::into).unwrap_or(path))
} }
/// Return the cache directory for the current platform or XDG_CACHE_HOME if specified. /// Return the cache directory for the current platform or XDG_CACHE_HOME if specified.
pub fn cache_dir() -> Option<PathBuf> { pub fn cache_dir() -> Option<AbsolutePathBuf> {
match std::env::var("XDG_CACHE_HOME").map(PathBuf::from) { std::env::var("XDG_CACHE_HOME")
Ok(xdg_cache) if xdg_cache.is_absolute() => { .ok()
Some(canonicalize(&xdg_cache).unwrap_or(xdg_cache)) .and_then(|path| AbsolutePathBuf::try_from(path).ok())
} .or_else(|| dirs::cache_dir().and_then(|path| AbsolutePathBuf::try_from(path).ok()))
_ => get_canonicalized_path(dirs::cache_dir()), .map(|path| path.canonicalize().map(Into::into).unwrap_or(path))
}
} }
/// Return the config directory for the current platform or XDG_CONFIG_HOME if specified. /// Return the config directory for the current platform or XDG_CONFIG_HOME if specified.
pub fn config_dir() -> Option<PathBuf> { pub fn config_dir() -> Option<AbsolutePathBuf> {
match std::env::var("XDG_CONFIG_HOME").map(PathBuf::from) { std::env::var("XDG_CONFIG_HOME")
Ok(xdg_config) if xdg_config.is_absolute() => { .ok()
Some(canonicalize(&xdg_config).unwrap_or(xdg_config)) .and_then(|path| AbsolutePathBuf::try_from(path).ok())
} .or_else(|| dirs::config_dir().and_then(|path| AbsolutePathBuf::try_from(path).ok()))
_ => get_canonicalized_path(dirs::config_dir()), .map(|path| path.canonicalize().map(Into::into).unwrap_or(path))
}
}
pub fn get_canonicalized_path(path: Option<PathBuf>) -> Option<PathBuf> {
let path = path?;
Some(canonicalize(&path).unwrap_or(path))
}
#[cfg(windows)]
pub fn canonicalize(path: &std::path::Path) -> std::io::Result<std::path::PathBuf> {
path.canonicalize()?.to_winuser_path()
}
#[cfg(not(windows))]
pub fn canonicalize(path: &std::path::Path) -> std::io::Result<std::path::PathBuf> {
path.canonicalize()
}
#[cfg(windows)]
pub fn simiplified(path: &std::path::Path) -> PathBuf {
path.to_winuser_path()
.unwrap_or_else(|_| path.to_path_buf())
}
#[cfg(not(windows))]
pub fn simiplified(path: &std::path::Path) -> PathBuf {
path.to_path_buf()
} }

View file

@ -11,7 +11,7 @@ mod trailing_slash;
pub use components::components; pub use components::components;
pub use expansions::{canonicalize_with, expand_path_with, expand_to_real_path, locate_in_dirs}; pub use expansions::{canonicalize_with, expand_path_with, expand_to_real_path, locate_in_dirs};
pub use helpers::{cache_dir, config_dir, data_dir, get_canonicalized_path, home_dir}; pub use helpers::{cache_dir, config_dir, data_dir, home_dir};
pub use path::*; pub use path::*;
pub use tilde::expand_tilde; pub use tilde::expand_tilde;
pub use trailing_slash::{has_trailing_slash, strip_trailing_slash}; pub use trailing_slash::{has_trailing_slash, strip_trailing_slash};

View file

@ -36,7 +36,7 @@ pub(crate) fn create_nu_constant(engine_state: &EngineState, span: Span) -> Valu
let config_path = match nu_path::config_dir() { let config_path = match nu_path::config_dir() {
Some(mut path) => { Some(mut path) => {
path.push("nushell"); path.push("nushell");
Ok(canonicalize_path(engine_state, &path)) Ok(canonicalize_path(engine_state, path.as_ref()))
} }
None => Err(Value::error( None => Err(Value::error(
ShellError::ConfigDirNotFound { span: Some(span) }, ShellError::ConfigDirNotFound { span: Some(span) },
@ -141,7 +141,7 @@ pub(crate) fn create_nu_constant(engine_state: &EngineState, span: Span) -> Valu
record.push( record.push(
"home-path", "home-path",
if let Some(path) = nu_path::home_dir() { if let Some(path) = nu_path::home_dir() {
let canon_home_path = canonicalize_path(engine_state, &path); let canon_home_path = canonicalize_path(engine_state, path.as_ref());
Value::string(canon_home_path.to_string_lossy(), span) Value::string(canon_home_path.to_string_lossy(), span)
} else { } else {
Value::error( Value::error(
@ -156,7 +156,7 @@ pub(crate) fn create_nu_constant(engine_state: &EngineState, span: Span) -> Valu
record.push( record.push(
"data-dir", "data-dir",
if let Some(path) = nu_path::data_dir() { if let Some(path) = nu_path::data_dir() {
let mut canon_data_path = canonicalize_path(engine_state, &path); let mut canon_data_path = canonicalize_path(engine_state, path.as_ref());
canon_data_path.push("nushell"); canon_data_path.push("nushell");
Value::string(canon_data_path.to_string_lossy(), span) Value::string(canon_data_path.to_string_lossy(), span)
} else { } else {
@ -172,7 +172,7 @@ pub(crate) fn create_nu_constant(engine_state: &EngineState, span: Span) -> Valu
record.push( record.push(
"cache-dir", "cache-dir",
if let Some(path) = nu_path::cache_dir() { if let Some(path) = nu_path::cache_dir() {
let mut canon_cache_path = canonicalize_path(engine_state, &path); let mut canon_cache_path = canonicalize_path(engine_state, path.as_ref());
canon_cache_path.push("nushell"); canon_cache_path.push("nushell");
Value::string(canon_cache_path.to_string_lossy(), span) Value::string(canon_cache_path.to_string_lossy(), span)
} else { } else {

View file

@ -121,7 +121,7 @@ pub(crate) fn read_config_file(
} }
} }
eval_config_contents(config_path, engine_state, stack); eval_config_contents(config_path.into(), engine_state, stack);
} }
} }
@ -141,7 +141,7 @@ pub(crate) fn read_loginshell_file(engine_state: &mut EngineState, stack: &mut S
warn!("loginshell_file: {}", config_path.display()); warn!("loginshell_file: {}", config_path.display());
if config_path.exists() { if config_path.exists() {
eval_config_contents(config_path, engine_state, stack); eval_config_contents(config_path.into(), engine_state, stack);
} }
} }
} }
@ -302,7 +302,7 @@ pub(crate) fn set_config_path(
Some(s) => canonicalize_with(&s.item, cwd).ok(), Some(s) => canonicalize_with(&s.item, cwd).ok(),
None => nu_path::config_dir().map(|mut p| { None => nu_path::config_dir().map(|mut p| {
p.push(NUSHELL_FOLDER); p.push(NUSHELL_FOLDER);
let mut p = canonicalize_with(&p, cwd).unwrap_or(p); let mut p = canonicalize_with(&p, cwd).unwrap_or(p.into());
p.push(default_config_name); p.push(default_config_name);
canonicalize_with(&p, cwd).unwrap_or(p) canonicalize_with(&p, cwd).unwrap_or(p)
}), }),

View file

@ -79,7 +79,7 @@ fn main() -> Result<()> {
// there is an error reading it, these values will be used. // there is an error reading it, these values will be used.
let nushell_config_path = if let Some(mut path) = nu_path::config_dir() { let nushell_config_path = if let Some(mut path) = nu_path::config_dir() {
path.push("nushell"); path.push("nushell");
path path.into()
} else { } else {
// Not really sure what to default this to if nu_path::config_dir() returns None // Not really sure what to default this to if nu_path::config_dir() returns None
std::path::PathBuf::new() std::path::PathBuf::new()
@ -99,8 +99,9 @@ fn main() -> Result<()> {
default: nushell_config_path.display().to_string(), default: nushell_config_path.display().to_string(),
}, },
); );
} else if let Some(old_config) = } else if let Some(old_config) = dirs::config_dir()
nu_path::get_canonicalized_path(dirs::config_dir()).map(|p| p.join("nushell")) .and_then(|p| p.canonicalize().ok())
.map(|p| p.join("nushell"))
{ {
let xdg_config_empty = nushell_config_path let xdg_config_empty = nushell_config_path
.read_dir() .read_dir()
@ -125,7 +126,7 @@ fn main() -> Result<()> {
let default_nushell_completions_path = if let Some(mut path) = nu_path::data_dir() { let default_nushell_completions_path = if let Some(mut path) = nu_path::data_dir() {
path.push("nushell"); path.push("nushell");
path.push("completions"); path.push("completions");
path path.into()
} else { } else {
std::path::PathBuf::new() std::path::PathBuf::new()
}; };
@ -220,7 +221,7 @@ fn main() -> Result<()> {
start_time = std::time::Instant::now(); start_time = std::time::Instant::now();
set_config_path( set_config_path(
&mut engine_state, &mut engine_state,
&init_cwd, init_cwd.as_ref(),
"config.nu", "config.nu",
"config-path", "config-path",
parsed_nu_cli_args.config_file.as_ref(), parsed_nu_cli_args.config_file.as_ref(),
@ -228,7 +229,7 @@ fn main() -> Result<()> {
set_config_path( set_config_path(
&mut engine_state, &mut engine_state,
&init_cwd, init_cwd.as_ref(),
"env.nu", "env.nu",
"env-path", "env-path",
parsed_nu_cli_args.env_file.as_ref(), parsed_nu_cli_args.env_file.as_ref(),
@ -257,7 +258,7 @@ fn main() -> Result<()> {
start_time = std::time::Instant::now(); start_time = std::time::Instant::now();
// First, set up env vars as strings only // First, set up env vars as strings only
gather_parent_env_vars(&mut engine_state, &init_cwd); gather_parent_env_vars(&mut engine_state, init_cwd.as_ref());
perf!("gather env vars", start_time, use_color); perf!("gather env vars", start_time, use_color);
engine_state.add_env_var( engine_state.add_env_var(

View file

@ -129,7 +129,7 @@ fn test_config_path_helper(playground: &mut Playground, config_dir_nushell: Path
fn test_default_config_path() { fn test_default_config_path() {
Playground::setup("default_config_path", |_, playground| { Playground::setup("default_config_path", |_, playground| {
let config_dir = nu_path::config_dir().expect("Could not get config directory"); let config_dir = nu_path::config_dir().expect("Could not get config directory");
test_config_path_helper(playground, config_dir.join("nushell")); test_config_path_helper(playground, config_dir.join("nushell").into());
}); });
} }