V analizatorju PVS-Studio za jezike C in C++ v sistemih Linux in macOS se je od različice 7.04 pojavila možnost preizkusa za preverjanje seznama določenih datotek. Z uporabo novega načina lahko konfigurirate analizator za preverjanje potrditev in zahtev za vlečenje. Ta članek vam bo povedal, kako nastaviti preverjanje seznama spremenjenih datotek projekta GitHub v tako priljubljenih sistemih CI (Continuous Integration), kot so Travis CI, Buddy in AppVeyor.
Način preverjanja seznama datotek
V različici PVS-Studio 7.04 za Linux in macOS se je pojavil način za preverjanje seznama izvornih datotek. To deluje za projekte, katerih gradbeni sistem omogoča ustvarjanje datoteke
Prav tako je mogoče uporabiti način preverjanja seznama datotek skupaj z dnevnikom sledenja strace zagonov prevajalnika (sled pvs-studio-analyzer). Če želite to narediti, boste morali najprej izvesti celotno gradnjo projekta in mu slediti, tako da analizator zbere popolne informacije o parametrih prevajanja vseh datotek, ki se preverjajo.
Vendar pa ima ta možnost pomembno pomanjkljivost - bodisi boste morali izvesti popolno sled gradnje celotnega projekta vsakič, ko ga zaženete, kar je samo po sebi v nasprotju z idejo o hitrem preverjanju objave. Ali pa, če predpomnite sam rezultat sledenja, bodo nadaljnji zagoni analizatorja morda nepopolni, če se po sledenju spremeni struktura odvisnosti izvornih datotek (na primer, eni od izvornih datotek je dodan nov #include).
Zato ne priporočamo uporabe načina preverjanja seznama datotek z dnevnikom sledenja za preverjanje potrditev ali zahtev za vlečenje. Če lahko pri preverjanju objave izvedete postopno gradnjo, razmislite o uporabi načina
Seznam izvornih datotek za analizo se shrani v besedilno datoteko in posreduje analizatorju s pomočjo parametra -S:
pvs-studio-analyzer analyze ... -f build/compile_commands.json -S check-list.txt
Ta datoteka določa relativne ali absolutne poti do datotek in vsaka nova datoteka mora biti v novi vrstici. Sprejemljivo je določiti ne samo imena datotek za analizo, ampak tudi različno besedilo. Analizator bo videl, da to ni datoteka, in bo prezrl vrstico. To je lahko koristno za komentiranje, če so datoteke določene ročno. Vendar pa bo med analizo v CI pogosto ustvarjen seznam datotek, to so lahko na primer datoteke iz zahteve za objavo ali vlečenje.
Zdaj lahko s tem načinom hitro preverite novo kodo, preden pride v glavno razvojno vejo. Da zagotovite, da se sistem skeniranja odzove na opozorila analizatorja, pripomoček plog-pretvornik dodana zastava --indicate-warnings:
plog-converter ... --indicate-warnings ... -o /path/to/report.tasks ...
S to zastavico bo pretvornik vrnil kodo, ki ni ničelna, če so v poročilu analizatorja opozorila. Z uporabo povratne kode lahko blokirate kavelj za predhodno objavo, objavo ali zahtevo za vlečenje, ustvarjeno poročilo analizatorja pa je mogoče prikazati, dati v skupno rabo ali poslati po e-pošti.
Opomba. Ko prvič začnete analizirati seznam datotek, bo analiziran celoten projekt, ker analizator mora ustvariti datoteko odvisnosti izvornih datotek projekta od datotek glave. To je funkcija analiziranja datotek C in C++. V prihodnosti bo datoteko odvisnosti mogoče shraniti v predpomnilnik in jo bo analizator samodejno posodobil. Prednost preverjanja potrditev pri uporabi načina preverjanja seznama datotek pred uporabo načina inkrementalne analize je, da morate predpomniti samo to datoteko in ne objektnih datotek.
Splošna načela analize zahtev po vleku
Analiza celotnega projekta vzame veliko časa, zato je smiselno preveriti le določen del. Težava je v tem, da morate nove datoteke ločiti od preostalih projektnih datotek.
Oglejmo si primer drevesa objave z dvema vejama:
Predstavljajmo si to obvezo A1 vsebuje precej veliko kodo, ki je že bila testirana. Malo prej smo naredili vejo iz zaveze A1 in spremenil nekaj datotek.
To ste seveda opazili po A1 sta se zgodili še dve predaji, vendar sta bili tudi to združitvi drugih vej, ker se ne zavezujemo mojster. In zdaj je prišel čas, ko hitri popravek pripravljena. Zato se je pojavila zahteva za združitev B3 и A3.
Seveda bi bilo mogoče preveriti celoten rezultat njihovega združevanja, vendar bi bilo to preveč zamudno in neupravičeno, saj je bilo spremenjenih le nekaj datotek. Zato je bolj učinkovito analizirati samo spremenjene.
Da bi to naredili, dobimo razliko med vejami, ki so v HEAD veje, iz katere se želimo združiti v master:
git diff --name-only HEAD origin/$MERGE_BASE > .pvs-pr.list
$MERGE_BASE kasneje si ga bomo podrobneje ogledali. Dejstvo je, da vsaka storitev CI ne zagotavlja potrebnih informacij o bazi podatkov za združevanje, zato morate vsakič najti nove načine za pridobitev teh podatkov. To bo podrobno opisano v nadaljevanju pri vsaki od opisanih spletnih storitev.
Tako smo dobili razliko med vejami oziroma seznam spremenjenih imen datotek. Zdaj moramo dati datoteko .pvs-pr.list (nanj smo preusmerili zgornji izhod) v analizator:
pvs-studio-analyzer analyze -j8
-o PVS-Studio.log
-S .pvs-pr.list
Po analizi moramo dnevniško datoteko (PVS-Studio.log) pretvoriti v lahko berljivo obliko:
plog-converter -t errorfile PVS-Studio.log --cerr -w
Ta ukaz bo prikazal seznam napak v
Samo zdaj moramo ne samo prikazati napake, ampak tudi obvestiti našo službo za montažo in testiranje o prisotnosti težav. V ta namen je bila pretvorniku dodana zastavica -W (--indicate-warnings). Če obstaja vsaj eno opozorilo analizatorja, povratna koda pripomočka plog-pretvornik se bo spremenilo v 2, kar bo posledično obvestilo storitev CI o prisotnosti morebitnih napak v datotekah z zahtevami za vlečenje.
Travis CI
Konfiguracija je narejena kot datoteka .travis.yml. Za udobje vam svetujem, da vse postavite v ločen bash skript s funkcijami, ki bodo klicane iz datoteke .travis.yml (bash ime_skripta.sh ime_funkcije).
Potrebno kodo bomo dodali v skript na bash, tako bomo pridobili več funkcionalnosti. V razdelku namestitev napišimo naslednje:
install:
- bash .travis.sh travis_install
Če ste imeli kakšna navodila, jih lahko prenesete v skript in odstranite vezaje.
Odprimo datoteko .travis.sh in funkciji dodajte nastavitev analizatorja travis_install():
travis_install() {
wget -q -O - https://files.viva64.com/etc/pubkey.txt
| sudo apt-key add -
sudo wget -O /etc/apt/sources.list.d/viva64.list
https://files.viva64.com/etc/viva64.list
sudo apt-get update -qq
sudo apt-get install -qq pvs-studio
}
Zdaj pa dodajmo v razdelek script zaženi analizo:
script:
- bash .travis.sh travis_script
In v skriptu bash:
travis_script() {
pvs-studio-analyzer credentials $PVS_USERNAME $PVS_KEY
if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
git diff --name-only origin/HEAD > .pvs-pr.list
pvs-studio-analyzer analyze -j8
-o PVS-Studio.log
-S .pvs-pr.list
--disableLicenseExpirationCheck
else
pvs-studio-analyzer analyze -j8
-o PVS-Studio.log
--disableLicenseExpirationCheck
fi
plog-converter -t errorfile PVS-Studio.log --cerr -w
}
To kodo je treba zagnati po gradnji projekta, na primer, če ste imeli gradnjo na CMake:
travis_script() {
CMAKE_ARGS="-DCMAKE_EXPORT_COMPILE_COMMANDS=On ${CMAKE_ARGS}"
cmake $CMAKE_ARGS CMakeLists.txt
make -j8
}
Izkazalo se bo takole:
travis_script() {
CMAKE_ARGS="-DCMAKE_EXPORT_COMPILE_COMMANDS=On ${CMAKE_ARGS}"
cmake $CMAKE_ARGS CMakeLists.txt
make -j8
pvs-studio-analyzer credentials $PVS_USERNAME $PVS_KEY
if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
git diff --name-only origin/HEAD > .pvs-pr.list
pvs-studio-analyzer analyze -j8
-o PVS-Studio.log
-S .pvs-pr.list
--disableLicenseExpirationCheck
else
pvs-studio-analyzer analyze -j8
-o PVS-Studio.log
--disableLicenseExpirationCheck
fi
plog-converter -t errorfile PVS-Studio.log --cerr -w
}
Verjetno ste že opazili te spremenljivke okolja $TRAVIS_PULL_REQUEST и $TRAVIS_BRANCH. Travis CI jih razglasi neodvisno:
- $TRAVIS_PULL_REQUEST shrani številko vlečne zahteve oz false, če je to običajna podružnica;
- $TRAVIS_REPO_SLUG shrani ime repozitorija projekta.
Algoritem za to funkcijo:
Travis CI se odziva na povratne kode, zato bo prisotnost opozoril sporočila storitvi, naj označi objavo, kot da vsebuje napake.
Zdaj pa si podrobneje oglejmo to vrstico kode:
git diff --name-only origin/HEAD > .pvs-pr.list
Dejstvo je, da Travis CI samodejno združuje veje, medtem ko analizira zahtevo za vlečenje:
Zato analiziramo A4In ne B3->A3. Zaradi te lastnosti moramo izračunati razliko z A3, ki je ravno vrh veje od poreklo.
Ostala je še ena pomembna podrobnost - predpomnjenje odvisnosti datotek glave od prevedenih prevajalskih enot (*.c, *.cc, *.cpp itd.). Analizator izračuna te odvisnosti, ko se prvič zažene v načinu preverjanja seznama datotek in jih nato shrani v imenik .PVS-Studio. Travis CI vam omogoča predpomnjenje map, zato bomo shranili podatke imenika .PVS-Studio/:
cache:
directories:
- .PVS-Studio/
To kodo je treba dodati v datoteko .travis.yml. V tem imeniku so shranjeni različni podatki, zbrani po analizi, kar bo znatno pospešilo nadaljnje izvajanje analize seznama datotek ali inkrementalne analize. Če tega ne storite, bo analizator dejansko vsakič analiziral vse datoteke.
Buddy
Tako kot Travis CI,
Najprej moramo na tekoči trak dodati novo dejanje:
Označimo prevajalnik, ki je bil uporabljen za izdelavo projekta. Opazite vsebnik dockerja, ki je nameščen v tem dejanju. Na primer, obstaja poseben vsebnik za GCC:
Zdaj pa namestimo PVS-Studio in potrebne pripomočke:
V urejevalnik dodamo naslednje vrstice:
apt-get update && apt-get -y install wget gnupg jq
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
Zdaj pa pojdimo na zavihek Zaženi (prva ikona) in dodamo naslednjo kodo v ustrezno polje urejevalnika:
pvs-studio-analyzer credentials $PVS_USERNAME $PVS_KEY
if [ "$BUDDY_EXECUTION_PULL_REQUEST_NO" != '' ]; then
PULL_REQUEST_ID="pulls/$BUDDY_EXECUTION_PULL_REQUEST_NO"
MERGE_BASE=`wget -qO -
https://api.github.com/repos/${BUDDY_REPO_SLUG}/${PULL_REQUEST_ID}
| jq -r ".base.ref"`
git diff --name-only HEAD origin/$MERGE_BASE > .pvs-pr.list
pvs-studio-analyzer analyze -j8
-o PVS-Studio.log
--disableLicenseExpirationCheck
-S .pvs-pr.list
else
pvs-studio-analyzer analyze -j8
-o PVS-Studio.log
--disableLicenseExpirationCheck
fi
plog-converter -t errorfile PVS-Studio.log --cerr -w
Če ste prebrali razdelek o Travs-CI, potem vam je ta koda že znana, vendar je zdaj nova stopnja:
Dejstvo je, da zdaj ne analiziramo rezultata združitve, ampak HEAD veje, iz katere je vložena zahteva za vlečenje:
Torej smo v pogojni zavezi B3 in moramo dobiti razliko od A3:
PULL_REQUEST_ID="pulls/$BUDDY_EXECUTION_PULL_REQUEST_NO"
MERGE_BASE=`wget -qO -
https://api.github.com/repos/${BUDDY_REPO_SLUG}/${PULL_REQUEST_ID}
| jq -r ".base.ref"`
git diff --name-only HEAD origin/$MERGE_BASE > .pvs-pr.list
Za določitev A3 Uporabimo GitHub API:
https://api.github.com/repos/${USERNAME}/${REPO}/pulls/${PULL_REQUEST_ID}
Uporabili smo naslednje spremenljivke, ki jih ponuja Buddy:
- $BUDDY_EXECUTION_PULL_REQEUST_NO — številka zahteve za vlečenje;
- $BUDDY_REPO_SLUG — kombinacija uporabniškega imena in repozitorija (na primer max/test).
Zdaj pa shranimo spremembe s spodnjim gumbom in omogočimo analizo zahteve za vlečenje:
Za razliko od Travis CI nam ni treba navesti .pvs-studio za predpomnjenje, saj Buddy samodejno predpomni vse datoteke za naslednje zagone. Zato ostane zadnja stvar, da shranite prijavo in geslo za PVS-Studio v Buddy. Po shranjevanju sprememb bomo preusmerjeni nazaj v Pipeline. Preiti moramo na nastavitev spremenljivk in dodajanje prijave in ključa za PVS-Studio:
Po tem bo pojav nove zahteve za vlečenje ali potrditev sprožil pregled. Če objava vsebuje napake, bo Buddy to označil na strani z zahtevo po vleki.
AppVeyor
Nastavitev AppVeyorja je podobna Buddyju, saj se vse dogaja v spletnem vmesniku in ni treba dodajati datoteke *.yml v repozitorij projekta.
Pojdimo na zavihek Nastavitve v pregledu projekta:
Pomaknimo se navzdol po tej strani in omogočimo shranjevanje predpomnilnika za zbiranje zahtev za vlečenje:
Zdaj pa pojdimo na zavihek Okolje, kjer določimo sliko za montažo in potrebne spremenljivke okolja:
Če ste prebrali prejšnje razdelke, dobro poznate ti dve spremenljivki − PVS_KEY и PVS_USERNAME. Če ne, naj vas spomnim, da so potrebni za preverjanje licence analizatorja PVS-Studio. V prihodnosti jih bomo spet videli v skriptih Bash.
Na isti strani spodaj navedemo mapo za predpomnjenje:
Če tega ne storimo, bomo analizirali celoten projekt namesto nekaj datotek, vendar bomo dobili izhod iz navedenih datotek. Zato je pomembno, da vnesete pravilno ime imenika.
Zdaj je čas za preizkus scenarija. Odprite zavihek Testi in izberite Skript:
V ta obrazec morate prilepiti naslednjo kodo:
sudo apt-get update && sudo apt-get -y install jq
wget -q -O - https://files.viva64.com/etc/pubkey.txt
| sudo apt-key add -
sudo wget -O /etc/apt/sources.list.d/viva64.list
https://files.viva64.com/etc/viva64.list
sudo apt-get update && sudo apt-get -y install pvs-studio
pvs-studio-analyzer credentials $PVS_USERNAME $PVS_KEY
PWD=$(pwd -L)
if [ "$APPVEYOR_PULL_REQUEST_NUMBER" != '' ]; then
PULL_REQUEST_ID="pulls/$APPVEYOR_PULL_REQUEST_NUMBER"
MERGE_BASE=`wget -qO -
https://api.github.com/repos/${APPVEYOR_REPO_NAME}/${PULL_REQUEST_ID}
| jq -r ".base.ref"`
git diff --name-only HEAD origin/$MERGE_BASE > .pvs-pr.list
pvs-studio-analyzer analyze -j8
-o PVS-Studio.log
--disableLicenseExpirationCheck
--dump-files --dump-log pvs-dump.log
-S .pvs-pr.list
else
pvs-studio-analyzer analyze -j8
-o PVS-Studio.log
--disableLicenseExpirationCheck
fi
plog-converter -t errorfile PVS-Studio.log --cerr -w
Bodimo pozorni na naslednji del kode:
PWD=$(pwd -L)
if [ "$APPVEYOR_PULL_REQUEST_NUMBER" != '' ]; then
PULL_REQUEST_ID="pulls/$APPVEYOR_PULL_REQUEST_NUMBER"
MERGE_BASE=`wget -qO -
https://api.github.com/repos/${APPVEYOR_REPO_NAME}/${PULL_REQUEST_ID}
| jq -r ".base.ref"`
git diff --name-only HEAD origin/$MERGE_BASE > .pvs-pr.list
pvs-studio-analyzer analyze -j8
-o PVS-Studio.log
--disableLicenseExpirationCheck
--dump-files --dump-log pvs-dump.log
-S .pvs-pr.list
else
pvs-studio-analyzer analyze -j8
-o PVS-Studio.log
--disableLicenseExpirationCheck
fi
Precej specifična dodelitev vrednosti ukaza pwd spremenljivki, ki bi morala shraniti to privzeto vrednost, se zdi na prvi pogled nenavadna, vendar bom zdaj vse pojasnil.
Med nastavljanjem analizatorja v AppVeyorju sem naletel na izjemno čudno obnašanje analizatorja. Po eni strani je vse delovalo pravilno, vendar se analiza ni začela. Veliko časa sem opazil, da smo v imeniku /home/appveyor/projects/testcalc/, analizator pa je prepričan, da smo v /opt/appveyor/build-agent/. Potem sem ugotovil, da spremenljivka $PWD malo laže. Iz tega razloga sem pred začetkom analize ročno posodobil njegovo vrednost.
In potem je vse kot prej:
Zdaj razmislite o naslednjem fragmentu:
PULL_REQUEST_ID="pulls/$APPVEYOR_PULL_REQUEST_NUMBER"
MERGE_BASE=`wget -qO -
https://api.github.com/repos/${APPVEYOR_REPO_NAME}/${PULL_REQUEST_ID}
| jq -r ".base.ref"`
V njem dobimo razliko med vejami, nad katerimi je deklarirana zahteva za vlečenje. Za to potrebujemo naslednje spremenljivke okolja:
- $APPVEYOR_PULL_REQUEST_NUMBER — številka zahteve za poteg;
- $APPVEYOR_REPO_NAME - uporabniško ime in repozitorij projekta.
Zaključek
Seveda nismo upoštevali vseh možnih storitev kontinuirane integracije, vendar imajo vse med seboj izjemno podobne specifike delovanja. Z izjemo predpomnjenja vsaka storitev naredi svoje “kolo”, tako da je vedno vse drugače.
Nekje, na primer v Travis-CI, nekaj vrstic kode in predpomnjenje deluje brezhibno; nekje, na primer v AppVeyorju, morate samo določiti mapo v nastavitvah; toda nekje morate ustvariti edinstvene ključe in poskušati prepričati sistem, da vam da možnost, da prepišete predpomnjeni fragment. Če torej želite nastaviti analizo zahtev za vleko na storitev neprekinjene integracije, ki ni bila obravnavana zgoraj, se najprej prepričajte, da ne boste imeli težav s predpomnjenjem.
Hvala za vašo pozornost. Če vam kaj ne uspe, nam pišite na
Če želite ta članek deliti z angleško govorečim občinstvom, uporabite povezavo za prevod: Maxim Zvyagintsev.
Vir: www.habr.com