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

make ls work like dir on windows #6990

Closed
wants to merge 9 commits into from

Conversation

richardmarklund
Copy link

Description

Related issue: #6857

This fix makes the ls command work like dir on windows. This hides more files like symfiles and other dirs that the dir command does not show.

Could not create any new tests since we have a strange way to create hidden files (by creating dotfiles) and could not find any way to create symlinks.

Tests + Formatting

Make sure you've done the following, if applicable:

  • Add tests that cover your changes (either in the command examples, the crate/tests folder, or in the /tests folder)
    • Try to think about corner cases and various ways how your changes could break. Cover those in the tests

Make sure you've run and fixed any issues with these commands:

  • cargo fmt --all -- --check to check standard code formatting (cargo fmt --all applies these changes)
  • cargo clippy --workspace --features=extra -- -D warnings -D clippy::unwrap_used -A clippy::needless_collect to check that you're using the standard code style
  • cargo test --workspace --features=extra to check that all tests pass

User-Facing Changes

If you're making changes that will affect the user experience of Nushell (ex: adding/removing a command, changing an input/output type, adding a new flag):

@@ -352,6 +352,7 @@ fn should_skip_dir(dir: impl AsRef<Path>) -> bool {
}

fn is_hidden_dir(metadata_attributes: u32) -> bool {
#[cfg(windows)]
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm guessing that this should be moved up so that is_hidden_dir is only available on windows.

Copy link
Author

Choose a reason for hiding this comment

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

Thanks!

@rgwood
Copy link
Contributor

rgwood commented Nov 3, 2022

Does this change always hide the directories? Or are they visible with the -a/--all flag?

@sholderbach sholderbach added the pr:breaking-change This PR implies a change affecting users and has to be noted in the release notes label Nov 3, 2022
@richardmarklund
Copy link
Author

@rgwood
All is visible with -a/--all
No change there.

@rgwood
Copy link
Contributor

rgwood commented Nov 4, 2022

@richardmarklund Looks like this has broken tests on Linux. Are you looking into that?

@richardmarklund
Copy link
Author

@rgwood
Yea, noticed this morning. I'll look into it

@dandavison
Copy link
Contributor

dandavison commented Nov 9, 2022

I see this is Windows-only, but what's the motivation for hiding symlinks? (other than emulating a Windows command)

Edit Oh, is it simply that Windows doesn't allow symlinks? Ignore me if so!

@rgwood
Copy link
Contributor

rgwood commented Nov 9, 2022

Windows does allow symlinks (but they're a little harder to create than on *nix).

I think the logic needs to be more complex than "is it a symlink?" because cmd.exe and PowerShell do show some symlinks. However, Nu shows a few symlinks that don't show up in cmd.exe and PowerShell:

image

I'm not sure what exactly differentiates those symlinks from the ones shown by cmd.exe and PowerShell.

symlinks in cmd.exe dir

image

symlinks in PowerShell ls

image

@ChrisDenton
Copy link
Contributor

They have the system attribute (as well as having the hidden attribute). In powershell try ls -System -Hidden.

@richardmarklund
Copy link
Author

@rgwood @ChrisDenton
Hello and thanks for your comments. That's the way I went from the start. The problem is that I still find differences when I run ls in powershell and ls in the nushell.
Powershell:

image

nushell:
image

So here I'm filtering out everything that's either system or hidden according to:
https://docs.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants

But if I also remove the symlinks it seems like its correct:
image

@richardmarklund
Copy link
Author

I also have a question:
The test that is failing now seems a little strange. So we have a test that is passing and works fine named: lists_all_hidden_files_when_glob_contains_dot that creates the following structure and returns 3 which is correct according to the test.
root1.txt
root2.txt
.dotfile1
dir_a
yehuda.10.txt
jonathan.10.txt
.dotfile2
dir_b
andres.10.txt
chicken_not_to_be_picked_up.100.txt
.dotfile3

command: ls **/.* | length

The next test: lists_all_hidden_files_when_glob_does_not_contain_dot
Has the same file structure but with this command:
ls **/* | length

The test wants that to return 5, which I find a bit strange. My returns 7 which also feels strange. My intuition wanted it to be 11. But I guess the command is run inside dir_a?

Anyways, how do you want this to work? My thought was that if you specify a glob pattern then you want all the results regardless of if the command is with a dot or not.

We could either go the route of if you are specifying a glob pattern and then give the full result or you'll have to add -a/-all to get the full result regardless of the glob pattern.

What's your thought?

@ChrisDenton
Copy link
Contributor

Sorry, I'm not very familiar with the code. How are you getting the attributes? The relevant attributes are on the symlink. If you have a DirEntry you can use the DirEntry::metadata method but if you just have a path you'll need to use Path::symlink_metadata (or GetFileAttributesW but that's very Windows specific).

@rgwood
Copy link
Contributor

rgwood commented Nov 10, 2022

But if I also remove the symlinks it seems like its correct:

@richardmarklund See my examples here; cmd.exe and pwsh do not hide all symlinks by default.

@rgwood rgwood marked this pull request as draft December 7, 2022 21:24
@deoradh
Copy link

deoradh commented Dec 22, 2022

Alternatively, why not just create a switch to opt into os-specific behavior (ie, ls --os=windows)? That, then, could be aliased as desired without inducing a breaking change or affecting the portability of any scripts. It also allows that behavior to be accessed outside of any specific OS install.

@rgwood
Copy link
Contributor

rgwood commented Jan 4, 2023

@richardmarklund Thanks for your work on this :). It seems like this PR has stalled so I'm going to close it for now, but if you want to pick it up again we can always reopen it.

@rgwood rgwood closed this Jan 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pr:breaking-change This PR implies a change affecting users and has to be noted in the release notes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants