Skip to content
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

Excludes should be relative to the site source #1916

Merged
merged 5 commits into from
Jan 11, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions lib/jekyll/core_ext.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,3 @@ def symbolize_keys
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
40 changes: 37 additions & 3 deletions lib/jekyll/entry_filter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -15,7 +31,7 @@ def filter(entries)
end

def included?(entry)
site.include.glob_include?(entry)
glob_include?(site.include, entry)
end

def special?(entry)
Expand All @@ -27,11 +43,29 @@ def backup?(entry)
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
10 changes: 5 additions & 5 deletions lib/jekyll/site.rb
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ def read_layouts
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(".")
Expand All @@ -157,7 +157,7 @@ def read_layouts
# 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
Expand Down Expand Up @@ -339,8 +339,8 @@ def site_payload
# 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.
Expand Down Expand Up @@ -381,7 +381,7 @@ def instantiate_subclasses(klass)
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

Expand Down
2 changes: 1 addition & 1 deletion site/_config.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
highlight: pygments
highlighter: pygments
relative_permalinks: false
gauges_id: 503c5af6613f5d0f19000027
permalink: /news/:year/:month/:day/:title/
Expand Down
22 changes: 0 additions & 22 deletions test/test_core_ext.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
38 changes: 36 additions & 2 deletions test/test_entry_filter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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"])
Expand Down Expand Up @@ -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