Анализ сишных исходников через Тимсити

11.04.2018 23:56:28

Я очень люблю и уважаю статический анализ кода. Когда-то прикручивал Кланг к сборкам, потом к нему добавился Сиппчек, сейчас я стараюсь оба анализатора использовать, хотя получается и не всегда. В прошлом году как раз прикручивал Сиппчек к нескольким проектам и возникла занятная задача интеграции с Тимсити.

Анализ должен прогоняться регулярно, так же, как и сборки. Поэтому возложить запуск анализа на Тимсити (ну или любой другой подобный инструмент, просто тут уж так сложилось, что у нас этим заведует именно Тимсити) выглядит вполне логичным. Вопрос в том, что потом делать с результатами.

С одной стороны, архив со сгенерированным веб-отчётом всегда можно положить в артефакты, но оттуда его надо доставать, открывать и вот это всё, не очень. С другой стороны, у Тимсити есть шикарная возможность интеграции веб-отчётов прямо во вкладки сборки, настраивается неприлично легко и вот, ура! результаты видны непосредственно в вебе, что гораздо приятнее.

Но всё-таки не идеально, ведь за результатами надо ещё и следить, а ну как кто набажит в новых коммитах, а никто не увидит? И вот тут-то мы и подбираемся к самому вкусному. На самом деле Тимсити умеет работать с выводом анализаторов кода, то есть, ему можно показать ошибки, а он будет вести их учёт, а раз он будет понимать, сколько там каких ошибок, он сможет, в том числе, реагировать на изменения показателей, например, считать сборку неуспешной при увеличении количества ошибок.

И всё бы хорошо, но, разумеется, в списке форматов, поддерживаемых Тимсити, нет Сиппчека. Однако, Сиппчек умеет выдавать ИксЭмЭль. И все прочие инструменты анализа, которые понимает Тимсити, тоже выдают ИксЭмЭль. Многие ИксЭмЭль почему-то не любят, а зря, потому что как раз для такого случая много лет назад придуман ИксСЛТ, позволяющий из исходного документа получить примерно всё, что угодно, причём, относительно недорого. В нашем случае из одного ИксЭмЭля другой.

В качестве целевого формата я выбрал Чекстайл, выбор ничем особым не обоснован, кроме того, что он мне показался наиболее простым и понятным (с документацией на эти форматы, кстати, не очень-то хорошо, хотя, казалось бы). В итоге, мне довольно быстро удалось соорудить конвертилку из сиппчекового формата в чекстайловый, выглядела она так:

<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 version="1.67">
    <xsl:for-each-group select="results/error" group-by="@file">
      <file>
        <xsl:attribute name="name">
          <xsl:value-of select="current-grouping-key()"/>
        </xsl:attribute>
        <xsl:for-each select="current-group()">
          <error line="{@line}" message="{@msg}" severity="{@severity}" source="{@id}" />
        </xsl:for-each>
      </file>
    </xsl:for-each-group>
  </checkstyle>
</xsl:template>
</xsl:stylesheet>

Но это больше для истории, так как по ошибке я взялся за первую версию иксэмэльного вывода самого Сиппчека, в норме, конечно, ориентироваться надо на вторую. Но и она несложна, буквально вот так преобразуется:

<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">
      <file>
        <xsl:attribute name="name">
          <xsl:value-of select="current-grouping-key()"/>
        </xsl:attribute>
        <xsl:for-each select="current-group()">
          <error line="{location/@line}" message="{@msg}" severity="{@severity}" source="{@id}" />
        </xsl:for-each>
      </file>
    </xsl:for-each-group>
  </checkstyle>
</xsl:template>
</xsl:stylesheet>

Единственный нюанс в том, что здесь используется стандарт XSLT 2.0, а как раз его совершенно не знает xsltproc, поэтому приходится работать через Саксон, выглядит это примерно так:

$ cppcheck --enable=all --xml --xml-version=2 . 2>cppcheck-report.xml
$ saxonb-xslt cppcheck-report.xml cppcheck-2-to-checkstyle.xslt >cppcheck-checkstyle.xml

Полученный cppcheck-checkstyle.xml отдаётся на съедение Тимсити, а далее появляются симпатичные счётчики и возможность ронять сборку при их увеличении, чего изначально и хотелось.

Закомментировать

Вам бы, по-хорошему, зарегистрироваться сначала надобно, прежде чем комментарии оставлять. Но, в порядке исключения, можете попробовать с OpenID проскочить, вдруг.