Любіце 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 да ўкаранення статычнага аналізатара:
Гэта значыць, усе памылкі, якія былі ў галінцы змены, пяройдуць у майстар галінку. Бо нам бы гэтага не жадалася, дадаем аналіз, і зараз схема выглядае наступным чынам:
Аналізуем changes2 і, калі памылак няма, прыманы merge request, а інакш адхіляем яго.
Дарэчы, калі вас цікавіць аналіз комітаў і pull request'аў для C/C++, тыя вы можаце пачытаць пра гэта
GitLab
Перад тым як прыступіць да рэалізацыі аналізу merge request'аў неабходна зарэгістравацца і загрузіць свой праект. Калі вы не ведаеце, як гэта зрабіць, то прапаную
Заўвага. Апісваны далей спосаб налады асяроддзя - адзін з магчымых. Мэта - паказаць крокі налады неабходнага для аналізу асяроддзя і запуску аналізатара. Магчыма, у вашым выпадку больш аптымальным будзе падзел этапаў падрыхтоўкі асяроддзя (даданне рэпазітароў, усталёўка аналізатара) і аналізу: напрыклад, падрыхтоўка Docker выяў з неабходным асяроддзем і іх выкарыстанне ці які-небудзь іншы спосаб.
Каб навочней зразумець, што зараз будзе адбывацца, я прапаную зірнуць на наступную схему:
Для працы аналізатару патрабуецца. NET Core SDK 3, таму перад усталёўкай аналізатара трэба дадаць рэпазітары Microsoft, з якіх будуць усталяваныя неабходныя для аналізатара залежнасці. Даданне рэпазітараў 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
Пяройдзем да самога скрыпту. Я сутыкнуўся з тым, што віртуальная машына нічога не ведае пра 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
ўтыліта
Дарэчы, калі вы жадаеце зручна працаваць з .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
Як толькі дадалі ўсё ў файл, націскаем на Commit changes. Для таго каб паглядзець, што ўсё правільна, заходзім у CI / CD -> Трубаправоды -> Праца. Адкрыецца акно віртуальнай машыны, у канцы якой павінна быць наступнае:
Убачылі Job succeeded - поспех, усё выдатна. Цяпер можна і пратэставаць зробленае.
Прыклады працы
Для прыкладу працы створым просты праект (у майстар) у якім будзе некалькі файлаў. Пасля гэтага ў іншай галінцы зменім толькі адзін файл і паспрабуем зрабіць merge request.
Разгледзім два выпадкі: калі зменены файл утрымоўвае памылку і калі не. Спачатку прыклад з памылкай.
Дапушчальны, у master галінцы ёсць файл Праграма.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