mirror of
https://github.com/nushell/nushell
synced 2025-01-27 12:25:19 +00:00
Remove extra mods
This commit is contained in:
parent
f8e01d8401
commit
338fa8400f
9 changed files with 271 additions and 332 deletions
|
@ -5,7 +5,7 @@ use nu_engine::env_to_string;
|
|||
use nu_path::dots::expand_ndots;
|
||||
use nu_path::{expand_to_real_path, home_dir};
|
||||
#[cfg(windows)]
|
||||
use nu_protocol::engine::os_windows;
|
||||
use nu_protocol::engine::expand_pwd;
|
||||
use nu_protocol::{
|
||||
engine::{EngineState, Stack, StateWorkingSet},
|
||||
Span,
|
||||
|
@ -177,17 +177,16 @@ pub fn complete_item(
|
|||
let cleaned_partial = surround_remove(partial);
|
||||
let isdir = cleaned_partial.ends_with(is_separator);
|
||||
#[cfg(windows)]
|
||||
let cleaned_partial = if let Some(absolute_path) =
|
||||
os_windows::fs_client::expand_pwd(stack, engine_state, Path::new(&cleaned_partial))
|
||||
{
|
||||
if let Some(abs_path_string) = absolute_path.as_path().to_str() {
|
||||
abs_path_string.to_string()
|
||||
let cleaned_partial =
|
||||
if let Some(absolute_path) = expand_pwd(stack, engine_state, Path::new(&cleaned_partial)) {
|
||||
if let Some(abs_path_string) = absolute_path.as_path().to_str() {
|
||||
abs_path_string.to_string()
|
||||
} else {
|
||||
absolute_path.display().to_string()
|
||||
}
|
||||
} else {
|
||||
absolute_path.display().to_string()
|
||||
}
|
||||
} else {
|
||||
cleaned_partial
|
||||
};
|
||||
cleaned_partial
|
||||
};
|
||||
let expanded_partial = expand_ndots(Path::new(&cleaned_partial));
|
||||
let should_collapse_dots = expanded_partial != Path::new(&cleaned_partial);
|
||||
let mut partial = expanded_partial.to_string_lossy().to_string();
|
||||
|
|
|
@ -23,7 +23,7 @@ use nu_engine::{convert_env_values, current_dir_str, env_to_strings};
|
|||
use nu_parser::{lex, parse, trim_quotes_str};
|
||||
use nu_protocol::{
|
||||
config::NuCursorShape,
|
||||
engine::{fs_client, EngineState, Stack, StateWorkingSet},
|
||||
engine::{expand_path_with, EngineState, Stack, StateWorkingSet},
|
||||
report_shell_error, HistoryConfig, HistoryFileFormat, PipelineData, ShellError, Span, Spanned,
|
||||
Value,
|
||||
};
|
||||
|
@ -824,7 +824,7 @@ fn parse_operation(
|
|||
orig = trim_quotes_str(&orig).to_string()
|
||||
}
|
||||
|
||||
let path = fs_client::expand_path_with(stack, engine_state, &orig, &cwd, true);
|
||||
let path = expand_path_with(stack, engine_state, &orig, &cwd, true);
|
||||
if looks_like_path(&orig) && is_dir(&path) && tokens.0.len() == 1 {
|
||||
Ok(ReplOperation::AutoCd {
|
||||
cwd,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#[allow(deprecated)]
|
||||
use nu_engine::{command_prelude::*, current_dir};
|
||||
use nu_protocol::{
|
||||
engine::{fs_client, StateWorkingSet},
|
||||
engine::{expand_path_with, StateWorkingSet},
|
||||
PluginRegistryFile,
|
||||
};
|
||||
use std::{
|
||||
|
@ -19,7 +19,7 @@ fn get_plugin_registry_file_path(
|
|||
let cwd = current_dir(engine_state, stack)?;
|
||||
|
||||
if let Some(ref custom_path) = custom_path {
|
||||
Ok(fs_client::expand_path_with(
|
||||
Ok(expand_path_with(
|
||||
stack,
|
||||
engine_state,
|
||||
&custom_path.item,
|
||||
|
@ -130,7 +130,7 @@ pub(crate) fn canonicalize_possible_filename_arg(
|
|||
// This results in the best possible chance of a match with the plugin item
|
||||
#[allow(deprecated)]
|
||||
if let Ok(cwd) = nu_engine::current_dir(engine_state, stack) {
|
||||
let path = fs_client::expand_path_with(stack, engine_state, arg, &cwd, true);
|
||||
let path = expand_path_with(stack, engine_state, arg, &cwd, true);
|
||||
// Try to canonicalize
|
||||
nu_path::locate_in_dirs(&path, &cwd, || get_plugin_dirs(engine_state, stack))
|
||||
// If we couldn't locate it, return the expanded path alone
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use nu_engine::command_prelude::*;
|
||||
use nu_protocol::engine::fs_client;
|
||||
use nu_protocol::engine::expand_path_with;
|
||||
use nu_utils::filesystem::{have_permission, PermissionResult};
|
||||
|
||||
#[derive(Clone)]
|
||||
|
@ -88,13 +88,8 @@ impl Command for Cd {
|
|||
});
|
||||
}
|
||||
} else {
|
||||
let path = fs_client::expand_path_with(
|
||||
stack,
|
||||
engine_state,
|
||||
path_no_whitespace,
|
||||
&cwd,
|
||||
true,
|
||||
);
|
||||
let path =
|
||||
expand_path_with(stack, engine_state, path_no_whitespace, &cwd, true);
|
||||
if !path.exists() {
|
||||
return Err(ShellError::DirectoryNotFound {
|
||||
dir: path_no_whitespace.to_string(),
|
||||
|
|
|
@ -5,7 +5,7 @@ use nu_path::AbsolutePathBuf;
|
|||
use nu_protocol::{
|
||||
ast::{Assignment, Block, Call, Expr, Expression, ExternalArgument, PathMember},
|
||||
debugger::DebugContext,
|
||||
engine::{fs_client, Closure, EngineState, Stack},
|
||||
engine::{expand_path_with, Closure, EngineState, Stack},
|
||||
eval_base::Eval,
|
||||
BlockId, Config, DataSource, IntoPipelineData, PipelineData, PipelineMetadata, ShellError,
|
||||
Span, Type, Value, VarId, ENV_VARIABLE_ID,
|
||||
|
@ -425,7 +425,7 @@ impl Eval for EvalRuntime {
|
|||
Ok(Value::string(path, span))
|
||||
} else {
|
||||
let cwd = engine_state.cwd(Some(stack))?;
|
||||
let path = fs_client::expand_path_with(stack, engine_state, path, cwd, true);
|
||||
let path = expand_path_with(stack, engine_state, path, cwd, true);
|
||||
|
||||
Ok(Value::string(path.to_string_lossy(), span))
|
||||
}
|
||||
|
@ -447,7 +447,7 @@ impl Eval for EvalRuntime {
|
|||
.cwd(Some(stack))
|
||||
.map(AbsolutePathBuf::into_std_path_buf)
|
||||
.unwrap_or_default();
|
||||
let path = fs_client::expand_path_with(stack, engine_state, path, cwd, true);
|
||||
let path = expand_path_with(stack, engine_state, path, cwd, true);
|
||||
|
||||
Ok(Value::string(path.to_string_lossy(), span))
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@ use nu_protocol::{
|
|||
ast::{Bits, Block, Boolean, CellPath, Comparison, Math, Operator},
|
||||
debugger::DebugContext,
|
||||
engine::{
|
||||
fs_client, Argument, Closure, EngineState, ErrorHandler, Matcher, Redirection, Stack,
|
||||
StateWorkingSet,
|
||||
expand_path_with, Argument, Closure, EngineState, ErrorHandler, Matcher, Redirection,
|
||||
Stack, StateWorkingSet,
|
||||
},
|
||||
ir::{Call, DataSlice, Instruction, IrAstRef, IrBlock, Literal, RedirectMode},
|
||||
DataSource, DeclId, ErrSpan, Flag, IntoPipelineData, IntoSpanned, ListStream, OutDest,
|
||||
|
@ -871,8 +871,7 @@ fn literal_value(
|
|||
Value::string(path, span)
|
||||
} else {
|
||||
let cwd = ctx.engine_state.cwd(Some(ctx.stack))?;
|
||||
let path =
|
||||
fs_client::expand_path_with(ctx.stack, ctx.engine_state, path, cwd, true);
|
||||
let path = expand_path_with(ctx.stack, ctx.engine_state, path, cwd, true);
|
||||
|
||||
Value::string(path.to_string_lossy(), span)
|
||||
}
|
||||
|
@ -892,8 +891,7 @@ fn literal_value(
|
|||
.cwd(Some(ctx.stack))
|
||||
.map(AbsolutePathBuf::into_std_path_buf)
|
||||
.unwrap_or_default();
|
||||
let path =
|
||||
fs_client::expand_path_with(ctx.stack, ctx.engine_state, path, cwd, true);
|
||||
let path = expand_path_with(ctx.stack, ctx.engine_state, path, cwd, true);
|
||||
|
||||
Value::string(path.to_string_lossy(), span)
|
||||
}
|
||||
|
@ -1407,7 +1405,7 @@ enum RedirectionStream {
|
|||
|
||||
/// Open a file for redirection
|
||||
fn open_file(ctx: &EvalContext<'_>, path: &Value, append: bool) -> Result<Arc<File>, ShellError> {
|
||||
let path_expanded = fs_client::expand_path_with(
|
||||
let path_expanded = expand_path_with(
|
||||
ctx.stack,
|
||||
ctx.engine_state,
|
||||
path.as_str()?,
|
||||
|
|
|
@ -29,7 +29,7 @@ pub use engine_state::*;
|
|||
pub use error_handler::*;
|
||||
pub use overlay::*;
|
||||
pub use pattern_match::*;
|
||||
pub use pwd_per_drive::*; //fs_client::expand_path_with
|
||||
pub use pwd_per_drive::*;
|
||||
pub use sequence::*;
|
||||
pub use stack::*;
|
||||
pub use stack_out_dest::*;
|
||||
|
|
|
@ -4,181 +4,153 @@ use crate::{Span, Value};
|
|||
use std::path::{Path, PathBuf};
|
||||
|
||||
// For file system command usage
|
||||
pub mod fs_client {
|
||||
use super::*;
|
||||
/// Proxy/Wrapper for
|
||||
/// nu_path::expand_path_with<P, Q>(path, relative_to, expand_tilde);
|
||||
///
|
||||
/// Usually if a command opens one file or directory, it uses
|
||||
/// nu_path::expand_path_with::<P, Q>(p, r, t) to expand '~','.' etc.; replacing it with
|
||||
/// nu_protocol::engine::fs_client::expand_path_with(stack, engine_state, p, r t) will
|
||||
/// first check if the path is relative for a drive;
|
||||
/// Commands that accept multiple files/directories as parameters usually depend on Glob,
|
||||
/// after near future revised Glob collection implementation done, all file system commands
|
||||
/// will support PWD-per-drive.
|
||||
pub fn expand_path_with<P, Q>(
|
||||
_stack: &Stack,
|
||||
_engine_state: &EngineState,
|
||||
path: P,
|
||||
relative_to: Q,
|
||||
expand_tilde: bool,
|
||||
) -> PathBuf
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
Q: AsRef<Path>,
|
||||
{
|
||||
#[cfg(windows)]
|
||||
if let Some(abs_path) = expand_pwd(_stack, _engine_state, path.as_ref()) {
|
||||
return abs_path;
|
||||
}
|
||||
|
||||
/// Proxy/Wrapper for
|
||||
/// nu_path::expand_path_with<P, Q>(path, relative_to, expand_tilde);
|
||||
///
|
||||
/// Usually if a command opens one file or directory, it uses
|
||||
/// nu_path::expand_path_with::<P, Q>(p, r, t) to expand '~','.' etc.; replacing it with
|
||||
/// nu_protocol::engine::fs_client::expand_path_with(stack, engine_state, p, r t) will
|
||||
/// first check if the path is relative for a drive;
|
||||
/// Commands that accept multiple files/directories as parameters usually depend on Glob,
|
||||
/// after near future revised Glob collection implementation done, all file system commands
|
||||
/// will support PWD-per-drive.
|
||||
pub fn expand_path_with<P, Q>(
|
||||
_stack: &Stack,
|
||||
_engine_state: &EngineState,
|
||||
path: P,
|
||||
relative_to: Q,
|
||||
expand_tilde: bool,
|
||||
) -> PathBuf
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
Q: AsRef<Path>,
|
||||
{
|
||||
#[cfg(windows)]
|
||||
if let Some(abs_path) =
|
||||
os_windows::fs_client::expand_pwd(_stack, _engine_state, path.as_ref())
|
||||
{
|
||||
return abs_path;
|
||||
nu_path::expand_path_with::<P, Q>(path, relative_to, expand_tilde)
|
||||
}
|
||||
|
||||
/// For maintainer to notify current pwd
|
||||
/// When user change current directory, maintainer notifies
|
||||
/// PWD-per-drive by calling set_pwd() with current stack and path;
|
||||
#[cfg(windows)]
|
||||
pub fn set_pwd(stack: &mut Stack, path: &Path) {
|
||||
if let Some(path_str) = path.to_str() {
|
||||
if let Some(drive) = extract_drive_letter(path_str) {
|
||||
stack.add_env_var(
|
||||
env_var_for_drive(drive),
|
||||
Value::string(path_str, Span::unknown()).clone(),
|
||||
);
|
||||
}
|
||||
|
||||
nu_path::expand_path_with::<P, Q>(path, relative_to, expand_tilde)
|
||||
}
|
||||
}
|
||||
|
||||
/// For file system command usage
|
||||
/// File system command implementation can also directly use expand_pwd
|
||||
/// to expand relate path for a drive and strip redundant double or
|
||||
/// single quote like bash.
|
||||
/// cd "''C:''nushell''"
|
||||
/// C:\Users\nushell>
|
||||
#[cfg(windows)]
|
||||
pub mod os_windows {
|
||||
use super::*;
|
||||
|
||||
/// For maintainer to notify current pwd
|
||||
pub mod maintainer {
|
||||
use super::*;
|
||||
|
||||
/// When user change current directory, maintainer notifies
|
||||
/// PWD-per-drive by calling set_pwd() with current stack and path;
|
||||
pub fn set_pwd(stack: &mut Stack, path: &Path) {
|
||||
use implementation::{env_var_for_drive, extract_drive_letter};
|
||||
|
||||
if let Some(path_str) = path.to_str() {
|
||||
if let Some(drive) = extract_drive_letter(path_str) {
|
||||
stack.add_env_var(
|
||||
env_var_for_drive(drive),
|
||||
Value::string(path_str, Span::unknown()).clone(),
|
||||
);
|
||||
}
|
||||
}
|
||||
pub fn expand_pwd(stack: &Stack, engine_state: &EngineState, path: &Path) -> Option<PathBuf> {
|
||||
if let Some(path_str) = path.to_str() {
|
||||
if let Some(drive_letter) = need_expand(path_str) {
|
||||
let mut base = PathBuf::from(get_pwd_on_drive(stack, engine_state, drive_letter));
|
||||
// need_expand() ensures path_str.len() >= 2
|
||||
base.push(&path_str[2..]); // Join PWD with path parts after "C:"
|
||||
return Some(base);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
/// For file system command usage
|
||||
pub mod fs_client {
|
||||
use super::*;
|
||||
/// Implementation for maintainer and fs_client
|
||||
/// Windows env var for drive
|
||||
/// essential for integration with windows native shell CMD/PowerShell
|
||||
/// and the core mechanism for supporting PWD-per-drive with nushell's
|
||||
/// powerful layered environment system.
|
||||
/// Returns uppercased "=X:".
|
||||
#[cfg(windows)]
|
||||
pub fn env_var_for_drive(drive_letter: char) -> String {
|
||||
let drive_letter = drive_letter.to_ascii_uppercase();
|
||||
format!("={}:", drive_letter)
|
||||
}
|
||||
|
||||
/// File system command implementation can also directly use expand_pwd
|
||||
/// to expand relate path for a drive and strip redundant double or
|
||||
/// single quote like bash.
|
||||
/// cd "''C:''nushell''"
|
||||
/// C:\Users\nushell>
|
||||
pub fn expand_pwd(
|
||||
stack: &Stack,
|
||||
engine_state: &EngineState,
|
||||
path: &Path,
|
||||
) -> Option<PathBuf> {
|
||||
use implementation::{get_pwd_on_drive, need_expand};
|
||||
|
||||
if let Some(path_str) = path.to_str() {
|
||||
if let Some(drive_letter) = need_expand(path_str) {
|
||||
let mut base =
|
||||
PathBuf::from(get_pwd_on_drive(stack, engine_state, drive_letter));
|
||||
// need_expand() ensures path_str.len() >= 2
|
||||
base.push(&path_str[2..]); // Join PWD with path parts after "C:"
|
||||
return Some(base);
|
||||
}
|
||||
}
|
||||
None
|
||||
/// get pwd for drive:
|
||||
/// 1. From env_var, if no,
|
||||
/// 2. From sys_absolute, if no,
|
||||
/// 3. Construct root path to drives
|
||||
#[cfg(windows)]
|
||||
pub fn get_pwd_on_drive(stack: &Stack, engine_state: &EngineState, drive_letter: char) -> String {
|
||||
let env_var_for_drive = env_var_for_drive(drive_letter);
|
||||
let mut abs_pwd: Option<String> = None;
|
||||
if let Some(pwd) = stack.get_env_var(engine_state, &env_var_for_drive) {
|
||||
if let Ok(pwd_string) = pwd.clone().into_string() {
|
||||
abs_pwd = Some(pwd_string);
|
||||
}
|
||||
}
|
||||
|
||||
/// Implementation for maintainer and fs_client
|
||||
pub(in crate::engine::pwd_per_drive) mod implementation {
|
||||
use super::*;
|
||||
|
||||
/// Windows env var for drive
|
||||
/// essential for integration with windows native shell CMD/PowerShell
|
||||
/// and the core mechanism for supporting PWD-per-drive with nushell's
|
||||
/// powerful layered environment system.
|
||||
/// Returns uppercased "=X:".
|
||||
pub fn env_var_for_drive(drive_letter: char) -> String {
|
||||
let drive_letter = drive_letter.to_ascii_uppercase();
|
||||
format!("={}:", drive_letter)
|
||||
if abs_pwd.is_none() {
|
||||
if let Some(sys_pwd) = get_full_path_name_w(&format!("{}:", drive_letter)) {
|
||||
abs_pwd = Some(sys_pwd);
|
||||
}
|
||||
}
|
||||
if let Some(pwd) = abs_pwd {
|
||||
ensure_trailing_delimiter(&pwd)
|
||||
} else {
|
||||
format!(r"{}:\", drive_letter)
|
||||
}
|
||||
}
|
||||
|
||||
/// get pwd for drive:
|
||||
/// 1. From env_var, if no,
|
||||
/// 2. From sys_absolute, if no,
|
||||
/// 3. Construct root path to drives
|
||||
pub fn get_pwd_on_drive(
|
||||
stack: &Stack,
|
||||
engine_state: &EngineState,
|
||||
drive_letter: char,
|
||||
) -> String {
|
||||
let env_var_for_drive = env_var_for_drive(drive_letter);
|
||||
let mut abs_pwd: Option<String> = None;
|
||||
if let Some(pwd) = stack.get_env_var(engine_state, &env_var_for_drive) {
|
||||
if let Ok(pwd_string) = pwd.clone().into_string() {
|
||||
abs_pwd = Some(pwd_string);
|
||||
}
|
||||
}
|
||||
if abs_pwd.is_none() {
|
||||
if let Some(sys_pwd) = get_full_path_name_w(&format!("{}:", drive_letter)) {
|
||||
abs_pwd = Some(sys_pwd);
|
||||
}
|
||||
}
|
||||
if let Some(pwd) = abs_pwd {
|
||||
ensure_trailing_delimiter(&pwd)
|
||||
} else {
|
||||
format!(r"{}:\", drive_letter)
|
||||
}
|
||||
}
|
||||
/// Check if input path is relative path for drive letter,
|
||||
/// which should be expanded with PWD-per-drive.
|
||||
/// Returns Some(drive_letter) or None, drive_letter is upper case.
|
||||
#[cfg(windows)]
|
||||
pub fn need_expand(path: &str) -> Option<char> {
|
||||
let chars: Vec<char> = path.chars().collect();
|
||||
if chars.len() == 2 || (chars.len() > 2 && chars[2] != '/' && chars[2] != '\\') {
|
||||
extract_drive_letter(path)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if input path is relative path for drive letter,
|
||||
/// which should be expanded with PWD-per-drive.
|
||||
/// Returns Some(drive_letter) or None, drive_letter is upper case.
|
||||
pub fn need_expand(path: &str) -> Option<char> {
|
||||
let chars: Vec<char> = path.chars().collect();
|
||||
if chars.len() == 2 || (chars.len() > 2 && chars[2] != '/' && chars[2] != '\\') {
|
||||
extract_drive_letter(path)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
/// Extract the drive letter from a path, return uppercased
|
||||
/// drive letter or None
|
||||
#[cfg(windows)]
|
||||
pub fn extract_drive_letter(path: &str) -> Option<char> {
|
||||
let chars: Vec<char> = path.chars().collect();
|
||||
if chars.len() >= 2 && chars[0].is_ascii_alphabetic() && chars[1] == ':' {
|
||||
Some(chars[0].to_ascii_uppercase())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Extract the drive letter from a path, return uppercased
|
||||
/// drive letter or None
|
||||
pub fn extract_drive_letter(path: &str) -> Option<char> {
|
||||
let chars: Vec<char> = path.chars().collect();
|
||||
if chars.len() >= 2 && chars[0].is_ascii_alphabetic() && chars[1] == ':' {
|
||||
Some(chars[0].to_ascii_uppercase())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
/// Ensure a path has a trailing `\\` or '/'
|
||||
#[cfg(windows)]
|
||||
pub fn ensure_trailing_delimiter(path: &str) -> String {
|
||||
if !path.ends_with('\\') && !path.ends_with('/') {
|
||||
format!(r"{}\", path)
|
||||
} else {
|
||||
path.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
/// Ensure a path has a trailing `\\` or '/'
|
||||
pub fn ensure_trailing_delimiter(path: &str) -> String {
|
||||
if !path.ends_with('\\') && !path.ends_with('/') {
|
||||
format!(r"{}\", path)
|
||||
} else {
|
||||
path.to_string()
|
||||
}
|
||||
}
|
||||
/// get_full_path_name_w
|
||||
/// Call Windows system API (via omnipath crate) to expand
|
||||
/// absolute path
|
||||
#[cfg(windows)]
|
||||
pub fn get_full_path_name_w(path_str: &str) -> Option<String> {
|
||||
use omnipath::sys_absolute;
|
||||
use std::path::Path;
|
||||
|
||||
/// get_full_path_name_w
|
||||
/// Call windows system API (via omnipath crate) to expand
|
||||
/// absolute path
|
||||
pub fn get_full_path_name_w(path_str: &str) -> Option<String> {
|
||||
use omnipath::sys_absolute;
|
||||
use std::path::Path;
|
||||
|
||||
if let Ok(path_sys_abs) = sys_absolute(Path::new(path_str)) {
|
||||
Some(path_sys_abs.to_str()?.to_string())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
if let Ok(path_sys_abs) = sys_absolute(Path::new(path_str)) {
|
||||
Some(path_sys_abs.to_str()?.to_string())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -187,158 +159,133 @@ pub mod os_windows {
|
|||
mod tests {
|
||||
use super::*;
|
||||
|
||||
mod fs_client_test {
|
||||
use super::*;
|
||||
#[test]
|
||||
fn test_expand_path_with() {
|
||||
let mut stack = Stack::new();
|
||||
let path_str = r"c:\users\nushell";
|
||||
let path = Path::new(path_str);
|
||||
set_pwd(&mut stack, path);
|
||||
let engine_state = EngineState::new();
|
||||
|
||||
#[test]
|
||||
fn test_fs_client_expand_path_with() {
|
||||
let mut stack = Stack::new();
|
||||
let path_str = r"c:\users\nushell";
|
||||
let path = Path::new(path_str);
|
||||
os_windows::maintainer::set_pwd(&mut stack, path);
|
||||
let engine_state = EngineState::new();
|
||||
let rel_path = Path::new("c:.config");
|
||||
let result = format!(r"{path_str}\.config");
|
||||
assert_eq!(
|
||||
Some(result.as_str()),
|
||||
fs_client::expand_path_with(
|
||||
&stack,
|
||||
&engine_state,
|
||||
rel_path,
|
||||
Path::new(path_str),
|
||||
false
|
||||
)
|
||||
.as_path()
|
||||
.to_str()
|
||||
);
|
||||
}
|
||||
|
||||
let rel_path = Path::new("c:.config");
|
||||
let result = format!(r"{path_str}\.config");
|
||||
assert_eq!(
|
||||
Some(result.as_str()),
|
||||
fs_client::expand_path_with(
|
||||
&stack,
|
||||
#[test]
|
||||
fn test_os_windows_maintainer_set_pwd() {
|
||||
let mut stack = Stack::new();
|
||||
let path_str = r"c:\uesrs\nushell";
|
||||
let path = Path::new(path_str);
|
||||
set_pwd(&mut stack, path);
|
||||
let engine_state = EngineState::new();
|
||||
assert_eq!(
|
||||
stack
|
||||
.get_env_var(
|
||||
&engine_state,
|
||||
rel_path,
|
||||
Path::new(path_str),
|
||||
false
|
||||
&os_windows::implementation::env_var_for_drive('c')
|
||||
)
|
||||
.unwrap()
|
||||
.clone()
|
||||
.into_string()
|
||||
.unwrap(),
|
||||
path_str.to_string()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_os_windows_fs_client_expand_pwd() {
|
||||
let mut stack = Stack::new();
|
||||
let path_str = r"c:\users\nushell";
|
||||
let path = Path::new(path_str);
|
||||
set_pwd(&mut stack, path);
|
||||
let engine_state = EngineState::new();
|
||||
|
||||
let rel_path = Path::new("c:.config");
|
||||
let result = format!(r"{path_str}\.config");
|
||||
assert_eq!(
|
||||
Some(result.as_str()),
|
||||
expand_pwd(&stack, &engine_state, rel_path)
|
||||
.unwrap()
|
||||
.as_path()
|
||||
.to_str()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_os_windows_implementation_env_var_for_drive() {
|
||||
for drive_letter in 'A'..='Z' {
|
||||
assert_eq!(env_var_for_drive(drive_letter), format!("={drive_letter}:"));
|
||||
}
|
||||
for drive_letter in 'a'..='z' {
|
||||
assert_eq!(
|
||||
env_var_for_drive(drive_letter),
|
||||
format!("={}:", drive_letter.to_ascii_uppercase())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
mod os_windows_tests {
|
||||
use super::*;
|
||||
#[test]
|
||||
fn test_os_windows_implementation_get_pwd_on_drive() {
|
||||
let mut stack = Stack::new();
|
||||
let path_str = r"c:\users\nushell";
|
||||
let path = Path::new(path_str);
|
||||
set_pwd(&mut stack, path);
|
||||
let engine_state = EngineState::new();
|
||||
let result = format!(r"{path_str}\");
|
||||
assert_eq!(result, get_pwd_on_drive(&stack, &engine_state, 'c'));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_os_windows_maintainer_set_pwd() {
|
||||
let mut stack = Stack::new();
|
||||
let path_str = r"c:\uesrs\nushell";
|
||||
let path = Path::new(path_str);
|
||||
os_windows::maintainer::set_pwd(&mut stack, path);
|
||||
let engine_state = EngineState::new();
|
||||
assert_eq!(
|
||||
stack
|
||||
.get_env_var(
|
||||
&engine_state,
|
||||
&os_windows::implementation::env_var_for_drive('c')
|
||||
)
|
||||
.unwrap()
|
||||
.clone()
|
||||
.into_string()
|
||||
.unwrap(),
|
||||
path_str.to_string()
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn test_os_windows_implementation_need_expand() {
|
||||
assert_eq!(need_expand(r"c:nushell\src"), Some('C'));
|
||||
assert_eq!(need_expand("C:src/"), Some('C'));
|
||||
assert_eq!(need_expand("a:"), Some('A'));
|
||||
assert_eq!(need_expand("z:"), Some('Z'));
|
||||
// Absolute path does not need expand
|
||||
assert_eq!(need_expand(r"c:\"), None);
|
||||
// Unix path does not need expand
|
||||
assert_eq!(need_expand("/usr/bin"), None);
|
||||
// Invalid path on drive
|
||||
assert_eq!(need_expand("1:usr/bin"), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_os_windows_fs_client_expand_pwd() {
|
||||
let mut stack = Stack::new();
|
||||
let path_str = r"c:\users\nushell";
|
||||
let path = Path::new(path_str);
|
||||
os_windows::maintainer::set_pwd(&mut stack, path);
|
||||
let engine_state = EngineState::new();
|
||||
#[test]
|
||||
fn test_os_windows_implementation_extract_drive_letter() {
|
||||
assert_eq!(extract_drive_letter("C:test"), Some('C'));
|
||||
assert_eq!(extract_drive_letter(r"d:\temp"), Some('D'));
|
||||
assert_eq!(extract_drive_letter(r"1:temp"), None);
|
||||
}
|
||||
|
||||
let rel_path = Path::new("c:.config");
|
||||
let result = format!(r"{path_str}\.config");
|
||||
assert_eq!(
|
||||
Some(result.as_str()),
|
||||
os_windows::fs_client::expand_pwd(&stack, &engine_state, rel_path)
|
||||
.unwrap()
|
||||
.as_path()
|
||||
.to_str()
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn test_os_windows_implementation_ensure_trailing_delimiter() {
|
||||
assert_eq!(ensure_trailing_delimiter("E:"), r"E:\");
|
||||
assert_eq!(ensure_trailing_delimiter(r"e:\"), r"e:\");
|
||||
assert_eq!(ensure_trailing_delimiter("c:/"), "c:/");
|
||||
}
|
||||
|
||||
mod implementation_test {
|
||||
use super::*;
|
||||
#[test]
|
||||
fn test_os_windows_implementation_get_full_path_name_w() {
|
||||
let result = get_full_path_name_w("C:");
|
||||
assert!(result.is_some());
|
||||
let path = result.unwrap();
|
||||
assert!(path.starts_with(r"C:\"));
|
||||
|
||||
#[test]
|
||||
fn test_os_windows_implementation_env_var_for_drive() {
|
||||
use os_windows::implementation::env_var_for_drive;
|
||||
|
||||
for drive_letter in 'A'..='Z' {
|
||||
assert_eq!(env_var_for_drive(drive_letter), format!("={drive_letter}:"));
|
||||
}
|
||||
for drive_letter in 'a'..='z' {
|
||||
assert_eq!(
|
||||
env_var_for_drive(drive_letter),
|
||||
format!("={}:", drive_letter.to_ascii_uppercase())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_os_windows_implementation_get_pwd_on_drive() {
|
||||
let mut stack = Stack::new();
|
||||
let path_str = r"c:\users\nushell";
|
||||
let path = Path::new(path_str);
|
||||
os_windows::maintainer::set_pwd(&mut stack, path);
|
||||
let engine_state = EngineState::new();
|
||||
let result = format!(r"{path_str}\");
|
||||
assert_eq!(
|
||||
result,
|
||||
os_windows::implementation::get_pwd_on_drive(&stack, &engine_state, 'c')
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_os_windows_implementation_need_expand() {
|
||||
use os_windows::implementation::need_expand;
|
||||
|
||||
assert_eq!(need_expand(r"c:nushell\src"), Some('C'));
|
||||
assert_eq!(need_expand("C:src/"), Some('C'));
|
||||
assert_eq!(need_expand("a:"), Some('A'));
|
||||
assert_eq!(need_expand("z:"), Some('Z'));
|
||||
// Absolute path does not need expand
|
||||
assert_eq!(need_expand(r"c:\"), None);
|
||||
// Unix path does not need expand
|
||||
assert_eq!(need_expand("/usr/bin"), None);
|
||||
// Invalid path on drive
|
||||
assert_eq!(need_expand("1:usr/bin"), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_os_windows_implementation_extract_drive_letter() {
|
||||
use os_windows::implementation::extract_drive_letter;
|
||||
|
||||
assert_eq!(extract_drive_letter("C:test"), Some('C'));
|
||||
assert_eq!(extract_drive_letter(r"d:\temp"), Some('D'));
|
||||
assert_eq!(extract_drive_letter(r"1:temp"), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_os_windows_implementation_ensure_trailing_delimiter() {
|
||||
use os_windows::implementation::ensure_trailing_delimiter;
|
||||
|
||||
assert_eq!(ensure_trailing_delimiter("E:"), r"E:\");
|
||||
assert_eq!(ensure_trailing_delimiter(r"e:\"), r"e:\");
|
||||
assert_eq!(ensure_trailing_delimiter("c:/"), "c:/");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_os_windows_implementation_get_full_path_name_w() {
|
||||
use os_windows::implementation::get_full_path_name_w;
|
||||
|
||||
let result = get_full_path_name_w("C:");
|
||||
assert!(result.is_some());
|
||||
let path = result.unwrap();
|
||||
assert!(path.starts_with(r"C:\"));
|
||||
|
||||
let result = get_full_path_name_w(r"c:nushell\src");
|
||||
assert!(result.is_some());
|
||||
let path = result.unwrap();
|
||||
assert!(path.starts_with(r"C:\") || path.starts_with(r"c:\"));
|
||||
assert!(path.ends_with(r"nushell\src"));
|
||||
}
|
||||
}
|
||||
let result = get_full_path_name_w(r"c:nushell\src");
|
||||
assert!(result.is_some());
|
||||
let path = result.unwrap();
|
||||
assert!(path.starts_with(r"C:\") || path.starts_with(r"c:\"));
|
||||
assert!(path.ends_with(r"nushell\src"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#[cfg(windows)]
|
||||
use crate::engine::pwd_per_drive::*;
|
||||
use crate::engine::pwd_per_drive;
|
||||
use crate::{
|
||||
engine::{
|
||||
ArgumentStack, EngineState, ErrorHandlerStack, Redirection, StackCallArgGuard,
|
||||
|
@ -764,7 +764,7 @@ impl Stack {
|
|||
let value = Value::string(path.to_string_lossy(), Span::unknown());
|
||||
self.add_env_var("PWD".into(), value);
|
||||
#[cfg(windows)] // Sync with PWD-per-drive
|
||||
os_windows::maintainer::set_pwd(self, &path);
|
||||
pwd_per_drive::set_pwd(self, &path);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue