Linux va macOS-da C va C++ tillari uchun PVS-Studio analizatorida 7.04 versiyasidan boshlab ko'rsatilgan fayllar ro'yxatini tekshirish uchun test opsiyasi paydo bo'ldi. Yangi rejimdan foydalanib, siz analizatorni majburiyatlarni tekshirish va so'rovlarni olish uchun sozlashingiz mumkin. Ushbu maqola sizga Travis CI, Buddy va AppVeyor kabi mashhur CI (Continuous Integration) tizimlarida GitHub loyihasining o'zgartirilgan fayllari ro'yxatini tekshirishni qanday sozlashni aytib beradi.
Fayllar ro'yxatini tekshirish rejimi
Linux va macOS uchun PVS-Studio 7.04 versiyasida manba fayllar ro'yxatini tekshirish rejimi paydo bo'ldi. Bu yaratish tizimi sizga fayl yaratishga imkon beradigan loyihalar uchun ishlaydi
Bundan tashqari, fayllar ro'yxatini tekshirish rejimi kompilyator ishga tushirilgandagi izlar jurnali (pvs-studio-analyzer trace) bilan birgalikda ishlatilishi mumkin. Buni amalga oshirish uchun avvalo loyihaning to'liq tuzilishini bajarishingiz va uni kuzatib borishingiz kerak, shunda analizator tekshirilayotgan barcha fayllarning kompilyatsiya parametrlari haqida to'liq ma'lumot to'playdi.
Biroq, bu variantning muhim kamchiliklari bor - siz har safar uni ishga tushirganingizda butun loyihani to'liq qurish izini bajarishingiz kerak bo'ladi, bu o'z-o'zidan majburiyatni tezda tekshirish g'oyasiga zid keladi. Yoki, agar siz iz natijasini keshlashtirsangiz, izdan keyin manba fayllarning qaramlik strukturasi o'zgarsa, analizatorning keyingi ishlashi to'liq bo'lmasligi mumkin (masalan, manba fayllardan biriga yangi #include qo'shiladi).
Shuning uchun, biz majburiyatlarni tekshirish yoki so'rovlarni olish uchun fayllar ro'yxatini tekshirish rejimidan kuzatuv jurnali bilan foydalanishni tavsiya etmaymiz. Agar majburiyatni tekshirishda qo'shimcha qurilishni amalga oshirishingiz mumkin bo'lsa, rejimdan foydalanishni o'ylab ko'ring
Tahlil qilish uchun manba fayllar ro'yxati matn faylida saqlanadi va parametr yordamida analizatorga uzatiladi -S:
pvs-studio-analyzer analyze ... -f build/compile_commands.json -S check-list.txt
Bu fayl fayllarga nisbatan nisbiy yoki mutlaq yo'llarni belgilaydi va har bir yangi fayl yangi qatorda bo'lishi kerak. Tahlil qilish uchun nafaqat fayl nomlarini, balki turli matnlarni ham ko'rsatish maqbuldir. Analizator bu fayl emasligini ko'radi va chiziqni e'tiborsiz qoldiradi. Bu, agar fayllar qo'lda ko'rsatilgan bo'lsa, sharhlash uchun foydali bo'lishi mumkin. Biroq, ko'pincha CIda tahlil qilish paytida fayllar ro'yxati yaratiladi, masalan, bu majburiyat yoki tortib olish so'rovidan olingan fayllar bo'lishi mumkin.
Endi ushbu rejimdan foydalanib, siz yangi kodni asosiy rivojlanish bo'limiga kirishdan oldin tezda tekshirishingiz mumkin. Skanerlash tizimining analizator ogohlantirishlariga javob berishini ta'minlash uchun yordamchi dastur plog-konvertor bayroq qo'shildi --ogohlantirishlar:
plog-converter ... --indicate-warnings ... -o /path/to/report.tasks ...
Analizator hisobotida ogohlantirishlar mavjud bo'lsa, bu bayroq bilan konvertor nolga teng bo'lmagan kodni qaytaradi. Qaytish kodidan foydalanib, siz oldindan so'rovni bloklashingiz, topshirishingiz yoki tortishingiz mumkin va yaratilgan analizator hisoboti ko'rsatilishi, baham ko'rilishi yoki elektron pochta orqali yuborilishi mumkin.
Eslatma. Fayllar ro'yxatini birinchi marta tahlil qilishni boshlaganingizda, butun loyiha tahlil qilinadi, chunki analizator loyiha manba fayllarining sarlavha fayllariga bog'liqlik faylini yaratishi kerak. Bu C va C++ fayllarini tahlil qilish xususiyatidir. Kelajakda bog'liqlik fayli keshlanishi mumkin va u analizator tomonidan avtomatik ravishda yangilanadi. Fayllar roʻyxatini tekshirish rejimini qoʻshimcha tahlil rejimidan foydalanishda majburiyatlarni tekshirishning afzalligi shundaki, siz obʼyekt fayllarini emas, balki faqat shu faylni keshlashingiz kerak.
Pull so'rovini tahlil qilishning umumiy tamoyillari
Butun loyihani tahlil qilish juda ko'p vaqtni oladi, shuning uchun uning faqat ma'lum bir qismini tekshirish mantiqan. Muammo shundaki, siz yangi fayllarni loyiha fayllarining qolgan qismidan ajratishingiz kerak.
Keling, ikkita novdali majburiy daraxt misolini ko'rib chiqaylik:
Keling, bu majburiyatni tasavvur qilaylik A1 allaqachon sinovdan o'tgan juda katta miqdordagi kodni o'z ichiga oladi. Biroz oldin biz majburiyatdan filial yasadik A1 va ba'zi fayllarni o'zgartirdi.
Albatta, siz buni keyin sezdingiz A1 yana ikkita majburiyat yuz berdi, lekin bular ham boshqa filiallarning birlashuvi edi, chunki biz majburiyat qilmaymiz usta. Va endi vaqt keldi tuzatish tayyor. Shuning uchun birlashish uchun tortishish so'rovi paydo bo'ldi B3 и A3.
Albatta, ularning birlashishi natijasini to'liq tekshirish mumkin edi, lekin bu juda ko'p vaqt talab qiladigan va asossiz bo'lar edi, chunki faqat bir nechta fayllar o'zgartirildi. Shuning uchun faqat o'zgartirilganlarni tahlil qilish samaraliroq.
Buning uchun biz magistrga birlashmoqchi bo'lgan filialning HEAD bo'lgan filiallar orasidagi farqni olamiz:
git diff --name-only HEAD origin/$MERGE_BASE > .pvs-pr.list
$MERGE_BASE keyinroq batafsil ko'rib chiqamiz. Gap shundaki, har bir CI xizmati birlashish uchun ma'lumotlar bazasi haqida kerakli ma'lumotlarni taqdim etmaydi, shuning uchun har safar ushbu ma'lumotlarni olishning yangi usullarini o'ylab topishga to'g'ri keladi. Bu quyida tavsiflangan veb-xizmatlarning har birida batafsil tavsiflanadi.
Shunday qilib, biz filiallar orasidagi farqni, aniqrog'i, o'zgartirilgan fayl nomlari ro'yxatini oldik. Endi biz faylni berishimiz kerak .pvs-pr.list (biz yuqoridagi chiqishni unga yo'naltirdik) analizatorga:
pvs-studio-analyzer analyze -j8
-o PVS-Studio.log
-S .pvs-pr.list
Tahlildan so'ng biz jurnal faylini (PVS-Studio.log) oson o'qiladigan formatga aylantirishimiz kerak:
plog-converter -t errorfile PVS-Studio.log --cerr -w
Bu buyruq xatolar ro'yxatini ko'rsatadi
Faqat endi biz nafaqat xatolarni ko'rsatishimiz, balki muammolar mavjudligi haqida yig'ish va sinov uchun xizmatimizga xabar berishimiz kerak. Shu maqsadda konvertorga bayroq qo'shildi -W (--ogohlantirishlar). Agar analizatorda kamida bitta ogohlantirish mavjud bo'lsa, yordamchi dasturni qaytarish kodi plog-konvertor 2 ga o'zgaradi, bu esa o'z navbatida CI xizmatini tortib olish so'rovi fayllarida mumkin bo'lgan xatolar mavjudligi haqida xabardor qiladi.
Travis C.I.
Konfiguratsiya fayl sifatida amalga oshiriladi .travis.yml. Qulaylik uchun men sizga hamma narsani fayldan chaqiriladigan funktsiyalari bilan alohida bash skriptiga qo'yishingizni maslahat beraman. .travis.yml (bash script_name.sh function_name).
Biz skriptga kerakli kodni qo'shamiz bosh, shu tarzda biz ko'proq funksionallikka ega bo'lamiz. Bo'limda o'rnatish quyidagini yozamiz:
install:
- bash .travis.sh travis_install
Agar sizda biron bir ko'rsatma bo'lsa, defislarni olib tashlagan holda ularni skriptga o'tkazishingiz mumkin.
Keling, faylni ochamiz .travis.sh va funksiyaga analizator sozlamalarini qo'shing 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
}
Endi bo'limga qo'shamiz stsenariy tahlil qilish:
script:
- bash .travis.sh travis_script
Va bash skriptida:
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
}
Ushbu kod loyihani qurgandan so'ng ishga tushirilishi kerak, masalan, agar siz CMake-da tuzgan bo'lsangiz:
travis_script() {
CMAKE_ARGS="-DCMAKE_EXPORT_COMPILE_COMMANDS=On ${CMAKE_ARGS}"
cmake $CMAKE_ARGS CMakeLists.txt
make -j8
}
Bu shunday bo'ladi:
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
}
Ehtimol, siz ushbu muhit o'zgaruvchilarini allaqachon payqagansiz $TRAVIS_PULL_REQUEST и $TRAVIS_BRANCH. Travis CI ularni mustaqil ravishda e'lon qiladi:
- $TRAVIS_PULL_REQUEST tortish so'rovi raqamini saqlaydi yoki yolg'on, agar bu oddiy filial bo'lsa;
- $TRAVIS_REPO_SLUG loyiha ombori nomini saqlaydi.
Ushbu funktsiyaning algoritmi:
Travis CI qaytarish kodlariga javob beradi, shuning uchun ogohlantirishlar mavjudligi xizmatga majburiyatni xatolarni o'z ichiga olgan deb belgilashni bildiradi.
Keling, ushbu kod qatorini batafsil ko'rib chiqaylik:
git diff --name-only origin/HEAD > .pvs-pr.list
Gap shundaki, Travis CI tortish so'rovini tahlil qilishda filiallarni avtomatik ravishda birlashtiradi:
Shuning uchun biz tahlil qilamiz A4, va emas B3->A3. Ushbu xususiyat tufayli biz farqni hisoblashimiz kerak А3, bu aniq dan filialning yuqori qismidir kelib chiqishi.
Bitta muhim tafsilot qoldi - sarlavha fayllarining kompilyatsiya qilingan tarjima birliklariga bog'liqligini keshlash (*.c, *.cc, *.cpp va boshqalar). Analizator ushbu bog'liqliklarni birinchi marta fayllar ro'yxatini tekshirish rejimida ishga tushirilganda hisoblab chiqadi va keyin ularni .PVS-Studio katalogida saqlaydi. Travis CI sizga papkalarni keshlash imkonini beradi, shuning uchun biz katalog ma'lumotlarini saqlaymiz .PVS-Studio/:
cache:
directories:
- .PVS-Studio/
Ushbu kod faylga qo'shilishi kerak .travis.yml. Ushbu katalog tahlildan so'ng to'plangan turli xil ma'lumotlarni saqlaydi, bu fayllar ro'yxatini tahlil qilish yoki qo'shimcha tahlil qilishning keyingi bosqichlarini sezilarli darajada tezlashtiradi. Agar bu bajarilmasa, analizator har safar barcha fayllarni tahlil qiladi.
Buddy
Travis CI kabi,
Avvalo, biz yig'ish liniyasiga yangi harakatni qo'shishimiz kerak:
Loyihani yaratishda foydalanilgan kompilyatorni ko'rsatamiz. Ushbu amalda o'rnatilgan docker konteyneriga e'tibor bering. Masalan, GCC uchun maxsus konteyner mavjud:
Endi PVS-Studio va kerakli yordamchi dasturlarni o'rnatamiz:
Keling, muharrirga quyidagi qatorlarni qo'shamiz:
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
Endi "Ishga tushirish" yorlig'iga o'tamiz (birinchi belgi) va tegishli tahrirlovchi maydoniga quyidagi kodni qo'shing:
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
Agar siz Travs-CI bo'limini o'qisangiz, bu kod sizga allaqachon tanish, ammo endi yangi bosqich mavjud:
Gap shundaki, endi biz birlashma natijasini emas, balki tortib olish so'rovi yuborilgan filialning HEAD ni tahlil qilamiz:
Shunday qilib, biz shartli majburiyatdamiz B3 va biz farqni olishimiz kerak 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
Aniqlash uchun A3 Keling, GitHub API dan foydalanamiz:
https://api.github.com/repos/${USERNAME}/${REPO}/pulls/${PULL_REQUEST_ID}
Biz Buddy taqdim etgan quyidagi o'zgaruvchilardan foydalandik:
- $BUDDY_EXECUTION_PULL_REQEUST_NO — so‘rov raqamini olish;
- $BUDDY_REPO_SLUG — foydalanuvchi nomi va omborning kombinatsiyasi (masalan, max/test).
Endi quyidagi tugma yordamida o'zgarishlarni saqlaymiz va tortish so'rovini tahlil qilishni yoqamiz:
Travis CI dan farqli o'laroq, biz aniqlashtirishimiz shart emas .pvs-studio keshlash uchun, chunki Buddy keyingi ishga tushirish uchun barcha fayllarni avtomatik ravishda keshlaydi. Shuning uchun, oxirgi narsa - Buddy-da PVS-Studio uchun login va parolni saqlash. O'zgarishlarni saqlaganimizdan so'ng, biz Pipeline-ga qaytamiz. Biz o'zgaruvchilarni sozlash va PVS-Studio uchun login va kalitni qo'shishga o'tishimiz kerak:
Shundan so'ng, yangi tortib olish so'rovi yoki majburiyatning paydo bo'lishi ko'rib chiqishni boshlaydi. Agar topshiriqda xatolar bo'lsa, Buddy buni tortish so'rovi sahifasida ko'rsatadi.
AppVeyor
AppVeyor-ni sozlash Buddy-ga o'xshaydi, chunki hamma narsa veb-interfeysda sodir bo'ladi va loyiha omboriga *.yml faylini qo'shishning hojati yo'q.
Keling, loyihaning umumiy ko'rinishidagi Sozlamalar yorlig'iga o'tamiz:
Keling, ushbu sahifani pastga aylantiramiz va tortishish so'rovlarini yig'ish uchun keshni saqlashni yoqamiz:
Endi "Atrof-muhit" yorlig'iga o'tamiz, u erda biz yig'ish uchun tasvirni va kerakli muhit o'zgaruvchilarini belgilaymiz:
Agar siz avvalgi bo'limlarni o'qigan bo'lsangiz, siz bu ikki o'zgaruvchi bilan juda yaxshi tanishsiz - PVS_KEY и PVS_USERNAME. Agar yo'q bo'lsa, sizga PVS-Studio analizatorining litsenziyasini tekshirish kerakligini eslatib o'taman. Kelajakda biz ularni yana Bash skriptlarida ko'ramiz.
Xuddi shu sahifada biz keshlash uchun papkani ko'rsatamiz:
Agar biz buni qilmasak, biz bir nechta fayl o'rniga butun loyihani tahlil qilamiz, lekin biz belgilangan fayllardan natijani olamiz. Shuning uchun katalog nomini to'g'ri kiritish muhimdir.
Endi skriptni sinab ko'rish vaqti keldi. Sinovlar yorlig'ini oching va skriptni tanlang:
Ushbu shaklga quyidagi kodni kiritishingiz kerak:
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
Keling, kodning quyidagi qismiga e'tibor beraylik:
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
Ushbu standart qiymatni saqlashi kerak bo'lgan o'zgaruvchiga pwd buyrug'i qiymatini o'ziga xos tarzda belgilash birinchi qarashda g'alati tuyuladi, ammo hozir hammasini tushuntiraman.
AppVeyor-da analizatorni o'rnatishda men analizatorning juda g'alati xatti-harakatlariga duch keldim. Bir tomondan, hamma narsa to'g'ri ishladi, lekin tahlil boshlanmadi. Men /home/appveyor/projects/testcalc/ katalogida ekanligimizni payqab ko'p vaqt sarfladim va analizator biz /opt/appveyor/build-agent/ ichida ekanligimizga ishonch hosil qildi. Keyin $PWD o'zgaruvchisi biroz yolg'on gapirayotganini angladim. Shu sababli, tahlilni boshlashdan oldin uning qiymatini qo'lda yangiladim.
Va keyin hamma narsa avvalgidek:
Endi quyidagi parchani ko'rib chiqing:
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"`
Unda biz tortish so'rovi e'lon qilingan filiallar orasidagi farqni olamiz. Buning uchun bizga quyidagi muhit o'zgaruvchilari kerak bo'ladi:
- $APPVEYOR_PULL_REQUEST_NUMBER - so'rov raqamini olish;
- $APPVEYOR_REPO_NAME - foydalanuvchi nomi va loyiha ombori.
xulosa
Albatta, biz barcha mumkin bo'lgan uzluksiz integratsiya xizmatlarini ko'rib chiqmadik, ammo ularning barchasi bir-biriga juda o'xshash operatsion xususiyatlarga ega. Keshlashdan tashqari, har bir xizmat o'zining "velosipedini" yaratadi, shuning uchun hamma narsa har doim boshqacha.
Qaerdadir, Travis-CI-da bo'lgani kabi, bir nechta kod qatorlari va keshlash mukammal ishlaydi; bir joyda, masalan, AppVeyor-da, sozlamalarda jildni ko'rsatish kifoya; lekin biror joyda siz noyob kalitlarni yaratishingiz va tizimni keshlangan fragmentni qayta yozish imkoniyatini berishga ishontirishga harakat qilishingiz kerak. Shuning uchun, agar siz yuqorida muhokama qilinmagan uzluksiz integratsiya xizmatida tortishish so'rovlarini tahlil qilishni o'rnatmoqchi bo'lsangiz, avval keshlash bilan bog'liq muammolarga duch kelmasligingizga ishonch hosil qiling.
E'tiboringiz uchun rahmat. Agar biror narsa ishlamasa, bizga yozing
Agar siz ushbu maqolani ingliz tilida so'zlashuvchi auditoriya bilan baham ko'rishni istasangiz, iltimos, tarjima havolasidan foydalaning: Maksim Zvyagintsev.
Manba: www.habr.com