Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use a uniform output format for searching ../ #113

Merged
merged 2 commits into from Oct 15, 2017
Merged

Use a uniform output format for searching ../ #113

merged 2 commits into from Oct 15, 2017

Conversation

jakwings
Copy link
Contributor

closes #107, fixes #82 by the way (Yeah, I don't want to split this patch.)

@jakwings
Copy link
Contributor Author

jakwings commented Oct 14, 2017

Ouch, now rebased after cargo fmt.
Again, rebased after fixing get_absolute_root_path() for Windows. :P

@jakwings
Copy link
Contributor Author

Copy link
Contributor

@reima reima left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added some minor nitpicks as comments.

src/output.rs Outdated
@@ -11,7 +11,11 @@ use std::os::unix::fs::PermissionsExt;
use ansi_term;

pub fn print_entry(base: &Path, entry: &PathBuf, config: &FdOptions) {
let path_full = base.join(entry);
let path_full = if *entry != PathBuf::new() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider if !entry.as_os_str().is_empty() to avoid the allocation.

tests/tests.rs Outdated
@@ -4,6 +4,21 @@ mod testenv;

use testenv::TestEnv;

fn get_absolute_root_path(env: &TestEnv) -> String {
let path = (*env)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to dereference env here. Rust does it automatically.

tests/tests.rs Outdated
te.assert_output_subdirectory(
&abs_path,
&[
"--absolute-path",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This flag is not needed, will be removed.

@sharkdp
Copy link
Owner

sharkdp commented Oct 14, 2017

@sharkdp Could you figure out what happened here: https://ci.appveyor.com/project/sharkdp/fd/build/1.0.108/job/agyctswxi2ymut4m#L202

Not sure ... does Windows treat ../.. correctly? Or should this be ..\..?

@reima
Copy link
Contributor

reima commented Oct 14, 2017

Windows can work with / as a path separator just fine.

I think the problem is that symlinks work differently on Windows. On Unix, a symlink symlink -> one/two is like an alias for one/two, so symlink/.. is equivalent to one/two/.., which is one. But on Windows symlink\.. is whatever directory symlink resides in.

I'm not certain if or how we should fix this. In my experience symlinks are still very rarely used in Windows land, so personally I wouldn't bother too much with this (i.e. disable the test on Windows or special case it).

@sharkdp
Copy link
Owner

sharkdp commented Oct 14, 2017

I think the problem is that symlinks work differently on Windows. On Unix, a symlink symlink -> one/two is like an alias for one/two, so symlink/.. is equivalent to one/two/.., which is one. But on Windows symlink.. is whatever directory symlink resides in.

Thanks, I didn't know that.

I'm not certain if or how we should fix this. In my experience symlinks are still very rarely used in Windows land, so personally I wouldn't bother too much with this (i.e. disable the test on Windows or special case it).

👍, in particular if we can add your explanation above as a comment why it's disabled/special-cased on Windows.

@sharkdp
Copy link
Owner

sharkdp commented Oct 14, 2017

Playing around with this, I've noticed the following (I'm inside a test folder, in the symlink directory):

> echo "$PWD" 
/home/shark/fd-tests.4ULpgs5vXW/symlink

> fd '' "$PWD"
/home/shark/fd-tests.4ULpgs5vXW/one/two/../../symlink/C.Foo2
/home/shark/fd-tests.4ULpgs5vXW/one/two/../../symlink/c.foo
/home/shark/fd-tests.4ULpgs5vXW/one/two/../../symlink/three
/home/shark/fd-tests.4ULpgs5vXW/one/two/../../symlink/three/d.foo
/home/shark/fd-tests.4ULpgs5vXW/one/two/../../symlink/three/directory_foo

@jakwings
Copy link
Contributor Author

jakwings commented Oct 14, 2017

Building on AppVeyor is really slow, can you enable cache for the "target" directory?

UPDATE: Ok, I modified appveyor.yml target\debug\deps -> Cargo.lock (failed builds do not cache, wait)

@jakwings
Copy link
Contributor Author

jakwings commented Oct 14, 2017

@reima Simply put, symlinks on Windows can refer to symlinks. They are references, not aliases to fixed real paths.

Corrected:

  1. The path of the current working directory of a Unix process cannot contain symlinks.

  2. The path of the current working directory of a Windows process can contain symlinks.

  3. On Windows, symlinks are resolved after the ".." component.

  4. On Unix, symlinks are resolved immediately as encountered.

@sharkdp
Copy link
Owner

sharkdp commented Oct 14, 2017

@iology Nice! Do you think there is anything we can do about #113 (comment) ?

@jakwings
Copy link
Contributor Author

Nice! Do you think there is anything we can do about #113 (comment) ?

It should be fixed, but you can try to create more complicated examples.

Also please add/amend comments in the code if you see fit. Must have a nice holidy after this tiresome work. :P

@sharkdp sharkdp self-requested a review October 15, 2017 08:08
Err(_) => error("Error: could not get current directory."),
};
let current_dir = current_dir_buf.as_path();
let current_dir = Path::new(".");
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you change this?

The detection of the current directory being missing does not seem to work anymore.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So it seems that .is_dir() doesn't really check the existence of path. :(

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe Path::exists helps? Does this have to be changed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.exists() doesn't help too, on both stable&nightly branches. Path::new("") is ok, but "." and ".." are not.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, "" doesn't mean current directory. I will ask the rust team.

Copy link
Owner

@sharkdp sharkdp Oct 15, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What was wrong with the old way (env::current_dir)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

env::current_dir() does check the existence. The returned path is resolved, so its value is used only when we don't have an absolute path.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if let Err(_) = env::current_dir() can help, but for root_dir, user still can pass in "." or "..". I hope there is an elegant way to check their existence.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now I'm not sure if we should care the existence of "." and "..". Just let it crash?

};

if path_display == PathDisplay::Absolute && root_dir_buf.is_relative() {
root_dir_buf = fshelper::absolute_path(root_dir_buf.as_path()).unwrap();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should avoid using unwrap here:

> fd -a non/existing/relative/path
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error { repr: Os { code: 2, message: "No such file or directory" } }', /checkout/src/libcore/result.rs:906:4
note: Run with `RUST_BACKTRACE=1` for a backtrace.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you forgot to add the pattern.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are absolutely right 😄. So unwrap was only called because the current directory did not exist (the issue above).

@@ -4,6 +4,20 @@ mod testenv;

use testenv::TestEnv;

fn get_absolute_root_path(env: &TestEnv) -> String {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@sharkdp sharkdp merged commit 54d9dde into sharkdp:master Oct 15, 2017
@sharkdp
Copy link
Owner

sharkdp commented Oct 15, 2017

Thank you very much! Very nice work.

sharkdp pushed a commit that referenced this pull request Oct 18, 2017
* Fix path check
* Fix full path matching
* Allow more simple driver names in Windows tests
* Factor out special is_dir() check for "." and ".."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Uniform output format when searching a parent directory Path of directory symlink is resolved to real path
3 participants