In l'analizzatore PVS-Studio per e lingue C è C++ nantu à Linux è macOS, partendu da a versione 7.04, una opzione di prova hè apparsa per verificà a lista di i schedari specificati. Utilizendu u novu modu, pudete cunfigurà l'analizzatore per verificà e cummissioni è pull requests. Questu articulu vi dicerà cumu cunfigurà a lista di i schedarii cambiati di un prughjettu GitHub in sistemi CI (Integrazione Continua) populari cum'è Travis CI, Buddy è AppVeyor.
Modu di cuntrollu di a lista di i schedari
In a versione PVS-Studio 7.04 per Linux è macOS, un modu per verificà a lista di i fugliali fonte hè apparsu. Questu travaglia per i prughjetti chì u sistema di creazione permette di generà un schedariu
Inoltre, u modu di cuntrollu di a lista di file pò esse aduprata inseme cù u logu di traccia di strace di i lanciari di compilatori (pvs-studio-analyzer trace). Per fà questu, avete bisognu di fà prima una custruzzione cumpleta di u prugettu è seguite per chì l'analizzatore recullà infurmazione cumpleta nantu à i paràmetri di compilazione di tutti i schedari verificati.
Tuttavia, sta opzione hà un inconveniente significativu - avete bisognu di fà una traccia di custruzzione cumpleta di tuttu u prughjettu ogni volta chì l'eseguite, chì in sè cuntradite l'idea di verificà rapidamente un impegnu. Or, se cache u risultatu di a traccia stessu, eseguiti successivi di l'analizzatore pò esse incomplete se a struttura di dependenza di i schedarii di fonte cambia dopu à a traccia (per esempiu, un novu #include hè aghjuntu à unu di i schedarii fonte).
Dunque, ùn ricumandemu micca d'utilizà u modu di cuntrollu di a lista di file cù u logu di traccia per verificà e cummissioni o pull requests. In casu chì pudete fà una custruzzione incrementale quandu verificate un impegnu, cunzidira à aduprà u modu
A lista di i fugliali fonte per l'analisi hè salvatu in un schedariu di testu è passatu à l'analizzatore utilizendu u paràmetru -S:
pvs-studio-analyzer analyze ... -f build/compile_commands.json -S check-list.txt
Stu schedariu specifica percorsi relative o assoluti à i schedari, è ogni novu schedariu deve esse nantu à una nova linea. Hè accettatu di specificà micca solu i nomi di schedarii per l'analisi, ma ancu diversi testi. L'analizzatore vede chì questu ùn hè micca un schedariu è ignurà a linea. Questu pò esse utile per cummentà se i schedari sò specificati manualmente. In ogni casu, spessu una lista di schedari serà generata durante l'analisi in CI, per esempiu, questi puderanu esse schedari da una dumanda di cummit o pull.
Avà, utilizendu stu modu, pudete verificà rapidamente u novu codice prima ch'ellu entre in u ramu di sviluppu principale. Per assicurà chì u sistema di scanning risponde à l'avvertimenti di l'analizzatore, l'utilità plog-convertitore bandiera aghjunta --indicate-avvertimenti:
plog-converter ... --indicate-warnings ... -o /path/to/report.tasks ...
Cù sta bandiera, u cunvertitore restituverà un codice micca zero se ci sò avvirtimenti in u rapportu di l'analizzatore. Utilizendu u codice di ritornu, pudete bluccà un precommit hook, commit, o pull request, è u rapportu di l'analizzatore generatu pò esse visualizatu, spartutu o mandatu per email.
Nota. Quandu avete principiatu à analizà una lista di schedarii, tuttu u prughjettu serà analizatu, perchè l'analizzatore hà bisognu di generà un schedariu di dipendenze di i fugliali fonte di u prughjettu nantu à i schedarii di l'intestazione. Questa hè una funzione di analizà i schedari C è C++. In u futuru, u schedariu di dependenza pò esse in cache è serà aghjurnatu automaticamente da l'analizzatore. U vantaghju di cuntrollà l'impegni quandu si usa u modu di cuntrollu di a lista di i fugliali nantu à l'usu di u modu di analisi incrementale hè chì avete solu bisognu di cache quellu schedariu è micca i fugliali di l'ughjettu.
Principii generali di l'analisi pull request
L'analisi di u prughjettu sanu pigghia assai tempu, cusì hè sensu di verificà solu una certa parte di questu. U prublema hè chì avete bisognu di separà i novi schedari da u restu di i schedarii di u prugettu.
Fighjemu un esempiu di un arbulu di cummissione cù dui rami:
Imaginemu quellu impegnu A1 cuntene una quantità abbastanza grande di codice chì hè digià statu pruvatu. Un pocu prima avemu fattu un ramu da u commit A1 è hà cambiatu certi schedari.
Di sicuru, avete nutatu chì dopu A1 Dui più cummitti sò accaduti, ma questi eranu ancu fusioni di altre rami, perchè ùn avemu micca impegnatu Maestru. È avà hè ghjuntu u tempu quandu hotfix pronti. Hè per quessa chì una dumanda di pull per a fusione hè apparsa B3 и A3.
Di sicuru, saria pussibule di verificà u risultatu tutale di a so fusione, ma questu seria troppu tempu è micca ghjustificatu, postu chì solu uni pochi di schedari sò stati cambiati. Per quessa, hè più efficaci per analizà solu i cambiati.
Per fà questu, avemu a diffarenza trà i rami, essendu in u CAPU di u ramu da quale vulemu unisce in maestru:
git diff --name-only HEAD origin/$MERGE_BASE > .pvs-pr.list
$MERGE_BASE Fighjeremu in dettagliu dopu. U fattu hè chì micca ogni serviziu CI furnisce l'infurmazioni necessarii nantu à a basa di dati per a fusione, cusì ogni volta avete da vene cun novi modi per ottene sta dati. Questu serà descrittu in dettagliu quì sottu in ognunu di i servizii web descritti.
Allora, avemu avutu a diffarenza trà e rami, o megliu, una lista di nomi di schedari chì sò stati cambiati. Avà avemu bisognu di dà u schedariu .pvs-pr.list (avemu redirettu l'output sopra à questu) à l'analizzatore:
pvs-studio-analyzer analyze -j8
-o PVS-Studio.log
-S .pvs-pr.list
Dopu l'analisi, avemu bisognu di cunvertisce u schedariu di log (PVS-Studio.log) in un furmatu faciule da leghje:
plog-converter -t errorfile PVS-Studio.log --cerr -w
Stu cumandamentu listerà l'errori in
Solu avà avemu bisognu di micca solu di vede errori, ma ancu informà u nostru serviziu per l'assemblea è a prova di a presenza di prublemi. Per questu scopu, una bandiera hè stata aghjunta à u cunvertitore -W (--indicate-avvertimenti). Se ci hè almenu un avvisu di l'analizzatore, u codice di ritornu di l'utilità plog-convertitore cambierà à 2, chì à u turnu informarà u serviziu CI nantu à a prisenza di errori potenziali in i schedarii di pull request.
Travis C.I.
A cunfigurazione hè fatta cum'è un schedariu .travis.yml. Per comodità, vi cunsigliu di mette tuttu in un script bash separatu cù funzioni chì saranu chjamati da u schedariu. .travis.yml (bash script_name.sh function_name).
Avemu da aghjunghje u codice necessariu à u script à bash, in questu modu averemu più funziunalità. In rùbbrica stallà scrivimu i seguenti:
install:
- bash .travis.sh travis_install
Sì avete avutu qualchì struzzioni, pudete trasfiriri in u script, sguassà i trattini.
Andemu apre u schedariu .travis.sh è aghjunghje l'analizzatore à a funzione 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
}
Avà aghjunghje à a rùbbrica scrittura esegui l'analisi:
script:
- bash .travis.sh travis_script
È in u script 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
}
Stu codice deve esse eseguitu dopu à custruisce u prughjettu, per esempiu, se avete avutu una custruzzione nantu à CMake:
travis_script() {
CMAKE_ARGS="-DCMAKE_EXPORT_COMPILE_COMMANDS=On ${CMAKE_ARGS}"
cmake $CMAKE_ARGS CMakeLists.txt
make -j8
}
Risultarà cusì:
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
}
Probabilmente avete digià nutatu queste variabili di l'ambiente $TRAVIS_PULL_REQUEST и $TRAVIS_BRANCH. Travis CI li dichjara in modu indipendenti:
- $TRAVIS_PULL_REQUEST almacena u numeru di dumanda di pull o sbagliate, se questu hè un ramu regulare;
- $TRAVIS_REPO_SLUG guarda u nome di u repositoriu di u prugettu.
L'algoritmu per sta funzione:
Travis CI risponde à i codici di ritornu, cusì a prisenza di avvirtimenti diciarà à u serviziu di marcà l'impegnu cum'è cuntene errori.
Avà fighjemu un ochju più vicinu à sta linea di codice:
git diff --name-only origin/HEAD > .pvs-pr.list
U fattu hè chì Travis CI unisce automaticamente i rami mentre analizza una dumanda di pull:
Dunque analizemu A4è micca B3->A3. A causa di sta funziunalità, avemu bisognu di calculà a diffarenza cù А3, chì hè precisamente a cima di u ramu da urìggini.
Ci hè un dettagliu impurtante lasciatu - cachendu e dipendenze di i fugliali di l'intestazione nantu à unità di traduzzione compilate (*.c, *.cc, *.cpp, etc.). L'analizzatore calcula queste dependenzii quandu hè prima lanciatu in u modu di cuntrollà una lista di i schedari è poi i salva in u cartulare .PVS-Studio. Travis CI permette di cache i cartulare, cusì salveremu i dati di u cartulare .PVS-Studio/:
cache:
directories:
- .PVS-Studio/
Stu codice deve esse aghjuntu à u schedariu .travis.yml. Stu repertoriu guarda diverse dati raccolti dopu l'analisi, chì accelerà significativamente e successive runs di analisi di lista di file o analisi incrementali. Se questu ùn hè micca fattu, allora l'analizzatore analizà in realtà tutti i fugliali ogni volta.
Buddy
Cum'è Travis CI,
Prima di tuttu, avemu bisognu di aghjunghje una nova azzione à a linea di assemblea:
Indicà u compilatore chì hè stata utilizata per custruisce u prugettu. Avvisu u cuntinuu docker chì hè stallatu in questa azione. Per esempiu, ci hè un cuntainer speciale per GCC:
Avà stallà PVS-Studio è e utilità necessarie:
Aghjunghjemu e seguenti linee à l'editore:
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
Avà andemu à a tabulazione Run (prima icona) è aghjunghje u seguente codice à u campu di l'editore currispundente:
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
Se leghjite a rùbbrica Travs-CI, allora stu codice hè digià familiarizatu per voi, ma avà hè una nova tappa:
U fattu hè chì avà analizemu micca u risultatu di a fusione, ma u CAPU di u ramu da quale a dumanda di pull hè fatta:
Dunque simu in un impegnu cundizionale B3 è avemu bisognu di piglià a diffarenza da 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
Per determinà A3 Utilizemu l'API GitHub:
https://api.github.com/repos/${USERNAME}/${REPO}/pulls/${PULL_REQUEST_ID}
Avemu usatu e seguenti variabili chì Buddy furnisce:
- $BUDDY_EXECUTION_PULL_REQEUST_NO - pull request number;
- $BUDDY_REPO_SLUG - una cumminazione di username è repository (per esempiu max/test).
Avà salvemu i cambiamenti usendu u buttone sottu è attivemu l'analisi di a dumanda di pull:
A cuntrariu di Travis CI, ùn avemu micca bisognu di specificà .pvs-studio per caching, postu chì Buddy cache automaticamente tutti i fugliali per i lanci successivi. Dunque, l'ultima cosa chì resta hè di salvà u login è a password per PVS-Studio in Buddy. Dopu avè salvatu i cambiamenti, seremu ripigliati in Pipeline. Avemu bisognu di passà à stallà variabili è aghjunghje un login è chjave per PVS-Studio:
Dopu questu, l'apparizione di una nova dumanda di pull o commit attivarà a revisione. Se un commit cuntene errori, Buddy indicà questu nantu à a pagina di dumanda di pull.
AppVeyor
L'installazione di AppVeyor hè simile à Buddy, postu chì tuttu succede in l'interfaccia web è ùn ci hè bisognu di aghjunghje un schedariu *.yml à u repository di u prugettu.
Andemu à a tabulazione Settings in a panoramica di u prugettu:
Scorrimu in questa pagina è attivemu a salvezza di cache per a cullizzioni di richieste di pull:
Avà andemu à a tabulazione Ambiente, induve spicificà l'imaghjini per l'assemblea è e variabili di l'ambienti necessarii:
Sè avete lettu e rùbbriche precedente, site assai familiarizatu cù sti dui variàbili - PVS_KEY и PVS_USERNAME. Se no, lasciami ricurdà chì sò necessarii per verificà a licenza di l'analizzatore PVS-Studio. Li verremu di novu in scripts Bash in u futuru.
In a stessa pagina sottu indichemu u cartulare per a cache:
Se ùn facemu micca questu, analizzeremu tuttu u prugettu invece di un coppiu di schedari, ma avemu da ottene u risultatu da i schedarii specificati. Dunque, hè impurtante entre in u nome di u cartulare currettu.
Avà hè u tempu per u script per pruvà. Aprite a tabulazione Tests è selezziunate Script:
Avete bisognu di incollà u seguente codice in questa forma:
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
Fighjemu attente à a seguente parte di u codice:
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
L'assignazione piuttostu specifica di u valore di u cumandimu pwd à una variàbile chì deve guardà stu valore predeterminatu pare stranu à u primu sguardu, però, spiegheraghju tuttu avà.
Durante a stallazione di l'analizzatore in AppVeyor, aghju scontru un cumpurtamentu estremamente stranu di l'analizzatore. Da una banda, tuttu hà travagliatu bè, ma l'analisi ùn hà micca cuminciatu. Aghju passatu assai tempu à nutà chì simu in u cartulare /home/appveyor/projects/testcalc/, è l'analizzatore hè sicuru chì simu in /opt/appveyor/build-agent/. Allora aghju realizatu chì a variàbile $ PWD giaceva un pocu. Per quessa, aghju aghjurnatu manualmente u so valore prima di inizià l'analisi.
È dopu tuttu hè cum'è prima:
Avà cunzidira u frammentu seguente:
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"`
In questu avemu a diffarenza trà e rami nantu à quale a dumanda di pull hè dichjarata. Per fà questu, avemu bisognu di e seguenti variabili ambientali:
- $APPVEYOR_PULL_REQUEST_NUMBER — pull request number;
- $APPVEYOR_REPO_NAME - nome d'utilizatore è repository di prughjettu.
cunchiusioni
Di sicuru, ùn avemu micca cunsideratu tutti i pussibuli servizii d'integrazione cuntinuu, in ogni modu, tutti anu una specificazione operativa estremamente simile à l'altru. Cù l'eccezzioni di caching, ogni serviziu face a so propria "bicicletta", cusì tuttu hè sempre diversu.
In qualchì locu, cum'è in Travis-CI, un coppiu di linee di codice è caching funziona perfettamente; in qualchì locu, cum'è in AppVeyor, basta à specificà u cartulare in i paràmetri; ma in un locu avete bisognu di creà chjavi unichi è pruvate à cunvince u sistema per dà l'uppurtunità di sovrascrive u fragmentu cache. Dunque, sè vo vulete stabilisce l'analisi di e dumande di pull in un serviziu d'integrazione cuntinuu chì ùn hè micca discututu sopra, prima assicuratevi chì ùn avete micca prublemi cù caching.
Grazie per a vostra attenzione. Se qualcosa ùn viaghja micca, sentite liberu di scrive à noi à
Se vulete sparte stu articulu cù un publicu anglofonu, per piacè utilizate u ligame di traduzzione: Maxim Zvyagintsev.
Source: www.habr.com