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", "umask",
"unicode-xid", "unicode-xid",
"users", "users",
"which",
] ]
[[package]] [[package]]
@ -4084,6 +4085,16 @@ dependencies = [
"wasm-bindgen", "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]] [[package]]
name = "widestring" name = "widestring"
version = "0.4.0" version = "0.4.0"

View file

@ -84,6 +84,7 @@ toml = "0.5.6"
typetag = "0.1.4" typetag = "0.1.4"
umask = "0.1" umask = "0.1"
unicode-xid = "0.2.0" unicode-xid = "0.2.0"
which = "3"
trash = { version = "1.0.0", optional = true } trash = { version = "1.0.0", optional = true }
clipboard = { version = "0.5", optional = true } clipboard = { version = "0.5", optional = true }

View file

@ -6,6 +6,7 @@ use crate::commands::whole_stream_command;
use crate::context::Context; use crate::context::Context;
#[cfg(not(feature = "starship-prompt"))] #[cfg(not(feature = "starship-prompt"))]
use crate::git::current_branch; use crate::git::current_branch;
use crate::path::canonicalize;
use crate::prelude::*; use crate::prelude::*;
use futures_codec::FramedRead; use futures_codec::FramedRead;
@ -22,7 +23,7 @@ use rustyline::{
use std::error::Error; use std::error::Error;
use std::io::{BufRead, BufReader, Write}; use std::io::{BufRead, BufReader, Write};
use std::iter::Iterator; use std::iter::Iterator;
use std::path::PathBuf; use std::path::{Path, PathBuf};
use std::sync::atomic::Ordering; use std::sync::atomic::Ordering;
fn load_plugin(path: &std::path::Path, context: &mut Context) -> Result<(), ShellError> { fn load_plugin(path: &std::path::Path, context: &mut Context) -> Result<(), ShellError> {
@ -775,9 +776,9 @@ async fn process_line(
.as_ref() .as_ref()
.map(NamedArguments::is_empty) .map(NamedArguments::is_empty)
.unwrap_or(true) .unwrap_or(true)
&& dunce::canonicalize(&name).is_ok() && canonicalize(ctx.shell_manager.path(), name).is_ok()
&& PathBuf::from(&name).is_dir() && Path::new(&name).is_dir()
&& ichwh::which(&name).await.unwrap_or(None).is_none() && which::which(&name).is_err()
{ {
// Here we work differently if we're in Windows because of the expected Windows behavior // Here we work differently if we're in Windows because of the expected Windows behavior
#[cfg(windows)] #[cfg(windows)]

View file

@ -467,12 +467,12 @@ fn spawn(
async fn did_find_command(name: &str) -> bool { async fn did_find_command(name: &str) -> bool {
#[cfg(not(windows))] #[cfg(not(windows))]
{ {
ichwh::which(name).await.unwrap_or(None).is_some() which::which(name).is_ok()
} }
#[cfg(windows)] #[cfg(windows)]
{ {
if ichwh::which(name).await.unwrap_or(None).is_some() { if which::which(name).is_ok() {
true true
} else { } else {
let cmd_builtins = [ let cmd_builtins = [

View file

@ -117,7 +117,7 @@ pub(crate) fn run_internal_command(
} }
CommandAction::EnterShell(location) => { CommandAction::EnterShell(location) => {
context.shell_manager.insert_at_current(Box::new( 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) => { 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() || (cmd.args.is_empty()
&& PathBuf::from(name).is_dir() && PathBuf::from(name).is_dir()
&& dunce::canonicalize(name).is_ok() && dunce::canonicalize(name).is_ok()
&& ichwh::which(&name).await.unwrap_or(None).is_none()) && which::which(&name).is_err())
{ {
Some(name) Some(name)
} else { } 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(); let last_path = path.clone();
FilesystemShell {
Ok(FilesystemShell {
path, path,
last_path, last_path,
completer: NuCompleter { completer: NuCompleter {
@ -80,7 +86,7 @@ impl FilesystemShell {
homedir: dirs::home_dir(), homedir: dirs::home_dir(),
}, },
hinter: HistoryHinter {}, hinter: HistoryHinter {},
} })
} }
} }
@ -978,7 +984,7 @@ impl Shell for FilesystemShell {
fn set_path(&mut self, path: String) { fn set_path(&mut self, path: String) {
let pathbuf = PathBuf::from(&path); let pathbuf = PathBuf::from(&path);
let path = match dunce::canonicalize(pathbuf.as_path()) { let path = match canonicalize(self.path(), pathbuf.as_path()) {
Ok(path) => { Ok(path) => {
let _ = std::env::set_current_dir(&path); let _ = std::env::set_current_dir(&path);
path path