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>
@ -607,6 +619,7 @@ exclude: ["Gemfile", "Gemfile.lock", "node_modules", "vendor/bundle/", "ven
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

@ -24,6 +24,7 @@ module Jekyll
"keep_files" => [".git", ".svn"],
"encoding" => "utf-8",
"markdown_ext" => "markdown,mkdown,mkdn,mkd,md",
"strict_front_matter" => false,
# Filtering Content
"show_drafts" => nil,

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