I'm working on a Vim compiler plugin for PHPUnit.
I've written the following errorformat
. The error message is correctly extracted, but file and line numbers are not.
CompilerSet errorformat=%E%n)\ %.%#,
\%C%m,
\%+C%$,
\%C%f:%l,
\%Z%$
PHPUnit's output looks something like this:
PHPUnit 3.5.12 by Sebastian Bergmann.
............................................................... 63 / 134 ( 47%)
.........................E.....
Time: 0 seconds, Memory: 11.25Mb
There was 1 error:
1) SomeClassTest::testSomething
Undefined property: SomeClass::$var
/path/to/SomeClass.php:99
/path/to/SomeClassTest.php:15
FAILURES!
Tests: 94, Assertions: 170, Errors: 1.
Press ENTER or type command to continue
I'm happy for the reported file and line to be either the first or last entry in the stack trace. The deepest call is the actual source of the issue. Jumping to the top-level call means I can use to step down into the call stack. I would prefer the latter, SomeClassTest.php:15
in the example above.
I think the problem is the phrasing of the %Z
rule. First I came up with this:
:set errorformat=%E%n)\ %.%#,%Z%f:%l,%C%m,%-G%.%#
That'll catch the first filename and associate that with the error message.
For some reason, association the last filename mentioned was a whole lot harder. I wasn't able to do it with efm
, but instead hacked together this Python filter:
import sys
import re
errors = []
OTHER = 0
MESSAGE = 1
FILE_LINE = 2
next_is = OTHER
lines = sys.stdin.readlines()
for line in lines:
line = line.strip()
if (next_is == OTHER):
if (re.search("^[0-9]+\)", line)):
next_is = MESSAGE
elif (next_is == MESSAGE):
errors.append([line, ''])
next_is = FILE_LINE
elif (next_is == FILE_LINE):
if (re.search("^.+:[0-9]+", line)):
errors[-1][1] = line
elif (len(line) == 0 and len(errors[-1][1]) > 0):
next_is = OTHER
for error in errors:
print "{0}:{1}".format(error[1], error[0])
This will capture all the errors and output them in a single-line format. The associated filename and line number are the last ones mentioned for the error. This script clobbers all other output, but that'd be solved by adding e.g. a print line
after line = line.strip()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With