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 {
let history_reader: Option<Box<dyn ReedlineHistory>> = match history.file_format {
HistoryFileFormat::Sqlite => {
SqliteBackedHistory::with_file(history_path.clone(), None, None)
SqliteBackedHistory::with_file(history_path.clone().into(), None, None)
.map(|inner| {
let boxed: Box<dyn ReedlineHistory> = Box::new(inner);
boxed
@ -77,7 +77,7 @@ impl Command for History {
HistoryFileFormat::PlainText => FileBackedHistory::with_file(
history.max_size as usize,
history_path.clone(),
history_path.clone().into(),
)
.map(|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() == "~" => {
components.next();
cwd = home_dir().unwrap_or(cwd_pathbuf);
cwd = home_dir().map(Into::into).unwrap_or(cwd_pathbuf);
prefix_len = 1;
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() {
// Path to store plugins signatures
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);
let plugin_path = canonicalize_with(&plugin_path, &cwd).unwrap_or(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::Sqlite => HISTORY_FILE_SQLITE,
});
history_path
history_path.into()
})
}

View file

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

View file

@ -1,6 +1,5 @@
use nu_cmd_base::util::get_init_cwd;
use nu_engine::command_prelude::*;
use nu_path::AbsolutePathBuf;
use nu_utils::filesystem::{have_permission, PermissionResult};
#[derive(Clone)]
@ -46,8 +45,8 @@ impl Command for Cd {
// user can use `cd` to recover PWD to a good state.
let cwd = engine_state
.cwd(Some(stack))
.map(AbsolutePathBuf::into_std_path_buf)
.unwrap_or(get_init_cwd());
.ok()
.unwrap_or_else(get_init_cwd);
let 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") {
oldpwd.to_path()?
} else {
cwd
cwd.into()
}
} else {
// 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| {
{
if path.exists() {
match nu_path::canonicalize_with(&path, &currentdir_path) {
Ok(canon_path) => canon_path,
Err(_) => path,
}
nu_path::canonicalize_with(&path, &currentdir_path).unwrap_or(path.into())
} else {
path
path.into()
}
}
.to_string_lossy()

View file

@ -1,4 +1,5 @@
use super::helpers;
#[cfg(windows)]
use omnipath::WinPathExt;
use std::path::{Component, Path, PathBuf};
/// 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)]

View file

@ -1,8 +1,9 @@
#[cfg(windows)]
use omnipath::WinPathExt;
use std::io;
use std::path::{Path, PathBuf};
use super::dots::{expand_dots, expand_ndots};
use super::helpers;
use super::tilde::expand_tilde;
// 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> {
let path = expand_tilde(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

View file

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

View file

@ -11,7 +11,7 @@ mod trailing_slash;
pub use components::components;
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 tilde::expand_tilde;
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() {
Some(mut path) => {
path.push("nushell");
Ok(canonicalize_path(engine_state, &path))
Ok(canonicalize_path(engine_state, path.as_ref()))
}
None => Err(Value::error(
ShellError::ConfigDirNotFound { span: Some(span) },
@ -141,7 +141,7 @@ pub(crate) fn create_nu_constant(engine_state: &EngineState, span: Span) -> Valu
record.push(
"home-path",
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)
} else {
Value::error(
@ -156,7 +156,7 @@ pub(crate) fn create_nu_constant(engine_state: &EngineState, span: Span) -> Valu
record.push(
"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");
Value::string(canon_data_path.to_string_lossy(), span)
} else {
@ -172,7 +172,7 @@ pub(crate) fn create_nu_constant(engine_state: &EngineState, span: Span) -> Valu
record.push(
"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");
Value::string(canon_cache_path.to_string_lossy(), span)
} 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());
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(),
None => nu_path::config_dir().map(|mut p| {
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);
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.
let nushell_config_path = if let Some(mut path) = nu_path::config_dir() {
path.push("nushell");
path
path.into()
} else {
// Not really sure what to default this to if nu_path::config_dir() returns None
std::path::PathBuf::new()
@ -99,8 +99,9 @@ fn main() -> Result<()> {
default: nushell_config_path.display().to_string(),
},
);
} else if let Some(old_config) =
nu_path::get_canonicalized_path(dirs::config_dir()).map(|p| p.join("nushell"))
} else if let Some(old_config) = dirs::config_dir()
.and_then(|p| p.canonicalize().ok())
.map(|p| p.join("nushell"))
{
let xdg_config_empty = nushell_config_path
.read_dir()
@ -125,7 +126,7 @@ fn main() -> Result<()> {
let default_nushell_completions_path = if let Some(mut path) = nu_path::data_dir() {
path.push("nushell");
path.push("completions");
path
path.into()
} else {
std::path::PathBuf::new()
};
@ -220,7 +221,7 @@ fn main() -> Result<()> {
start_time = std::time::Instant::now();
set_config_path(
&mut engine_state,
&init_cwd,
init_cwd.as_ref(),
"config.nu",
"config-path",
parsed_nu_cli_args.config_file.as_ref(),
@ -228,7 +229,7 @@ fn main() -> Result<()> {
set_config_path(
&mut engine_state,
&init_cwd,
init_cwd.as_ref(),
"env.nu",
"env-path",
parsed_nu_cli_args.env_file.as_ref(),
@ -257,7 +258,7 @@ fn main() -> Result<()> {
start_time = std::time::Instant::now();
// 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);
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() {
Playground::setup("default_config_path", |_, playground| {
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());
});
}