diff --git a/lib/jekyll/utils.rb b/lib/jekyll/utils.rb index c30a986a..ab516767 100644 --- a/lib/jekyll/utils.rb +++ b/lib/jekyll/utils.rb @@ -207,5 +207,34 @@ module Jekyll template end + + # Work the same way as Dir.glob but seperating the input into two parts + # ('dir' + '/' + 'pattern') to make sure the first part('dir') does not act + # as a pattern. + # + # For example, Dir.glob("path[/*") always returns an empty array, + # because the method fails to find the closing pattern to '[' which is ']' + # + # Examples: + # safe_glob("path[", "*") + # # => ["path[/file1", "path[/file2"] + # + # safe_glob("path", "*", File::FNM_DOTMATCH) + # # => ["path/.", "path/..", "path/file1"] + # + # dir - the dir where glob will be executed under + # (the dir will be included to each result) + # pattern - the pattern which will be applied under the dir + # flags - the flags which will be applied to the pattern + # + # Returns matched pathes + def safe_glob(dir, pattern, flags = 0) + return [] unless Dir.exist?(dir) + return [dir] if pattern.nil? || pattern.empty? + Dir.chdir(dir) do + Dir.glob(pattern, flags).map { |f| File.join(dir, f) } + end + end + end end diff --git a/test/safe_glob_test[/find_me.txt b/test/safe_glob_test[/find_me.txt new file mode 100644 index 00000000..e69de29b diff --git a/test/test_utils.rb b/test/test_utils.rb index 9d4a5a4d..02ebb09a 100644 --- a/test/test_utils.rb +++ b/test/test_utils.rb @@ -180,4 +180,38 @@ class TestUtils < JekyllUnitTest assert_equal "/:basename", Utils.add_permalink_suffix("/:basename", "/:title") end end + + context "The \`Utils.safe_glob\` method" do + should "not apply pattern to the dir" do + dir = "test/safe_glob_test[" + assert_equal [], Dir.glob(dir + "/*") + assert_equal ["test/safe_glob_test[/find_me.txt"], Utils.safe_glob(dir, "*") + end + + should "return the same data to #glob" do + dir = "test" + assert_equal Dir.glob(dir + "/*"), Utils.safe_glob(dir, "*") + assert_equal Dir.glob(dir + "/**/*"), Utils.safe_glob(dir, "**/*") + end + + should "return the same data to #glob if dir is not found" do + dir = "dir_not_exist" + assert_equal [], Utils.safe_glob(dir, "*") + assert_equal Dir.glob(dir + "/*"), Utils.safe_glob(dir, "*") + end + + should "return the same data to #glob if pattern is blank" do + dir = "test" + assert_equal [dir], Utils.safe_glob(dir, "") + assert_equal Dir.glob(dir), Utils.safe_glob(dir, "") + assert_equal Dir.glob(dir), Utils.safe_glob(dir, nil) + end + + should "return the same data to #glob if flag is given" do + dir = "test" + assert_equal Dir.glob(dir + "/*", File::FNM_DOTMATCH), + Utils.safe_glob(dir, "*", File::FNM_DOTMATCH) + end + end + end