Path migration 1 (#13309)

# Description
Part 1 of replacing `std::path` types with `nu_path` types added in
#13115.
This commit is contained in:
Ian Manske 2024-07-09 09:25:23 +00:00 committed by GitHub
parent 399a7c8836
commit e98b2ceb8c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 51 additions and 54 deletions

View File

@ -336,6 +336,7 @@ fn loop_iteration(ctx: LoopContext) -> (bool, Stack, Reedline) {
.with_cwd(Some( .with_cwd(Some(
engine_state engine_state
.cwd(None) .cwd(None)
.map(|cwd| cwd.into_std_path_buf())
.unwrap_or_default() .unwrap_or_default()
.to_string_lossy() .to_string_lossy()
.to_string(), .to_string(),

View File

@ -1,3 +1,4 @@
use nu_path::AbsolutePathBuf;
use nu_protocol::{ use nu_protocol::{
engine::{EngineState, Stack}, engine::{EngineState, Stack},
Range, ShellError, Span, Value, Range, ShellError, Span, Value,
@ -15,6 +16,7 @@ pub fn get_init_cwd() -> PathBuf {
pub fn get_guaranteed_cwd(engine_state: &EngineState, stack: &Stack) -> PathBuf { pub fn get_guaranteed_cwd(engine_state: &EngineState, stack: &Stack) -> PathBuf {
engine_state engine_state
.cwd(Some(stack)) .cwd(Some(stack))
.map(AbsolutePathBuf::into_std_path_buf)
.unwrap_or(crate::util::get_init_cwd()) .unwrap_or(crate::util::get_init_cwd())
} }

View File

@ -60,12 +60,13 @@ impl Command for ConfigEnv {
let (editor_name, editor_args) = get_editor(engine_state, stack, call.head)?; let (editor_name, editor_args) = get_editor(engine_state, stack, call.head)?;
let paths = nu_engine::env::path_str(engine_state, stack, call.head)?; let paths = nu_engine::env::path_str(engine_state, stack, call.head)?;
let cwd = engine_state.cwd(Some(stack))?; let cwd = engine_state.cwd(Some(stack))?;
let editor_executable = let editor_executable = crate::which(&editor_name, &paths, cwd.as_ref()).ok_or(
crate::which(&editor_name, &paths, &cwd).ok_or(ShellError::ExternalCommand { ShellError::ExternalCommand {
label: format!("`{editor_name}` not found"), label: format!("`{editor_name}` not found"),
help: "Failed to find the editor executable".into(), help: "Failed to find the editor executable".into(),
span: call.head, span: call.head,
})?; },
)?;
let Some(env_path) = engine_state.get_config_path("env-path") else { let Some(env_path) = engine_state.get_config_path("env-path") else {
return Err(ShellError::GenericError { return Err(ShellError::GenericError {

View File

@ -64,12 +64,13 @@ impl Command for ConfigNu {
let (editor_name, editor_args) = get_editor(engine_state, stack, call.head)?; let (editor_name, editor_args) = get_editor(engine_state, stack, call.head)?;
let paths = nu_engine::env::path_str(engine_state, stack, call.head)?; let paths = nu_engine::env::path_str(engine_state, stack, call.head)?;
let cwd = engine_state.cwd(Some(stack))?; let cwd = engine_state.cwd(Some(stack))?;
let editor_executable = let editor_executable = crate::which(&editor_name, &paths, cwd.as_ref()).ok_or(
crate::which(&editor_name, &paths, &cwd).ok_or(ShellError::ExternalCommand { ShellError::ExternalCommand {
label: format!("`{editor_name}` not found"), label: format!("`{editor_name}` not found"),
help: "Failed to find the editor executable".into(), help: "Failed to find the editor executable".into(),
span: call.head, span: call.head,
})?; },
)?;
let Some(config_path) = engine_state.get_config_path("config-path") else { let Some(config_path) = engine_state.get_config_path("config-path") else {
return Err(ShellError::GenericError { return Err(ShellError::GenericError {

View File

@ -1,5 +1,6 @@
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)]
@ -43,7 +44,10 @@ impl Command for Cd {
// If getting PWD failed, default to the initial directory. This way, the // If getting PWD failed, default to the initial directory. This way, the
// 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.cwd(Some(stack)).unwrap_or(get_init_cwd()); let cwd = engine_state
.cwd(Some(stack))
.map(AbsolutePathBuf::into_std_path_buf)
.unwrap_or(get_init_cwd());
let path_val = { let path_val = {
if let Some(path) = path_val { if let Some(path) = path_val {

View File

@ -1,13 +1,11 @@
use super::PathSubcommandArguments; use super::PathSubcommandArguments;
use nu_engine::command_prelude::*; use nu_engine::command_prelude::*;
use nu_path::AbsolutePathBuf;
use nu_protocol::engine::StateWorkingSet; use nu_protocol::engine::StateWorkingSet;
use std::{ use std::{io, path::Path};
io,
path::{Path, PathBuf},
};
struct Arguments { struct Arguments {
pwd: PathBuf, pwd: AbsolutePathBuf,
} }
impl PathSubcommandArguments for Arguments {} impl PathSubcommandArguments for Arguments {}

View File

@ -39,7 +39,7 @@ On Windows based systems, Nushell will wait for the command to finish and then e
let name: Spanned<String> = call.req(engine_state, stack, 0)?; let name: Spanned<String> = call.req(engine_state, stack, 0)?;
let executable = { let executable = {
let paths = nu_engine::env::path_str(engine_state, stack, call.head)?; let paths = nu_engine::env::path_str(engine_state, stack, call.head)?;
let Some(executable) = crate::which(&name.item, &paths, &cwd) else { let Some(executable) = crate::which(&name.item, &paths, cwd.as_ref()) else {
return Err(crate::command_not_found( return Err(crate::command_not_found(
&name.item, &name.item,
call.head, call.head,

View File

@ -79,7 +79,7 @@ impl Command for External {
// Determine the PATH to be used and then use `which` to find it - though this has no // Determine the PATH to be used and then use `which` to find it - though this has no
// effect if it's an absolute path already // effect if it's an absolute path already
let paths = nu_engine::env::path_str(engine_state, stack, call.head)?; let paths = nu_engine::env::path_str(engine_state, stack, call.head)?;
let Some(executable) = which(expanded_name, &paths, &cwd) else { let Some(executable) = which(expanded_name, &paths, cwd.as_ref()) else {
return Err(command_not_found(&name_str, call.head, engine_state, stack)); return Err(command_not_found(&name_str, call.head, engine_state, stack));
}; };
executable executable
@ -228,7 +228,7 @@ pub fn eval_arguments_from_call(
match arg { match arg {
// Expand globs passed to run-external // Expand globs passed to run-external
Value::Glob { val, no_expand, .. } if !no_expand => args.extend( Value::Glob { val, no_expand, .. } if !no_expand => args.extend(
expand_glob(&val, &cwd, expr.span, engine_state.signals())? expand_glob(&val, cwd.as_ref(), expr.span, engine_state.signals())?
.into_iter() .into_iter()
.map(|s| s.into_spanned(expr.span)), .map(|s| s.into_spanned(expr.span)),
), ),

View File

@ -83,7 +83,7 @@ prints out the list properly."#
separator_param, separator_param,
env_str, env_str,
use_grid_icons, use_grid_icons,
&cwd, cwd.as_ref(),
)?) )?)
} else { } else {
Ok(PipelineData::empty()) Ok(PipelineData::empty())
@ -101,7 +101,7 @@ prints out the list properly."#
separator_param, separator_param,
env_str, env_str,
use_grid_icons, use_grid_icons,
&cwd, cwd.as_ref(),
)?) )?)
} else { } else {
// dbg!(data); // dbg!(data);
@ -124,7 +124,7 @@ prints out the list properly."#
separator_param, separator_param,
env_str, env_str,
use_grid_icons, use_grid_icons,
&cwd, cwd.as_ref(),
)?) )?)
} }
x => { x => {

View File

@ -1,6 +1,6 @@
#[allow(deprecated)] #[allow(deprecated)]
use crate::{current_dir, get_config, get_full_help}; use crate::{current_dir, get_config, get_full_help};
use nu_path::expand_path_with; use nu_path::{expand_path_with, AbsolutePathBuf};
use nu_protocol::{ use nu_protocol::{
ast::{ ast::{
Assignment, Block, Call, Expr, Expression, ExternalArgument, PathMember, PipelineElement, Assignment, Block, Call, Expr, Expression, ExternalArgument, PathMember, PipelineElement,
@ -679,7 +679,10 @@ impl Eval for EvalRuntime {
} else if quoted { } else if quoted {
Ok(Value::string(path, span)) Ok(Value::string(path, span))
} else { } else {
let cwd = engine_state.cwd(Some(stack)).unwrap_or_default(); let cwd = engine_state
.cwd(Some(stack))
.map(AbsolutePathBuf::into_std_path_buf)
.unwrap_or_default();
let path = expand_path_with(path, cwd, true); let path = expand_path_with(path, cwd, true);
Ok(Value::string(path.to_string_lossy(), span)) Ok(Value::string(path.to_string_lossy(), span))

View File

@ -12,6 +12,7 @@ use crate::{
}; };
use fancy_regex::Regex; use fancy_regex::Regex;
use lru::LruCache; use lru::LruCache;
use nu_path::AbsolutePathBuf;
use std::{ use std::{
collections::HashMap, collections::HashMap,
num::NonZeroUsize, num::NonZeroUsize,
@ -922,58 +923,44 @@ impl EngineState {
/// ///
/// If `stack` is supplied, also considers modifications to the working /// If `stack` is supplied, also considers modifications to the working
/// directory on the stack that have yet to be merged into the engine state. /// directory on the stack that have yet to be merged into the engine state.
pub fn cwd(&self, stack: Option<&Stack>) -> Result<PathBuf, ShellError> { pub fn cwd(&self, stack: Option<&Stack>) -> Result<AbsolutePathBuf, ShellError> {
// Helper function to create a simple generic error. // Helper function to create a simple generic error.
fn error(msg: &str, cwd: impl AsRef<Path>) -> Result<PathBuf, ShellError> { fn error(msg: &str, cwd: impl AsRef<nu_path::Path>) -> ShellError {
Err(ShellError::GenericError { ShellError::GenericError {
error: msg.into(), error: msg.into(),
msg: format!("$env.PWD = {}", cwd.as_ref().display()), msg: format!("$env.PWD = {}", cwd.as_ref().display()),
span: None, span: None,
help: Some("Use `cd` to reset $env.PWD into a good state".into()), help: Some("Use `cd` to reset $env.PWD into a good state".into()),
inner: vec![], inner: vec![],
}) }
}
// Helper function to check if a path is a root path.
fn is_root(path: &Path) -> bool {
path.parent().is_none()
}
// Helper function to check if a path has trailing slashes.
fn has_trailing_slash(path: &Path) -> bool {
nu_path::components(path).last()
== Some(std::path::Component::Normal(std::ffi::OsStr::new("")))
} }
// Retrieve $env.PWD from the stack or the engine state. // Retrieve $env.PWD from the stack or the engine state.
let pwd = if let Some(stack) = stack { let pwd = if let Some(stack) = stack {
stack.get_env_var(self, "PWD") stack.get_env_var(self, "PWD")
} else { } else {
self.get_env_var("PWD").map(ToOwned::to_owned) self.get_env_var("PWD").cloned()
}; };
if let Some(pwd) = pwd { let pwd = pwd.ok_or_else(|| error("$env.PWD not found", ""))?;
if let Value::String { val, .. } = pwd {
let path = PathBuf::from(val);
// Technically, a root path counts as "having trailing slashes", but if let Value::String { val, .. } = pwd {
// for the purpose of PWD, a root path is acceptable. let path = AbsolutePathBuf::try_from(val)
if !is_root(&path) && has_trailing_slash(&path) { .map_err(|path| error("$env.PWD is not an absolute path", path))?;
error("$env.PWD contains trailing slashes", path)
} else if !path.is_absolute() { // Technically, a root path counts as "having trailing slashes", but
error("$env.PWD is not an absolute path", path) // for the purpose of PWD, a root path is acceptable.
} else if !path.exists() { if path.parent().is_some() && nu_path::has_trailing_slash(path.as_ref()) {
error("$env.PWD points to a non-existent directory", path) Err(error("$env.PWD contains trailing slashes", &path))
} else if !path.is_dir() { } else if !path.exists() {
error("$env.PWD points to a non-directory", path) Err(error("$env.PWD points to a non-existent directory", &path))
} else { } else if !path.is_dir() {
Ok(path) Err(error("$env.PWD points to a non-directory", &path))
}
} else { } else {
error("$env.PWD is not a string", format!("{pwd:?}")) Ok(path)
} }
} else { } else {
error("$env.PWD not found", "") Err(error("$env.PWD is not a string", format!("{pwd:?}")))
} }
} }