From c704157bc8aec542a2afc5170b13d863d84ec59e Mon Sep 17 00:00:00 2001 From: Kevin Del Castillo Date: Mon, 27 Apr 2020 12:49:53 -0500 Subject: [PATCH] Replace `ichwh` with `which` and some fixes for auto-cd (canonicalization) (#1672) * fix: absolutize path against its parent if it was a symlink. On Linux this happens because Rust calls readlink but doesn't canonicalize the resultant path. * feat: playground function to create symlinks * fix: use playground dirs * feat: test for #1631, shift tests names * Creation of FilesystemShell with custom location may fail * Replace ichwh with which * Creation of FilesystemShell with custom location may fail * Replace ichwh with which * fix: add ichwh again since it cannot be completely replaced * fix: replace one more use of which --- Cargo.lock | 11 +++++++++++ crates/nu-cli/Cargo.toml | 1 + crates/nu-cli/src/cli.rs | 9 +++++---- crates/nu-cli/src/commands/classified/external.rs | 4 ++-- crates/nu-cli/src/commands/classified/internal.rs | 2 +- crates/nu-cli/src/commands/run_external.rs | 2 +- crates/nu-cli/src/shell/filesystem_shell.rs | 14 ++++++++++---- 7 files changed, 31 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9bae8292c..bb97240b8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2199,6 +2199,7 @@ dependencies = [ "umask", "unicode-xid", "users", + "which", ] [[package]] @@ -4084,6 +4085,16 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "which" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724" +dependencies = [ + "failure", + "libc", +] + [[package]] name = "widestring" version = "0.4.0" diff --git a/crates/nu-cli/Cargo.toml b/crates/nu-cli/Cargo.toml index 345000115..6368b7b81 100644 --- a/crates/nu-cli/Cargo.toml +++ b/crates/nu-cli/Cargo.toml @@ -84,6 +84,7 @@ toml = "0.5.6" typetag = "0.1.4" umask = "0.1" unicode-xid = "0.2.0" +which = "3" trash = { version = "1.0.0", optional = true } clipboard = { version = "0.5", optional = true } diff --git a/crates/nu-cli/src/cli.rs b/crates/nu-cli/src/cli.rs index 752dff030..afc1035ea 100644 --- a/crates/nu-cli/src/cli.rs +++ b/crates/nu-cli/src/cli.rs @@ -6,6 +6,7 @@ use crate::commands::whole_stream_command; use crate::context::Context; #[cfg(not(feature = "starship-prompt"))] use crate::git::current_branch; +use crate::path::canonicalize; use crate::prelude::*; use futures_codec::FramedRead; @@ -22,7 +23,7 @@ use rustyline::{ use std::error::Error; use std::io::{BufRead, BufReader, Write}; use std::iter::Iterator; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::sync::atomic::Ordering; fn load_plugin(path: &std::path::Path, context: &mut Context) -> Result<(), ShellError> { @@ -775,9 +776,9 @@ async fn process_line( .as_ref() .map(NamedArguments::is_empty) .unwrap_or(true) - && dunce::canonicalize(&name).is_ok() - && PathBuf::from(&name).is_dir() - && ichwh::which(&name).await.unwrap_or(None).is_none() + && canonicalize(ctx.shell_manager.path(), name).is_ok() + && Path::new(&name).is_dir() + && which::which(&name).is_err() { // Here we work differently if we're in Windows because of the expected Windows behavior #[cfg(windows)] diff --git a/crates/nu-cli/src/commands/classified/external.rs b/crates/nu-cli/src/commands/classified/external.rs index eb3390695..85abb351d 100644 --- a/crates/nu-cli/src/commands/classified/external.rs +++ b/crates/nu-cli/src/commands/classified/external.rs @@ -467,12 +467,12 @@ fn spawn( async fn did_find_command(name: &str) -> bool { #[cfg(not(windows))] { - ichwh::which(name).await.unwrap_or(None).is_some() + which::which(name).is_ok() } #[cfg(windows)] { - if ichwh::which(name).await.unwrap_or(None).is_some() { + if which::which(name).is_ok() { true } else { let cmd_builtins = [ diff --git a/crates/nu-cli/src/commands/classified/internal.rs b/crates/nu-cli/src/commands/classified/internal.rs index 13c302ab8..a22fd32cf 100644 --- a/crates/nu-cli/src/commands/classified/internal.rs +++ b/crates/nu-cli/src/commands/classified/internal.rs @@ -117,7 +117,7 @@ pub(crate) fn run_internal_command( } CommandAction::EnterShell(location) => { context.shell_manager.insert_at_current(Box::new( - FilesystemShell::with_location(location, context.registry().clone()), + FilesystemShell::with_location(location, context.registry().clone())?, )); } CommandAction::AddAlias(name, args, block) => { diff --git a/crates/nu-cli/src/commands/run_external.rs b/crates/nu-cli/src/commands/run_external.rs index f7f9a16af..c9a4daa95 100644 --- a/crates/nu-cli/src/commands/run_external.rs +++ b/crates/nu-cli/src/commands/run_external.rs @@ -181,7 +181,7 @@ async fn maybe_autocd_dir<'a>(cmd: &ExternalCommand, ctx: &mut Context) -> Optio || (cmd.args.is_empty() && PathBuf::from(name).is_dir() && dunce::canonicalize(name).is_ok() - && ichwh::which(&name).await.unwrap_or(None).is_none()) + && which::which(&name).is_err()) { Some(name) } else { diff --git a/crates/nu-cli/src/shell/filesystem_shell.rs b/crates/nu-cli/src/shell/filesystem_shell.rs index cc575a4c0..f980a032b 100644 --- a/crates/nu-cli/src/shell/filesystem_shell.rs +++ b/crates/nu-cli/src/shell/filesystem_shell.rs @@ -69,9 +69,15 @@ impl FilesystemShell { }) } - pub fn with_location(path: String, commands: CommandRegistry) -> FilesystemShell { + pub fn with_location( + path: String, + commands: CommandRegistry, + ) -> Result { + let path = canonicalize(std::env::current_dir()?, &path)?; + let path = path.display().to_string(); let last_path = path.clone(); - FilesystemShell { + + Ok(FilesystemShell { path, last_path, completer: NuCompleter { @@ -80,7 +86,7 @@ impl FilesystemShell { homedir: dirs::home_dir(), }, hinter: HistoryHinter {}, - } + }) } } @@ -978,7 +984,7 @@ impl Shell for FilesystemShell { fn set_path(&mut self, path: String) { let pathbuf = PathBuf::from(&path); - let path = match dunce::canonicalize(pathbuf.as_path()) { + let path = match canonicalize(self.path(), pathbuf.as_path()) { Ok(path) => { let _ = std::env::set_current_dir(&path); path