forked from extern/nushell
nu-path crate refactor (#3730)
* Resolve rebase artifacts * Remove leftover dependencies on removed feature * Remove unnecessary 'pub' * Start taking notes and fooling around * Split canonicalize to two versions; Add TODOs One that takes `relative_to` and one that doesn't. More TODO notes. * Merge absolutize to and rename resolve_dots * Add custom absolutize fn and use it in path expand * Convert a couple of dunce::canonicalize to ours * Update nu-path description * Replace all canonicalize with nu-path version * Remove leftover dunce dependencies * Fix broken autocd with trailing slash Trailing slash is preserved *only* in paths that do not contain "." or "..". This should be fixed in the future to cover all paths but for now it at least covers basic cases. * Use dunce::canonicalize for canonicalizing * Alow cd recovery from non-existent cwd * Disable removed canonicalize functionality tests Remove unused import * Break down nu-path into separate modules * Remove unused public imports * Remove abundant cow mapping * Fix clippy warning * Reformulate old canonicalize tests to expand_path They wouldn't work with the new canonicalize. * Canonicalize also ~ and ndots; Unify path joining Also, add doc comments in nu_path::expansions. * Add comment * Avoid expanding ndots if path is not valid UTF-8 With this change, no lossy path->string conversion should happen in the nu-path crate. * Fmt * Slight expand_tilde refactor; Add doc comments * Start nu-path integration tests * Add tests TODO * Fix docstring typo * Fix some doc strings * Add README for nu-path crate * Add a couple of canonicalize tests * Add nu-path integration tests * Add trim trailing slashes tests * Update nu-path dependency * Remove unused import * Regenerate lockfile
This commit is contained in:
@ -9,7 +9,7 @@ use crate::{
|
||||
};
|
||||
use encoding_rs::Encoding;
|
||||
use nu_data::config::LocalConfigDiff;
|
||||
use nu_path::canonicalize;
|
||||
use nu_path::{canonicalize, canonicalize_with, expand_path_with};
|
||||
use nu_protocol::{CommandAction, ConfigPath, TaggedDictBuilder, Value};
|
||||
use nu_source::{Span, Tag};
|
||||
use nu_stream::{ActionStream, Interruptible, IntoActionStream, OutputStream};
|
||||
@ -77,7 +77,7 @@ impl FilesystemShell {
|
||||
path: String,
|
||||
mode: FilesystemShellMode,
|
||||
) -> Result<FilesystemShell, std::io::Error> {
|
||||
let path = canonicalize(std::env::current_dir()?, &path)?;
|
||||
let path = canonicalize_with(&path, std::env::current_dir()?)?;
|
||||
let path = path.display().to_string();
|
||||
let last_path = path.clone();
|
||||
|
||||
@ -237,13 +237,20 @@ impl Shell for FilesystemShell {
|
||||
if target == Path::new("-") {
|
||||
PathBuf::from(&self.last_path)
|
||||
} else {
|
||||
let path = canonicalize(self.path(), target).map_err(|_| {
|
||||
ShellError::labeled_error(
|
||||
// Extra expand attempt allows cd from /home/user/non-existent-dir/..
|
||||
// to /home/user
|
||||
let path = match canonicalize_with(&target, self.path()) {
|
||||
Ok(p) => p,
|
||||
_ => expand_path_with(&target, self.path()),
|
||||
};
|
||||
|
||||
if !path.exists() {
|
||||
return Err(ShellError::labeled_error(
|
||||
"Cannot change to directory",
|
||||
"directory not found",
|
||||
&tag,
|
||||
)
|
||||
})?;
|
||||
));
|
||||
}
|
||||
|
||||
if !path.is_dir() {
|
||||
return Err(ShellError::labeled_error(
|
||||
@ -291,7 +298,7 @@ impl Shell for FilesystemShell {
|
||||
//Loading local configs in script mode, makes scripts behave different on different
|
||||
//filesystems and might therefore surprise users. That's why we only load them in cli mode.
|
||||
if self.is_cli() {
|
||||
match dunce::canonicalize(self.path()) {
|
||||
match canonicalize(self.path()) {
|
||||
Err(e) => {
|
||||
let err = ShellError::untagged_runtime_error(format!(
|
||||
"Could not get absolute path from current fs shell. The error was: {:?}",
|
||||
@ -388,7 +395,7 @@ impl Shell for FilesystemShell {
|
||||
if entry.is_file() {
|
||||
let sources = sources.paths_applying_with(|(source_file, _depth_level)| {
|
||||
if destination.is_dir() {
|
||||
let mut dest = canonicalize(&path, &dst.item)?;
|
||||
let mut dest = canonicalize_with(&dst.item, &path)?;
|
||||
if let Some(name) = entry.file_name() {
|
||||
dest.push(name);
|
||||
}
|
||||
@ -427,7 +434,7 @@ impl Shell for FilesystemShell {
|
||||
|
||||
let sources = sources.paths_applying_with(|(source_file, depth_level)| {
|
||||
let mut dest = destination.clone();
|
||||
let path = canonicalize(&path, &source_file)?;
|
||||
let path = canonicalize_with(&source_file, &path)?;
|
||||
|
||||
let comps: Vec<_> = path
|
||||
.components()
|
||||
@ -773,7 +780,7 @@ impl Shell for FilesystemShell {
|
||||
|
||||
fn pwd(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let path = PathBuf::from(self.path());
|
||||
let p = match dunce::canonicalize(path.as_path()) {
|
||||
let p = match canonicalize(path.as_path()) {
|
||||
Ok(p) => p,
|
||||
Err(_) => {
|
||||
return Err(ShellError::labeled_error(
|
||||
@ -792,7 +799,7 @@ impl Shell for FilesystemShell {
|
||||
|
||||
fn set_path(&mut self, path: String) {
|
||||
let pathbuf = PathBuf::from(&path);
|
||||
let path = match canonicalize(self.path(), pathbuf.as_path()) {
|
||||
let path = match canonicalize_with(pathbuf.as_path(), self.path()) {
|
||||
Ok(path) => {
|
||||
let _ = std::env::set_current_dir(&path);
|
||||
std::env::set_var("PWD", &path);
|
||||
|
@ -1,5 +1,5 @@
|
||||
use nu_errors::ShellError;
|
||||
use nu_path::canonicalize;
|
||||
use nu_path::canonicalize_with;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
#[derive(Default)]
|
||||
@ -47,7 +47,7 @@ impl FileStructure {
|
||||
}
|
||||
|
||||
fn build(&mut self, src: &Path, lvl: usize) -> Result<(), ShellError> {
|
||||
let source = canonicalize(std::env::current_dir()?, src)?;
|
||||
let source = canonicalize_with(src, std::env::current_dir()?)?;
|
||||
|
||||
if source.is_dir() {
|
||||
for entry in std::fs::read_dir(src)? {
|
||||
|
@ -1,6 +1,7 @@
|
||||
use crate::plugin::run_plugin::PluginCommandBuilder;
|
||||
use log::trace;
|
||||
use nu_errors::ShellError;
|
||||
use nu_path::canonicalize;
|
||||
use nu_plugin::jsonrpc::JsonRpc;
|
||||
use nu_protocol::{Signature, Value};
|
||||
use std::io::{BufRead, BufReader, Write};
|
||||
@ -48,7 +49,7 @@ pub fn build_plugin_command(
|
||||
let request_raw = serde_json::to_string(&request)?;
|
||||
trace!(target: "nu::load", "plugin infrastructure config -> path {:#?}, request {:?}", &path, &request_raw);
|
||||
stdin.write_all(format!("{}\n", request_raw).as_bytes())?;
|
||||
let path = dunce::canonicalize(path)?;
|
||||
let path = canonicalize(path)?;
|
||||
|
||||
let mut input = String::new();
|
||||
let result = match reader.read_line(&mut input) {
|
||||
@ -134,7 +135,7 @@ pub fn scan(
|
||||
let is_executable = {
|
||||
#[cfg(windows)]
|
||||
{
|
||||
bin_name.ends_with(".exe")
|
||||
bin_name.ends_with(".exe")
|
||||
|| bin_name.ends_with(".bat")
|
||||
|| bin_name.ends_with(".cmd")
|
||||
|| bin_name.ends_with(".py")
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{evaluate::internal::InternalIterator, maybe_print_errors, run_block, shell::CdArgs};
|
||||
use crate::{BufCodecReader, MaybeTextCodec, StringOrBinary};
|
||||
use nu_errors::ShellError;
|
||||
use nu_path::canonicalize;
|
||||
use nu_path::{canonicalize_with, trim_trailing_slash};
|
||||
use nu_protocol::hir::{
|
||||
Call, ClassifiedCommand, Expression, ExternalRedirection, InternalCommand, Literal,
|
||||
NamedArguments, SpannedExpression,
|
||||
@ -66,7 +66,6 @@ pub fn process_script(
|
||||
let (block, err) = nu_parser::parse(line, span_offset, &ctx.scope);
|
||||
|
||||
debug!("{:#?}", block);
|
||||
//println!("{:#?}", pipeline);
|
||||
|
||||
if let Some(failure) = err {
|
||||
return LineResult::Error(line.to_string(), failure.into());
|
||||
@ -116,7 +115,7 @@ pub fn process_script(
|
||||
.as_ref()
|
||||
.map(NamedArguments::is_empty)
|
||||
.unwrap_or(true)
|
||||
&& canonicalize(ctx.shell_manager().path(), name).is_ok()
|
||||
&& canonicalize_with(name, ctx.shell_manager().path()).is_ok()
|
||||
&& Path::new(&name).is_dir()
|
||||
&& !ctx.host().lock().is_external_cmd(name)
|
||||
{
|
||||
@ -160,6 +159,8 @@ pub fn process_script(
|
||||
}
|
||||
};
|
||||
|
||||
let path = trim_trailing_slash(&path);
|
||||
|
||||
let cd_args = CdArgs {
|
||||
path: Some(Tagged {
|
||||
item: PathBuf::from(path),
|
||||
|
Reference in New Issue
Block a user