Чи любите GitLab і не любите помилки? Бажаєте підвищити якість вихідного коду? Тоді ви потрапили на адресу. Сьогодні ми розповімо, як налаштувати C# аналізатор PVS-Studio для перевірки merge request'ів. Усім єдинорідного настрою та приємного читання.
До речі, у нас відбувся реліз PVS-Studio 7.08, у якому ми зробили багато всього
- аналізатор C# під Linux та macOS;
- плагін для Rider;
- новий режим перевірки списку файлів.
Режим перевірки списку файлів
Раніше для того, щоб перевірити певні файли, необхідно було передати аналізатору .xml зі списком файлів. Але, оскільки це не дуже зручно, ми додали можливість передачі .txt, що дуже спрощує життя.
Щоб перевірити певні файли, необхідно вказати прапор -sourceFiles (-f) і передати .txt зі списком файлів. Виглядає це так:
pvs-studio-dotnet -t path/to/solution.sln -f fileList.txt -o project.json
Якщо вам цікаво налаштувати перевірку коммітів або pull requests, ви також можете це зробити, використовуючи даний режим. Відмінність полягатиме в отриманні списку файлів для аналізу та залежатиме від того, які системи ви використовуєте.
Принцип перевірки merge request
Основна суть перевірки полягає в тому, щоб проблеми, виявлені аналізатором, при злитті не потрапляли в майстер гілку. Також ми не хочемо щоразу аналізувати проект цілком. Тим більше, що при злитті гілок у нас є список змінених файлів. Тому пропоную додати перевірку merge request.
Ось так виглядає merge request до впровадження статичного аналізатора:
Тобто всі помилки, які були у гілці зміни, перейдуть у майстер гілку. Так як нам цього не хотілося, додаємо аналіз, і тепер схема виглядає наступним чином:
аналізуємо зміни2 і якщо помилок немає, приймаємо merge request, а інакше відхиляємо його.
До речі, якщо вас цікавить аналіз коммітів та pull request'ів для C/C++, то ви можете почитати про це
GitLab
Перед тим як розпочати реалізацію аналізу merge request'ів необхідно зареєструватися та завантажити свій проект. Якщо ви не знаєте, як це зробити, то пропоную
Примітка. Описуваний спосіб налаштування оточення – один з можливих. Мета – показати кроки налаштування необхідного для аналізу оточення та запуску аналізатора. Можливо, у вашому випадку більш оптимальним буде поділ етапів підготовки оточення (додавання репозиторіїв, встановлення аналізатора) та аналізу: наприклад, підготовка Docker образів з необхідним оточенням та їх використання чи якийсь інший спосіб.
Щоб наочніше зрозуміти, що зараз відбуватиметься, я пропоную поглянути на таку схему:
Для роботи аналізатору потрібно. Додавання репозиторіїв Microsoft для різних дистрибутивів Linux
Для встановлення PVS-Studio через пакетний менеджер також потрібно додати репозиторії PVS-Studio. Додавання репозиторіїв для різних дистрибутивів докладніше описано в
Для роботи аналізатору потрібний ліцензійний ключ. Отримати пробну ліцензію можна на
Примітка. Зверніть увагу, що для режиму роботи (аналіз merge requests) потрібна Enterprise ліцензія. Тому, якщо ви хочете спробувати цей режим роботи, у полі "Повідомлення" не забудьте вказати, що вам потрібна саме ліцензія Enterprise.
Якщо відбувається merge request, то потрібно буде проаналізувати тільки список змінених файлів, а інакше аналізуємо всі файли. Після аналізу потрібно сконвертувати логи в потрібний формат.
Тепер, маючи перед очима алгоритм роботи, можна переходити до написання сценарію. Щоб це зробити, потрібно змінити файл .gitlab-ci.yml або, якщо її немає, створити. Для його створення потрібно натиснути на назву вашого проекту -> Set up CI/CD.
Тепер ми готові до написання скрипта. Давайте спочатку напишемо код, який встановить аналізатор та запровадить ліцензію:
before_script:
- apt-get update && apt-get -y install wget gnupg
- apt-get -y install git
- wget https://packages.microsoft.com/config/debian/10/
packages-microsoft-prod.deb -O packages-microsoft-prod.deb
- dpkg -i packages-microsoft-prod.deb
- apt-get update
- apt-get install apt-transport-https
- apt-get update
- wget -q -O - https://files.viva64.com/etc/pubkey.txt | apt-key add -
- wget -O /etc/apt/sources.list.d/viva64.list
https://files.viva64.com/etc/viva64.list
- apt-get update
- apt-get -y install pvs-studio-dotnet
- pvs-studio-analyzer credentials $PVS_NAME $PVS_KEY
- dotnet restore "$CI_PROJECT_DIR"/Test/Test.sln
Так як встановлення та активація має відбуватися перед усіма іншими скриптами, то використовуємо спеціальну мітку before_script. Трохи поясню цей фрагмент.
Підготовка до встановлення аналізатора:
- wget https://packages.microsoft.com/config/debian/10/
packages-microsoft-prod.deb -O packages-microsoft-prod.deb
- dpkg -i packages-microsoft-prod.deb
- apt-get update
- apt-get install apt-transport-https
- apt-get update
Додавання репозиторіїв PVS-Studio та аналізатора:
- wget -q -O - https://files.viva64.com/etc/pubkey.txt | apt-key add -
- wget -O /etc/apt/sources.list.d/viva64.list
https://files.viva64.com/etc/viva64.list
- apt-get update
- apt-get -y install pvs-studio-dotnet
Активація ліцензії:
- pvs-studio-analyzer credentials $PVS_NAME $PVS_KEY
$PVS_NAME - Ім'я користувача.
$PVS_KEY - Ключ продукту.
Відновлення залежностей проекту, де $CI_PROJECT_DIR - Повний шлях до директорії проекту:
- dotnet restore "$CI_PROJECT_DIR"/Path/To/Solution.sln
Для коректного аналізу проект має успішно збиратися, а його залежності мають бути відновлені (наприклад, мають бути завантажені необхідні пакети NuGet).
Задати змінні оточення, що містять ліцензійну інформацію, можна, натиснувши на Установка, а потім - на CI/CD.
У вікні знаходимо пункт Змінні, праворуч натискаємо на кнопку Розширювати і додаємо змінні. В результаті має вийти таке:
Тепер можна переходити до аналізу. Спочатку додамо скрипт для повного аналізу. У прапор -t передаємо шлях до solution, у прапор -o пишемо шлях до файлу, куди будуть записані результати аналізу. Також нас цікавить код повернення. У цьому випадку нам цікаво, щоб робота припинялася, коли код повернення містить інформацію про те, що під час аналізу було видано попередження. Ось як виглядає цей фрагмент:
job:
script:
- exit_code=0
- pvs-studio-dotnet -t "$CI_PROJECT_DIR"/Test/Test.sln -o
PVS-Studio.json || exit_code=$?
- exit_code=$((($exit_code & 8)/8))
- if [[ $exit_code == 1 ]]; then exit 1; else exit 0; fi
Коди повернення працюють за принципом маски біта. Наприклад, якщо в результаті аналізу були видані попередження, то код повернення дорівнюватиме 8. Якщо ліцензія закінчиться протягом місяця, то код повернення дорівнюватиме 4. Якщо ж в ході аналізу були виявлені помилки, а також ліцензія закінчується протягом місяця, код повернення будуть записані обидва значення: складаємо числа разом і отримуємо підсумковий код повернення - 8 + 4 = 12. Таким чином, перевіряючи відповідні біти, можна отримувати інформацію про різні стани під час аналізу. Докладніше коди повернення описуються у розділі "Коди повернення pvs-studio-dotnet (Linux / macOS)" документа "
У цьому випадку нас цікавлять усі коди повернення, де фігурує 8.
- exit_code=$((($exit_code & 8)/8))
Ми отримаємо 1, коли код повернення містить цікавий для нас біт числа, а інакше отримаємо 0.
Настав час додати аналіз merge request. Перед тим, як це зробити, підготуємо місце для скрипту. Нам необхідно, щоб він виконувався лише тоді, коли відбувається merge request. Виглядає це так:
merge:
script:
only:
- merge_requests
Перейдемо до самого скрипту. Я зіткнувся з тим, що віртуальна машина нічого не знає про походження/майстер. Тому допомагаємо їй небагато:
- git fetch origin
Тепер отримаємо різницю гілок і зберігаємо результат у TXT файл:
- git diff --name-only origin/master $CI_COMMIT_SHA > pvs-fl.txt
Де $CI_COMMIT_SHA - Хеш останнього комміту.
Далі запускаємо аналіз списку файлів, використовуючи прапор -f. У нього передаємо отриманий ранній файл .txt. Ну і за аналогією з повним аналізом дивимося коди повернення:
- exit_code=0
- pvs-studio-dotnet -t "$CI_PROJECT_DIR"/Test/Test.sln -f
pvs-fl.txt -o PVS-Studio.json || exit_code=$?
- exit_code=$((($exit_code & 8)/8))
- if [[ $exit_code == 1 ]]; then exit 1; else exit 0; fi
Повний скрипт для перевірки merge request виглядатиме ось так:
merge:
script:
- git fetch origin
- git diff --name-only origin/master $CI_COMMIT_SHA > pvs-fl.txt
- exit_code=0
- pvs-studio-dotnet -t "$CI_PROJECT_DIR"/Test/Test.sln -f
pvs-fl.txt -o PVS-Studio.json || exit_code=$?
- exit_code=$((($exit_code & 8)/8))
- if [[ $exit_code == 1 ]]; then exit 1; else exit 0; fi
only:
- merge_requests
Залишається лише додати конвертацію лога після того, як відпрацювали усі скрипти. Використовуємо мітку after_script та утиліту plog-converter:
after_script:
- plog-converter -t html -o eLog ./PVS-Studio.json
Утиліта
До речі, якщо ви хочете зручно працювати з .json звітом локально з IDE, то пропоную наш
Для зручності ось .gitlab-ci.yml повністю:
image: debian
before_script:
- apt-get update && apt-get -y install wget gnupg
- apt-get -y install git
- wget https://packages.microsoft.com/config/debian/10/
packages-microsoft-prod.deb -O packages-microsoft-prod.deb
- dpkg -i packages-microsoft-prod.deb
- apt-get update
- apt-get install apt-transport-https
- apt-get update
- wget -q -O - https://files.viva64.com/etc/pubkey.txt | apt-key add -
- wget -O /etc/apt/sources.list.d/viva64.list
https://files.viva64.com/etc/viva64.list
- apt-get update
- apt-get -y install pvs-studio-dotnet
- pvs-studio-analyzer credentials $PVS_NAME $PVS_KEY
- dotnet restore "$CI_PROJECT_DIR"/Test/Test.sln
merge:
script:
- git fetch origin
- git diff --name-only origin/master $CI_COMMIT_SHA > pvs-fl.txt
- exit_code=0
- pvs-studio-dotnet -t "$CI_PROJECT_DIR"/Test/Test.sln -f
pvs-fl.txt -o PVS-Studio.json || exit_code=$?
- exit_code=$((($exit_code & 8)/8))
- if [[ $exit_code == 1 ]]; then exit 1; else exit 0; fi
only:
- merge_requests
job:
script:
- exit_code=0
- pvs-studio-dotnet -t "$CI_PROJECT_DIR"/Test/Test.sln -o
PVS-Studio.json || exit_code=$?
- exit_code=$((($exit_code & 8)/8))
- if [[ $exit_code == 1 ]]; then exit 1; else exit 0; fi
after_script:
- plog-converter -t html -o eLog ./PVS-Studio.json
Як тільки додали все до файлу, натискаємо на Прийняти зміни. Для того щоб подивитися, що все правильно, заходимо в CI/CD -> Трубопроводи -> Робота. Відкриється вікно віртуальної машини, наприкінці якої має бути наступне:
Побачили Job succeeded - Успіх, все чудово. Тепер можна і протестувати зроблене.
Приклади роботи
Для прикладу роботи створимо простий проект (у майстер) У якому буде кілька файлів. Після цього в іншій гілці змінимо лише один файл і спробуємо зробити merge request.
Розглянемо два випадки: коли змінений файл містить помилку та коли ні. Спочатку приклад із помилкою.
Допустимо, в master гілці є файл Program.cs, Що не містить помилок, а в іншій гілці розробник додав помилковий код і хоче зробити merge request. Якої саме помилки він припустився – не так важливо, головне, що вона є. Наприклад, забув оператор кидати (так,
void MyAwesomeMethod(String name)
{
if (name == null)
new ArgumentNullException(....);
// do something
....
}
Погляньмо на результат аналізу прикладу з помилкою. Також щоб переконатися, що тільки один файл був проаналізований, я додав прапор -r у рядок запуску pvs-studio-dotnet:
Ми, що аналізатор знайшов помилку і дозволив зробити злиття гілок.
Перевіряємо приклад без помилок. Виправляємо код:
void MyAwesomeMethod(String name)
{
if (name == null)
throw new ArgumentNullException(....);
// do something
....
}
Результати аналізу merge request:
Як бачимо, помилок не знайдено, і виконання завдання пройшло успішно, що ми хотіли перевірити.
Висновок
Відсівати поганий код до злиття гілок це дуже зручно і приємно. Тому, якщо ви використовуєте CI/CD, спробуйте вбудувати статичний аналізатор для перевірки. Тим більше, що робиться це досить просто.
Дякую за увагу.
Якщо хочете поділитися цією статтею з англомовною аудиторією, прошу використати посилання на переклад: Nikolay Mironov.
Джерело: habr.com