diff --git a/lib/jekyll/core_ext.rb b/lib/jekyll/core_ext.rb index ce74d2ba..43edcb13 100644 --- a/lib/jekyll/core_ext.rb +++ b/lib/jekyll/core_ext.rb @@ -53,11 +53,3 @@ class Hash dup.symbolize_keys! end end - -module Enumerable - # Returns true if path matches against any glob pattern. - # Look for more detail about glob pattern in method File::fnmatch. - def glob_include?(e) - any? { |exp| File.fnmatch?(exp, e) } - end -end diff --git a/lib/jekyll/entry_filter.rb b/lib/jekyll/entry_filter.rb index a547ae8b..11db9e11 100644 --- a/lib/jekyll/entry_filter.rb +++ b/lib/jekyll/entry_filter.rb @@ -2,8 +2,24 @@ module Jekyll class EntryFilter attr_reader :site - def initialize(site) + def initialize(site, base_directory = nil) @site = site + @base_directory = derive_base_directory(@site, base_directory.to_s.dup) + end + + def base_directory + @base_directory.to_s + end + + def derive_base_directory(site, base_dir) + if base_dir.start_with?(site.source) + base_dir[site.source] = "" + end + base_dir + end + + def relative_to_source(entry) + File.join(base_directory, entry) end def filter(entries) @@ -15,7 +31,7 @@ module Jekyll end def included?(entry) - site.include.glob_include?(entry) + glob_include?(site.include, entry) end def special?(entry) @@ -27,11 +43,29 @@ module Jekyll end def excluded?(entry) - site.exclude.glob_include?(entry) + excluded = glob_include?(site.exclude, relative_to_source(entry)) + Jekyll.logger.debug "excluded?(#{relative_to_source(entry)}) ==> #{excluded}" + excluded end def symlink?(entry) File.symlink?(entry) && site.safe end + + def ensure_leading_slash(path) + path[0..0] == "/" ? path : "/#{path}" + end + + # Returns true if path matches against any glob pattern. + # Look for more detail about glob pattern in method File::fnmatch. + def glob_include?(enum, e) + entry = ensure_leading_slash(e) + enum.any? do |exp| + item = ensure_leading_slash(exp) + Jekyll.logger.debug "glob_include?(#{entry})" + Jekyll.logger.debug " ==> File.fnmatch?(#{item}, #{entry}) == #{File.fnmatch?(item, entry)}" + File.fnmatch?(item, entry) + end + end end end diff --git a/lib/jekyll/site.rb b/lib/jekyll/site.rb index 95bb46f9..48173835 100644 --- a/lib/jekyll/site.rb +++ b/lib/jekyll/site.rb @@ -140,7 +140,7 @@ module Jekyll base = File.join(self.source, self.config['layouts']) return unless File.exists?(base) entries = [] - Dir.chdir(base) { entries = filter_entries(Dir['**/*.*']) } + Dir.chdir(base) { entries = filter_entries(Dir['**/*.*'], base) } entries.each do |f| name = f.split(".")[0..-2].join(".") @@ -157,7 +157,7 @@ module Jekyll # Returns nothing. def read_directories(dir = '') base = File.join(self.source, dir) - entries = Dir.chdir(base) { filter_entries(Dir.entries('.')) } + entries = Dir.chdir(base) { filter_entries(Dir.entries('.'), base) } self.read_posts(dir) self.read_drafts(dir) if self.show_drafts @@ -339,8 +339,8 @@ module Jekyll # entries - The Array of String file/directory entries to filter. # # Returns the Array of filtered entries. - def filter_entries(entries) - EntryFilter.new(self).filter(entries) + def filter_entries(entries, base_directory = nil) + EntryFilter.new(self, base_directory).filter(entries) end # Get the implementation class for the given Converter. @@ -381,7 +381,7 @@ module Jekyll def get_entries(dir, subfolder) base = File.join(self.source, dir, subfolder) return [] unless File.exists?(base) - entries = Dir.chdir(base) { filter_entries(Dir['**/*']) } + entries = Dir.chdir(base) { filter_entries(Dir['**/*'], base) } entries.delete_if { |e| File.directory?(File.join(base, e)) } end diff --git a/site/_config.yml b/site/_config.yml index fc1fd46d..7181a663 100644 --- a/site/_config.yml +++ b/site/_config.yml @@ -1,4 +1,4 @@ -highlight: pygments +highlighter: pygments relative_permalinks: false gauges_id: 503c5af6613f5d0f19000027 permalink: /news/:year/:month/:day/:title/ diff --git a/test/test_core_ext.rb b/test/test_core_ext.rb index 0b79f33f..c3e62cb5 100644 --- a/test/test_core_ext.rb +++ b/test/test_core_ext.rb @@ -63,26 +63,4 @@ class TestCoreExt < Test::Unit::TestCase end end - - context "enumerable" do - context "glob_include?" do - should "return false with no glob patterns" do - assert ![].glob_include?("a.txt") - end - - should "return false with all not match path" do - data = ["a*", "b?"] - assert !data.glob_include?("ca.txt") - assert !data.glob_include?("ba.txt") - end - - should "return true with match path" do - data = ["a*", "b?", "**/a*"] - assert data.glob_include?("a.txt") - assert data.glob_include?("ba") - assert data.glob_include?("c/a/a.txt") - assert data.glob_include?("c/a/b/a.txt") - end - end - end end diff --git a/test/test_entry_filter.rb b/test/test_entry_filter.rb index c295a57c..ce50b6a8 100644 --- a/test/test_entry_filter.rb +++ b/test/test_entry_filter.rb @@ -18,8 +18,8 @@ class TestEntryFilter < Test::Unit::TestCase end should "filter entries with exclude" do - excludes = %w[README TODO] - files = %w[index.html site.css .htaccess] + excludes = %w[README TODO vendor/bundle] + files = %w[index.html site.css .htaccess vendor] @site.exclude = excludes + ["exclude*"] assert_equal files, @site.filter_entries(excludes + files + ["excludeA"]) @@ -71,4 +71,38 @@ class TestEntryFilter < Test::Unit::TestCase assert_not_equal [], site.static_files end end + + context "glob_include?" do + setup do + stub(Jekyll).configuration do + Jekyll::Configuration::DEFAULTS.merge({'source' => source_dir, 'destination' => dest_dir}) + end + @site = Site.new(Jekyll.configuration) + @filter = EntryFilter.new(@site) + end + + should "return false with no glob patterns" do + assert !@filter.glob_include?([], "a.txt") + end + + should "return false with all not match path" do + data = ["a*", "b?"] + assert !@filter.glob_include?(data, "ca.txt") + assert !@filter.glob_include?(data, "ba.txt") + end + + should "return true with match path" do + data = ["a*", "b?", "**/a*"] + assert @filter.glob_include?(data, "a.txt") + assert @filter.glob_include?(data, "ba") + assert @filter.glob_include?(data, "c/a/a.txt") + assert @filter.glob_include?(data, "c/a/b/a.txt") + end + + should "match even if there is no leading slash" do + data = ['vendor/bundle'] + assert @filter.glob_include?(data, '/vendor/bundle') + assert @filter.glob_include?(data, 'vendor/bundle') + end + end end