
PVS-Studio analüsaator C ja C++ keelte jaoks Linuxis ja macOSis, alates versioonist 7.04, pakub katsetamisvõimalust kontrollida loetletud failide nimekirja. Uue režiimiga saab analüsaatorit konfigureerida commit'ide ja pull request'ide kontrollimiseks. Käesolevas artiklis käsitletakse, kuidas seadistada GitHub-projekti muudetud failide nimekirja kontrollimist sellistes populaarsetes CI (Continuous Integration) süsteemides nagu Travis CI, Buddy ja AppVeyor.
Failide nimekirja kontrollimise režiim
on tööriist, mis aitab avastada vigu ja potentsiaalseid haavatavusi programmide lähtekoodis, mis on kirjutatud keeltes C, C++, C# ja Java. See töötab 64-bitistes süsteemides Windowsis, Linuxis ja macOSis.
PVS-Studio 7.04 versioonis Linuxile ja macOS-ile on lisandunud lähtefailide nimekirja kontrollimise režiim. See töötab projektide puhul, mille ehitussüsteem suudab genereerida faili . See on vajalik, et analüsaator saaks tuvastada nimetatud failide kompileerimise kohta teabe. Kui teie ehitussüsteem ei toeta compile_commands.json faili genereerimist, võite proovida genereerida sellise faili utiliidi .
Samuti saab failide nimekirja kontrollimise režiimi kasutada koos kompilatsiooni jälgimise logiga (pvs-studio-analyzer trace). Selleks peate esmalt andma projekti täieliku kogumise ja jälgima seda, et analüsaator koguks täieliku teabe kõigi kontrollitavate failide kompilatsiooni parameetrite kohta.
Kuid sellisel variandil on tõsine puudus - peate kas tegema kogu projekti kogumise jälgimise iga käivituse ajal, mis aga on vastuolus kiire muudatuste kontrollimise ideega. Või kui salvestada jälgimise tulemused, võivad analüsaatori järgmised käivitused olla puudulikud, kui jälgimise järel muudetakse allikafailide sõltuvuste struktuuri (näiteks kui ühte allikafaili lisatakse uus #include).
Seetõttu ei soovita me kasutada failide nimekirja kontrollimise režiimi koos jälgimise logiga muudatuste või pull request'ide kontrollimise jaoks. Kui saate muudatuste kontrollimisel teha inkrementaalset kogumist, kaaluge inkrementaalse analüüsi režiimi kasutamist. .
Töötluseks mõeldud lähtefailide nimekiri salvestatakse tekstifaili ja edastatakse analüsaatorile parameetri abil -S:
pvs-studio-analyzer analyze ... -f build/compile_commands.json -S check-list.txtSelles failis märgitakse esile suhtelised või absoluutsed failiteed ning iga uus fail peab olema uuel real. Lubatud on märkida mitte ainult töötlemiseks mõeldud failide nimed, vaid ka erinev tekst. Analüsaator näeb, et see ei ole fail, ja ignoreerib rida. See võib olla kasulik kommentaaride tegemiseks, kui failid märgitakse käsitsi. Siiski genereeritakse failide nimekiri sageli analüüsi käigus CI-s, näiteks võivad need olla failid commit’ist või pull request’ist.
Nüüd on selle režiimi abil võimalik kiiresti kontrollida uut koodi enne selle pääsemist peamisse arendusokku. Selleks, et kontrollimissüsteem reageeriks analüsaatori hoiatuste olemasolule, on tööriista plog-converter lisatud lipp —indicate-warnings:
plog-converter ... --indicate-warnings ... -o /path/to/report.tasks ...Selle lipuga tagastab muundur nullist erineva koodi, kui analüsaatori aruandes on hoiatusi. Tagastuskoode saab kasutada pre-commit hook'i, commit'i või pull request'i blokeerimiseks ning genereeritud analüsaatori aruannet saab kuvada, jagada või e-posti teel saata.
Märkus. Esmakordsel failide nimekirja analüüsimisel analüüsitakse kogu projekti, kuna analüsaator peab genereerima projekti lähtefailide ja peafailide sõltuvuste faili. See on C ja C++ failide analüüsi eripära. Tulevikus saab sõltuvuste faili vahemällu salvestada ja analüsaator uuendab seda automaatselt. Kommituste kontrollimise eelised failide nimekirja kontrollimise režiimis enne inkrementaalse analüüsi režiimi kasutamist seisnevad selles, et tuleb vahemällu salvestada ainult see fail, mitte objekti failid.
Pull request'i analüüsi üldpõhimõtted
Kogu projekti analüüsimine võtab märkimisväärselt aega, seetõttu on mõttekas kontrollida ainult mõnda selle osa. Probleem on selles, et tuleb eristada uusi faile teistest projekti failidest.
Käime läbi commit-puu näite, kus on kaks haru:

Kujutage ette, et commit A1 sisaldab piisavalt suurt koodihulka, mis on juba üle vaadatud. Veidi varem lõime haru commit'ist A1 ja muutsime mingeid faile.
Te kindlasti märkate, et pärast A1 on toimunud veel kaks commit'i, kuid need olid samuti teiste harude liitmist, sest me ei kommenteeri ju master. Ja nüüd on aeg, kui hotfix on valmis. Seetõttu on tekkinud pull request nende liitmiseks B3 ja A3.
Loomulikult oleks olnud võimalik kontrollida kogu nende liitmise tulemust, kuid see oleks liiga pikk ja põhjendamatu, kuna muudeti ainult mõningaid faile. Seega on efektiivsem analüüsida ainult muudetud.
Selleks saame erinevuse harude vahel, olles HEAD harus, millest tahame masterisse sulanduda:
git diff --name-only HEAD origin/$MERGE_BASE > .pvs-pr.list$MERGE_BASE millest räägime üksikasjalikult hiljem. Asjaolu on see, et kaugel mitte iga CI teenus ei paku vajalikku teavet sulandumisbaasi kohta, seetõttu tuleb iga kord välja mõelda uusi viise nende andmete saamiseks. See on üksikasjalikult kirjas allpool igas mainitud veebiteenuses.
Nüüd on meil eristatud harude vahel ning täpsemalt — failinimede loend, mis on muutunud. Nüüd peame faili edastama .pvs-pr.list (kuhu me suunatasime ülaltoodud väljundi) analüsaatorile:
pvs-studio-analyzer analyze -j8
-o PVS-Studio.log
-S .pvs-pr.listPärast analüüsi peame logifaili (PVS-Studio.log) konverteerima mugavasse formaati:
plog-converter -t errorfile PVS-Studio.log --cerr -wSee käsk annab välja vigade loendi (standardne veateate väljund).
Aga me peame mitte ainult vigu välja andma, vaid ka andma meie koostamise ja testimise teenusele teada probleemide olemasolust. Selleks on konverterile lisatud lipp -W (—indicate-warnings). Kui analüsaatoril on vähemalt üks hoiatus, kahtub utiliidi tagastusväärtus plog-converter 2-ks, mis omakorda teavitab CI teenust võimalike vigade olemasolust pull request'i failides.
Travis CI
Konfiguratsioon on vormistatud faili .travis.yml. Mugavuse huvides soovitan kõik välja tuua eraldi bash-skriptis koos funktsioonidega, mida kutsutakse failist .travis.yml (bash skripti_nimi.sh funktsiooni_nimi).
Lisame vajalikku koodi skripti bash, nii saame suurema funktsionaalsuse. Jaotises install kirjutame järgmist:
install:
- bash .travis.sh travis_installKui teil on mingeid juhiseid, võite need kopeerida skriptisse, eemaldades sidekriipsud.
Avame faili .travis.sh ja lisame analüsaatori instalatsiooni 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-skriptis:
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 pärast projekti koostamist, näiteks, kui teil oli CMake'i koostamine:
travis_script() {
CMAKE_ARGS="-DCMAKE_EXPORT_COMPILE_COMMANDS=On ${CMAKE_ARGS}"
cmake $CMAKE_ARGS CMakeLists.txt
make -j8
}Saab olema selline:
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
}Võimalik, et olete juba märganud, et siinkohal on keskkonnamuutujad $TRAVIS_PULL_REQUEST ja $TRAVIS_BRANCH. Travis CI määrab need automaatselt:
- $TRAVIS_PULL_REQUEST salvestab pull request'i numbri või false, kui see on tavaline haru;
- $TRAVIS_REPO_SLUG salvestab projekti repot nime.
Selle funktsiooni tööpõhimõte:

Travis CI reageerib tagastuskoodidele, seega hoiatuste olemasolu näitab teenusele, et järgmine kinnitus sisaldab vigu.
Ja nüüd vaatame seda koodirida lähemalt:
git diff --name-only origin/HEAD > .pvs-pr.listAsjaolu on see, et Travis CI automaatselt liitb harude vahel analüüsi käigus pull request'i:

Seega analüüsime A4, mitte B3->A3. Selle omaduse tõttu peame me arvutama erinevuse A3, mis on haru ülemine punkt. origin.
Üks oluline detail jäi veel — päistesse failidesse viidatavate sõltuvuste vahemälu (* .c, *.cc, *.cpp jne) salvestamine. Need sõltuvused analüsaator arvutab esmakordsel käivitamisel failide nimekirja kontrollimise režiimis ja salvestab seejärel katalooge .PVS-Studio. Travis CI võimaldab kaustu vahemälustada, seega salvestame selle katalooge andmed. .PVS-Studio/:
vahemälu:
kataloogid:
- .PVS-Studio/See kood tuleb lisada faili .travis.yml. See kataloog sisaldab erinevaid analüüsi käigus kogutud andmeid, mis kiirendavad oluliselt edasisi failide nimekirja analüüse või inkrementaalanalüüse. Kui seda ei tehta, analüüsib analüsaator sisuliselt iga kord kõiki faile.
Buddy
Nagu Travis CI, pakub automatiseeritud projekti koostamise ja testimise võimalust, mis on salvestatud GitHubi. Erinevalt Travis CI-st seadistatakse see veebiliidese kaudu (tuginedes bash-le), seega ei ole vaja salvestada konfiguratsioonifaile projektis.
Esiteks peame lisama uue tegevuse koostamisliini:

Määrame kompilaatori, mida kasutati projekti koostamisel. Pange tähele, et selle toimingu jaoks on installitud docker konteiner. Näiteks GCC jaoks on spetsiaalne konteiner:

Nüüd installime 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 liikume vahekaardile Run (esimene ikoon) ja vastavasse redaktori välja lisame 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 Travs-CI-le pühendatud osa, siis on see kood teile juba tuttav, kuid nüüd on lisandunud uus etapp:

Asi on see, et nüüd analüüsime mitte ühendamise tulemust, vaid HEAD haru, millest pull request tehakse:

Seetõttu oleme tinglikus commit'is B3 ja peame saama 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ääratlemiseks A3 kasutame GitHub API-d:
https://api.github.com/repos/${USERNAME}/${REPO}/pulls/${PULL_REQUEST_ID}Kasutame järgmisi muutujaid, mille Buddy pakub:
- $BUDDY_EXECUTION_PULL_REQEUST_NO — pull request'i number;
- $BUDDY_REPO_SLUG — kasutajanime ja repositorio kombinatsioon (näiteks max/test).
Nüüd salvestame muudatused, kasutades allolevat nuppu, ja aktiveerime pull request'i analüüsi:

Kuna meil ei ole vaja näidata .pvs-studio vahemälu, kuna Buddy salvestab kõik failid automaatselt järgmisteks käivitusteks. Seega jääb veel viimane — salvestada PVS-Studio login ja parool Buddy's. Pärast muudatuste salvestamist naaseme Pipeline'i. Me peame minema muutujate seadete juurde ja lisama PVS-Studio login ja võtme:

Pärast seda käivitab uue pull request’i või commit’i ilmumine kontrolli. Kui commit sisaldab vigu, siis Buddy märgib selle pull request’i lehel.
AppVeyor
AppVeyori seadistamine on sarnane Buddy’le, kuna kõik toimub veebiliideses ja ei ole vaja lisada projekti hoidlas *.yml faili.
Liigume projekti ülevaates vahekaardile Seaded:

Kerime lehte allapoole ja aktiveerime pull request’ide ehitamise vahemälu salvestamise:

Nüüd liigume vahekaardile Keskkond, kus määrame ehituskuva ja vajalikud keskkonna muutuja:

Kui oled eelnevaid jaotisi lugenud, siis oled nende kahe muutujaga hästi tuttav — PVS_KEY ja PVS_USERNAME. Kui ei, siis tuletan meelde, et need on vajalikud PVS-Studio analüsaatori litsentsi kontrollimiseks. Edasi kohtame neid taas Bash skriptides.
Sellel lehe alumises osas määrame vahemälu salvestamise kausta:

Kui me seda ei tee, siis analüüsime mitte paari faili, vaid kogu projekti, kuid saame väljundi märkitud failide kohta. Seetõttu on oluline sisestada õige kaustanimi.
Nüüd on aeg kontrollimise skripti jaoks. Avame vahekaart Testid 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 -wTähtis on tähele panna järgmine koodi osa:
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
fiPakub üsna spetsiifilist väärtuse määramist käsk pwd muutujale, mis peaks seda väärtust vaikimisi hoidma, tundub esmapilgul kummaline, kuid lubage mul selgitada.
AppVeyoris analyzisa seadistades kogesin äärmiselt kummalist käitumist. Ühest küljest toimis kõik õigesti, kuid analüüsi ei alustatud. Kulutasin palju aega, et märkida, et oleme kataloogis /home/appveyor/projects/testcalc/, kuid analyzis on kindel, et oleme /opt/appveyor/build-agent/. Siis taipasin, et muutuja $PWD ütleb veidi vale infot. Seetõttu uuendasin selle väärtust käsitsi enne analüüsi käivitamist.
Ja edasi on kõik nagu varem:

Nüüd vaatame järgmisi fragmente:
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"`Siin saame erinevust harude vahel, mille üle on tehtud pull request. Selleks vajame järgmisi keskkonnamuutujaid:
- $APPVEYOR_PULL_REQUEST_NUMBER — pull request'i number;
- $APPVEYOR_REPO_NAME — kasutajanimi ja projekti hoidla nimi.
Kokkuvõte
Loomulikult ei ole me käsitlenud kõiki pideva integreerimise teenuseid, kuid nende tööspetsifikatsioonid on üksteisega äärmiselt sarnased. Välja arvatud vahemälu, kõik teenused loovad oma „jalgratta”, seega on alati kõik erinev.
Mõnes, nagu Travis-CI, piisab paarist koodireast ja vahemälu töötab veatult; teises, nagu AppVeyor, tuleb lihtsalt seadistustes märkida kaust; kuid mõnes tuleb luua unikaalsed võtmed ja proovida veenda süsteemi, et ta annaks võimaluse vahemälus olev fragment üle kirjutada. Seega, kui soovite seadistada pull requestide analüüsi integreerimisteenusel, mida eelnevalt ei käsitletud, veenduge esmalt, et teil ei tekiks vahemäluga probleeme.
Aitäh tähelepanu eest. Kui midagi ei toimi, kirjutage meile julgelt . Me aitame ja juhendame teid.
Kui soovite seda artiklit jagada ingliskeelse publikuga, palun kasutage tõlke linki: Maxim Zvyagintsev. .
Allikas: habr.com
