From b24bdad056a49859b5f005cb4c69710f9afd5ba6 Mon Sep 17 00:00:00 2001 From: Taufek Johar Date: Mon, 12 Feb 2018 23:21:16 +0800 Subject: [PATCH] Extract Out PreCommit Message Methods to Utils Extracted PreCommit context message processor methods to Utils module. This is a step closer to make these PreCommit hooks usable on other context. --- lib/overcommit/hook/pre_commit/base.rb | 68 ++--------------------- lib/overcommit/utils/messages_utils.rb | 75 ++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 65 deletions(-) create mode 100644 lib/overcommit/utils/messages_utils.rb diff --git a/lib/overcommit/hook/pre_commit/base.rb b/lib/overcommit/hook/pre_commit/base.rb index 7d53d565..e1a7b3d5 100644 --- a/lib/overcommit/hook/pre_commit/base.rb +++ b/lib/overcommit/hook/pre_commit/base.rb @@ -1,4 +1,5 @@ require 'forwardable' +require 'overcommit/utils/messages_utils' module Overcommit::Hook::PreCommit # Functionality common to all pre-commit hooks. @@ -9,71 +10,8 @@ class Base < Overcommit::Hook::Base private - # Extract file, line number, and type of message from an error/warning - # messages in output. - # - # Assumes each element of `output` is a separate error/warning with all - # information necessary to identify it. - # - # @param output_messages [Array] unprocessed error/warning messages - # @param regex [Regexp] regular expression defining `file`, `line` and - # `type` capture groups used to extract file locations and error/warning - # type from each line of output - # @param type_categorizer [Proc] function executed against the `type` - # capture group to convert it to a `:warning` or `:error` symbol. Assumes - # `:error` if `nil`. - # @raise [Overcommit::Exceptions::MessageProcessingError] line of output did - # not match regex - # @return [Array] - def extract_messages(output_messages, regex, type_categorizer = nil) - output_messages.map.with_index do |message, index| - unless match = message.match(regex) - raise Overcommit::Exceptions::MessageProcessingError, - 'Unexpected output: unable to determine line number or type ' \ - "of error/warning for output:\n" \ - "#{output_messages[index..-1].join("\n")}" - end - - file = extract_file(match, message) - line = extract_line(match, message) if match.names.include?('line') && match[:line] - type = extract_type(match, message, type_categorizer) - - Overcommit::Hook::Message.new(type, file, line, message) - end - end - - def extract_file(match, message) - return unless match.names.include?('file') - - if match[:file].to_s.empty? - raise Overcommit::Exceptions::MessageProcessingError, - "Unexpected output: no file found in '#{message}'" - end - - match[:file] - end - - def extract_line(match, message) - return unless match.names.include?('line') - Integer(match[:line]) - rescue ArgumentError, TypeError - raise Overcommit::Exceptions::MessageProcessingError, - "Unexpected output: invalid line number found in '#{message}'" - end - - def extract_type(match, message, type_categorizer) - if type_categorizer - type_match = match.names.include?('type') ? match[:type] : nil - type = type_categorizer.call(type_match) - unless Overcommit::Hook::MESSAGE_TYPES.include?(type) - raise Overcommit::Exceptions::MessageProcessingError, - "Invalid message type '#{type}' for '#{message}': must " \ - "be one of #{Overcommit::Hook::MESSAGE_TYPES.inspect}" - end - type - else - :error # Assume error since no categorizer was defined - end + def extract_messages(*args) + Overcommit::Utils::MessagesUtils.extract_messages(*args) end end end diff --git a/lib/overcommit/utils/messages_utils.rb b/lib/overcommit/utils/messages_utils.rb new file mode 100644 index 00000000..caca39d2 --- /dev/null +++ b/lib/overcommit/utils/messages_utils.rb @@ -0,0 +1,75 @@ +module Overcommit::Utils + # Utility to process messages + module MessagesUtils + class << self + # Extract file, line number, and type of message from an error/warning + # messages in output. + # + # Assumes each element of `output` is a separate error/warning with all + # information necessary to identify it. + # + # @param output_messages [Array] unprocessed error/warning messages + # @param regex [Regexp] regular expression defining `file`, `line` and + # `type` capture groups used to extract file locations and error/warning + # type from each line of output + # @param type_categorizer [Proc] function executed against the `type` + # capture group to convert it to a `:warning` or `:error` symbol. Assumes + # `:error` if `nil`. + # @raise [Overcommit::Exceptions::MessageProcessingError] line of output did + # not match regex + # @return [Array] + def extract_messages(output_messages, regex, type_categorizer = nil) + output_messages.map.with_index do |message, index| + unless match = message.match(regex) + raise Overcommit::Exceptions::MessageProcessingError, + 'Unexpected output: unable to determine line number or type ' \ + "of error/warning for output:\n" \ + "#{output_messages[index..-1].join("\n")}" + end + + file = extract_file(match, message) + line = extract_line(match, message) if match.names.include?('line') && match[:line] + type = extract_type(match, message, type_categorizer) + + Overcommit::Hook::Message.new(type, file, line, message) + end + end + + private + + def extract_file(match, message) + return unless match.names.include?('file') + + if match[:file].to_s.empty? + raise Overcommit::Exceptions::MessageProcessingError, + "Unexpected output: no file found in '#{message}'" + end + + match[:file] + end + + def extract_line(match, message) + return unless match.names.include?('line') + Integer(match[:line]) + rescue ArgumentError, TypeError + raise Overcommit::Exceptions::MessageProcessingError, + "Unexpected output: invalid line number found in '#{message}'" + end + + def extract_type(match, message, type_categorizer) + if type_categorizer + type_match = match.names.include?('type') ? match[:type] : nil + type = type_categorizer.call(type_match) + unless Overcommit::Hook::MESSAGE_TYPES.include?(type) + raise Overcommit::Exceptions::MessageProcessingError, + "Invalid message type '#{type}' for '#{message}': must " \ + "be one of #{Overcommit::Hook::MESSAGE_TYPES.inspect}" + end + type + else + :error # Assume error since no categorizer was defined + end + end + end + end +end