Merge pull request #4859 from jekyll/feature/allow-excludes-to-leave-the-insane-asylum

Merge pull request 4859
This commit is contained in:
jekyllbot 2016-05-12 12:16:35 -05:00
commit 1504864d9e
4 changed files with 72 additions and 17 deletions

View File

@ -36,4 +36,5 @@ Gem::Specification.new do |s|
s.add_runtime_dependency('rouge', '~> 1.7') s.add_runtime_dependency('rouge', '~> 1.7')
s.add_runtime_dependency('jekyll-sass-converter', '~> 1.0') s.add_runtime_dependency('jekyll-sass-converter', '~> 1.0')
s.add_runtime_dependency('jekyll-watch', '~> 1.1') s.add_runtime_dependency('jekyll-watch', '~> 1.1')
s.add_runtime_dependency("pathutil", "~> 0.9")
end end

View File

@ -16,6 +16,7 @@ end
require 'rubygems' require 'rubygems'
# stdlib # stdlib
require "pathutil"
require 'forwardable' require 'forwardable'
require 'fileutils' require 'fileutils'
require 'time' require 'time'

View File

@ -1,12 +1,15 @@
module Jekyll module Jekyll
class EntryFilter class EntryFilter
SPECIAL_LEADING_CHARACTERS = ['.', '_', '#', '~'].freeze
attr_reader :site attr_reader :site
SPECIAL_LEADING_CHARACTERS = [
'.', '_', '#', '~'
].freeze
def initialize(site, base_directory = nil) def initialize(site, base_directory = nil)
@site = site @site = site
@base_directory = derive_base_directory(@site, base_directory.to_s.dup) @base_directory = derive_base_directory(
@site, base_directory.to_s.dup
)
end end
def base_directory def base_directory
@ -14,14 +17,14 @@ module Jekyll
end end
def derive_base_directory(site, base_dir) def derive_base_directory(site, base_dir)
if base_dir.start_with?(site.source) base_dir[site.source] = "" if base_dir.start_with?(site.source)
base_dir[site.source] = ""
end
base_dir base_dir
end end
def relative_to_source(entry) def relative_to_source(entry)
File.join(base_directory, entry) File.join(
base_directory, entry
)
end end
def filter(entries) def filter(entries)
@ -33,7 +36,9 @@ module Jekyll
end end
def included?(entry) def included?(entry)
glob_include?(site.include, entry) glob_include?(site.include,
entry
)
end end
def special?(entry) def special?(entry)
@ -51,25 +56,62 @@ module Jekyll
excluded excluded
end end
# --
# Check if a file is a symlink.
# NOTE: This can be converted to allowing even in safe,
# since we use Pathutil#in_path? now.
# --
def symlink?(entry) def symlink?(entry)
site.safe && File.symlink?(entry) && symlink_outside_site_source?(entry) site.safe && File.symlink?(entry) && symlink_outside_site_source?(entry)
end end
# --
# NOTE: Pathutil#in_path? gets the realpath.
# @param [<Anything>] entry the entry you want to validate.
# Check if a path is outside of our given root.
# --
def symlink_outside_site_source?(entry) def symlink_outside_site_source?(entry)
! File.realpath(entry).start_with?(File.realpath(@site.source)) !Pathutil.new(entry).in_path?(
end site.in_source_dir
)
def ensure_leading_slash(path)
path[0..0] == "/" ? path : "/#{path}"
end end
# --
# Check if an entry matches a specific pattern and return true,false.
# Returns true if path matches against any glob pattern. # 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) def glob_include?(enum, e)
entry = ensure_leading_slash(e) entry = Pathutil.new(site.in_source_dir).join(e)
enum.any? do |exp| enum.any? do |exp|
item = ensure_leading_slash(exp)
File.fnmatch?(item, entry) || entry.start_with?(item) # Users who send a Regexp knows what they want to
# exclude, so let them send a Regexp to exclude files,
# we will not bother caring if it works or not, it's
# on them at this point.
if exp.is_a?(Regexp)
entry =~ exp
else
item = Pathutil.new(site.in_source_dir).join(exp)
# If it's a directory they want to exclude, AKA
# ends with a "/" then we will go on to check and
# see if the entry falls within that path and
# exclude it if that's the case.
if e.end_with?("/")
entry.in_path?(
item
)
else
File.fnmatch?(item, entry) ||
entry.to_path.start_with?(
item
)
end
end
end end
end end
end end

View File

@ -14,6 +14,17 @@ class TestEntryFilter < JekyllUnitTest
assert_equal %w[foo.markdown bar.markdown baz.markdown .htaccess], entries assert_equal %w[foo.markdown bar.markdown baz.markdown .htaccess], entries
end end
should "allow regexp filtering" do
files = %w(README.md)
@site.exclude = excludes = [
/README/
]
assert_empty @site.reader.filter_entries(
files
)
end
should "filter entries with exclude" do should "filter entries with exclude" do
excludes = %w[README TODO vendor/bundle] excludes = %w[README TODO vendor/bundle]
files = %w[index.html site.css .htaccess vendor] files = %w[index.html site.css .htaccess vendor]