lib/xcpretty/parser.rb in xcpretty-0.1.7 vs lib/xcpretty/parser.rb in xcpretty-0.1.8

- old
+ new

@@ -14,10 +14,15 @@ 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 command path + # $2 arguments + SHELL_COMMAND_MATCHER = /^\s{4}(cd|setenv|(?:[\w\/:\\\s\-.]+?\/)?[\w\-]+)\s(.*)$/ + # @regex Nothing returned here for now CLEAN_REMOVE_MATCHER = /^Clean.Remove/ # @regex Captured groups # $1 target @@ -34,22 +39,32 @@ CODESIGN_FRAMEWORK_MATCHER = /^CodeSign\s((?:\\ |[^ ])*.framework)\/Versions/ # @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.*/ + COMPILE_MATCHER = /^CompileC\s.+?\s((?:\\.|[^ ])+\/((?:\\.|[^ ])+\.(?:m|mm|c|cc|cpp|cxx)))\s.*/ # @regex Captured groups # $1 compiler_command - COMPILE_COMMAND_MATCHER = /^\s*(.*\/usr\/bin\/clang\s.*\.o)$/ + # $2 file_path + COMPILE_COMMAND_MATCHER = /^\s*(.*\/usr\/bin\/clang\s.*\s\-c\s(.*\.(?:m|mm|c|cc|cpp|cxx))\s.*\.o)$/ # @regex Captured groups # $1 file_path # $2 file_name (e.g. MainMenu.xib) COMPILE_XIB_MATCHER = /^CompileXIB\s(.*\/(.*\.xib))/ # @regex Captured groups + # $1 source file + # $2 target file + COPY_HEADER_MATCHER = /^CpHeader\s(.*\.h)\s(.*\.h)/ + + # @regex Captured groups + # $1 source file + # $2 target file + COPY_PLIST_MATCHER = /^CopyPlistFile\s(.*\.plist)\s(.*\.plist)/ + # $1 file COPY_STRINGS_MATCHER = /^CopyStringsFile.*\/(.*.strings)/ # @regex Captured groups # $1 resource @@ -90,18 +105,28 @@ # $1 = suite # $2 = test_case PENDING_TEST_MATCHER = /^Test Case\s'-\[(.*)\s(.*)PENDING\]'\spassed/ # @regex Captured groups + # $1 = suite + # $2 = test_case + # $3 = time + MEASURING_TEST_MATCHER = /^[^:]*:[^:]*:\sTest Case\s'-\[(.*)\s(.*)\]'\smeasured\s\[Time,\sseconds\]\saverage:\s(\d*\.\d{3}),/ + + # @regex Captured groups # $1 = script_name PHASE_SCRIPT_EXECUTION_MATCHER = /^PhaseScriptExecution\s(.*)\s\// # @regex Captured groups # $1 = file PROCESS_PCH_MATCHER = /^ProcessPCH\s.*\s(.*.pch)/ # @regex Captured groups + # $1 file_path + PROCESS_PCH_COMMAND_MATCHER = /^\s*.*\/usr\/bin\/clang\s.*\s\-c\s(.*)\s\-o\s.*/ + + # @regex Captured groups # $1 = file PREPROCESS_MATCHER = /^Preprocess\s(?:(?:\\ |[^ ])*)\s((?:\\ |[^ ])*)$/ # @regex Captured groups # $1 = file @@ -132,10 +157,28 @@ # @regex Captured groups # $1 file_path # $2 file_name TOUCH_MATCHER = /^Touch\s(.*\/([\w+\.]+))/ + # @regex Captured groups + # $1 file_path + WRITE_FILE_MATCHER = /^write-file\s(.*)/ + + # @regex Captured groups + WRITE_AUXILIARY_FILES = /^Write auxiliary files/ + + module Warnings + # $1 = file_path + # $2 = file_name + # $3 = reason + COMPILE_WARNING_MATCHER = /^(\/.+\/(.*):.*:.*):\swarning:\s(.*)$/ + + # @regex Captured groups + # $1 = whole warning + GENERIC_WARNING_MATCHER = /^warning:\s(.*)$/ + end + module Errors # @regex Captured groups # $1 = whole error CLANG_ERROR_MATCHER = /^(clang: error:.*)$/ @@ -145,22 +188,21 @@ # @regex Captured groups # $1 = file_path # $2 = file_name # $3 = reason - COMPILE_ERROR_MATCHER = /^(\/.+\/(.*):.*:.*):(?:\sfatal)?\serror:\s(.*)$/ + COMPILE_ERROR_MATCHER = /^(\/.+\/(.*):.*:.*):\s(?:fatal\s)?error:\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 @@ -189,10 +231,11 @@ class Parser include Matchers include Matchers::Errors + include Matchers::Warnings attr_reader :formatter def initialize(formatter) @formatter = formatter @@ -202,10 +245,11 @@ update_test_state(text) update_error_state(text) update_linker_failure_state(text) return format_compile_error if should_format_error? + return format_compile_warning if should_format_warning? return format_undefined_symbols if should_format_undefined_symbols? return format_duplicate_symbols if should_format_duplicate_symbols? case text when ANALYZE_MATCHER @@ -229,13 +273,17 @@ 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) + formatter.format_compile_command($1, $2) when COMPILE_XIB_MATCHER formatter.format_compile_xib($2, $1) + when COPY_HEADER_MATCHER + formatter.format_copy_header_file($1, $2) + when COPY_PLIST_MATCHER + formatter.format_copy_plist_file($1, $2) when CPRESOURCE_MATCHER formatter.format_cpresource($1) when EXECUTED_MATCHER format_summary_if_needed(text) when FAILING_TEST_MATCHER @@ -248,10 +296,12 @@ formatter.format_error($1) when LIBTOOL_MATCHER formatter.format_libtool($1) when LINKING_MATCHER formatter.format_linking($1, $2, $3) + when MEASURING_TEST_MATCHER + formatter.format_measuring_test($1, $2, $3) when PENDING_TEST_MATCHER formatter.format_pending_test($1, $2) when PASSING_TEST_MATCHER formatter.format_passing_test($1, $2, $3) when PODS_ERROR_MATCHER @@ -260,10 +310,12 @@ formatter.format_process_info_plist(*unescaped($2, $1)) when PHASE_SCRIPT_EXECUTION_MATCHER formatter.format_phase_script_execution(*unescaped($1)) when PROCESS_PCH_MATCHER formatter.format_process_pch($1) + when PROCESS_PCH_COMMAND_MATCHER + formatter.format_process_pch_command($1) when PREPROCESS_MATCHER formatter.format_preprocess($1) when PBXCP_MATCHER formatter.format_pbxcp($1) when TESTS_RUN_COMPLETION_MATCHER @@ -274,10 +326,18 @@ formatter.format_test_suite_started($1) when TIFFUTIL_MATCHER formatter.format_tiffutil($1) when TOUCH_MATCHER formatter.format_touch($1, $2) + when WRITE_FILE_MATCHER + formatter.format_write_file($1) + when WRITE_AUXILIARY_FILES + formatter.format_write_auxiliary_files + when SHELL_COMMAND_MATCHER + formatter.format_shell_command($1, $2) + when GENERIC_WARNING_MATCHER + formatter.format_warning($1) else "" end end @@ -296,20 +356,25 @@ end end # @ return Hash { :file_name, :file_path, :reason, :line } def update_error_state(text) + update_error = lambda { + current_issue[:reason] = $3 + current_issue[:file_path] = $1 + current_issue[:file_name] = $2 + } if text =~ COMPILE_ERROR_MATCHER @formatting_error = true - current_error[:reason] = $3 - current_error[:file_path] = $1 - current_error[:file_name] = $2 + update_error.call + elsif text =~ COMPILE_WARNING_MATCHER + @formatting_warning = true + update_error.call elsif text =~ CURSOR_MATCHER - @formatting_error = false - current_error[:cursor] = $1.chomp - elsif @formatting_error - current_error[:line] = text.chomp + current_issue[:cursor] = $1.chomp + elsif @formatting_error || @formatting_warning + current_issue[:line] = text.chomp end end def update_linker_failure_state(text) if text =~ LINKER_UNDEFINED_SYMBOLS_MATCHER || @@ -330,13 +395,21 @@ end end # TODO: clean up the mess around all this def should_format_error? - current_error[:reason] && current_error[:cursor] && current_error[:line] + @formatting_error && error_or_warning_is_present end + def should_format_warning? + @formatting_warning && error_or_warning_is_present + end + + def error_or_warning_is_present + current_issue[:reason] && current_issue[:cursor] && current_issue[:line] + end + def should_format_undefined_symbols? current_linker_failure[:message] && current_linker_failure[:symbol] && current_linker_failure[:reference] end @@ -344,28 +417,40 @@ def should_format_duplicate_symbols? current_linker_failure[:message] && current_linker_failure[:files].count > 1 end - def current_error - @current_error ||= {} + def current_issue + @current_issue ||= {} end def current_linker_failure @linker_failure ||= { :files => [] } end def format_compile_error - error = current_error.dup - @current_error = {} + error = current_issue.dup + @current_issue = {} + @formatting_error = false formatter.format_compile_error(error[:file_name], error[:file_path], error[:reason], error[:line], error[:cursor]) end + def format_compile_warning + warning = current_issue.dup + @current_issue = {} + @formatting_warning = false + formatter.format_compile_warning(warning[:file_name], + warning[:file_path], + warning[:reason], + warning[:line], + warning[:cursor]) + end + def format_undefined_symbols result = formatter.format_undefined_symbols( current_linker_failure[:message], current_linker_failure[:symbol], current_linker_failure[:reference] @@ -416,6 +501,5 @@ escaped_values.map { |v| v.gsub('\\', '') } end end end -