diff --git a/app/lib/linting/linter.rb b/app/lib/linting/linter.rb index d88de75..61630f2 100644 --- a/app/lib/linting/linter.rb +++ b/app/lib/linting/linter.rb @@ -20,7 +20,7 @@ def lint(options: {}) output end - def lint_with_ui(options:, show_ui: true) # rubocop:disable Metrics/MethodLength + def lint_with_ui(options:, show_ui: true) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize with_spinner(title: 'Checking {{bold:publish.yaml}} exists', show: show_ui) do check_publish_file_exists end @@ -31,6 +31,11 @@ def lint_with_ui(options:, show_ui: true) # rubocop:disable Metrics/MethodLength end return unless annotations.blank? + with_spinner(title: 'Attempting to parse book', show: show_ui) do + book + end + return unless annotations.blank? + with_spinner(title: 'Validating image references', show: show_ui) do annotations.concat(Linting::ImageLinter.new(book: book).lint) end @@ -78,11 +83,23 @@ def check_publish_file_exists false end - def book + def book # rubocop:disable Metrics/MethodLength @book ||= begin parser = Parser::Publish.new(file: file) parser.parse end + rescue Parser::Error => e + line_number = (e.message.match(/at line (\d+)/)&.captures&.first&.to_i || 0) + 1 + annotations.push( + Annotation.new( + absolute_path: e.file, + annotation_level: 'failure', + start_line: line_number, + end_line: line_number, + message: e.message, + title: 'Unable to parse book.' + ) + ) end end end diff --git a/app/lib/parser/error.rb b/app/lib/parser/error.rb new file mode 100644 index 0000000..d6e66be --- /dev/null +++ b/app/lib/parser/error.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module Parser + # An error for capturing parsing issues + class Error < StandardError + attr_reader :file + + def initialize(file:, error: nil, msg: nil) + message = "There was a problem parsing #{file}" + message += "\n#{error.class.name}\n#{error.message}" if error.present? + message += "\n#{msg}" if msg.present? + + super(message) + @file = file + end + end +end diff --git a/app/lib/parser/markdown_metadata.rb b/app/lib/parser/markdown_metadata.rb index aa7ef55..84b1f38 100644 --- a/app/lib/parser/markdown_metadata.rb +++ b/app/lib/parser/markdown_metadata.rb @@ -12,7 +12,13 @@ def extract_metadata end def metadata - @metadata ||= Psych.load(extract_metadata).deep_symbolize_keys + @metadata ||= begin + Psych.load(extract_metadata, symbolize_names: true).tap do |metadata| + raise Parser::Error.new(file: path, msg: 'Unable to locate metadata at the top of the markdown') unless metadata.present? + end + end + rescue Psych::SyntaxError => e + raise Parser::Error.new(file: path, error: e) end def simple_attributes