U analizatoru PVS-Studio za jezike C i C++ na Linuxu i macOS-u, počevši od verzije 7.04, pojavila se testna opcija za provjeru popisa navedenih datoteka. Koristeći novi način rada, možete konfigurirati analizator da provjerava predaje i zahtjeve za povlačenjem. Ovaj članak će vam reći kako postaviti provjeru popisa promijenjenih datoteka GitHub projekta u popularnim CI (Continuous Integration) sustavima kao što su Travis CI, Buddy i AppVeyor.
Način provjere popisa datoteka
U verziji PVS-Studio 7.04 za Linux i macOS pojavio se način za provjeru popisa izvornih datoteka. Ovo funkcionira za projekte čiji vam sustav izrade omogućuje generiranje datoteke
Također, način provjere popisa datoteka može se koristiti zajedno sa strace zapisom praćenja pokretanja prevoditelja (pvs-studio-analyzer trag). Da biste to učinili, morat ćete prvo izvršiti punu izgradnju projekta i pratiti ga tako da analizator prikupi potpune informacije o parametrima kompilacije svih datoteka koje se provjeravaju.
Međutim, ova opcija ima značajan nedostatak - morat ćete izvršiti potpuno praćenje izgradnje cijelog projekta svaki put kada ga pokrenete, što je samo po sebi u suprotnosti s idejom brze provjere predaje. Ili, ako predmemorirate sam rezultat praćenja, naknadna pokretanja analizatora mogu biti nepotpuna ako se struktura ovisnosti izvornih datoteka promijeni nakon praćenja (na primjer, novi #include je dodan jednoj od izvornih datoteka).
Stoga ne preporučujemo korištenje načina provjere popisa datoteka s zapisnikom praćenja za provjeru obveza ili zahtjeva za povlačenjem. U slučaju da možete napraviti inkrementalnu izgradnju kada provjeravate predaju, razmislite o korištenju načina
Popis izvornih datoteka za analizu sprema se u tekstualnu datoteku i prosljeđuje analizatoru pomoću parametra -S:
pvs-studio-analyzer analyze ... -f build/compile_commands.json -S check-list.txt
Ova datoteka navodi relativne ili apsolutne staze do datoteka, a svaka nova datoteka mora biti u novom retku. Prihvatljivo je navesti ne samo nazive datoteka za analizu, već i različite tekstove. Analizator će vidjeti da ovo nije datoteka i zanemarit će redak. Ovo može biti korisno za komentiranje ako su datoteke navedene ručno. Međutim, često će se tijekom analize u CI-ju generirati popis datoteka, na primjer, to mogu biti datoteke iz zahtjeva za predaju ili povlačenje.
Sada, koristeći ovaj način, možete brzo provjeriti novi kod prije nego što uđe u glavnu razvojnu granu. Kako bi se osiguralo da sustav za skeniranje reagira na upozorenja analizatora, uslužni program plog-pretvarač zastava dodana --indicate-warnings:
plog-converter ... --indicate-warnings ... -o /path/to/report.tasks ...
Uz ovu zastavu, pretvarač će vratiti kod različit od nule ako postoje upozorenja u izvješću analizatora. Koristeći povratni kod, možete blokirati precommit hook, commit ili zahtjev za povlačenjem, a generirano izvješće analizatora može se prikazati, dijeliti ili poslati e-poštom.
Bilješka. Kada prvi put počnete analizirati popis datoteka, analizirat će se cijeli projekt, jer analizator treba generirati datoteku ovisnosti izvornih datoteka projekta o datotekama zaglavlja. Ovo je značajka analize C i C++ datoteka. U budućnosti se datoteka ovisnosti može predmemorirati i analizator će je automatski ažurirati. Prednost provjere obveza kada se koristi način provjere popisa datoteka u odnosu na korištenje načina inkrementalne analize je u tome što trebate spremiti samo tu datoteku u predmemoriju, a ne objektne datoteke.
Opća načela analize zahtjeva za povlačenjem
Analiza cjelokupnog projekta oduzima puno vremena, stoga ima smisla provjeriti samo određeni dio. Problem je u tome što trebate odvojiti nove datoteke od ostalih datoteka projekta.
Pogledajmo primjer stabla urezivanja s dvije grane:
Zamislimo taj commit A1 sadrži prilično veliku količinu koda koji je već testiran. Nešto ranije napravili smo granu iz commita A1 i promijenio neke datoteke.
Vi ste to, naravno, primijetili nakon A1 dogodila su se još dva commita, ali i to su bila spajanja drugih ogranaka, jer mi se ne obvezujemo majstor. A sada je došlo vrijeme kada hitni popravak spreman. Zato se pojavio zahtjev za povlačenje spajanja B3 и A3.
Naravno, bilo bi moguće provjeriti cijeli rezultat njihovog spajanja, ali bi to bilo predugo i neopravdano, jer je promijenjeno samo nekoliko datoteka. Stoga je učinkovitije analizirati samo one promijenjene.
Da bismo to učinili, dobivamo razliku između grana, koje su u HEAD-u grane iz koje se želimo spojiti u master:
git diff --name-only HEAD origin/$MERGE_BASE > .pvs-pr.list
$MERGE_BASE kasnije ćemo ga detaljno pogledati. Činjenica je da svaka CI usluga ne pruža potrebne informacije o bazi podataka za spajanje, tako da svaki put morate smisliti nove načine za dobivanje tih podataka. To će biti detaljno opisano u nastavku u svakoj od opisanih web usluga.
Dakle, dobili smo razliku između grana, odnosno popis imena datoteka koje su promijenjene. Sada moramo dati datoteku .pvs-pr.list (preusmjerili smo izlaz iznad na njega) na analizator:
pvs-studio-analyzer analyze -j8
-o PVS-Studio.log
-S .pvs-pr.list
Nakon analize moramo pretvoriti log datoteku (PVS-Studio.log) u format koji je lako čitljiv:
plog-converter -t errorfile PVS-Studio.log --cerr -w
Ova naredba će ispisati pogreške u
Tek sada moramo ne samo prikazati pogreške, već i obavijestiti našu službu za montažu i testiranje o prisutnosti problema. U tu svrhu, pretvaraču je dodana zastavica -W (--indicate-warnings). Ako postoji barem jedno upozorenje analizatora, povratni kod pomoćnog programa plog-pretvarač promijenit će se u 2, što će zauzvrat obavijestiti CI uslugu o prisutnosti potencijalnih pogrešaka u datotekama zahtjeva za povlačenje.
Travis C.I.
Konfiguracija je napravljena kao datoteka .travis.yml. Radi praktičnosti, savjetujem vam da sve stavite u zasebnu bash skriptu s funkcijama koje će se pozivati iz datoteke .travis.yml (bash naziv_skripte.sh naziv_funkcije).
Dodat ćemo potreban kod u skriptu na udariti, na ovaj način ćemo dobiti više funkcionalnosti. U odjeljku instalirati napišimo sljedeće:
install:
- bash .travis.sh travis_install
Ako ste imali ikakve upute, možete ih prenijeti u skriptu, uklanjajući crtice.
Otvorimo datoteku .travis.sh i dodajte postavku analizatora u funkciju 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
}
Sada dodajmo dio rukopis pokreni analizu:
script:
- bash .travis.sh travis_script
I u 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
}
Ovaj kod treba pokrenuti nakon izgradnje projekta, na primjer, ako ste imali nadogradnju na CMakeu:
travis_script() {
CMAKE_ARGS="-DCMAKE_EXPORT_COMPILE_COMMANDS=On ${CMAKE_ARGS}"
cmake $CMAKE_ARGS CMakeLists.txt
make -j8
}
Ispast će ovako:
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
}
Vjerojatno ste već primijetili ove varijable okoline $TRAVIS_PULL_REQUEST и $TRAVIS_BRANCH. Travis CI ih neovisno izjavljuje:
- $TRAVIS_PULL_REQUEST pohranjuje broj zahtjeva za povlačenje ili lažan, ako je ovo obična grana;
- $TRAVIS_REPO_SLUG pohranjuje naziv repozitorija projekta.
Algoritam za ovu funkciju:
Travis CI odgovara na povratne kodove, tako da će prisutnost upozorenja reći servisu da označi predaju da sadrži pogreške.
Sada pogledajmo pobliže ovu liniju koda:
git diff --name-only origin/HEAD > .pvs-pr.list
Činjenica je da Travis CI automatski spaja grane dok analizira zahtjev za povlačenjem:
Stoga analiziramo A4I ne B3->A3. Zbog ove značajke, moramo izračunati razliku sa A3, što je upravo vrh grane iz podrijetlo.
Ostao je još jedan važan detalj - predmemoriranje ovisnosti datoteka zaglavlja o kompajliranim jedinicama prevođenja (*.c, *.cc, *.cpp itd.). Analizator izračunava te ovisnosti kada se prvi put pokrene u načinu provjere popisa datoteka i zatim ih sprema u direktorij .PVS-Studio. Travis CI vam omogućuje spremanje mapa u predmemoriju, tako da ćemo mi spremiti podatke imenika .PVS-Studio/:
cache:
directories:
- .PVS-Studio/
Ovaj kod treba dodati u datoteku .travis.yml. Ovaj direktorij pohranjuje različite podatke prikupljene nakon analize, što će značajno ubrzati naknadne analize popisa datoteka ili inkrementalne analize. Ako se to ne učini, tada će analizator zapravo svaki put analizirati sve datoteke.
Prijatelj
Kao Travis CI,
Prije svega, moramo dodati novu radnju na pokretnu traku:
Naznačimo kompilator koji je korišten za izgradnju projekta. Obratite pozornost na docker spremnik koji je instaliran u ovoj akciji. Na primjer, postoji poseban spremnik za GCC:
Sada instalirajmo PVS-Studio i potrebne pomoćne programe:
Dodajmo sljedeće retke u editor:
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
Sada idemo na karticu Run (prva ikona) i dodamo sljedeći kod u odgovarajuće polje uređivača:
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
Ako ste pročitali odjeljak o Travs-CI, onda vam je ovaj kod već poznat, međutim, sada postoji nova faza:
Činjenica je da sada ne analiziramo rezultat spajanja, već HEAD grane iz koje je napravljen zahtjev za povlačenjem:
Dakle, mi smo u uvjetnom obvezanju B3 i moramo dobiti razliku 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
Da bismo odredili A3 Upotrijebimo GitHub API:
https://api.github.com/repos/${USERNAME}/${REPO}/pulls/${PULL_REQUEST_ID}
Koristili smo sljedeće varijable koje Buddy daje:
- $BUDDY_EXECUTION_PULL_REQEUST_NO — broj zahtjeva za povlačenje;
- $BUDDY_REPO_SLUG — kombinacija korisničkog imena i repozitorija (na primjer max/test).
Sada spremimo promjene pomoću gumba ispod i omogućimo analizu zahtjeva za povlačenjem:
Za razliku od Travisa CI-ja, ne trebamo specificirati .pvs-studio za predmemoriju, jer Buddy automatski sprema sve datoteke za kasnija pokretanja. Stoga, posljednje što preostaje je spremiti prijavu i lozinku za PVS-Studio u Buddy. Nakon spremanja promjena, vratit ćemo se na Pipeline. Moramo prijeći na postavljanje varijabli i dodavanje prijave i ključa za PVS-Studio:
Nakon toga, pojavljivanje novog zahtjeva za povlačenjem ili predaje pokrenut će pregled. Ako predaja sadrži pogreške, Buddy će to naznačiti na stranici sa zahtjevima za povlačenje.
AppVeyor
Postavljanje AppVeyora slično je Buddyju, jer se sve događa u web sučelju i nema potrebe dodavati *.yml datoteku u repozitorij projekta.
Idemo na karticu Postavke u pregledu projekta:
Pomaknimo se prema dolje na ovoj stranici i omogućimo spremanje predmemorije za prikupljanje zahtjeva za povlačenjem:
Sada idemo na karticu Okruženje, gdje navodimo sliku za sklapanje i potrebne varijable okruženja:
Ako ste pročitali prethodne odjeljke, dobro ste upoznati s ove dvije varijable − PVS_KEY и PVS_USERNAME. Ako ne, podsjetit ću vas da su potrebni za provjeru licence analizatora PVS-Studio. U budućnosti ćemo ih ponovno vidjeti u Bash skriptama.
Na istoj stranici ispod označavamo mapu za predmemoriju:
Ako to ne učinimo, analizirat ćemo cijeli projekt umjesto nekoliko datoteka, ali ćemo dobiti izlaz iz navedenih datoteka. Stoga je važno unijeti točan naziv imenika.
Sada je vrijeme za testiranje scenarija. Otvorite karticu Testovi i odaberite Skripta:
Morate zalijepiti sljedeći kod u ovaj obrazac:
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
Obratimo pozornost na sljedeći dio koda:
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
Prilično specifično dodjeljivanje vrijednosti pwd naredbe varijabli koja bi trebala pohraniti ovu zadanu vrijednost na prvi pogled djeluje čudno, međutim, sada ću sve objasniti.
Prilikom postavljanja analizatora u AppVeyoru, naišao sam na krajnje čudno ponašanje analizatora. S jedne strane, sve je radilo ispravno, ali analiza nije krenula. Proveo sam dosta vremena primjećujući da smo u direktoriju /home/appveyor/projects/testcalc/, a analizator je siguran da smo u /opt/appveyor/build-agent/. Onda sam shvatio da varijabla $PWD malo laže. Iz tog sam razloga ručno ažurirao njegovu vrijednost prije početka analize.
I onda je sve kao prije:
Sada razmotrite sljedeći fragment:
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"`
U njemu dobivamo razliku između grana nad kojima je deklariran zahtjev za povlačenjem. Da bismo to učinili potrebne su nam sljedeće varijable okruženja:
- $APPVEYOR_PULL_REQUEST_NUMBER — broj zahtjeva za povlačenje;
- $APPVEYOR_REPO_NAME - korisničko ime i repozitorij projekta.
Zaključak
Naravno, nismo uzeli u obzir sve moguće usluge kontinuirane integracije, ali sve one imaju vrlo slične operativne specifičnosti jedna drugoj. Osim keširanja, svaki servis radi svoj “bicikl” pa je uvijek sve drugačije.
Negdje, kao u Travis-CI, par redaka koda i predmemoriranje radi besprijekorno; negdje, kao u AppVeyoru, samo trebate odrediti mapu u postavkama; ali negdje morate stvoriti jedinstvene ključeve i pokušati uvjeriti sustav da vam da priliku da prebrišete predmemorirani fragment. Stoga, ako želite postaviti analizu zahtjeva za povlačenjem na uslugu kontinuirane integracije koja nije gore spomenuta, prvo se uvjerite da nećete imati problema s predmemoriranjem.
Hvala vam na pažnji. Ako nešto ne uspije, slobodno nam pišite na
Ako želite podijeliti ovaj članak s publikom koja govori engleski, upotrijebite vezu za prijevod: Maxim Zvyagintsev.
Izvor: www.habr.com