PVS-Studio analizatorā C un C++ valodām operētājsistēmās Linux un macOS, sākot no versijas 7.04, ir parādījusies testa opcija, lai pārbaudītu norādīto failu sarakstu. Izmantojot jauno režīmu, jūs varat konfigurēt analizatoru, lai pārbaudītu commits un pull pieprasījumus. Šajā rakstā tiks parādīts, kā iestatīt GitHub projekta mainīto failu saraksta pārbaudi tādās populārās CI (nepārtrauktās integrācijas) sistēmās kā Travis CI, Buddy un AppVeyor.
Failu saraksta pārbaudes režīms
Versijā PVS-Studio 7.04 operētājsistēmai Linux un macOS ir parādījies avota failu saraksta pārbaudes režīms. Tas darbojas projektiem, kuru veidošanas sistēma ļauj ģenerēt failu
Arī failu saraksta pārbaudes režīmu var izmantot kopā ar kompilatora palaišanas trace žurnālu (pvs-studio-analyzer trace). Lai to izdarītu, vispirms ir jāveic pilna projekta būve un jāizseko tā, lai analizators apkopotu pilnīgu informāciju par visu pārbaudāmo failu kompilācijas parametriem.
Tomēr šai opcijai ir būtisks trūkums — katru reizi, kad to palaižat, jums būs jāveic visa projekta pilnīga izveides izsekošana, kas pats par sevi ir pretrunā ar ideju par ātru saistību pārbaudi. Vai arī, ja kešatmiņā saglabājat pašu izsekošanas rezultātu, turpmākās analizatora darbības var būt nepilnīgas, ja pēc izsekošanas mainās avota failu atkarības struktūra (piemēram, vienam no avota failiem tiek pievienots jauns #include).
Tāpēc mēs neiesakām izmantot failu saraksta pārbaudes režīmu ar izsekošanas žurnālu, lai pārbaudītu saistības vai izvilkšanas pieprasījumus. Ja, pārbaudot saistību izpildi, varat veikt pakāpenisku veidošanu, apsveriet iespēju izmantot režīmu
Analīzes avota failu saraksts tiek saglabāts teksta failā un, izmantojot parametru, tiek nodots analizatoram -S:
pvs-studio-analyzer analyze ... -f build/compile_commands.json -S check-list.txt
Šis fails norāda relatīvos vai absolūtos ceļus uz failiem, un katram jaunajam failam ir jāatrodas jaunā rindā. Ir pieņemams analīzei norādīt ne tikai failu nosaukumus, bet arī dažādu tekstu. Analizators redzēs, ka tas nav fails, un ignorēs rindu. Tas var būt noderīgi komentēšanai, ja faili ir norādīti manuāli. Tomēr bieži vien CI analīzes laikā tiek ģenerēts failu saraksts, piemēram, tie var būt faili no commit vai pull pieprasījuma.
Tagad, izmantojot šo režīmu, varat ātri pārbaudīt jauno kodu, pirms tas nonāk galvenajā izstrādes nozarē. Lai nodrošinātu, ka skenēšanas sistēma reaģē uz analizatora brīdinājumiem, utilīta plog pārveidotājs pievienots karogs --norādīt-brīdinājumus:
plog-converter ... --indicate-warnings ... -o /path/to/report.tasks ...
Izmantojot šo karogu, pārveidotājs atgriezīs kodu, kas nav nulle, ja analizatora pārskatā ir brīdinājumi. Izmantojot atgriešanas kodu, varat bloķēt pirmssaistīšanas āķa, izpildes vai izvilkšanas pieprasījumu, un ģenerēto analizatora pārskatu var parādīt, kopīgot vai nosūtīt pa e-pastu.
Piezīme. Kad pirmo reizi sākat analizēt failu sarakstu, tiks analizēts viss projekts, jo analizatoram ir jāģenerē projekta avota failu atkarību fails no galvenes failiem. Šī ir C un C++ failu analīzes funkcija. Nākotnē atkarības failu var saglabāt kešatmiņā, un analizators to automātiski atjauninās. Saistību pārbaudes priekšrocība, izmantojot failu saraksta pārbaudes režīmu, salīdzinot ar pakāpeniskas analīzes režīmu, ir tāda, ka kešatmiņā ir jāglabā tikai šis fails, nevis objekta faili.
Vilkšanas pieprasījuma analīzes vispārīgie principi
Visa projekta analīze aizņem daudz laika, tāpēc ir lietderīgi pārbaudīt tikai noteiktu tā daļu. Problēma ir tā, ka jums ir jāatdala jaunie faili no pārējiem projekta failiem.
Apskatīsim piemēru kokam ar diviem zariem:
Iedomāsimies šo apņemšanos A1 satur diezgan lielu koda daudzumu, kas jau ir pārbaudīts. Nedaudz agrāk mēs izveidojām zaru no apņemšanās A1 un mainīja dažus failus.
Jūs, protams, to pamanījāt pēc tam A1 notika vēl divas saistības, bet tās bija arī citu filiāļu apvienošanās, jo mēs neapņemamies meistars. Un tagad ir pienācis laiks, kad labojumfails gatavs. Tāpēc parādījās apvienošanas pieprasījums B3 и A3.
Protams, būtu iespējams pārbaudīt visu to apvienošanas rezultātu, taču tas būtu pārāk laikietilpīgi un nepamatoti, jo tika mainīti tikai daži faili. Tāpēc efektīvāk ir analizēt tikai mainītos.
Lai to izdarītu, mēs iegūstam atšķirību starp zariem, atrodoties filiāles GALVĀ, no kuras mēs vēlamies apvienoties par galveno:
git diff --name-only HEAD origin/$MERGE_BASE > .pvs-pr.list
$MERGE_BASE mēs to sīkāk aplūkosim vēlāk. Fakts ir tāds, ka ne katrs CI pakalpojums sniedz nepieciešamo informāciju par datubāzi apvienošanai, tāpēc katru reizi jums ir jāizdomā jauni veidi, kā iegūt šos datus. Tas tiks detalizēti aprakstīts turpmāk katrā no aprakstītajiem tīmekļa pakalpojumiem.
Tātad, mēs saņēmām atšķirību starp filiālēm vai, drīzāk, mainīto failu nosaukumu sarakstu. Tagad mums ir jāiesniedz fails .pvs-pr.list (mēs novirzījām uz to iepriekš esošo izvadi) uz analizatoru:
pvs-studio-analyzer analyze -j8
-o PVS-Studio.log
-S .pvs-pr.list
Pēc analīzes mums ir jāpārvērš žurnālfails (PVS-Studio.log) viegli lasāmā formātā:
plog-converter -t errorfile PVS-Studio.log --cerr -w
Šī komanda uzskaitīs kļūdas
Tikai tagad mums ir ne tikai jāparāda kļūdas, bet arī jāinformē mūsu serviss montāžai un pārbaudei par problēmu esamību. Šim nolūkam pārveidotājam tika pievienots karogs -W (--norādīt-brīdinājumus). Ja ir vismaz viens analizatora brīdinājums, utilītas atgriešanas kods plog pārveidotājs mainīsies uz 2, kas savukārt informēs CI pakalpojumu par iespējamu kļūdu esamību pull pieprasījuma failos.
Travis CI
Konfigurācija tiek veikta kā fails .travis.yml. Ērtības labad iesaku visu ievietot atsevišķā bash skriptā ar funkcijām, kuras tiks izsauktas no faila .travis.yml (bash skripta_nosaukums.sh funkcijas_nosaukums).
Mēs pievienosim nepieciešamo kodu skriptam plkst stipri iesist, tādā veidā mēs iegūsim vairāk funkcionalitātes. Sadaļā uzstādīt rakstīsim sekojošo:
install:
- bash .travis.sh travis_install
Ja jums bija kādi norādījumi, varat tos pārsūtīt skriptā, noņemot defises.
Atvērsim failu .travis.sh un pievienojiet funkcijai analizatora iestatījumu 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
}
Tagad pievienosim sadaļu scenārijs palaist analīzi:
script:
- bash .travis.sh travis_script
Un bash skriptā:
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
}
Šis kods ir jāpalaiž pēc projekta izveides, piemēram, ja jums bija versija CMake:
travis_script() {
CMAKE_ARGS="-DCMAKE_EXPORT_COMPILE_COMMANDS=On ${CMAKE_ARGS}"
cmake $CMAKE_ARGS CMakeLists.txt
make -j8
}
Tas izrādīsies šādi:
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
}
Jūs droši vien jau esat pamanījis šos vides mainīgos $TRAVIS_PULL_REQUEST и $TRAVIS_BRANCH. Travis CI tos paziņo neatkarīgi:
- $TRAVIS_PULL_REQUEST saglabā izvilkšanas pieprasījuma numuru vai nepatiess, ja šī ir parasta filiāle;
- $TRAVIS_REPO_SLUG saglabā projekta repozitorija nosaukumu.
Šīs funkcijas algoritms:
Travis CI reaģē uz atgriešanas kodiem, tāpēc brīdinājumu klātbūtne liks pakalpojumam atzīmēt apņemšanos kā kļūdu.
Tagad apskatīsim šo koda rindiņu tuvāk:
git diff --name-only origin/HEAD > .pvs-pr.list
Fakts ir tāds, ka Travis CI automātiski apvieno filiāles, analizējot vilkšanas pieprasījumu:
Tāpēc mēs analizējam A4Un ne B3->A3. Šīs funkcijas dēļ mums ir jāaprēķina atšķirība ar A3, kas ir tieši zara augšdaļa no izcelšanās.
Ir palikusi viena svarīga detaļa - galvenes failu atkarību saglabāšana kešatmiņā no apkopotajām tulkošanas vienībām (*.c, *.cc, *.cpp utt.). Analizators aprēķina šīs atkarības, kad tas pirmo reizi tiek palaists failu saraksta pārbaudes režīmā, un pēc tam saglabā tos .PVS-Studio direktorijā. Travis CI ļauj saglabāt mapes kešatmiņā, tāpēc mēs saglabāsim direktoriju datus .PVS-Studio/:
cache:
directories:
- .PVS-Studio/
Šis kods ir jāpievieno failam .travis.yml. Šajā direktorijā tiek glabāti dažādi pēc analīzes savāktie dati, kas ievērojami paātrinās turpmākās failu saraksta analīzes vai pakāpeniskas analīzes izpildes. Ja tas nav izdarīts, analizators faktiski katru reizi analizēs visus failus.
Draugs
Tāpat kā Travis CI,
Pirmkārt, montāžas līnijai jāpievieno jauna darbība:
Norādīsim kompilatoru, kas tika izmantots projekta izveidei. Ievērojiet šajā darbībā instalēto doka konteineru. Piemēram, ir īpašs konteiners GCC:
Tagad instalēsim PVS-Studio un nepieciešamās utilītas:
Pievienosim redaktoram šādas rindas:
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
Tagad pāriesim uz cilni Palaist (pirmā ikona) un atbilstošajam redaktora laukam pievienojiet šādu kodu:
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
Ja lasāt sadaļu par Travs-CI, tad šis kods jums jau ir pazīstams, taču tagad ir jauns posms:
Fakts ir tāds, ka tagad mēs analizējam nevis sapludināšanas rezultātu, bet gan filiāles HEAD, no kuras tiek veikts izvilkšanas pieprasījums:
Tātad mēs esam nosacītā saistībā B3 un mums ir jāsaņem atšķirība no 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
Lai noteiktu A3 Izmantosim GitHub API:
https://api.github.com/repos/${USERNAME}/${REPO}/pulls/${PULL_REQUEST_ID}
Mēs izmantojām šādus mainīgos, ko nodrošina Buddy:
- $BUDDY_EXECUTION_PULL_REQEUST_NO — izvilkšanas pieprasījuma numurs;
- $BUDDY_REPO_SLUG — lietotājvārda un repozitorija kombinācija (piemēram, max/test).
Tagad saglabāsim izmaiņas, izmantojot tālāk esošo pogu, un iespējosim vilkšanas pieprasījuma analīzi:
Atšķirībā no Travis CI, mums nav jāprecizē .pvs-studio kešatmiņai, jo Buddy automātiski kešatmiņā saglabā visus failus turpmākajām palaišanas reizēm. Tāpēc pēdējā lieta, kas atliek, ir saglabāt PVS-Studio pieteikumvārdu un paroli pakalpojumā Buddy. Pēc izmaiņu saglabāšanas mēs tiksim novirzīti atpakaļ uz Pipeline. Mums ir jāpāriet uz mainīgo iestatīšanu un PVS-Studio pieteikumvārda un atslēgas pievienošanu:
Pēc tam pārskatīšana tiks aktivizēta, parādoties jaunam izvilkšanas pieprasījumam vai saistībām. Ja saistībā ir kļūdas, Buddy to norādīs izvilkšanas pieprasījuma lapā.
AppVeyor
AppVeyor iestatīšana ir līdzīga Buddy iestatīšanai, jo viss notiek tīmekļa saskarnē un projekta repozitorijai nav jāpievieno *.yml fails.
Dosimies uz cilni Iestatījumi projekta pārskatā:
Ritināsim uz leju šo lapu un iespējosim kešatmiņas saglabāšanu, lai apkopotu vilkšanas pieprasījumus:
Tagad pāriesim uz cilni Vide, kur mēs norādām montāžas attēlu un nepieciešamos vides mainīgos:
Ja esat izlasījis iepriekšējās sadaļas, jūs ļoti labi pārzināt šos divus mainīgos - PVS_KEY и PVS_USERNAME. Ja nē, atgādināšu, ka tie ir nepieciešami, lai pārbaudītu PVS-Studio analizatora licenci. Nākotnē mēs tos atkal redzēsim Bash skriptos.
Tajā pašā lapā zemāk mēs norādām kešatmiņas mapi:
Ja mēs to nedarīsim, mēs analizēsim visu projektu, nevis dažus failus, bet mēs saņemsim izvadi no norādītajiem failiem. Tāpēc ir svarīgi ievadīt pareizo direktorijas nosaukumu.
Tagad ir pienācis laiks skriptam pārbaudīt. Atveriet cilni Testi un atlasiet Skripts:
Šajā veidlapā ir jāielīmē šāds kods:
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
Pievērsīsim uzmanību šādai koda daļai:
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
Diezgan specifiska komandas pwd vērtības piešķiršana mainīgajam, kuram būtu jāsaglabā šī noklusējuma vērtība, pirmajā mirklī šķiet dīvaina, tomēr tagad visu paskaidrošu.
Iestatot analizatoru programmā AppVeyor, es saskāros ar ārkārtīgi dīvainu analizatora uzvedību. No vienas puses, viss darbojās pareizi, bet analīze nesākās. Es pavadīju daudz laika, lai pamanītu, ka atrodamies direktorijā /home/appveyor/projects/testcalc/, un analizators ir pārliecināts, ka atrodamies /opt/appveyor/build-agent/. Tad es sapratu, ka mainīgais $PWD nedaudz melo. Šī iemesla dēļ pirms analīzes sākšanas es manuāli atjaunināju tā vērtību.
Un tad viss ir kā agrāk:
Tagad apsveriet šādu 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"`
Tajā mēs iegūstam atšķirību starp filiālēm, kurās tiek deklarēts vilkšanas pieprasījums. Lai to izdarītu, mums ir nepieciešami šādi vides mainīgie:
- $APPVEYOR_PULL_REQUEST_NUMBER — izvilkšanas pieprasījuma numurs;
- $APPVEYOR_REPO_NAME — lietotājvārds un projekta repozitorijs.
Secinājums
Protams, mēs neesam apsvēruši visus iespējamos nepārtrauktās integrācijas pakalpojumus, taču tiem visiem ir ļoti līdzīga darbības specifika. Katrs pakalpojums, izņemot kešatmiņu, veido savu “velosipēdu”, tāpēc viss vienmēr ir atšķirīgs.
Kaut kur, piemēram, Travis-CI, pāris koda rindiņas un kešatmiņa darbojas nevainojami; kaut kur, piemēram, AppVeyor, jums vienkārši jānorāda mape iestatījumos; bet kaut kur jums ir jāizveido unikālas atslēgas un jāmēģina pārliecināt sistēmu, lai tā dotu jums iespēju pārrakstīt kešatmiņā saglabāto fragmentu. Tāpēc, ja vēlaties iestatīt nepārtrauktas integrācijas pakalpojuma vilkšanas pieprasījumu analīzi, kas netika apspriests iepriekš, vispirms pārliecinieties, vai jums nebūs problēmu ar kešatmiņu.
Paldies par jūsu uzmanību. Ja kaut kas neizdodas, droši rakstiet mums uz
Ja vēlaties dalīties ar šo rakstu ar angliski runājošu auditoriju, lūdzu, izmantojiet tulkošanas saiti: Maksims Zvjagintsevs.
Avots: www.habr.com