forked from extern/nushell
a562f492e3
This PR is an incremental improvement to `ls` when it encounters 'illegal' file paths on Windows. Related: https://github.com/nushell/nushell/issues/7869 ## Context We have trouble with filenames that Windows doesn't like, for example [files with a `.` at the end of their name](https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#naming-conventions). To make a long story short, the Rust stdlib and several Win32 APIs will choke if asked to do something with an illegal filepath. This is a problem because files with illegal names can be created via other means (like `touch foo.` in MINGW bash). Previously `ls` would fail completely in a directory with a bad file, which isn't great. After this PR, bad files get included in `ls` results but without any metadata columns. This is not quite where we want to be — eventually we want to be able to display file metadata for _all_ files (even naughty ones) — but it's an improvement on the status quo. ### Before ![image](https://user-images.githubusercontent.com/26268125/217340906-26afd6d3-0ec3-454f-bed4-2bfcc9cf3a2f.png) ### After ![image](https://user-images.githubusercontent.com/26268125/217344373-6b81cc39-50b8-4390-8061-3e570502a784.png) ## Future work Try the workarounds @ChrisDenton suggested: https://github.com/nushell/nushell/issues/7869#issuecomment-1405977221 Some info on verbatim paths: https://users.rust-lang.org/t/understanding-windows-paths/58583 ## Testing I tried to write a test for this, but it looks like our testing sandbox can't create files with illegal filenames.😔 Here's the code in case it proves useful someday: ```rust /// Windows doesn't like certain file names, like file names ending with a period: /// https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#naming-conventions /// However, those files can still be created with tools like MINGW bash. /// We may not be able to get full metadata for those files, but we should test that we can at least include them in ls results #[test] #[cfg(windows)] fn can_list_illegal_files() { Playground::setup("ls_test_all_columns", |dirs, sandbox| { sandbox.with_files(vec![ EmptyFile("foo"), EmptyFile("bar."), EmptyFile("baz"), ]); let actual = nu!( cwd: dirs.test(), "ls | length" ); assert_eq!(actual.out, "3"); let actual = nu!( cwd: dirs.test(), "ls" ); assert_eq!(actual.out, "1"); let actual = nu!( cwd: dirs.test(), "ls | where {|f| $f.name | str ends-with 'bar.'} | length" ); assert_eq!(actual.out, "1"); }) } ``` |
||
---|---|---|
.. | ||
assets | ||
proptest-regressions/format_conversions | ||
src | ||
tests | ||
build.rs | ||
Cargo.toml | ||
LICENSE |