Add option to fail a build with front matter syntax errors (#5832)

Merge pull request 5832
This commit is contained in:
Jonathan Hooper 2017-05-09 19:17:36 -05:00 committed by jekyllbot
parent 86d2b77f3b
commit 308ba550ef
8 changed files with 109 additions and 49 deletions

View File

@ -305,6 +305,18 @@ class="flag">flags</code> (specified on the command-line) that control them.
<p><code class="flag">--profile</code></p>
</td>
</tr>
<tr class="setting">
<td>
<p class="name"><strong>Strict Front Matter</strong></p>
<p class="description">
Cause a build to fail if there is a YAML syntax error in a page's front matter.
</p>
</td>
<td class="align-center">
<p><code class="option">strict_front_matter: BOOL</code></p>
<p><code class="flag">--strict_front_matter</code></p>
</td>
</tr>
</tbody>
</table>
</div>
@ -601,12 +613,13 @@ collections:
output: true
# Handling Reading
safe: false
include: [".htaccess"]
exclude: ["Gemfile", "Gemfile.lock", "node_modules", "vendor/bundle/", "vendor/cache/", "vendor/gems/", "vendor/ruby/"]
keep_files: [".git", ".svn"]
encoding: "utf-8"
markdown_ext: "markdown,mkdown,mkdn,mkd,md"
safe: false
include: [".htaccess"]
exclude: ["Gemfile", "Gemfile.lock", "node_modules", "vendor/bundle/", "vendor/cache/", "vendor/gems/", "vendor/ruby/"]
keep_files: [".git", ".svn"]
encoding: "utf-8"
markdown_ext: "markdown,mkdown,mkdn,mkd,md"
strict_front_matter: false
# Filtering Content
show_drafts: null

View File

@ -46,6 +46,7 @@ module Jekyll
# c - the Jekyll::Command to add these options to
#
# Returns nothing
# rubocop:disable Metrics/MethodLength
def add_build_options(c)
c.option "config", "--config CONFIG_FILE[,CONFIG_FILE2,...]",
Array, "Custom configuration file"
@ -66,7 +67,10 @@ module Jekyll
c.option "quiet", "-q", "--quiet", "Silence output."
c.option "verbose", "-V", "--verbose", "Print verbose output."
c.option "incremental", "-I", "--incremental", "Enable incremental rebuild."
c.option "strict_front_matter", "--strict_front_matter",
"Fail if errors are present in front matter"
end
# rubocop:enable Metrics/MethodLength
end
end
end

View File

@ -6,71 +6,72 @@ module Jekyll
# Strings rather than symbols are used for compatibility with YAML.
DEFAULTS = Configuration[{
# Where things are
"source" => Dir.pwd,
"destination" => File.join(Dir.pwd, "_site"),
"plugins_dir" => "_plugins",
"layouts_dir" => "_layouts",
"data_dir" => "_data",
"includes_dir" => "_includes",
"collections" => {},
"source" => Dir.pwd,
"destination" => File.join(Dir.pwd, "_site"),
"plugins_dir" => "_plugins",
"layouts_dir" => "_layouts",
"data_dir" => "_data",
"includes_dir" => "_includes",
"collections" => {},
# Handling Reading
"safe" => false,
"include" => [".htaccess"],
"exclude" => %w(
"safe" => false,
"include" => [".htaccess"],
"exclude" => %w(
Gemfile Gemfile.lock node_modules vendor/bundle/ vendor/cache/ vendor/gems/
vendor/ruby/
),
"keep_files" => [".git", ".svn"],
"encoding" => "utf-8",
"markdown_ext" => "markdown,mkdown,mkdn,mkd,md",
"keep_files" => [".git", ".svn"],
"encoding" => "utf-8",
"markdown_ext" => "markdown,mkdown,mkdn,mkd,md",
"strict_front_matter" => false,
# Filtering Content
"show_drafts" => nil,
"limit_posts" => 0,
"future" => false,
"unpublished" => false,
"show_drafts" => nil,
"limit_posts" => 0,
"future" => false,
"unpublished" => false,
# Plugins
"whitelist" => [],
"plugins" => [],
"whitelist" => [],
"plugins" => [],
# Conversion
"markdown" => "kramdown",
"highlighter" => "rouge",
"lsi" => false,
"excerpt_separator" => "\n\n",
"incremental" => false,
"markdown" => "kramdown",
"highlighter" => "rouge",
"lsi" => false,
"excerpt_separator" => "\n\n",
"incremental" => false,
# Serving
"detach" => false, # default to not detaching the server
"port" => "4000",
"host" => "127.0.0.1",
"baseurl" => "",
"show_dir_listing" => false,
"detach" => false, # default to not detaching the server
"port" => "4000",
"host" => "127.0.0.1",
"baseurl" => "",
"show_dir_listing" => false,
# Output Configuration
"permalink" => "date",
"paginate_path" => "/page:num",
"timezone" => nil, # use the local timezone
"permalink" => "date",
"paginate_path" => "/page:num",
"timezone" => nil, # use the local timezone
"quiet" => false,
"verbose" => false,
"defaults" => [],
"quiet" => false,
"verbose" => false,
"defaults" => [],
"liquid" => {
"liquid" => {
"error_mode" => "warn",
},
"rdiscount" => {
"rdiscount" => {
"extensions" => [],
},
"redcarpet" => {
"redcarpet" => {
"extensions" => [],
},
"kramdown" => {
"kramdown" => {
"auto_ids" => true,
"toc_levels" => "1..6",
"entity_output" => "as_char",

View File

@ -48,8 +48,10 @@ module Jekyll
end
rescue SyntaxError => e
Jekyll.logger.warn "YAML Exception reading #{filename}: #{e.message}"
raise e if self.site.config["strict_front_matter"]
rescue => e
Jekyll.logger.warn "Error reading file #{filename}: #{e.message}"
raise e if self.site.config["strict_front_matter"]
end
self.data ||= {}

View File

@ -259,11 +259,8 @@ module Jekyll
merge_defaults
read_content(opts)
read_post_data
rescue SyntaxError => e
Jekyll.logger.error "Error:", "YAML Exception reading #{path}: #{e.message}"
rescue => e
raise e if e.is_a? Jekyll::Errors::FatalException
Jekyll.logger.error "Error:", "could not read file #{path}: #{e.message}"
handle_read_error(e)
end
end
end
@ -457,6 +454,19 @@ module Jekyll
generate_excerpt
end
private
def handle_read_error(error)
if error.is_a? SyntaxError
Jekyll.logger.error "Error:", "YAML Exception reading #{path}: #{error.message}"
else
Jekyll.logger.error "Error:", "could not read file #{path}: #{error.message}"
end
if site.config["strict_front_matter"] || error.is_a?(Jekyll::Errors::FatalException)
raise error
end
end
private
def populate_title
if relative_path =~ DATE_FILENAME_MATCHER

View File

@ -0,0 +1,4 @@
---
bad yaml: [
---
Real content starts here

View File

@ -33,6 +33,14 @@ class TestConvertible < JekyllUnitTest
assert_match(%r!#{File.join(@base, name)}!, out)
end
should "raise for broken front matter with `strict_front_matter` set" do
name = "broken_front_matter2.erb"
@convertible.site.config["strict_front_matter"] = true
assert_raises do
@convertible.read_yaml(@base, name)
end
end
should "not allow ruby objects in YAML" do
out = capture_stderr do
@convertible.read_yaml(@base, "exploit_front_matter.erb")

View File

@ -280,6 +280,24 @@ class TestSite < JekyllUnitTest
Site.new(site_configuration("destination" => File.join(source_dir, "..")))
end
end
should "raise for bad frontmatter if strict_front_matter is set" do
site = Site.new(site_configuration(
"collections" => ["broken"],
"strict_front_matter" => true
))
assert_raises do
site.process
end
end
should "not raise for bad frontmatter if strict_front_matter is not set" do
site = Site.new(site_configuration(
"collections" => ["broken"],
"strict_front_matter" => false
))
site.process
end
end
context "with orphaned files in destination" do