lib/xcpretty/parser.rb in xcpretty-0.1.4 vs lib/xcpretty/parser.rb in xcpretty-0.1.5
- old
+ new
@@ -14,14 +14,10 @@
BUILD_TARGET_MATCHER = /^=== BUILD TARGET\s(.*)\sOF PROJECT\s(.*)\sWITH.*CONFIGURATION\s(.*)\s===/
# @regex Nothing returned here for now
CHECK_DEPENDENCIES_MATCHER = /^Check dependencies/
- # @regex Captured groups
- # $1 = whole error
- CLANG_ERROR_MATCHER = /^(clang: error:.*)$/
-
# @regex Nothing returned here for now
CLEAN_REMOVE_MATCHER = /^Clean.Remove/
# @regex Captured groups
# $1 target
@@ -36,23 +32,17 @@
# @regex Captured groups
# $1 = file
CODESIGN_FRAMEWORK_MATCHER = /^CodeSign\s((?:\\ |[^ ])*.framework)\/Versions/
# @regex Captured groups
- # $1 = whole error
- CODESIGN_ERROR_MATCHER = /^(Code\s?Sign error:.*)$/
-
- # @regex Captured groups
# $1 file_path
# $2 file_name (e.g. KWNull.m)
COMPILE_MATCHER = /^CompileC\s.*\s(.*\/(.*\.(?:m|mm|c|cc|cpp|cxx)))\s.*/
# @regex Captured groups
- # $1 = file_path
- # $2 = file_name
- # $3 = reason
- COMPILE_ERROR_MATCHER = /^(\/.+\/(.*):.*:.*):(?:\sfatal)?\serror:\s(.*)$/
+ # $1 compiler_command
+ COMPILE_COMMAND_MATCHER = /^\s*(.*\/usr\/bin\/clang\s.*\.o)$/
# @regex Captured groups
# $1 file_path
# $2 file_name (e.g. MainMenu.xib)
COMPILE_XIB_MATCHER = /^CompileXIB\s(.*\/(.*\.xib))/
@@ -64,14 +54,10 @@
# @regex Captured groups
# $1 resource
CPRESOURCE_MATCHER = /^CpResource\s(.*)\s\//
# @regex Captured groups
- # $1 cursor (with whitespaces and tildes)
- CURSOR_MATCHER = /^([\s~]*\^[\s~]*)$/
-
- # @regex Captured groups
#
EXECUTED_MATCHER = /^\s*Executed/
# @regex Captured groups
# $1 = file
@@ -79,31 +65,18 @@
# $3 = test_case
# $4 = reason
FAILING_TEST_MATCHER = /^\s*(.+:\d+):\serror:\s[\+\-]\[(.*)\s(.*)\]\s:(?:\s'.*'\s\[FAILED\],)?\s(.*)/
# @regex Captured groups
- # $1 = whole error.
- # it varies a lot, not sure if it makes sense to catch everything separately
- FATAL_ERROR_MATCHER = /^(fatal error:.*)$/
-
- # @regex Captured groups
# $1 = dsym
GENERATE_DSYM_MATCHER = /^GenerateDSYMFile \/.*\/(.*\.dSYM)/
# @regex Captured groups
# $1 = library
LIBTOOL_MATCHER = /^Libtool.*\/(.*\.a)/
# @regex Captured groups
- # $1 = whole error
- LD_ERROR_MATCHER = /^(ld:.*not found for.*)/
-
- # @regex Captured groups
- # $1 reason
- LINKER_FAILURE_MATCHER = /^(Undefined symbols for architecture .*):$/
-
- # @regex Captured groups
# $1 = target
# $2 = build_variants (normal, profile, debug)
# $3 = architecture
LINKING_MATCHER = /^Ld \/.*\/(.*) (.*) (.*)$/
@@ -121,13 +94,10 @@
# @regex Captured groups
# $1 = script_name
PHASE_SCRIPT_EXECUTION_MATCHER = /^PhaseScriptExecution\s(.*)\s\//
# @regex Captured groups
- PODS_ERROR_MATCHER = /^error:\s(.*)/
-
- # @regex Captured groups
# $1 = file
PROCESS_PCH_MATCHER = /^ProcessPCH\s.*\s(.*.pch)/
# @regex Captured groups
# $1 = file
@@ -140,14 +110,10 @@
# @regex Captured groups
# $1 = file
PROCESS_INFO_PLIST_MATCHER = /^ProcessInfoPlistFile\s.*\.plist\s(.*\/+(.*\.plist))/
# @regex Captured groups
- # $1 = reference
- SYMBOL_REFERENCED_FROM_MATCHER = /\s+"(.*)", referenced from:$/
-
- # @regex Captured groups
# $1 = suite
# $2 = time
TESTS_RUN_COMPLETION_MATCHER = /^\s*Test Suite '(?:.*\/)?(.*[ox]ctest.*)' finished at (.*)/
# @regex Captured groups
@@ -165,15 +131,69 @@
# @regex Captured groups
# $1 file_path
# $2 file_name
TOUCH_MATCHER = /^Touch\s(.*\/([\w+\.]+))/
+
+ module Errors
+ # @regex Captured groups
+ # $1 = whole error
+ CLANG_ERROR_MATCHER = /^(clang: error:.*)$/
+
+ # @regex Captured groups
+ # $1 = whole error
+ CODESIGN_ERROR_MATCHER = /^(Code\s?Sign error:.*)$/
+
+ # @regex Captured groups
+ # $1 = file_path
+ # $2 = file_name
+ # $3 = reason
+ COMPILE_ERROR_MATCHER = /^(\/.+\/(.*):.*:.*):(?:\sfatal)?\serror:\s(.*)$/
+
+ # @regex Captured groups
+ # $1 cursor (with whitespaces and tildes)
+ CURSOR_MATCHER = /^([\s~]*\^[\s~]*)$/
+
+ # @regex Captured groups
+ # $1 = whole error.
+ # it varies a lot, not sure if it makes sense to catch everything separately
+ FATAL_ERROR_MATCHER = /^(fatal error:.*)$/
+
+ # @regex Captured groups
+ # $1 = whole error
+ LD_ERROR_MATCHER = /^(ld:.*not found for.*)/
+
+ # @regex Captured groups
+ # $1 file path
+ LINKER_DUPLICATE_SYMBOLS_LOCATION_MATCHER = /^\s+(\/.*\.o[\)]?)$/
+
+ # @regex Captured groups
+ # $1 reason
+ LINKER_DUPLICATE_SYMBOLS_MATCHER = /^(duplicate symbol .*):$/
+
+ # @regex Captured groups
+ # $1 symbol location
+ LINKER_UNDEFINED_SYMBOL_LOCATION_MATCHER = /^(.* in .*\.o)$/
+
+ # @regex Captured groups
+ # $1 reason
+ LINKER_UNDEFINED_SYMBOLS_MATCHER = /^(Undefined symbols for architecture .*):$/
+
+ # @regex Captured groups
+ PODS_ERROR_MATCHER = /^error:\s(.*)/
+
+ # @regex Captured groups
+ # $1 = reference
+ SYMBOL_REFERENCED_FROM_MATCHER = /\s+"(.*)", referenced from:$/
+ end
end
class Parser
include Matchers
+ include Matchers::Errors
+
attr_reader :formatter
def initialize(formatter)
@formatter = formatter
end
@@ -182,11 +202,12 @@
update_test_state(text)
update_error_state(text)
update_linker_failure_state(text)
return format_compile_error if should_format_error?
- return format_linker_failure if should_format_linker_failure?
+ return format_undefined_symbols if should_format_undefined_symbols?
+ return format_duplicate_symbols if should_format_duplicate_symbols?
case text
when ANALYZE_MATCHER
formatter.format_analyze($2, $1)
when BUILD_TARGET_MATCHER
@@ -207,10 +228,12 @@
formatter.format_codesign($1)
when CODESIGN_ERROR_MATCHER
formatter.format_error($1)
when COMPILE_MATCHER
formatter.format_compile($2, $1)
+ when COMPILE_COMMAND_MATCHER
+ formatter.format_compile_command($1)
when COMPILE_XIB_MATCHER
formatter.format_compile_xib($2, $1)
when CPRESOURCE_MATCHER
formatter.format_cpresource($1)
when EXECUTED_MATCHER
@@ -287,38 +310,50 @@
current_error[:line] = text.chomp
end
end
def update_linker_failure_state(text)
- if text =~ LINKER_FAILURE_MATCHER
- @formatting_linker_error = true
+ if text =~ LINKER_UNDEFINED_SYMBOLS_MATCHER ||
+ text =~ LINKER_DUPLICATE_SYMBOLS_MATCHER
+
current_linker_failure[:message] = $1
- elsif text =~ SYMBOL_REFERENCED_FROM_MATCHER
+ @formatting_linker_failure = true
+ end
+ return unless @formatting_linker_failure
+
+ case text
+ when SYMBOL_REFERENCED_FROM_MATCHER
current_linker_failure[:symbol] = $1
- elsif @formatting_linker_error
+ when LINKER_UNDEFINED_SYMBOL_LOCATION_MATCHER
current_linker_failure[:reference] = text.strip
- @formatting_linker_error = false
+ when LINKER_DUPLICATE_SYMBOLS_LOCATION_MATCHER
+ current_linker_failure[:files] << $1
end
end
# TODO: clean up the mess around all this
def should_format_error?
current_error[:reason] && current_error[:cursor] && current_error[:line]
end
- def should_format_linker_failure?
+ def should_format_undefined_symbols?
current_linker_failure[:message] &&
current_linker_failure[:symbol] &&
current_linker_failure[:reference]
end
+ def should_format_duplicate_symbols?
+ current_linker_failure[:message] &&
+ current_linker_failure[:files].count > 1
+ end
+
def current_error
@current_error ||= {}
end
def current_linker_failure
- @linker_failure ||= {}
+ @linker_failure ||= { :files => [] }
end
def format_compile_error
error = current_error.dup
@current_error = {}
@@ -327,15 +362,31 @@
error[:reason],
error[:line],
error[:cursor])
end
- def format_linker_failure
- failure = current_linker_failure.dup
- @linker_failure = {}
- formatter.format_linker_failure(failure[:message],
- failure[:symbol],
- failure[:reference])
+ def format_undefined_symbols
+ result = formatter.format_undefined_symbols(
+ current_linker_failure[:message],
+ current_linker_failure[:symbol],
+ current_linker_failure[:reference]
+ )
+ reset_linker_format_state
+ result
+ end
+
+ def format_duplicate_symbols
+ result = formatter.format_duplicate_symbols(
+ current_linker_failure[:message],
+ current_linker_failure[:files]
+ )
+ reset_linker_format_state
+ result
+ end
+
+ def reset_linker_format_state
+ @linker_failure = nil
+ @formatting_linker_failure = false
end
def store_failure(file, test_suite, test_case, reason)
failures_per_suite[test_suite] ||= []
failures_per_suite[test_suite] << {