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
This commit is contained in:
Kevin Del Castillo 2020-04-27 12:49:53 -05:00 committed by GitHub
parent 6abb9181d5
commit c704157bc8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 31 additions and 12 deletions

11
Cargo.lock generated
View File

@ -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"

View File

@ -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 }

View File

@ -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)]

View File

@ -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 = [

View File

@ -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) => {

View File

@ -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 {

View File

@ -69,9 +69,15 @@ impl FilesystemShell {
})
}
pub fn with_location(path: String, commands: CommandRegistry) -> FilesystemShell {
pub fn with_location(
path: String,
commands: CommandRegistry,
) -> Result<FilesystemShell, std::io::Error> {
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