Në analizuesin PVS-Studio për gjuhët C dhe C++ në Linux dhe macOS, duke filluar nga versioni 7.04, është shfaqur një opsion testimi për të kontrolluar listën e skedarëve të specifikuar. Duke përdorur modalitetin e ri, mund të konfiguroni analizuesin për të kontrolluar kryerjet dhe tërheqjen e kërkesave. Ky artikull do t'ju tregojë se si të vendosni kontrollin e listës së skedarëve të ndryshuar të një projekti GitHub në sisteme të tilla të njohura CI (Integrimi i vazhdueshëm) si Travis CI, Buddy dhe AppVeyor.
Mënyra e kontrollit të listës së skedarëve
Në versionin PVS-Studio 7.04 për Linux dhe macOS, është shfaqur një mënyrë për të kontrolluar listën e skedarëve burimor. Kjo funksionon për projektet, sistemi i ndërtimit të të cilave ju lejon të gjeneroni një skedar
Gjithashtu, modaliteti i kontrollit të listës së skedarëve mund të përdoret së bashku me regjistrin e gjurmës së gjurmës së nisjeve të përpiluesit (gjurmë pvs-studio-analyzer). Për ta bërë këtë, së pari do t'ju duhet të kryeni një ndërtim të plotë të projektit dhe ta gjurmoni atë në mënyrë që analizuesi të mbledhë informacion të plotë në lidhje me parametrat e përpilimit të të gjithë skedarëve që kontrollohen.
Sidoqoftë, ky opsion ka një pengesë domethënëse - ose do t'ju duhet të kryeni një gjurmë të plotë të ndërtimit të të gjithë projektit sa herë që e ekzekutoni, gjë që në vetvete bie në kundërshtim me idenë e kontrollit të shpejtë të një kryerjeje. Ose, nëse e ruani vetë rezultatin e gjurmimit, ekzekutimet e mëvonshme të analizuesit mund të jenë jo të plota nëse struktura e varësisë së skedarëve burim ndryshon pas gjurmimit (për shembull, një #include i ri shtohet në një nga skedarët burimor).
Prandaj, ne nuk rekomandojmë përdorimin e modalitetit të kontrollit të listës së skedarëve me regjistrin e gjurmëve për të kontrolluar kryerjet ose kërkesat për tërheqje. Në rast se mund të bëni një ndërtim në rritje kur kontrolloni një angazhim, merrni parasysh përdorimin e modalitetit
Lista e skedarëve burim për analizë ruhet në një skedar teksti dhe i kalon analizuesit duke përdorur parametrin -S:
pvs-studio-analyzer analyze ... -f build/compile_commands.json -S check-list.txt
Ky skedar specifikon shtigjet relative ose absolute për skedarët, dhe çdo skedar i ri duhet të jetë në një rresht të ri. Është e pranueshme të specifikohen jo vetëm emrat e skedarëve për analizë, por edhe tekste të ndryshme. Analizuesi do të shohë që ky nuk është një skedar dhe do të injorojë rreshtin. Kjo mund të jetë e dobishme për të komentuar nëse skedarët specifikohen manualisht. Sidoqoftë, shpesh një listë skedarësh do të gjenerohet gjatë analizës në CI, për shembull, këto mund të jenë skedarë nga një kërkesë për kryerje ose tërheqje.
Tani, duke përdorur këtë mënyrë, mund të kontrolloni shpejt kodin e ri përpara se të futet në degën kryesore të zhvillimit. Për të siguruar që sistemi i skanimit u përgjigjet paralajmërimeve të analizuesit, programi plog-konverter flamuri i shtuar --trego-paralajmërime:
plog-converter ... --indicate-warnings ... -o /path/to/report.tasks ...
Me këtë flamur, konverteri do të kthejë një kod jo zero nëse ka paralajmërime në raportin e analizuesit. Duke përdorur kodin e kthimit, ju mund të bllokoni një kërkesë për fiksim, kryerje ose tërheqje paraprake dhe raporti i gjeneruar i analizuesit mund të shfaqet, ndahet ose dërgohet me email.
Shënim. Kur filloni për herë të parë të analizoni një listë skedarësh, i gjithë projekti do të analizohet, sepse analizuesi duhet të gjenerojë një skedar të varësive të skedarëve burim të projektit në skedarët e kokës. Kjo është një veçori e analizimit të skedarëve C dhe C++. Në të ardhmen, skedari i varësisë mund të ruhet në memorie dhe do të përditësohet automatikisht nga analizuesi. Avantazhi i kontrollit të kryerjes kur përdorni modalitetin e kontrollit të listës së skedarëve ndaj përdorimit të mënyrës së analizës në rritje është se ju duhet vetëm të ruani memorien e skedarit dhe jo skedarët e objektit.
Parimet e përgjithshme të analizës së kërkesës për tërheqje
Analizimi i të gjithë projektit kërkon shumë kohë, kështu që ka kuptim të kontrolloni vetëm një pjesë të caktuar të tij. Problemi është se ju duhet të ndani skedarët e rinj nga pjesa tjetër e skedarëve të projektit.
Le të shohim një shembull të një peme commit me dy degë:
Le ta imagjinojmë atë angazhim A1 përmban një sasi mjaft të madhe kodi që tashmë është testuar. Pak më parë bëmë një degë nga commit A1 dhe ndryshoi disa skedarë.
Ju, sigurisht, e keni vënë re këtë pas A1 ndodhën edhe dy angazhime të tjera, por këto ishin edhe bashkime të degëve të tjera, sepse ne nuk angazhohemi për mjeshtër. Dhe tani ka ardhur koha kur hotfix gati. Kjo është arsyeja pse u shfaq një kërkesë tërheqjeje për bashkim B3 и A3.
Sigurisht, do të ishte e mundur të kontrollohej i gjithë rezultati i bashkimit të tyre, por kjo do të merrte shumë kohë dhe do të ishte e pajustifikuar, pasi vetëm disa skedarë u ndryshuan. Prandaj, është më efikase të analizohen vetëm ato të ndryshuara.
Për ta bërë këtë, ne marrim ndryshimin midis degëve, duke qenë në KREU të degës nga e cila duam të shkrihemi në master:
git diff --name-only HEAD origin/$MERGE_BASE > .pvs-pr.list
$MERGE_BASE do ta shikojmë në detaje më vonë. Fakti është se jo çdo shërbim CI ofron informacionin e nevojshëm në lidhje me bazën e të dhënave për bashkim, kështu që çdo herë duhet të gjeni mënyra të reja për të marrë këto të dhëna. Kjo do të përshkruhet në detaje më poshtë në secilin prej shërbimeve të përshkruara në internet.
Pra, morëm ndryshimin midis degëve, ose më mirë, një listë me emrat e skedarëve që u ndryshuan. Tani duhet të japim skedarin .pvs-pr.lista (ne ridrejtuam daljen e mësipërme në të) në analizues:
pvs-studio-analyzer analyze -j8
-o PVS-Studio.log
-S .pvs-pr.list
Pas analizës, ne duhet të konvertojmë skedarin e regjistrit (PVS-Studio.log) në një format të lehtë për t'u lexuar:
plog-converter -t errorfile PVS-Studio.log --cerr -w
Kjo komandë do të listojë gabimet në
Vetëm tani duhet jo vetëm të shfaqim gabime, por edhe të informojmë shërbimin tonë për montim dhe testim për praninë e problemeve. Për këtë qëllim, një flamur iu shtua konvertuesit -W (--trego-paralajmërime). Nëse ka të paktën një paralajmërim të analizuesit, kodi i kthimit të shërbimeve plog-konverter do të ndryshojë në 2, e cila nga ana tjetër do të informojë shërbimin CI për praninë e gabimeve të mundshme në skedarët e kërkesës për tërheqje.
Travis C.I.
Konfigurimi është bërë si skedar .travis.yml. Për lehtësi, ju këshilloj të vendosni gjithçka në një skript të veçantë bash me funksione që do të thirren nga skedari .travis.yml (bash script_name.sh emri_funksionit).
Ne do të shtojmë kodin e nevojshëm në skript në përplas, në këtë mënyrë do të kemi më shumë funksionalitet. Në seksion instaloj le të shkruajmë sa vijon:
install:
- bash .travis.sh travis_install
Nëse keni pasur ndonjë udhëzim, mund t'i transferoni ato në skenar, duke hequr vizat.
Le të hapim skedarin .travis.sh dhe shtoni cilësimin e analizuesit në funksion 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
}
Tani le të shtojmë në seksion dorëshkrim analiza e ekzekutuar:
script:
- bash .travis.sh travis_script
Dhe në skenarin 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
}
Ky kod duhet të ekzekutohet pas ndërtimit të projektit, për shembull, nëse keni pasur një ndërtim në CMake:
travis_script() {
CMAKE_ARGS="-DCMAKE_EXPORT_COMPILE_COMMANDS=On ${CMAKE_ARGS}"
cmake $CMAKE_ARGS CMakeLists.txt
make -j8
}
Do të dalë kështu:
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
}
Ju ndoshta i keni vënë re tashmë këto variabla të mjedisit $TRAVIS_PULL_REQUEST и $TRAVIS_BRANCH. Travis CI i deklaron ato në mënyrë të pavarur:
- $TRAVIS_PULL_REQUEST ruan numrin e kërkesës për tërheqje ose i rremë, nëse kjo është një degë e rregullt;
- $TRAVIS_REPO_SLUG ruan emrin e depove të projektit.
Algoritmi për këtë funksion:
Travis CI u përgjigjet kodeve të kthimit, kështu që prania e paralajmërimeve do t'i tregojë shërbimit të shënojë kryerjen si gabime.
Tani le të hedhim një vështrim më të afërt në këtë linjë kodi:
git diff --name-only origin/HEAD > .pvs-pr.list
Fakti është se Travis CI bashkon automatikisht degët ndërsa analizon një kërkesë tërheqjeje:
Prandaj analizojmë A4Dhe jo B3->A3. Për shkak të kësaj veçorie, ne duhet të llogarisim diferencën me A3, e cila është pikërisht maja e degës nga origjinë.
Mbetet një detaj i rëndësishëm - ruajtja e varësive të skedarëve të kokës në njësitë e përkthimit të përpiluar (*.c, *.cc, *.cpp, etj.). Analizuesi llogarit këto varësi kur lansohet për herë të parë në modalitetin e kontrollit të një liste skedarësh dhe më pas i ruan ato në direktorinë .PVS-Studio. Travis CI ju lejon të ruani dosjet në memorie, kështu që ne do t'i ruajmë të dhënat e drejtorisë .PVS-Studio/:
cache:
directories:
- .PVS-Studio/
Ky kod duhet të shtohet në skedar .travis.yml. Kjo direktori ruan të dhëna të ndryshme të mbledhura pas analizës, të cilat do të përshpejtojnë ndjeshëm ekzekutimet e mëvonshme të analizës së listës së skedarëve ose analizës në rritje. Nëse kjo nuk është bërë, atëherë analizuesi në të vërtetë do të analizojë të gjithë skedarët çdo herë.
mik
Ashtu si Travis CI,
Para së gjithash, ne duhet të shtojmë një veprim të ri në linjën e montimit:
Le të tregojmë përpiluesin që është përdorur për të ndërtuar projektin. Vini re kontejnerin docker që është instaluar në këtë veprim. Për shembull, ekziston një enë e veçantë për GCC:
Tani le të instalojmë PVS-Studio dhe shërbimet e nevojshme:
Le të shtojmë rreshtat e mëposhtëm në redaktues:
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
Tani le të shkojmë te skeda Run (ikona e parë) dhe të shtojmë kodin e mëposhtëm në fushën përkatëse të redaktuesit:
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
Nëse lexoni seksionin në Travs-CI, atëherë ky kod është tashmë i njohur për ju, megjithatë, tani ka një fazë të re:
Fakti është se tani ne analizojmë jo rezultatin e bashkimit, por KRYETARIN e degës nga e cila bëhet kërkesa për tërheqje:
Pra, ne jemi në një angazhim të kushtëzuar B3 dhe ne duhet të marrim ndryshimin nga 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
Për të përcaktuar A3 Le të përdorim GitHub API:
https://api.github.com/repos/${USERNAME}/${REPO}/pulls/${PULL_REQUEST_ID}
Ne përdorëm variablat e mëposhtëm që ofron Buddy:
- $BUDDY_EXECUTION_PULL_REQEUST_NO — numri i kërkesës për tërheqje;
- $BUDDY_REPO_SLUG — një kombinim i emrit të përdoruesit dhe depove (për shembull max/test).
Tani le t'i ruajmë ndryshimet duke përdorur butonin më poshtë dhe të aktivizojmë analizën e kërkesës për tërheqje:
Ndryshe nga Travis CI, ne nuk kemi nevojë të specifikojmë .pvs-studio për caching, pasi Buddy i ruan automatikisht të gjithë skedarët për lëshimet e mëvonshme. Prandaj, gjëja e fundit që mbetet është të ruani hyrjen dhe fjalëkalimin për PVS-Studio në Buddy. Pas ruajtjes së ndryshimeve, ne do të kthehemi te Pipeline. Ne duhet të kalojmë në konfigurimin e variablave dhe shtimin e një hyrje dhe çelësi për PVS-Studio:
Pas kësaj, shfaqja e një kërkese të re tërheqjeje ose angazhimi do të shkaktojë rishikimin. Nëse një kryerje përmban gabime, Buddy do ta tregojë këtë në faqen e kërkesës për tërheqje.
AppVeyor
Vendosja e AppVeyor është e ngjashme me Buddy, pasi gjithçka ndodh në ndërfaqen e internetit dhe nuk ka nevojë të shtoni një skedar *.yml në depon e projektit.
Le të shkojmë te skeda Cilësimet në përmbledhjen e projektit:
Le të lëvizim poshtë kësaj faqe dhe të aktivizojmë ruajtjen e memories për mbledhjen e kërkesave për tërheqje:
Tani le të shkojmë te skeda Mjedisi, ku specifikojmë imazhin për montim dhe variablat e nevojshëm të mjedisit:
Nëse i keni lexuar seksionet e mëparshme, jeni shumë të njohur me këto dy variabla − PVS_KEY и PVS_USERNAME. Nëse jo, më lejoni t'ju kujtoj se ato janë të nevojshme për të verifikuar licencën e analizuesit PVS-Studio. Do t'i shohim përsëri në skriptet e Bash në të ardhmen.
Në të njëjtën faqe më poshtë ne tregojmë dosjen për caching:
Nëse nuk e bëjmë këtë, ne do të analizojmë të gjithë projektin në vend të disa skedarëve, por do të marrim rezultatin nga skedarët e specifikuar. Prandaj, është e rëndësishme të vendosni emrin e saktë të drejtorisë.
Tani është koha që skenari të testohet. Hapni skedën Testet dhe zgjidhni Skript:
Ju duhet të ngjisni kodin e mëposhtëm në këtë formë:
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
Le t'i kushtojmë vëmendje pjesës së mëposhtme të kodit:
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
Caktimi mjaft specifik i vlerës së komandës pwd në një ndryshore që duhet të ruajë këtë vlerë të paracaktuar duket e çuditshme në shikim të parë, megjithatë, unë do të shpjegoj gjithçka tani.
Gjatë vendosjes së analizuesit në AppVeyor, hasa në sjellje jashtëzakonisht të çuditshme të analizuesit. Nga njëra anë, gjithçka funksionoi si duhet, por analiza nuk filloi. Kalova shumë kohë duke vënë re se jemi në drejtorinë /home/appveyor/projects/testcalc/ dhe analizuesi është i sigurt se jemi në /opt/appveyor/build-agent/. Pastaj kuptova se ndryshorja $PWD ishte pak e gënjyer. Për këtë arsye, unë përditësova manualisht vlerën e tij përpara se të filloja analizën.
Dhe pastaj gjithçka është si më parë:
Tani merrni parasysh fragmentin e mëposhtëm:
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"`
Në të marrim diferencën midis degëve mbi të cilat deklarohet kërkesa për tërheqje. Për ta bërë këtë, na duhen variablat e mëposhtëm të mjedisit:
- $APPVEYOR_PULL_REQUEST_NUMBER — numri i kërkesës për tërheqje;
- $APPVEYOR_REPO_NAME - emri i përdoruesit dhe depoja e projektit.
Përfundim
Sigurisht, ne nuk kemi marrë parasysh të gjitha shërbimet e mundshme të integrimit të vazhdueshëm, megjithatë, të gjitha ato kanë specifika operative jashtëzakonisht të ngjashme me njëra-tjetrën. Me përjashtim të caching, çdo shërbim bën "biçikletën" e tij, kështu që gjithçka është gjithmonë e ndryshme.
Diku, si në Travis-CI, disa rreshta kodi dhe memorie funksionojnë në mënyrë të përsosur; diku, si në AppVeyor, thjesht duhet të specifikoni dosjen në cilësimet; por diku ju duhet të krijoni çelësa unikë dhe të përpiqeni të bindni sistemin që t'ju japë mundësinë për të mbishkruar fragmentin e ruajtur në memorie. Prandaj, nëse dëshironi të konfiguroni analizën e kërkesave për tërheqje në një shërbim të integrimit të vazhdueshëm që nuk u diskutua më lart, atëherë së pari sigurohuni që nuk do të keni probleme me ruajtjen e memories.
Faleminderit per vemendjen. Nëse diçka nuk funksionon, mos ngurroni të na shkruani në
Nëse dëshironi ta ndani këtë artikull me një audiencë anglishtfolëse, ju lutemi përdorni lidhjen e përkthimit: Maxim Zvyagintsev.
Burimi: www.habr.com