Skip to content

Commit

Permalink
[GR-34365] Add sorting for Dir.glob (#2523)
Browse files Browse the repository at this point in the history
PullRequest: truffleruby/3044
  • Loading branch information
eregon committed Nov 9, 2021
2 parents 5684c00 + ffa39a7 commit a4298d7
Show file tree
Hide file tree
Showing 6 changed files with 18 additions and 19 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ Compatibility:
* Handle `Kernel#clone(freeze: true)` (#2512, @andrykonchin).
* Relax `Fiber#transfer` limitations (#2453).
* Implement `Fiber#blocking?` like CRuby 3 (#2453, @aardvark179).
* Sort by default for `Dir.{glob,[]}` and add `sort:` keyword argument (#2523, @Strech).

Performance:

Expand Down
3 changes: 0 additions & 3 deletions spec/tags/core/dir/glob_tags.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1 @@
fails:Dir.glob recursively matches files and directories in nested dot subdirectory with 'nested/**/*' from the current directory and option File::FNM_DOTMATCH
fails:Dir.glob result is sorted by default
fails:Dir.glob result is sorted with sort: true
fails:Dir.glob sort: false returns same files
7 changes: 4 additions & 3 deletions src/main/ruby/truffleruby/core/dir.rb
Original file line number Diff line number Diff line change
Expand Up @@ -212,18 +212,18 @@ def home(user=nil)
PrivateFile.expand_path("~#{user}")
end

def [](*patterns, base: nil)
def [](*patterns, base: nil, sort: true)
if patterns.size == 1
pattern = Truffle::Type.coerce_to_path(patterns[0], false)
return [] if pattern.empty?
raise ArgumentError, 'nul-separated glob pattern is deprecated' if pattern.include? "\0"
patterns = [pattern]
end

glob patterns, base: base
glob patterns, base: base, sort: sort
end

def glob(pattern, flags=0, base: nil, &block)
def glob(pattern, flags=0, base: nil, sort: true, &block)
if Primitive.object_kind_of?(pattern, Array)
patterns = pattern
else
Expand All @@ -236,6 +236,7 @@ def glob(pattern, flags=0, base: nil, &block)

matches = []
index = 0
flags |= File::FNM_GLOB_NOSORT if Primitive.object_equal(sort, false)

normalized_base = if Primitive.nil? base
nil
Expand Down
8 changes: 5 additions & 3 deletions src/main/ruby/truffleruby/core/dir_glob.rb
Original file line number Diff line number Diff line change
Expand Up @@ -405,12 +405,14 @@ def self.single_compile(glob, flags=0)
last
end

def self.run(node, all_matches, glob_base_dir)
def self.run(node, all_matches, glob_base_dir, flags = 0)
if ConstantEntry === node
node.process_directory all_matches, nil, nil, glob_base_dir
else
matches = []
node.process_directory matches, nil, nil, glob_base_dir
matches.sort! if (flags & File::FNM_GLOB_NOSORT) == 0

all_matches.concat(matches)
end
end
Expand Down Expand Up @@ -461,10 +463,10 @@ def self.glob(base_dir, pattern, flags, matches)
patterns = compile(pattern, left_brace_index, flags)

patterns.each do |node|
run node, matches, base_dir
run node, matches, base_dir, flags
end
elsif node = single_compile(pattern, flags)
run node, matches, base_dir
run node, matches, base_dir, flags
else
matches
end
Expand Down
11 changes: 6 additions & 5 deletions src/main/ruby/truffleruby/core/file.rb
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,12 @@ module Constants
W_OK = 2 # test for write permission
R_OK = 4 # test for read permission

FNM_NOESCAPE = 0x01
FNM_PATHNAME = 0x02
FNM_DOTMATCH = 0x04
FNM_CASEFOLD = 0x08
FNM_EXTGLOB = 0x10
FNM_NOESCAPE = 0x01
FNM_PATHNAME = 0x02
FNM_DOTMATCH = 0x04
FNM_CASEFOLD = 0x08
FNM_EXTGLOB = 0x10
FNM_GLOB_NOSORT = 0x40

if Truffle::Platform.windows?
NULL = 'NUL'
Expand Down
7 changes: 2 additions & 5 deletions test/mri/excludes/TestDir.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,10 @@
exclude :test_chdir, "needs investigation"
exclude :test_glob_base, "needs investigation"
exclude :test_glob_base_dir, "needs investigation"
exclude :test_glob_cases, "needs investigation"
exclude :test_glob_cases, "fails on macOS in CI"
exclude :test_glob_gc_for_fd, "needs investigation"
exclude :test_glob_too_may_open_files, "needs investigation"
exclude :test_seek, "needs investigation"
exclude :test_seek, "fails on macOS in CI"
exclude :test_unknown_keywords, "needs investigation"
exclude :test_chdir_conflict, "needs investigation"
exclude :test_glob_order, "needs investigation"
exclude :test_symlink, "needs investigation"
exclude :test_symlinks_not_resolved, "needs investigation"
exclude :test_foreach, "needs investigation"

0 comments on commit a4298d7

Please sign in to comment.