From 3ce57cdbf10b599aa7396baec5d003c7ee05788e Mon Sep 17 00:00:00 2001 From: Ashwin Maroli Date: Thu, 11 Jan 2018 12:09:28 +0530 Subject: [PATCH 1/6] Glob scope path only if configured with a pattern --- lib/jekyll/frontmatter_defaults.rb | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/lib/jekyll/frontmatter_defaults.rb b/lib/jekyll/frontmatter_defaults.rb index f6b89f6bb60..d1743e6ec16 100644 --- a/lib/jekyll/frontmatter_defaults.rb +++ b/lib/jekyll/frontmatter_defaults.rb @@ -101,13 +101,15 @@ def applies_path?(scope, path) return true if !scope.key?("path") || scope["path"].empty? sanitized_path = Pathname.new(sanitize_path(path)) - - site_path = Pathname.new(@site.source) + site_path = Pathname.new(@site.source) rel_scope_path = Pathname.new(scope["path"]) abs_scope_path = File.join(@site.source, rel_scope_path) - Dir.glob(abs_scope_path).each do |scope_path| - scope_path = Pathname.new(scope_path).relative_path_from site_path - return true if path_is_subpath?(sanitized_path, scope_path) + + if glob_pattern?(rel_scope_path) + Dir.glob(abs_scope_path).each do |scope_path| + scope_path = Pathname.new(scope_path).relative_path_from site_path + return true if path_is_subpath?(sanitized_path, scope_path) + end end path_is_subpath?(sanitized_path, rel_scope_path) @@ -123,6 +125,13 @@ def path_is_subpath?(path, parent_path) false end + def glob_pattern?(path) + path.each_filename do |str| + return true if str =~ %r!\*+|\?|\[.*\]|{.*}! + end + false + end + # Determines whether the scope applies to type. # The scope applies to the type if: # 1. no 'type' is specified From 28559b787068ec69616acb6eedb36016eaeba465 Mon Sep 17 00:00:00 2001 From: Ashwin Maroli Date: Thu, 11 Jan 2018 20:17:04 +0530 Subject: [PATCH 2/6] test if a scope path is not globbed unnecessarily --- lib/jekyll/frontmatter_defaults.rb | 3 +++ test/test_front_matter_defaults.rb | 12 ++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/jekyll/frontmatter_defaults.rb b/lib/jekyll/frontmatter_defaults.rb index d1743e6ec16..8c1cab5416f 100644 --- a/lib/jekyll/frontmatter_defaults.rb +++ b/lib/jekyll/frontmatter_defaults.rb @@ -97,6 +97,7 @@ def applies?(scope, path, type) applies_path?(scope, path) && applies_type?(scope, type) end + # rubocop:disable Metrics/AbcSize def applies_path?(scope, path) return true if !scope.key?("path") || scope["path"].empty? @@ -108,12 +109,14 @@ def applies_path?(scope, path) if glob_pattern?(rel_scope_path) Dir.glob(abs_scope_path).each do |scope_path| scope_path = Pathname.new(scope_path).relative_path_from site_path + Jekyll.logger.debug "Globbed Scope Path:", scope_path return true if path_is_subpath?(sanitized_path, scope_path) end end path_is_subpath?(sanitized_path, rel_scope_path) end + # rubocop:enable Metrics/AbcSize def path_is_subpath?(path, parent_path) path.ascend do |ascended_path| diff --git a/test/test_front_matter_defaults.rb b/test/test_front_matter_defaults.rb index b1773ba0ecb..2f996a9f303 100644 --- a/test/test_front_matter_defaults.rb +++ b/test/test_front_matter_defaults.rb @@ -16,7 +16,7 @@ class TestFrontMatterDefaults < JekyllUnitTest }, },], }) - @site.process + @output = capture_output { @site.process } @affected = @site.pages.find { |page| page.relative_path == "contacts/bar.html" } @not_affected = @site.pages.find { |page| page.relative_path == "about.html" } end @@ -25,6 +25,10 @@ class TestFrontMatterDefaults < JekyllUnitTest assert_equal @affected.data["key"], "val" assert_nil @not_affected.data["key"] end + + should "not call Dir.glob block" do + refute_includes @output, "Globbed Scope Path:" + end end context "A site with full front matter defaults (glob)" do @@ -40,7 +44,7 @@ class TestFrontMatterDefaults < JekyllUnitTest }, },], }) - @site.process + @output = capture_output { @site.process } @affected = @site.pages.find { |page| page.relative_path == "contacts/bar.html" } @not_affected = @site.pages.find { |page| page.relative_path == "about.html" } end @@ -49,6 +53,10 @@ class TestFrontMatterDefaults < JekyllUnitTest assert_equal @affected.data["key"], "val" assert_nil @not_affected.data["key"] end + + should "call Dir.glob block" do + assert_includes @output, "Globbed Scope Path:" + end end context "A site with front matter type pages and an extension" do From 776433109b96cb644938ffbf9caf4923bdde4d7f Mon Sep 17 00:00:00 2001 From: Ashwin Maroli Date: Mon, 15 Jan 2018 16:24:27 +0530 Subject: [PATCH 3/6] limit scope path globbing to just patterns with * --- lib/jekyll/frontmatter_defaults.rb | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/lib/jekyll/frontmatter_defaults.rb b/lib/jekyll/frontmatter_defaults.rb index 8c1cab5416f..8fe1314c21e 100644 --- a/lib/jekyll/frontmatter_defaults.rb +++ b/lib/jekyll/frontmatter_defaults.rb @@ -106,7 +106,7 @@ def applies_path?(scope, path) rel_scope_path = Pathname.new(scope["path"]) abs_scope_path = File.join(@site.source, rel_scope_path) - if glob_pattern?(rel_scope_path) + if scope["path"].to_s.include?("*") Dir.glob(abs_scope_path).each do |scope_path| scope_path = Pathname.new(scope_path).relative_path_from site_path Jekyll.logger.debug "Globbed Scope Path:", scope_path @@ -128,13 +128,6 @@ def path_is_subpath?(path, parent_path) false end - def glob_pattern?(path) - path.each_filename do |str| - return true if str =~ %r!\*+|\?|\[.*\]|{.*}! - end - false - end - # Determines whether the scope applies to type. # The scope applies to the type if: # 1. no 'type' is specified From d409d4a8a854eeccf34f26defc226c60e4d57946 Mon Sep 17 00:00:00 2001 From: Ashwin Maroli Date: Mon, 15 Jan 2018 16:49:16 +0530 Subject: [PATCH 4/6] update docs on globbing in Front Matter defaults --- docs/_docs/configuration.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/_docs/configuration.md b/docs/_docs/configuration.md index 63ebd047440..b1e1a2f9614 100644 --- a/docs/_docs/configuration.md +++ b/docs/_docs/configuration.md @@ -549,7 +549,9 @@ defaults: In this example, the `layout` is set to `default` inside the [collection](../collections/) with the name `my_collection`. -It is also possible to use glob patterns when matching defaults. For example, it is possible to set specific layout for each `special-page.html` in any subfolder of `section` folder. {%- include docs_version_badge.html version="3.7.0" -%} +### Glob patterns in Front Matter defaults + +It is also possible to use glob patterns (currently limited to patterns that contain `*`) when matching defaults. For example, it is possible to set specific layout for each `special-page.html` in any subfolder of `section` folder. {%- include docs_version_badge.html version="3.7.0" -%} ```yaml collections: @@ -564,6 +566,17 @@ defaults: layout: "specific-layout" ``` +
+
Globbing and Performance
+

+ Please note that globbing a path is a known performance-poison and is + currently not optimized, especially on Windows. Globbing a path will + increase your build times in proportion to the size of the associated + collection directory. +

+
+ + ### Precedence Jekyll will apply all of the configuration settings you specify in the `defaults` section of your `_config.yml` file. However, you can choose to override settings from other scope/values pair by specifying a more specific path for the scope. From a69ffba8268f7894edac960c24a388cd9474c866 Mon Sep 17 00:00:00 2001 From: Ashwin Maroli Date: Thu, 18 Jan 2018 18:37:52 +0530 Subject: [PATCH 5/6] add an else branch for better readability --- lib/jekyll/frontmatter_defaults.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/jekyll/frontmatter_defaults.rb b/lib/jekyll/frontmatter_defaults.rb index 8fe1314c21e..be749384c6b 100644 --- a/lib/jekyll/frontmatter_defaults.rb +++ b/lib/jekyll/frontmatter_defaults.rb @@ -112,9 +112,10 @@ def applies_path?(scope, path) Jekyll.logger.debug "Globbed Scope Path:", scope_path return true if path_is_subpath?(sanitized_path, scope_path) end + false + else + path_is_subpath?(sanitized_path, rel_scope_path) end - - path_is_subpath?(sanitized_path, rel_scope_path) end # rubocop:enable Metrics/AbcSize From 5b90b7ee3c8f3a07d96972b1a98ae512a06e6ebe Mon Sep 17 00:00:00 2001 From: Ashwin Maroli Date: Thu, 18 Jan 2018 20:31:00 +0530 Subject: [PATCH 6/6] rephrase note in documentation --- docs/_docs/configuration.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/_docs/configuration.md b/docs/_docs/configuration.md index b1e1a2f9614..6f00ab535de 100644 --- a/docs/_docs/configuration.md +++ b/docs/_docs/configuration.md @@ -569,10 +569,10 @@ defaults:
Globbing and Performance

- Please note that globbing a path is a known performance-poison and is - currently not optimized, especially on Windows. Globbing a path will - increase your build times in proportion to the size of the associated - collection directory. + Please note that globbing a path is known to have a negative effect on + performance and is currently not optimized, especially on Windows. + Globbing a path will increase your build times in proportion to the size + of the associated collection directory.