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
Meaning of "hidden files" in Dir.glob
#13196
Comments
It would be very bad choice to make the definition of hidden dependent on the OS. File names starting with a dot need to be considered as hidden everywhere or nowhere. We've chosen everywhere so that must apply on Windows, too. Files marked as hidden in the file system on windows should be considered hidden as well. We can do the same on Unix if available, but that's probably not very relevant. For reference, the API was generally inspired by Ruby. But Ruby has no # dotfile
Dir.glob("*") # => []
Dir.glob("*", File::FNM_DOTMATCH) # => [".dotfile"]
# FS hidden attribute
Dir.glob("C:/System Volume Information") # => ["C:/System Volume Information"]
Dir.glob("C:/System Volume Information", File::FNM_DOTMATCH) #=> ["C:/System Volume Information"] |
IMO the Kernel should be the main focus here. Yes Basically. If it runs under NT Kernel|NT-Clones/ReactOS? then Yes. File Names shouldn't have any effect on File Attributes. Thats basically forcing Unix-Conventions on NT. |
It would be clear if the option was called It could be renamed with deprecation. |
That would blatantly break the premise of portability that guarantees Crystal programs using the standard library behave the same on all platforms (at least as much as technically possible). With a folder containing the same files, the result of
That would perhaps more accurately describe the current implementation on Unix systems. But what would it mean on Windows? Would a hidden file system attribute count as "dotfile"? If not, what would be a different way to include/exclude such files? |
Similarly there are several other notions of "hidden files" exclusive to macOS / HFS+ as well: https://stackoverflow.com/a/15236292 IMO if a filesystem supports a hidden attribute and a file uses it, then it is no longer the "same" as an otherwise identical file on a filesystem not supporting such an attribute; therefore making |
@straight-shoota I'd differentiate between the hidden and dot files by means of giving two separate options. |
@HertzDevil Good point. Sigh. I guess we might have to use two separate parameters then in order to indicate different semantics as appropriate. |
I did some research looking for prior art how other languages or libraries represent hidden files. It seems most either do not have a generic concept for that, or it's platform specific, i.e. the semantics on Windows and Unix are different. I did not find a single instance of a cross-platform abstraction that would allow you to use Unix semantics on Windows. There are certainly use cases for that, but I suppose it's also easy to implement the Unix semantics when iterating the file names. So that could be a reason why people choose not to bother for a generic API. However, I still think it would be convenient to have a portable abstraction ready to use. |
We could define the overloads like Also perhaps we should define |
Yes, I suppose that could be a viable solution. However, the word "hidden" is problematic due to its ambiguity. I wished |
Another idea, but it might be too complex / over-engineered: How about expressing the So there would be two original members, For semantic compatibility, the mapping for boolean |
It might be more appropriate to name it |
On BSD-like systems, including macOS, |
Yes, those would need to be different options. Dotfiles are not really a OS policy. It's just a convention used by programs independent of the OS. |
Windows has two attributes to hide files, first one being standard hidden attribute and the second being the system attribute. |
That means the
then:
If additionally those filenames start with a period then We could also respect the current Explorer settings, although this is probably a step too far: # shjobj_core.cr
lib LibC
struct SHELLSTATE
flags1 : BOOL
dwWin95Unused : DWORD
uWin95Unused : UInt
lParamSort : LONG
iSortDirection : Int
version : UInt
uNotUsed : UInt
flags2 : BOOL
end
# bitfield masks
SHELLSTATE_flags1_fShowAllObjects = 0x00000001
SHELLSTATE_flags1_fShowSuperHidden = 0x00008000
SSF_SHOWALLOBJECTS = 0x00000001
SSF_SHOWSUPERHIDDEN = 0x00040000
fun SHGetSetSettings(psfs : SHELLSTATE*, dwMask : DWORD, bSet : BOOL)
end
LibC.SHGetSetSettings(out shell_settings, LibC::SSF_SHOWALLOBJECTS | LibC::SSF_SHOWSUPERHIDDEN, 0)
shell_settings.flags1.bits_set?(LibC::SHELLSTATE_flags1_fShowAllObjects) # Show hidden files, folders, and drives
shell_settings.flags1.bits_set?(LibC::SHELLSTATE_flags1_fShowSuperHidden) # (don't) Hide protected operating system files
It's the opposite because the flags would be used to control which files are matched, not excluded. So |
I would suggest the possibility that any file exclusion behavior in (I don't necessarily advocate strongly for this position; just suggesting it.) Given:
I don't believe there is any reasonable way to capture this complexity in a small number of arguments to Requiring the application to manually do a separate |
That would put IMO unnecessary burden of boilerplate code for the stdlib consumers. It's not consistent across different OSes indeed, in a same time it's a widely-used convention - dotfiles are regarded as hidden/special by many different pieces of the OS/web stack (for protection against http access for instance). |
Dir.glob
has amatch_hidden
parameter, which to my knowledge is the only standard library API that deals with the notion of hidden files. It says:A file or directory is hidden if and only if its name begins with a
.
:crystal/src/dir/glob.cr
Lines 197 to 200 in c931553
But this is not how hidden files in Windows work. A file is hidden there if
dwFileAttributes & FILE_ATTRIBUTE_HIDDEN != 0
in any of the relevant structs returned by Win32 functions; that file has a transparent icon in Windows Explorer.Should we change how
Dir.glob
works even if it means the same directory structure will behave differently depending on the host system? (Of course, the directory structure isn't technically the same on most occasions, unless the standard library attempts to support NTFS natively on Unix-like systems)The text was updated successfully, but these errors were encountered: