Аналіз merge request'аў у GitLab з дапамогай PVS-Studio для C#

Аналіз merge request'аў у GitLab з дапамогай PVS-Studio для C#
Любіце GitLab і не любіце памылкі? Жадаеце павысіць якасць зыходнага кода? Тады вы патрапілі па адрасе. Сёння мы раскажам, як наладзіць C# аналізатар PVS-Studio для праверкі merge request'аў. Усім аднарожнага настрою і прыемнага чытання.

PVS-студыя - Гэта прылада для выяўлення памылак і патэнцыйных уразлівасцяў у зыходным кодзе праграм, напісаных на мовах C, C++, C# і Java. Працуе ў 64-бітных сістэмах на Windows, Linux і macOS. Можа аналізаваць код, прызначаны для 32-бітных, 64-бітных і ўбудавальных ARM платформаў.

Дарэчы, у нас адбыўся рэліз 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 да ўкаранення статычнага аналізатара:

Аналіз merge request'аў у GitLab з дапамогай PVS-Studio для C#
Гэта значыць, усе памылкі, якія былі ў галінцы змены, пяройдуць у майстар галінку. Бо нам бы гэтага не жадалася, дадаем аналіз, і зараз схема выглядае наступным чынам:

Аналіз merge request'аў у GitLab з дапамогай PVS-Studio для C#
Аналізуем changes2 і, калі памылак няма, прыманы merge request, а інакш адхіляем яго.

Дарэчы, калі вас цікавіць аналіз комітаў і pull request'аў для C/C++, тыя вы можаце пачытаць пра гэта тут.

GitLab

GitLab — вэб-інструмент жыццёвага цыклу DevOps з адкрытым зыходным кодам, які прадстаўляе сістэму кіравання рэпазітарамі кода для Git з уласнай вікі, сістэмай адсочвання памылак, CI/CD пайплайнам і іншымі функцыямі.

Перад тым як прыступіць да рэалізацыі аналізу merge request'аў неабходна зарэгістравацца і загрузіць свой праект. Калі вы не ведаеце, як гэта зрабіць, то прапаную артыкул майго калегі.

Заўвага. Апісваны далей спосаб налады асяроддзя - адзін з магчымых. Мэта - паказаць крокі налады неабходнага для аналізу асяроддзя і запуску аналізатара. Магчыма, у вашым выпадку больш аптымальным будзе падзел этапаў падрыхтоўкі асяроддзя (даданне рэпазітароў, усталёўка аналізатара) і аналізу: напрыклад, падрыхтоўка Docker выяў з неабходным асяроддзем і іх выкарыстанне ці які-небудзь іншы спосаб.

Каб навочней зразумець, што зараз будзе адбывацца, я прапаную зірнуць на наступную схему:

Аналіз merge request'аў у GitLab з дапамогай PVS-Studio для C#
Для працы аналізатару патрабуецца. NET Core SDK 3, таму перад усталёўкай аналізатара трэба дадаць рэпазітары Microsoft, з якіх будуць усталяваныя неабходныя для аналізатара залежнасці. Даданне рэпазітараў Microsoft для розных дыстрыбутываў Linux апісана ў адпаведным дакуменце.

Для ўсталёўкі PVS-Studio праз пакетны мэнэджар таксама запатрабуецца дадаць рэпазітары PVS-Studio. Даданне рэпазітараў для розных дыстрыбутываў больш падрабязна апісана ў адпаведным раздзеле дакументацыі.

Для працы аналізатару неабходны ліцэнзійны ключ. Атрымаць пробную ліцэнзію можна на старонцы загрузкі аналізатара.

Заўвага. Звярніце ўвагу, што для апісванага рэжыму працы (аналіз merge requests) патрэбна Enterprise ліцэнзія. Таму, калі вы жадаеце паспрабаваць дадзены рэжым працы, у поле "Паведамленне" не забудзьцеся паказаць, што вам патрэбна менавіта Enterprise ліцэнзія.

Калі адбываецца merge request, то нам запатрабуецца прааналізаваць толькі спіс змененых файлаў, а інакш аналізуем усе файлы. Пасля аналізу трэба сканвертаваць логі ў патрэбны нам фармат.

Цяпер, маючы перад вачыма алгарытм працы, можна пераходзіць да напісання скрыпту. Каб гэта зрабіць, неабходна змяніць файл .gitlab-ci.yml ці, калі яго няма, стварыць. Для яго стварэння трэба націснуць на назву вашага праекта -> Set up CI/CD.

Аналіз merge request'аў у GitLab з дапамогай PVS-Studio для C#
Вось зараз мы гатовы да напісання скрыпту. Давайце спачатку напішам код, які ўсталюе аналізатар і ўвядзе ліцэнзію:

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.

Аналіз merge request'аў у GitLab з дапамогай PVS-Studio для C#
У якое адкрылася акне знаходзім пункт зменныя, справа націскаем на кнопку Пашыраць і дадаем зменныя. У выніку павінна атрымацца наступнае:

Аналіз merge request'аў у GitLab з дапамогай PVS-Studio для C#
Цяпер можна пераходзіць да аналізу. Спачатку дадамо скрыпт для поўнага аналізу. У сцяг -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)" дакумента "Праверка праектаў Visual Studio / MSBuild / .NET Core з каманднага радка з дапамогай PVS-Studio".

У дадзеным выпадку нас цікавяць усе коды звароту, дзе фігуруе 8.

  - exit_code=$((($exit_code & 8)/8))

Мы атрымаем 1, калі код звароту ўтрымоўвае які цікавіць нас біт лікі, а інакш атрымаем 0.

Надышоў час дадаць аналіз merge request. Перад тым як гэта зрабіць, падрыхтуем месца для скрыпту. Нам неабходна, каб ён выконваўся толькі тады, калі адбываецца merge request. Выглядае гэта вось так:

merge:
  script:
  only:
  - merge_requests

Пяройдзем да самога скрыпту. Я сутыкнуўся з тым, што віртуальная машына нічога не ведае пра origin/master. Таму дапамагаем ёй няшмат:

  - 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

ўтыліта plog-converter - гэта open source праект, які выкарыстоўваецца для пераўтварэння справаздачы пра памылкі аналізатара ў розныя формы, напрыклад, HTML. Больш падрабязнае апісанне ўтыліты прыводзіцца ў падраздзеле "Утыліта Plog Converter" адпаведнага раздзела дакументацыі.

Дарэчы, калі вы жадаеце зручна працаваць з .json справаздачай лакальна з IDE, то прапаную наш убудова для IDE Rider. Больш падрабязна яго выкарыстанне апісана ў адпаведным дакуменце.

Для зручнасці вось .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

Як толькі дадалі ўсё ў файл, націскаем на Commit changes. Для таго каб паглядзець, што ўсё правільна, заходзім у CI / CD -> Трубаправоды -> Праца. Адкрыецца акно віртуальнай машыны, у канцы якой павінна быць наступнае:

Аналіз merge request'аў у GitLab з дапамогай PVS-Studio для C#
Убачылі Job succeeded - поспех, усё выдатна. Цяпер можна і пратэставаць зробленае.

Прыклады працы

Для прыкладу працы створым просты праект (у майстар) у якім будзе некалькі файлаў. Пасля гэтага ў іншай галінцы зменім толькі адзін файл і паспрабуем зрабіць merge request.

Разгледзім два выпадкі: калі зменены файл утрымоўвае памылку і калі не. Спачатку прыклад з памылкай.

Дапушчальны, у master галінцы ёсць файл Праграма.cs, які не ўтрымлівае памылак, а ў іншай галінцы распрацоўшчык дадаў памылковы код і хоча зрабіць merge request. Якую менавіта памылку ён дапусціў - не гэтак важна, галоўнае, што яна ёсць. Напрыклад, забыўся аператар кідаць (так, так памыляюцца):

void MyAwesomeMethod(String name)
{
  if (name == null)
    new ArgumentNullException(....);
  // do something
  ....
}

Паглядзім на вынік аналізу прыкладу з памылкай. Таксама каб пераканацца ў тым, што толькі адзін файл быў прааналізаваны, я дадаў сьцяг -r у радок запуску pvs-studio-dotnet:

Аналіз merge request'аў у GitLab з дапамогай PVS-Studio для C#
Мы бачым, што аналізатар знайшоў памылку і не дазволіў зрабіць зліццё галінак.

Правяраем прыклад без памылкі. Выпраўляем код:

void MyAwesomeMethod(String name)
{
  if (name == null)
    throw new ArgumentNullException(....);
  // do something
  ....
}

Вынікі аналізу merge request:

Аналіз merge request'аў у GitLab з дапамогай PVS-Studio для C#
Як мы бачым, памылкі не знойдзены, і выкананне задачы прайшло паспяхова, што мы і хацелі праверыць.

Заключэнне

Адсяваць дрэнны код да зліцця галінак - гэта вельмі зручна і прыемна. Таму, калі вы карыстаецеся CI/CD, паспрабуйце ўбудаваць статычны аналізатар для праверкі. Тым больш што робіцца гэта дастаткова проста.

Дзякуй за ўвагу.

Аналіз merge request'аў у GitLab з дапамогай PVS-Studio для C#
Калі хочаце падзяліцца гэтым артыкулам з англамоўнай аўдыторыяй, то прашу выкарыстаць спасылку на пераклад: Nikolay Mironov. Analysis of merge requests in GitLab з дапамогай PVS-Studio for C#.

Крыніца: habr.com

Дадаць каментар