Reputation: 1406
I run cppcheck on my code in TeamCity and want to report its errors as build problems. So I changed the cppcheck output format to
"##teamcity[buildProblem\tdescription='{file}({line}):\t{severity}:\t{message}']"
The general idea is OK. But the problem is that some of the messages contain the character ' and this causes an error in parsing the output becasue TeamCity requires escaping apostrophes. For example, here's an excerpt from my build log:
[17:20:05][Step 2/2] Checking ..\..\..\services_package\Services\FaultsManager\FaultsManager.c...
[17:20:14][Step 2/2] ##teamcity[buildProblem description='..\..\..\services_package\Services\FaultsManager\FaultsManager.c(83): style: The scope of the variable 'channelID' can be reduced.']
[17:20:15]
[Step 2/2] Property value not found
Valid property list format is (name( )*=( )*'escaped_value'( )*)* where escape symbol is "|"
[17:20:14][Step 2/2] ##teamcity[buildProblem description='..\..\..\services_package\Services\FaultsManager\CommonDef.h(32): warning: Redundant code: Found a statement that begins with numeric constant.']
The second error gets reported but the first doesn't. I think it's becasue the first contains 'channelID' and this confuses the parser.
How can I get TeamCity to display the error messages nicely? Obviously I can get it to fail the build if the analysis fails but I want the overview page to display meaningful data - number of errors, number of new ones, the list of errors, etc. (similaly to failed tests).
Upvotes: 2
Views: 1465
Reputation: 4977
There is also another possibility that I wrote about in my blog post in Russian. You can use Teamcity XML report processing and all of its associated functionality ("Code Inspection" tab, metrics, automated changes tracking), but you need to convert cppcheck's XML output into something Teamcity understands. I've used XSLT for that:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="UTF-8" indent="yes" method="xml"></xsl:output>
<xsl:template match="/">
<checkstyle>
<xsl:attribute name="version">
<xsl:value-of select="results/cppcheck[@version]"/>
</xsl:attribute>
<xsl:for-each-group select="results/errors/error" group-by="(location/@file)[1]">
<file>
<xsl:attribute name="name">
<xsl:value-of select="current-grouping-key()"/>
</xsl:attribute>
<xsl:for-each select="current-group()">
<error line="{(location/@line)[1]}" message="{@msg}" severity="{@severity}" source="{@id}" />
</xsl:for-each>
</file>
</xsl:for-each-group>
</checkstyle>
</xsl:template>
</xsl:stylesheet>
Which produces Checkstyle XML. It's used like this:
$ cppcheck --enable=all --xml --xml-version=2 . 2>cppcheck-report.xml
$ saxonb-xslt cppcheck-report.xml cppcheck-2-to-checkstyle.xslt >cppcheck-checkstyle.xml
Teamcity configuration to process the resulting XML:
Integrating cppcheck this way has some advantages (aside from "Code Inspection" tab that just has a better interface than plain log line) in that you're in a better control of the build behaviour. Using "buildProblem" you're failing the build and that probably is OK when you're dealing with a tightly controlled small clean codebase, but it certainly is not when you're working on some kind of huge legacy codebase that has thousands of warnings (fixing all of them is just way too expensive and cppcheck also has false positives). It allows you to make some rules like "warning/error counters should not increase" and easily catch new problems, like this:
Notice that it uses "latest successful build" as a reference point so that if someone fixes some old problem you have new (lower) reference counts that successive builds will be compared against.
Upvotes: 3
Reputation: 1406
I ended up writing a script which post-processes the output: http://blogs.microsoft.co.il/dinazil/2015/08/31/more-on-code-quality/
Upvotes: 0