
PVS-Studio analüsaator C ja C++ keeltele Linuxil ja macOS-il, alates versioonist 7.04, on saanud katsefunktsiooni, mis võimaldab kontrollida määratud failide nimekirja. Uue režiimi abil saate seadistada analüsaatori commitide ja pull request'ide kontrollimiseks. Selles artiklis räägitakse, kuidas seadistada GitHub projekti muudetud failide nimekirja kontrollimist sellistes populaarsetes CI (Continuous Integration) süsteemides nagu Travis CI, Buddy ja AppVeyor.
Failide loendi kontrollimise režiim
— on tööriist vigu ja võimalikke haavatavusi tuvastamiseks programmide lähtekoodis, mis on kirjutatud keeltes C, C++, C# ja Java. Töötab 64-bitistes süsteemides Windowsis, Linuxis ja macOS-is.
PVS-Studio versioonis 7.04 Linuxile ja macOS-ile on ilmunud lähtefailide nimekirja kontrollimise režiim. See töötab projektide jaoks, mille ehitussüsteem suudab genereerida faili . See on vajalik, et analüsaator saaks väljavõtte teave määratud failide kompileerimise kohta. Kui teie ehitussüsteem ei toeta faili compile_commands.json genereerimist, võite proovida seda faili genereerida utiliidi abil .
Samuti saab lähtefailide nimekirja kontrollimise režiimi kasutada koos kompilatsioonide jälgimise logidega (pvs-studio-analyzer trace). Selleks peate kõigepealt tegema täiendava ehituse projekti jaoks ja seda jälgima, et analüsaator koguks täielikku teavet kõikide kontrollitavate failide kompileerimisseadete kohta.
Siiski on selle variandi oluline puudus — peate kas iga käivituse ajal tegema kogu projekti ehituse jälgimise, mis on vastuolus kiire commit'i kontrollimise ideega. Või, kui salvestate jälgimise tulemuse, võivad analüsaatori järgmised käivitused osutuda puudulikeks, kui pärast jälgimist muudetakse lähtefailide sõltuvuste struktuuri (näiteks lisatakse ühte lähtefaili uus #include).
Seetõttu ei soovita me lähtefailide nimekirja kontrollimise režiimi kasutada koos jälgimise logiga commit'ide või pull request'ide kontrollimiseks. Kui saate commit'i kontrollimise käigus teha inkrementaalse ehituse, kaaluge inkrementaalse analüüsi režiimi kasutamist. .
Lähtefailide nimekiri analüüsimiseks salvestatakse tekstifaili ja edastatakse analüsaatorile parameetri abil -S:
pvs-studio-analyzer analyze ... -f build/compile_commands.json -S check-list.txtSelles failis näidatakse suhtelisi või absoluutseid teid failidele, kusjuures iga uus fail peab olema uuel real. Lubatud on näidata mitte ainult analüüsitavate failide nimesid, vaid ka erinevat teksti. Analüsaator näeb, et see ei ole fail, ja ignoreerib rida. See võib olla kasulik, kui failid on käsitsi märgitud. Siiski on sageli failide loetelu genereeritud analüüsi käigus CI-s, näiteks võivad need olla failid commit'i või tõmbe päringu (pull request) kaudu.
Nüüd saab selle režiimi abil kiiresti kontrollida uut koodi, enne kui see peamiseks arendusoksaks jõuab. Et kontrollimise süsteem reageeriks analüsaatori hoiatustele, peab utiliit plog-converter lisatud lipp —indicate-warnings:
plog-converter ... --indicate-warnings ... -o /path/to/report.tasks ...Selle lipuga tagastab konverter mitte-nullkoodi, kui analüsaatori aruandes on hoiatusi. Tagastatud koodi abil saab blokeerida enne commit'i toimingu, commit'i või tõmbe päringu, ning genereeritud analüsaatori aruande kuvada ekraanil, jagada või saata e-posti teel.
Märkus. Esimese failide loendi analüüsi käigus analüüsitakse kogu projekti, kuna analüsaator peab genereerima projektifailide sõltuvuste faili päiseid. See on C ja C++ failide analüüsi omadus. Edaspidi saab sõltuvuste faili vahemällu salvestada ja see uuendatakse automaatselt analüsaatori poolt. Komiteerimise kontrollimise eelisteks failide loendi kontrollimise režiimi kasutamisel võrreldes inkrementaalse analüüsi režiimiga on see, et tuleb vahemällu salvestada ainult see fail, mitte objektifailid.
Pull request'i analüüsi üldpõhimõtted
Kogu projekti analüüs võtab piisavalt kaua aega, seetõttu on mõistlik kontrollida ainult teatud osa sellest. Probleem on selles, et tuleb eraldada uued failid ülejäänud projekti failidest.
Vaatame commit'ide puu näidet kahes harus:

Kujutage ette, et commit A1 sisaldab piisavalt suurt hulka koodi, mis on juba kontrollitud. Veidi varem tegime me haru commit'ist A1 ja muutsime mõningaid faile.
Te olete kindlasti märganud, et pärast A1 toimus veel kaks commit'i, aga need olid samuti teiste harude sulandumised, sest me ei komitee siiski master. Ja nüüd on käes aeg, mil hotfix valmis. Seetõttu tekkis pull request liitmiseks B3 ja A3.
Loomulikult oleks olnud võimalik kontrollida kogu nende liitmise tulemust, kuid see oleks olnud liiga aeganõudev ja põhjendamatu, kuna muudeti vaid mõnda faili. Seega on efektiivsem analüüsida ainult muudetud faile.
Selleks saame vahe nende harude vahel, olles HEAD haru peal, kust soovime masterisse liituda:
git diff --name-only HEAD origin/$MERGE_BASE > .pvs-pr.list$MERGE_BASE kui me vaatame seda hiljem. Asi on selles, et kaugel enamus CI teenustest ei paku vajalikku teavet liitmise alusinfo kohta, seega tuleb igal korral välja mõelda uusi viise nende andmete saamiseks. See on detailsemalt kirjeldatud allpool iga kirjeldatud veebiteenuse puhul.
Nii, oleme saanud vahe nende harude vahel, täpsemalt — nimekirja failidest, mis on muudetud. Nüüd peame andma faili .pvs-pr.list (me suunasime väljundi ülal) analüsaatorile:
pvs-studio-analyzer analyze -j8
-o PVS-Studio.log
-S .pvs-pr.listPärast analüüsi peame konverteerima logifaili (PVS-Studio.log) arusaadavasse vormingusse:
plog-converter -t errorfile PVS-Studio.log --cerr -wSee käsk tagastab loendi vigadest (veateate standardväljund).
Aga meil on vaja mitte ainult vigu väljundada, vaid ka teavitada meie koostamis- ja testimise teenust probleemide olemasolust. Selle jaoks on konverterisse lisatud märgis -W (—indicate-warnings). Kui analüsaator tuvastab vähemalt ühe hoiatuse, siis utiliidi väljakutsumise tagastuskood plog-converter muutub arvuks 2, mis omakorda teavitab CI teenust potentsiaalsetest vigadest pull requesti failides.
Travis CI
Konfiguratsioon on teostatud faili .travis.yml. Mugavuse tõttu soovitan kõik välja tuua eraldi bash-skripti, mille funktsioone hakatakse kutsuma failist .travis.yml (bash skripti_nimi.sh funktsiooni_nimi).
Lisame vajalikku koodi skripti bash, sel viisil saame suurema funktsionaalsuse. Sektsiooni install kirjutame järgmist:
install:
- bash .travis.sh travis_installKui teil on olnud mõni juhend, saate selle skripti sisse kanda, eemaldades sidekriipsud.
Avame faili .travis.sh ja lisame analüsaatori installi funktsiooni 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
}Nüüd lisame sektsiooni script analüüsi käivitamine:
script:
- bash .travis.sh travis_scriptJa bash-skripti:
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
}Seda koodi tuleb käivitada projekti koostamise järel, näiteks kui teil on olnud koostamine CMake'iga:
travis_script() {
CMAKE_ARGS="-DCMAKE_EXPORT_COMPILE_COMMANDS=On ${CMAKE_ARGS}"
cmake $CMAKE_ARGS CMakeLists.txt
make -j8
}See peaks olema niimoodi:
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
}Tõenäoliselt olete juba märganud mainitud keskkonnamuutujaid $TRAVIS_PULL_REQUEST ja $TRAVIS_BRANCH. Travis CI kuulutab need välja automaatselt:
- $TRAVIS_PULL_REQUEST hoiab pull request'i numbrit või false, kui see on tavaline haru;
- $TRAVIS_REPO_SLUG hoiab projekti repositoore nime.
Selle funktsiooni tööloogika on järgmine:

Travis CI reageerib tagastuskoodidele, seetõttu hoiatuste olemasolu tähistab teenusele, et commit sisaldab vigu.
Nüüd vaatame seda koodirida lähemalt:
git diff --name-only origin/HEAD > .pvs-pr.listAsi on selles, et Travis CI teeb automaatselt harude ühinemisi pull request'ide analüüsi ajal:

Seetõttu analüüsime A4, mitte B3->A3. Selle omaduse tõttu peame arvutama erinevuse A3, mis on just see haru tipus origin..
Üks oluline detail on - koostamisseansside (*.c, *.cc, *.cpp jne) pealkirifailide sõltuvuste vahemälu. Need sõltuvused analüüsija arvutab esmakordselt failide nimekirja kontrollimise režiimis ja salvestab seejärel kausta .PVS-Studio. Travis CI võimaldab kauste vahemällu salvestada, seega salvestame kausta andmed .PVS-Studio/:
cache:
directories:
- .PVS-Studio/See kood tuleb lisada faili .travis.yml. See kataloog sisaldab erinevaid andmeid, mis on kogutud analüüsi käigus ja mis kiirendavad oluliselt edasisi failide nimekirja analüüse või inkrementaalset analüüsi. Kui seda ei tehta, peab analüsaator tegelikult iga kord kõik failid analüüsima.
Buddy
Nagu Travis CI, pakub automaatsete kogumise ja testimise võimalust projektidele, mis on salvestatud GitHub'is. Erinevalt Travis CI-st configureeritakse see veebiliidese kaudu (bash toe olemas), seega pole vaja konfiguratsioonifaile projektis hoida.
Esmalt peame lisama uue toimingu kogumisse:

Määratleme kompilaatori, mida kasutati projekti kogumisel. Pange tähele, et selle toimingu puhul on kasutusel docker konteiner. Näiteks, GCC jaoks on olemas eraldi konteiner:

Nüüd paigaldame PVS-Studio ja vajalikud utiliidid:

Lisame redaktorisse järgmised read:
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-studioNüüd läheme vahekaardile Run (esimene ikoon) ja lisame redaktori vastavasse välja järgmise koodi:
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 -wKui olete lugenud Travis-CI-le pühendatud jaotist, siis on see kood teile juba tuttav, kuid nüüd on lisandunud uus etapp:

Asi on selles, et nüüd analüüsime mitte sulandamise tulemust, vaid HEAD haru, millisest pull request tehakse:

Seega oleme tinglikus commitis B3 ja peame leidma erinevuse 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.listMääramiseks A3 kasutame GitHub API-d:
https://api.github.com/repos/${USERNAME}/${REPO}/pulls/${PULL_REQUEST_ID}Kasutasime järgmisi muutujaid, mida pakub Buddy:
- $BUDDY_EXECUTION_PULL_REQEUST_NO — pull request'i number;
- $BUDDY_REPO_SLUG — kasutajanime ja reposti kombinatsioon (näiteks max/test).
Salvestame muudatused, kasutades allolevat nuppu, ja aktiveerime pull request'i analüüsi:

Erinevalt Travis CI-st ei ole meil vaja näidata .pvs-studio vahemälu jaoks, kuna Buddy salvestab automaatselt kõik failid edasiste käivituste jaoks. Jäänud on vaid viimane samm - salvestada PVS-Studio kasutajanimi ja parool Buddy's. Pärast muudatuste salvestamist naaseme Pipeline'i. Peame minema muutujate seadistamise juurde ja lisama PVS-Studio kasutajanime ja võtme:

Pärast seda, kui uus pull request või commit ilmub, käivitub kontroll. Kui commit sisaldab vigu, siis Buddy näitab seda pull request'i lehel.
AppVeyor
AppVeyori seadistamine sarnaneb Buddy'le, kuna kõik toimub veebiliideses ja pole vaja lisada *.yml faili projekti hoidlasse.
Liigume projekti ülevaates Seaded vahekaardile:

Kerime lehte alla ja lülitame sisse vahemälu salvestamise pull request'ide koostamiseks:

Nüüd liigume keskkonna vahekaardile, kus näitame koostamispilti ja vajalikke keskkonnamuutujad:

Kui oled eelnevaid jaotisi lugenud, siis tunned neid kahte muutujat hästi - PVS_KEY ja PVS_USERNAME. Kui ei, siis meenutan, et need on vajalikud PVS-Studio analüsaatori litsentsi kontrollimiseks. Hiljem kohtame neid taas Bash skriptides.
Sama lehe alumises osas määrame vahemälu kausta:

Kui me seda ei tee, analüüsime mitte paarikaupa faile, vaid kogu projekti, kuid väljund saadakse antud failide põhjal. Seetõttu on oluline sisestada õige kausta nimi.
Nüüd on aeg skripti jaoks kontrollimiseks. Avame Testide vahekaardi ja valime Skript:

Sellesse vormi tuleb sisestada järgmine kood:
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 -wJätkame koodi järgmise osa tähelepanemist:
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
fiEsmapärane, et pwd-käsu väärtuse määramine muutujale, mis peaks seda väärtust sisaldama, tundub esmapilgul veider, kuid ma selgitan hetke.
AppVeyoris analüsaatori seadistamise ajal kohtasin ma väga veidrat analüsaatori käitumist. Ühelt poolt töötas kõik õigesti, kuid analüüs ei käivitunud. Kulutasin palju aega, et märgata, et oleme kataloogis /home/appveyor/projects/testcalc/, samas kui analüsaator arvas, et oleme /opt/appveyor/build-agent/. Siis sain aru, et muutuja $PWD valetab veidi. Sellepärast värskendasin selle väärtust käsitsi enne analüüsi käivitamist.
Ja edasi on kõik nagu varem:

Nüüd vaatame järgmist fragmenti:
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"`Selles saame erisuse nende harude vahel, mille üle on tehtud pull-request. Selleks vajame järgmisi keskkonnamuutujaid:
- $APPVEYOR_PULL_REQUEST_NUMBER — pull-requesti number;
- $APPVEYOR_REPO_NAME — projekti kasutajanimi ja hoidla nimi.
Kokkuvõte
Muidugi ei käsitlenud me kõiki võimalikke pideva integreerimise teenuseid, kuid neil on kõikidel üsna sarnased tegevusspetsiifilised omadused. Välja arvatud vahemälu, iga teenus ehitab oma 'ratta', seega on kõik alati erinev.
Kusagil, nagu Travis-CI-s, paar koodiread ja vahemälu töötab veatult; kusagil, nagu AppVeyor, tuleb lihtsalt seades kaust määrata; kuid kusagil tuleb luua unikaalsed võtmed ja püüda veenda süsteemi, et ta annaks võimaluse vahemälustatud fragmenti uuesti kirjutada. Seetõttu, kui soovite seadistada pull-requestide analüüsi pideva integreerimise teenuses, mida eespool pole käsitletud, veenduge esmalt, et vahemäluga ei tekiks probleeme.
Aitäh tähelepanu eest. Kui midagi ei õnnestu, siis kirjutage julgelt meile . Me juhendame ja aitame teid.
Kui soovite seda artiklit jagada ingliskeelse publikuga, palun kasutage tõlke linki: Maxim Zvyagintsev. .
Allikas: habr.com
