Как в GitHub смотреть красивые отчеты об ошибках с помощью SARIF

от автора

Вы пользуетесь GitHub, пишете код и делаете прочие веселые штуки. Для повышения качества своей работы и оптимизации своего времени используете статический анализатор. И вот вам приходит идея — а почему бы не смотреть на ошибки, которые выдал анализатор, прямо в GitHub? Да и еще, чтобы это красиво выглядело. Что же делать в этом случае? Ответ очень простой. Ваш выбор – SARIF. О том что это такое, как это настроить, и будет рассказано в данной статье. Приятного чтения.

Что такое SARIF?

SARIF (Static Analysis Results Interchange Format) – это формат обмена результатами статического анализа на основе JSON для вывода инструментов статического анализа. То есть нам достаточно получить отчет анализатора в этом формате, и далее мы можем его использовать в тех продуктах, которые поддерживают данный формат — например, на GitHub или в Visual Studio Code.

Этот формат появился из-за того, что в мире инструментов статического анализа каждый создавал свой собственный выходной формат. Однако, даже если отчёты разных анализаторов представлены в одном и том же формате (например, JSON), структура самих отчетов может кардинально отличаться друг от друга. Поэтому один общий стандарт был лишь вопросом времени.

Данный формат (SARIF) быстро развивается, и его начинают использовать все чаще и чаще. Однако на данный момент у него есть небольшой недостаток. Иногда он меняет свою структуру, и приходится немного корректировать код, чтобы SARIF файл проходил валидацию. Однако это мелочи по сравнению с тем, какую пользу он несёт. В теории, в идеальном мире, достаточно получить отчет в этом формате и далее его можно открыть в любой программе\системе, которая работает с результатами статического анализа. Ну красота же!

Настройка репозитория GitHub

Чтобы GitHub начал анализировать SARIF файлы, сначала необходимо настроить репозиторий. При настройке мы пользовались вот этой инструкцией.

Итак, открываем свой репозиторий и нажимаем на «Security».

Находим по центру «Code scanning alerts» и нажимаем справа на кнопку «Set up code scanning».

Далее нажимаем на «Set up this workflow».

Теперь даем имя для yml файла (например upload-sarif.yml) и пишем следующее содержимое:

name: "Upload SARIF"  # Run workflow each time code is pushed to your repository and on a schedule. # The scheduled workflow runs every at 00:00 on Sunday UTC time. on:   push:   schedule:   - cron: '0 0 * * 0'  jobs:   build:     runs-on: ubuntu-latest     steps:     # This step checks out a copy of your repository.     - name: Checkout repository       uses: actions/checkout@v2     - name: Upload SARIF file       uses: github/codeql-action/upload-sarif@v1       with:         # Path to SARIF file relative to the root of the repository         sarif_file: results.sarif 

Выглядеть это должно следующим образом:

Теперь нажимаем «Start commit», пишем какое-то сообщение (например «Create upload-sarif.yml») и коммитим.

Отлично, мы настроили репозиторий! Можно приступать к получению SARIF файла.

Получение SARIF файла

Как вы поняли, SARIF – унифицированный стандарт, и получить его можно с помощью разных статических анализаторов и инструментов. В этой статье мы будем использовать PVS-Studio и PlogConverter. Обо всем об этом – далее.

Проверяем проект

Чтобы получить SARIF файл, сначала нам необходимо проверить проект с помощью статического анализатора. Поэтому в настроенный выше репозиторий мы добавили небольшой тестовый С++ проект с одним файлом для демонстрации. Ибо что мы будет проверять-то в самом деле? 🙂 Вот содержимое файла:

#include <iostream> void f(unsigned int ch)  {   unsigned int chx = -1;   if (ch >= 0x0fff0)   {     if ( !((ch >= 0x0FF10) &amp;&amp; (ch &lt;= 0x0FF19))         || ((ch >= 0x0FF21) &amp;&amp; (ch &lt;= 0x0FF3A))         || ((ch >= 0x0FF41) &amp;&amp; (ch &lt;= 0x0FF5A)))     {       ch = chx;     }   } } int main() {   std::cout &lt;&lt; "error" &lt;&lt; std::endl; } 

Кстати, синтетический пример с ошибкой имеет реальный прототип, описанный в статье «Как PVS-Studio оказался внимательнее, чем три с половиной программиста«.

Как уже было упомянуто выше, проверка будет осуществляться с помощью статического анализатора PVS-Studio. А именно — с помощью консольной утилиты «PVS-Studio_Cmd.exe». Данная утилита позволяет производить анализ C++, C# MSBuild-проектов на Windows. По умолчанию найти ее можно по пути «C:\Program Files (x86)\PVS-Studio». Подробнее о данной утилите Вы можете почитать здесь.

Если у вас нет лицензии для проверки, то не отчаивайтесь. Кликнув сюда, вы перейдёте на сайт анализатора, где сможете скачать его, а также получить триальную лицензию.

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

PVS-Studio_Cmd.exe -t "D:\Use_SARIF_Example\BestProjectCpp.sln" \ -o "D:\Use_SARIF_Example\results.plog" -e "D:\Use_SARIF_Example\" 

Рассмотрим строку запуска немного подробнее. Флаг «-t» является обязательным. Он позволяет указать объект для проверки (sln или csproj/vcxproj файл). Флаг «-o» отвечает за путь до файла, в который будут записаны результаты анализа. Флаг «-e» — корневая часть пути, которую PVS-Studio будет использовать при генерации относительных путей в предупреждениях. Нужно это потому, что отчет будет обрабатываться в облаке.

Отлично, теперь нужно преобразовать plog файл в SARIF файл. Для этого воспользуемся утилитой PlogConverter.

Преобразование из Plog в SARIF

Преобразование мы будем выполнять с помощью утилиты PlogConverter, поэтому пару слов о ней. PlogConverter – это утилита с открытым исходным кодом, предназначенная для преобразования отчетов анализатора PVS-Studio из одного формата в другой. Более подробно утилита описана в документации.

Итак, нам необходимо найти PlogConverter.exe на компьютере. Эта утилита устанавливается вместе с PVS-Studio и располагается рядом с «PVS-Studio_Cmd.exe». Переходим туда, открываем консоль и пишем следующую команду:

PlogConverter.exe "D:\Use_SARIF_Example\results.plog" \ -o "D:\Use_SARIF_Example" -t sarif -n results 

Вот и все. Теперь можно заливать этот файл и смотреть результаты анализа.

Проверяем, что все работает

Чтобы проверить, что мы все сделали правильно, быстренько загрузим наш SARIF файл руками и посмотрим результаты анализа. Для этого переходим в репозиторий и нажимаем «Add file -> Upload files».

Далее добавляем SARIF файл и ждем, пока он обработается. Если хочется посмотреть, как там проходит обработка, то необходимо нажать на «Actions» и далее выбрать работающую задачу.

Как только все будет готово, заходим во вкладку «Security». В ней выбираем слева «Code scanning alerts -> PVS-Studio».

Справа у нас и будут сообщения анализатора. Откроем какое-нибудь предупреждение:

Мы видим:

  1. Быстрый фильтр по ошибкам;

  2. Сообщение об ошибке. Оно же и указывает, где именно в исходном коде находится ошибка;

  3. Ссылка на документацию для предупреждения анализатора.

Реальный сценарий использования SARIF в GitHub

Пришло время посмотреть, как это все может работать на практике. Предлагаю рассмотреть сценарий, когда человек скачает репозиторий, выполнит какую-то работу и с помощью описанных выше команд, создаст SARIF файл и зальет изменения в отдельную ветку. В итоге такой сценарий позволит нам смотреть не только, какие файлы изменил пользователь, но и какие ошибки он допустил. Поэтому скачиваем репозиторий и делаем изменения в файле с C++ кодом:

#include <iostream> void f(unsigned int ch)  {   unsigned int chx = -1;   if (ch >= 0x0fff0)   {     if (!((ch >= 0x0FF10) &amp;&amp; (ch &lt;= 0x0FF19))        || ((ch >= 0x0FF21) &amp;&amp; (ch &lt;= 0x0FF3A))        || ((ch >= 0x0FF41) &amp;&amp; (ch &lt;= 0x0FF5A)))     {       ch = chx;     }   } }  int ComputeProjectionMatrixFOV(float fov) {   float yScale = 1.0 / tan((3.141592538 / 180.0) * fov / 2);   return yScale; }  int main() {   std::cout &lt;&lt; "error" &lt;&lt; std::endl; } 

Далее проверяем файл, сохраняем отчет, получаем SARIF файл (заменяя им уже лежащий в скаченном репозитории) и делаем коммит в отдельную ветку. Все, пользователь сделал свое дело. Теперь черед смотреть ошибки.

Заходим в репозиторий. Далее «Security» -> «Code scanning alerts» -> «PVS-Studio» и справа в «Branch» выбираем нужную ветку. Смотрим результаты:

Как вы видите, сообщения об ошибках в ветке хранятся отдельно. Согласитесь, это достаточно удобно. При желании можно, например, создать bat файл, который будет запускать анализатор, конвертировать отчет в SARIF и заменять существующий SARIF файл.

Что можно делать результатами?

Итак, вы остались один на один с отчетом. Что доступно в вашем распоряжении? Первое, на что нужно обратить внимание, — это то, что все ошибки разделены на две группы. Это «Open» и «Closed». «Open» — это активные ошибки, которые мы не обработали. «Closed» – это ошибки, которые мы исправили или пометили как ложные.

Второе — это фильтры по статусам ошибок (закрытые, отрытые и все такое).

Еще есть фильтры по характеристикам ошибок. Например, можно отсортировать по номеру ошибки.

Также GitHub позволяет нам помечать сообщения как «false positive», «used in tests», и мое любимое «won’t fix» :). Чтобы пометить сообщение, необходимо его выбрать (слева от сообщения есть checkbox) и справа вверху нажать на «Dismiss».

Сообщения, которые вы так разметите, не будут попадать в графу открытых ошибок при следующей загрузке SARIF файла.

Если у нас появилась необходимость вернуть сообщения в «Open», то это очень легко сделать. Для этого выбираем «Closed», далее выбираем то, что хотим вернуть, и нажимаем справа «Reopen».

Также обратите внимание, что если загрузить новый лог, то он перезаписывает текущие открытые ошибки. Если ошибки, которые были в «Open», не встретились в новом логе, то они попадают в «Closed». Поэтому рекомендуем использовать SARIF только для анализа всего проекта. Если вам требуется проанализировать только pull request, то для этого у нас есть ряд статей на эту тему. Например, вот эта. Использовать же SARIF для анализа pull request будет не очень удобно.

А работает только для C++?

Конечно же нет, вы вообще не зависите от языка. Все, что вам нужно – это инструмент статического анализа, который сможет проанализировать ваш код и создать SARIF файл. Например, используемый в этой статье PVS-Studio умеет анализировать C++, C#, Java. Поэтому давайте еще попробуем проверить код на C#, потому что это лучший язык в мире один из авторов статьи его любит. Для примера быстренько проделываем все то же самое, о чем говорилось в статье, но уже для C# проекта. Вот содержимое файла, который был проанализирован:

using System; using System.Collections.Generic; using System.Linq;  namespace TestSarif {   class Program   {     static void Main()     {       var result = Formula42(3, 5);     }      static int Formula42(int? coefficientA, int? coefficientB)     {       var data = new List<int>();       if (coefficientA != null)         data.Add(Formula42(coefficientA.Value));       else if (coefficientB != null)         data.Add(Formula42(coefficientA.Value));       return data.SingleOrDefault();     }      static private int Formula42(int coefficient)     {       return coefficient;     }   } } 

Вот результат:

Ну и посмотрим на саму ошибку.

Вывод

Подводя итог, хочется сказать, что SARIF — это удобный формат, который позволяет просматривать результаты анализа. Да и настройка использования SARIF быстрая и простая. Например, в VS Code это вообще делается в пару кликов. Кстати, если вам будет интересно, как это сделать, то напишите об этом в комментариях. Да и вообще, если у вас есть какие-то пожелания по темам статьи, то напишите об этом.

Так что пробуйте и пользуйтесь. Спасибо за внимание.

Если хотите поделиться этой статьей с англоязычной аудиторией, то прошу использовать ссылку на перевод: Nikolay Mironov, Evgeniy Ovsannikov. How to Get Nice Error Reports Using SARIF.

ссылка на оригинал статьи https://habr.com/ru/company/pvs-studio/blog/541542/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *