More on Code Quality

August 31, 2015

one comment

Lately I’ve been investing my time in raising the code quality in my team. cppcheck has long been used in the department (well, in some teams of the department). We even had it configured in our continuous integration environment TeamCity (TC). We simply configured cppcheck to output its results into an XML file and saved this file as artifacts. But there are several problem with this solution:

  1. The XML format is not very human-readable [I don’t know why we went specifically for the XML. It was like that when I got here Smile]:image
  2. Unlike TC’s usual informative messages in the Overview tab, we simply get a general error message because the batch script returns a non-zero error code:image

If we want to interact with TC, we need to speak its language. Namely, output messages in the correct format according to the documentation. Luckily, cppcheck supports setting the output format using the “–template” argument. So we can just set

--template=##teamcity[buildProblem description=\'{file}:{line}: {severity}: {message}\']

and get these nice messages, right?

image

Wrong! Some of the messages have the following format:

##teamcity[buildProblem description=’this_and_that.h(1049): style: Variable ‘variable’ hides enumerator with same name’]

Note the single quotes around the variable name. This confuses TC and is against the rules. Turns out there are some characters which require escaping. It even says so in the documentation. The result is that some of the messages are displayed nicely in the Overview tab and some cause a parsing error and appear as internal errors in the build log:

image

So I tried to ask the cppcheck guys to add a feature for controlling the escaping. They didn’t add the feature but suggested a workaround – to use sed to reformat the output. I (well, Sasha) couldn’t get sed nor gawk to do it, plus I’m on Windows anyway, but this gave me the idea to reformat the output with Python. As it is, I had a very intricate PowerShell script setting up the entire environment (include directories, preprocessor definitions, etc.) and I was pondering about rewriting it in Python, so this was great timing.

You can find the final result on my GitHub repo (with all the input files processing), but here’s the important part:

def handle_output_line(line):
    if line != "":
        line = line.strip('\n')
        m = re.search("^(##teamcity[^']*\s+description=')(.*)('[^']*)$", line)
        if m is None:
            print line
        else:
            escaped = re.sub("(['|\[\]])", "|\\1", m.group(2))
            print m.group(1) + escaped + m.group(3)
        return True
    else:
        return False

def main():
    # ...

    # if the output format is None identify whether under TC or not and set message format accordingly
    # if format set to TC will also need to escape messages
    if args.ot is None:
        if teamcity.is_running_under_teamcity():
            args.ot = "tc"
        else:
            args.ot = "vs"

    arguments = ...

    # run the process and redirect both stdout and stderr for further processing if needed
    if args.ot == "tc":
        process = subprocess.Popen(get_cppcheck_path() + arguments, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        while True:
            more = handle_output_line(process.stdout.readline())
            if not more:
                break
        return process.returncode
    else:
        return subprocess.call(get_cppcheck_path() + arguments)

if __name__ == "__main__":
    main()

I use a really useful Python package called teamcity-messages developed by the TC people. It allows me to figure out during run time whether the script is running under TC or not. If it is, I just redirect its output back to my script and do the required escaping. And now all the messages are displayed in the Overview tab and all’s well.

One last thing: while we’re at the subject of displaying error messages nicely on TC, check out teamcity-cpp (another gem by the TC people). It will allow your boost tests to output their messages in a TC-friendly format. And that is absolutely awesome!

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

one comment

  1. Pingback: TeamCity and cppcheck output template - HTML CODE