Skip to content

Commit

Permalink
Fix Globber.constant_entry? matching patterns (#13955)
Browse files Browse the repository at this point in the history
Co-authored-by: Quinton Miller <[email protected]>
  • Loading branch information
GeopJr and HertzDevil authored Nov 27, 2023
1 parent 35eb340 commit a59b5ab
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 38 deletions.
113 changes: 77 additions & 36 deletions spec/std/dir_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -193,15 +193,15 @@ describe "Dir" do

describe "glob" do
it "tests glob with a single pattern" do
Dir["#{datapath}/dir/*.txt"].sort.should eq [
Dir["#{Path[datapath].to_posix}/dir/*.txt"].sort.should eq [
datapath("dir", "f1.txt"),
datapath("dir", "f2.txt"),
datapath("dir", "g2.txt"),
].sort
end

it "tests glob with multiple patterns" do
Dir["#{datapath}/dir/*.txt", "#{datapath}/dir/subdir/*.txt"].sort.should eq [
Dir["#{Path[datapath].to_posix}/dir/*.txt", "#{Path[datapath].to_posix}/dir/subdir/*.txt"].sort.should eq [
datapath("dir", "f1.txt"),
datapath("dir", "f2.txt"),
datapath("dir", "g2.txt"),
Expand All @@ -211,7 +211,7 @@ describe "Dir" do

it "tests glob with a single pattern with block" do
result = [] of String
Dir.glob("#{datapath}/dir/*.txt") do |filename|
Dir.glob("#{Path[datapath].to_posix}/dir/*.txt") do |filename|
result << filename
end
result.sort.should eq([
Expand All @@ -222,19 +222,19 @@ describe "Dir" do
end

it "tests a recursive glob" do
Dir["#{datapath}/dir/**/*.txt"].sort.should eq [
Dir["#{Path[datapath].to_posix}/dir/**/*.txt"].sort.should eq [
datapath("dir", "f1.txt"),
datapath("dir", "f2.txt"),
datapath("dir", "g2.txt"),
datapath("dir", "subdir", "f1.txt"),
datapath("dir", "subdir", "subdir2", "f2.txt"),
].sort

Dir["#{datapath}/dir/**/subdir2/f2.txt"].sort.should eq [
Dir["#{Path[datapath].to_posix}/dir/**/subdir2/f2.txt"].sort.should eq [
datapath("dir", "subdir", "subdir2", "f2.txt"),
].sort

Dir["#{datapath}/dir/**/subdir2/*.txt"].sort.should eq [
Dir["#{Path[datapath].to_posix}/dir/**/subdir2/*.txt"].sort.should eq [
datapath("dir", "subdir", "subdir2", "f2.txt"),
].sort
end
Expand Down Expand Up @@ -274,15 +274,15 @@ describe "Dir" do
end

it "tests a recursive glob with '?'" do
Dir["#{datapath}/dir/f?.tx?"].sort.should eq [
Dir["#{Path[datapath].to_posix}/dir/f?.tx?"].sort.should eq [
datapath("dir", "f1.txt"),
datapath("dir", "f2.txt"),
datapath("dir", "f3.txx"),
].sort
end

it "tests a recursive glob with alternation" do
Dir["#{datapath}/{dir,dir/subdir}/*.txt"].sort.should eq [
Dir["#{Path[datapath].to_posix}/{dir,dir/subdir}/*.txt"].sort.should eq [
datapath("dir", "f1.txt"),
datapath("dir", "f2.txt"),
datapath("dir", "g2.txt"),
Expand All @@ -291,7 +291,7 @@ describe "Dir" do
end

it "tests a glob with recursion inside alternation" do
Dir["#{datapath}/dir/{**/*.txt,**/*.txx}"].sort.should eq [
Dir["#{Path[datapath].to_posix}/dir/{**/*.txt,**/*.txx}"].sort.should eq [
datapath("dir", "f1.txt"),
datapath("dir", "f2.txt"),
datapath("dir", "f3.txx"),
Expand All @@ -302,15 +302,56 @@ describe "Dir" do
end

it "tests a recursive glob with nested alternations" do
Dir["#{datapath}/dir/{?1.*,{f,g}2.txt}"].sort.should eq [
Dir["#{Path[datapath].to_posix}/dir/{?1.*,{f,g}2.txt}"].sort.should eq [
datapath("dir", "f1.txt"),
datapath("dir", "f2.txt"),
datapath("dir", "g2.txt"),
].sort
end

it "tests with []" do
Dir["#{Path[datapath].to_posix}/dir/[a-z][0-9].txt"].sort.should eq [
datapath("dir", "f1.txt"),
datapath("dir", "f2.txt"),
datapath("dir", "g2.txt"),
].sort
end

it "tests with {}" do
Dir["#{Path[datapath].to_posix}/dir/{f,g}{1,2,3}.tx{t,x}"].sort.should eq [
datapath("dir", "f1.txt"),
datapath("dir", "f2.txt"),
datapath("dir", "f3.txx"),
datapath("dir", "g2.txt"),
].sort
end

{% if flag?(:windows) %}
pending "tests with \\"
{% else %}
it "tests with \\" do
with_tempfile "glob-escape-pattern" do |path|
Dir.mkdir_p path
Dir.cd(path) do
File.touch "g1.txt"
File.touch %q(\g3)
File.touch %q(\g4*)

Dir[%q(\\g*)].sort.should eq [
"\\g3",
"\\g4*",
].sort

Dir[%q(*g?\*)].sort.should eq [
"\\g4*",
].sort
end
end
end
{% end %}

it "tests with *" do
Dir["#{datapath}/dir/*"].sort.should eq [
Dir["#{Path[datapath].to_posix}/dir/*"].sort.should eq [
datapath("dir", "dots"),
datapath("dir", "f1.txt"),
datapath("dir", "f2.txt"),
Expand All @@ -322,7 +363,7 @@ describe "Dir" do
end

it "tests with ** (same as *)" do
Dir["#{datapath}/dir/**"].sort.should eq [
Dir["#{Path[datapath].to_posix}/dir/**"].sort.should eq [
datapath("dir", "dots"),
datapath("dir", "f1.txt"),
datapath("dir", "f2.txt"),
Expand All @@ -334,7 +375,7 @@ describe "Dir" do
end

it "tests with */" do
Dir["#{datapath}/dir/*/"].sort.should eq [
Dir["#{Path[datapath].to_posix}/dir/*/"].sort.should eq [
datapath("dir", "dots", ""),
datapath("dir", "subdir", ""),
datapath("dir", "subdir2", ""),
Expand All @@ -350,15 +391,15 @@ describe "Dir" do
end

it "tests with relative path" do
Dir["#{datapath}/dir/*/"].sort.should eq [
Dir["#{Path[datapath].to_posix}/dir/*/"].sort.should eq [
datapath("dir", "dots", ""),
datapath("dir", "subdir", ""),
datapath("dir", "subdir2", ""),
].sort
end

it "tests with relative path (starts with .)" do
Dir["./#{datapath}/dir/*/"].sort.should eq [
Dir["./#{Path[datapath].to_posix}/dir/*/"].sort.should eq [
File.join(".", "spec", "std", "data", "dir", "dots", ""),
File.join(".", "spec", "std", "data", "dir", "subdir", ""),
File.join(".", "spec", "std", "data", "dir", "subdir2", ""),
Expand All @@ -368,7 +409,7 @@ describe "Dir" do
it "tests with relative path (starts with ..)" do
Dir.cd(datapath) do
base_path = Path["..", "data", "dir"]
Dir["#{base_path}/*/"].sort.should eq [
Dir["#{base_path.to_posix}/*/"].sort.should eq [
base_path.join("dots", "").to_s,
base_path.join("subdir", "").to_s,
base_path.join("subdir2", "").to_s,
Expand All @@ -394,11 +435,11 @@ describe "Dir" do
File.symlink(datapath("dir", "f1.txt"), link)
File.symlink(datapath("dir", "nonexisting"), non_link)

Dir["#{path}/*_link.txt"].sort.should eq [
Dir["#{Path[path].to_posix}/*_link.txt"].sort.should eq [
link.to_s,
non_link.to_s,
].sort
Dir["#{path}/non_link.txt"].should eq [non_link.to_s]
Dir["#{Path[path].to_posix}/non_link.txt"].should eq [non_link.to_s]
end
end

Expand All @@ -414,8 +455,8 @@ describe "Dir" do
File.write(non_link, "")
File.symlink(target, link_dir)

Dir.glob("#{path}/glob/*/a.txt").sort.should eq [] of String
Dir.glob("#{path}/glob/*/a.txt", follow_symlinks: true).sort.should eq [
Dir.glob("#{Path[path].to_posix}/glob/*/a.txt").sort.should eq [] of String
Dir.glob("#{Path[path].to_posix}/glob/*/a.txt", follow_symlinks: true).sort.should eq [
File.join(path, "glob", "dir", "a.txt"),
]
end
Expand All @@ -435,27 +476,27 @@ describe "Dir" do
end

it "pattern ending with .." do
Dir["#{datapath}/dir/.."].sort.should eq [
Dir["#{Path[datapath].to_posix}/dir/.."].sort.should eq [
datapath("dir", ".."),
].sort
end

it "pattern ending with */.." do
Dir["#{datapath}/dir/*/.."].sort.should eq [
Dir["#{Path[datapath].to_posix}/dir/*/.."].sort.should eq [
datapath("dir", "dots", ".."),
datapath("dir", "subdir", ".."),
datapath("dir", "subdir2", ".."),
].sort
end

it "pattern ending with ." do
Dir["#{datapath}/dir/."].sort.should eq [
Dir["#{Path[datapath].to_posix}/dir/."].sort.should eq [
datapath("dir", "."),
].sort
end

it "pattern ending with */." do
Dir["#{datapath}/dir/*/."].sort.should eq [
Dir["#{Path[datapath].to_posix}/dir/*/."].sort.should eq [
datapath("dir", "dots", "."),
datapath("dir", "subdir", "."),
datapath("dir", "subdir2", "."),
Expand All @@ -464,26 +505,26 @@ describe "Dir" do

context "match: :dot_files / match_hidden" do
it "matches dot files" do
Dir.glob("#{datapath}/dir/dots/**/*", match: :dot_files).sort.should eq [
Dir.glob("#{Path[datapath].to_posix}/dir/dots/**/*", match: :dot_files).sort.should eq [
datapath("dir", "dots", ".dot.hidden"),
datapath("dir", "dots", ".hidden"),
datapath("dir", "dots", ".hidden", "f1.txt"),
].sort
Dir.glob("#{datapath}/dir/dots/**/*", match_hidden: true).sort.should eq [
Dir.glob("#{Path[datapath].to_posix}/dir/dots/**/*", match_hidden: true).sort.should eq [
datapath("dir", "dots", ".dot.hidden"),
datapath("dir", "dots", ".hidden"),
datapath("dir", "dots", ".hidden", "f1.txt"),
].sort
end

it "ignores hidden files" do
Dir.glob("#{datapath}/dir/dots/*", match: :none).should be_empty
Dir.glob("#{datapath}/dir/dots/*", match_hidden: false).should be_empty
Dir.glob("#{Path[datapath].to_posix}/dir/dots/*", match: :none).should be_empty
Dir.glob("#{Path[datapath].to_posix}/dir/dots/*", match_hidden: false).should be_empty
end

it "ignores hidden files recursively" do
Dir.glob("#{datapath}/dir/dots/**/*", match: :none).should be_empty
Dir.glob("#{datapath}/dir/dots/**/*", match_hidden: false).should be_empty
Dir.glob("#{Path[datapath].to_posix}/dir/dots/**/*", match: :none).should be_empty
Dir.glob("#{Path[datapath].to_posix}/dir/dots/**/*", match_hidden: false).should be_empty
end
end

Expand Down Expand Up @@ -534,10 +575,10 @@ describe "Dir" do
expected_hidden = (expected + [hidden_txt, hidden_dir, inside_hidden]).sort!
expected_system_hidden = (expected_hidden + [system_hidden_txt, system_hidden_dir, inside_system_hidden]).sort!

Dir.glob("#{path}/**/*", match: :none).sort.should eq(expected)
Dir.glob("#{path}/**/*", match: :native_hidden).sort.should eq(expected_hidden)
Dir.glob("#{path}/**/*", match: :os_hidden).sort.should eq(expected)
Dir.glob("#{path}/**/*", match: File::MatchOptions[NativeHidden, OSHidden]).sort.should eq(expected_system_hidden)
Dir.glob("#{Path[path].to_posix}/**/*", match: :none).sort.should eq(expected)
Dir.glob("#{Path[path].to_posix}/**/*", match: :native_hidden).sort.should eq(expected_hidden)
Dir.glob("#{Path[path].to_posix}/**/*", match: :os_hidden).sort.should eq(expected)
Dir.glob("#{Path[path].to_posix}/**/*", match: File::MatchOptions[NativeHidden, OSHidden]).sort.should eq(expected_system_hidden)
end
end
{% end %}
Expand All @@ -550,8 +591,8 @@ describe "Dir" do
]

it "posix path" do
Dir[Path.posix(datapath, "dir", "*.txt")].sort.should eq expected
Dir[[Path.posix(datapath, "dir", "*.txt")]].sort.should eq expected
Dir[Path.posix(Path[datapath].to_posix, "dir", "*.txt")].sort.should eq expected
Dir[[Path.posix(Path[datapath].to_posix, "dir", "*.txt")]].sort.should eq expected
end

it "windows path" do
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/crystal/command/format.cr
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ class Crystal::Command
format_file filename
end
elsif Dir.exists?(filename)
filename = filename.chomp('/')
filename = ::Path[filename.chomp('/')].to_posix
filenames = Dir["#{filename}/**/*.cr"]
format_many filenames
else
Expand Down
1 change: 1 addition & 0 deletions src/compiler/crystal/command/spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class Crystal::Command
locations << {file, line}
else
if Dir.exists?(filename)
filename = ::Path[filename].to_posix
target_filenames.concat Dir["#{filename}/**/*_spec.cr"]
elsif File.file?(filename)
target_filenames << filename
Expand Down
2 changes: 1 addition & 1 deletion src/dir/glob.cr
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ class Dir

private def self.constant_entry?(file)
file.each_char do |char|
return false if char.in?('*', '?')
return false if char.in?('*', '?', '[', '\\')
end

true
Expand Down

0 comments on commit a59b5ab

Please sign in to comment.