Dimulai dengan versi 7.04, penganalisa PVS-Studio untuk bahasa C dan C ++ di Linux dan macOS memiliki kemampuan uji untuk memeriksa daftar file yang ditentukan. Dengan menggunakan mode baru, Anda dapat mengonfigurasikan penganalisis untuk memeriksa komit dan menarik permintaan. Artikel ini akan menunjukkan kepada Anda cara mengkonfigurasi memeriksa daftar file yang dimodifikasi dari proyek GitHub di sistem CI (Continuous Integration) populer seperti Travis CI, Buddy dan AppVeyor.
Mode Pemeriksaan Daftar File
PVS-Studio adalah alat untuk mendeteksi kesalahan dan kerentanan potensial dalam kode sumber program yang ditulis dalam C, C ++, C # dan Java. Ini bekerja pada sistem 64-bit pada Windows, Linux dan macOS.
Dalam PVS-Studio versi 7.04 untuk Linux dan macOS, mode memeriksa daftar file sumber muncul. Ini berfungsi untuk proyek yang sistem
bangunnya memungkinkan file
compile_commands.json dihasilkan. Diperlukan agar penganalisa untuk mengekstrak informasi tentang kompilasi file yang ditentukan. Jika sistem build Anda tidak mendukung pembuatan file compile_commands.json, Anda dapat mencoba membuat file seperti itu menggunakan utilitas
Bear .
Juga, mode pemeriksaan daftar file dapat digunakan bersama dengan strace trace log dari compiler dimulai (pvs-studio-analyzer trace). Untuk melakukan ini, pertama-tama Anda perlu melakukan perakitan lengkap proyek dan melacaknya sehingga penganalisa mengumpulkan informasi lengkap tentang parameter kompilasi semua file yang diuji.
Namun, opsi ini memiliki kelemahan yang signifikan - Anda harus membuat jejak lengkap dari seluruh perakitan proyek di setiap permulaan, yang dengan sendirinya bertentangan dengan gagasan pengecekan cepat komit. Atau, jika hasil penelusuran itu sendiri di-cache, maka penganalisis yang dimulai mungkin tidak lengkap jika struktur dependensi dari file sumber berubah setelah jejak (misalnya, #include baru ditambahkan ke salah satu file sumber).
Oleh karena itu, kami tidak menyarankan menggunakan mode pemeriksaan daftar file dengan log jejak untuk memeriksa komit atau menarik permintaan. Jika Anda dapat melakukan rakitan tambahan saat memeriksa komit, pertimbangkan untuk menggunakan mode
analisis tambahan .
Daftar file sumber untuk analisis disimpan dalam file teks dan ditransfer ke analyzer menggunakan parameter
-S :
pvs-studio-analyzer analyze ... -f build/compile_commands.json -S check-list.txt
Dalam file ini, jalan relatif atau absolut ke file ditunjukkan, dan setiap file baru harus di baris baru. Diijinkan untuk menentukan tidak hanya nama file untuk analisis, tetapi juga berbagai teks. Penganalisa akan melihat bahwa ini bukan file, dan akan mengabaikan baris. Ini berguna untuk berkomentar jika file ditentukan secara manual. Namun, sering kali daftar file akan dihasilkan selama analisis dalam CI, misalnya, ini mungkin file dari permintaan komit atau tarik.
Sekarang menggunakan mode ini, Anda dapat dengan cepat memeriksa kode baru sebelum masuk ke cabang pengembangan utama. Agar sistem verifikasi menanggapi peringatan penganalisa, bendera
--indicate-warnings telah ditambahkan ke
utilitas plog-converter :
plog-converter ... --indicate-warnings ... -o /path/to/report.tasks ...
Dengan tanda ini, konverter akan mengembalikan kode bukan nol jika ada peringatan dalam laporan analisa. Dengan menggunakan kode pengembalian, Anda dapat memblokir kait pra-komit, melakukan atau menarik permintaan, dan menampilkan laporan analisa yang dihasilkan di layar, membagikan atau mengirim melalui surat.
Catatan Pertama kali Anda menjalankan analisis daftar file, seluruh proyek akan dianalisis, karena penganalisa perlu menghasilkan file dependensi dari file sumber proyek dari file header. Ini adalah fitur analisis file C dan C ++. Di masa depan, file dependensi dapat di-cache dan akan diperbarui secara otomatis oleh penganalisa. Keuntungan memeriksa komit ketika menggunakan mode verifikasi daftar file daripada menggunakan mode analisis tambahan adalah bahwa Anda hanya perlu men-cache file ini, bukan file objek.Prinsip umum analisis permintaan tarik
Analisis keseluruhan proyek membutuhkan banyak waktu, jadi masuk akal untuk memeriksa hanya bagian tertentu saja. Masalahnya adalah Anda harus memisahkan file baru dari sisa file proyek.
Pertimbangkan contoh pohon komit dengan dua cabang:
Mari kita bayangkan komit
A1 berisi sejumlah besar kode yang telah diuji. Beberapa waktu sebelumnya, kami membuat cabang dari komit
A1 dan mengubah beberapa file.
Tentu saja, Anda perhatikan bahwa setelah
A1 ada dua komitmen lagi, tetapi ini juga merger dari cabang-cabang lain, karena kami tidak berkomitmen pada
master . Dan sekarang saatnya telah tiba ketika
perbaikan terbaru siap. Oleh karena itu, muncul permintaan tarik untuk penggabungan
B3 dan
A3 .
Tentu saja, orang dapat memeriksa seluruh hasil merger mereka, tetapi ini akan terlalu lama dan tidak dapat dibenarkan, karena hanya beberapa file yang diubah. Oleh karena itu, lebih efisien untuk menganalisis hanya yang berubah.
Untuk melakukan ini, kita mendapatkan perbedaan antara cabang-cabang, berada di KEPALA cabang yang ingin kita gabungkan menjadi master:
git diff --name-only HEAD origin/$MERGE_BASE > .pvs-pr.list
$ MERGE_BASE akan kami pertimbangkan secara rinci nanti. Faktanya adalah bahwa tidak setiap layanan CI menyediakan informasi yang diperlukan tentang dasar untuk penggabungan, jadi setiap kali Anda harus menemukan cara baru untuk mendapatkan data ini. Ini akan dirinci di bawah ini di setiap layanan web yang dijelaskan.
Jadi, kami mendapat perbedaan antara cabang, atau lebih tepatnya, daftar nama file yang telah diubah. Sekarang kita perlu memberikan file
.pvs-pr.list (kita mengarahkan hasilnya ke atas) ke penganalisa:
pvs-studio-analyzer analyze -j8 \ -o PVS-Studio.log \ -S .pvs-pr.list
Setelah analisis, kita perlu mengkonversi file log (PVS-Studio.log) ke dalam format yang mudah dibaca:
plog-converter -t errorfile PVS-Studio.log --cerr -w
Perintah ini akan mencantumkan kesalahan dalam
stderr (aliran output pesan kesalahan standar).
Hanya sekarang kita perlu tidak hanya menampilkan kesalahan, tetapi juga menginformasikan layanan kami untuk perakitan dan pengujian masalah. Untuk melakukan ini, bendera
-W (
--indikasikan-peringatan ) telah ditambahkan ke konverter. Jika setidaknya ada satu penganalisa peringatan, kode pengembalian utilitas
plog-converter akan berubah menjadi 2, yang, pada gilirannya, akan menginformasikan layanan CI tentang adanya kesalahan potensial dalam file permintaan tarik.
Travis ci
Konfigurasi dibuat sebagai file
.travis.yml . Untuk kenyamanan, saya menyarankan Anda untuk meletakkan semuanya dalam skrip bash terpisah dengan fungsi yang akan dipanggil dari file
.travis.yml (
bash script_name.sh function_name ).
Kami akan menambahkan kode yang diperlukan ke skrip
bash , jadi kami mendapatkan lebih banyak fungsi. Di bagian
instal , tulis yang berikut ini:
install: - bash .travis.sh travis_install
Jika Anda memiliki instruksi, Anda dapat mentransfernya ke skrip dengan menghapus tanda hubung.
Buka file
.travis.sh dan tambahkan instalasi analyzer ke fungsi
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 }
Sekarang tambahkan analisis lari ke bagian
skrip :
script: - bash .travis.sh travis_script
Dan dalam skrip 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 }
Kode ini perlu dijalankan setelah membangun proyek, misalnya, jika Anda memiliki build di CMake:
travis_script() { CMAKE_ARGS="-DCMAKE_EXPORT_COMPILE_COMMANDS=On ${CMAKE_ARGS}" cmake $CMAKE_ARGS CMakeLists.txt make -j8 }
Ini akan menjadi seperti ini:
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 }
Anda mungkin sudah memperhatikan variabel lingkungan yang ditentukan
$ TRAVIS_PULL_REQUEST dan
$ TRAVIS_BRANCH . Travis CI mengumumkannya sendiri:
- $ TRAVIS_PULL_REQUEST menyimpan nomor permintaan tarik atau salah jika itu cabang biasa;
- $ TRAVIS_REPO_SLUG menyimpan nama repositori proyek.
Algoritma dari fungsi ini:
Travis CI merespons kode kembali, sehingga keberadaan peringatan akan memberi tahu layanan untuk menandai komit sebagai berisi kesalahan.
Sekarang, mari kita lihat lebih dekat pada baris kode ini:
git diff --name-only origin/HEAD > .pvs-pr.list
Faktanya adalah bahwa Travis CI secara otomatis menggabungkan cabang selama analisis permintaan tarik:
Oleh karena itu, kami menganalisis
A4 , bukan
B3-> A3 . Karena fitur ini, kita perlu menghitung selisihnya dengan
A3 , yang tepatnya merupakan puncak cabang dari
asalnya .
Satu detail penting tetap ada - dependensi caching file header pada unit terjemahan yang dikompilasi (* .c, * .cc, * .cpp, dll.). Alat analisis menghitung dependensi ini pada awal pertama dalam mode memeriksa daftar file dan kemudian menyimpannya dalam direktori .PVS-Studio. Travis CI memungkinkan Anda untuk melakukan cache folder, jadi kami akan menyimpan data dari
direktori .PVS-Studio / :
cache: directories: - .PVS-Studio/
Kode ini perlu ditambahkan ke file
.travis.yml . Direktori ini menyimpan berbagai data yang dikumpulkan setelah analisis, yang secara signifikan akan mempercepat peluncuran analisis daftar file berikutnya atau analisis tambahan. Jika ini tidak dilakukan, maka penganalisa akan benar-benar menganalisis semua file setiap saat.
Sobat
Seperti Travis CI,
Buddy menyediakan kemampuan untuk secara otomatis membangun dan menguji proyek yang disimpan di GitHub. Tidak seperti Travis CI, ini dikonfigurasi dalam antarmuka web (dukungan bash tersedia), sehingga tidak perlu menyimpan file konfigurasi dalam proyek.
Pertama-tama, kita perlu menambahkan tindakan baru ke jalur perakitan:
Kami menunjukkan kompiler yang digunakan untuk membangun proyek. Perhatikan wadah buruh pelabuhan yang dipasang dalam tindakan ini. Misalnya, ada wadah khusus untuk GCC:
Sekarang instal PVS-Studio dan utilitas yang diperlukan:
Tambahkan baris berikut ke 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
Sekarang buka tab Run (ikon pertama) dan tambahkan kode berikut ke bidang editor yang sesuai:
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
Jika Anda membaca bagian tentang Travs-CI, maka kode ini sudah tidak asing lagi bagi Anda, namun sekarang telah muncul tahapan baru:
Faktanya adalah bahwa sekarang kita menganalisis bukan hasil merger, tetapi KEPALA cabang dari mana permintaan tarik dibuat:
Oleh karena itu, kita berada dalam komit
B3 bersyarat dan kita perlu mendapatkan perbedaan dengan
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
Untuk menentukan
A3, gunakan API GitHub:
https://api.github.com/repos/${USERNAME}/${REPO}/pulls/${PULL_REQUEST_ID}
Kami menggunakan variabel berikut yang disediakan oleh Sobat:
- $ BUDDY_EXECUTION_PULL_REQEUST_NO - tarik nomor permintaan ;
- $ BUDDY_REPO_SLUG - kombinasi nama pengguna dan repositori (misalnya maks / pengujian).
Sekarang simpan perubahan menggunakan tombol di bawah ini dan aktifkan analisis permintaan tarik:
Tidak seperti Travis CI, kita tidak perlu menentukan
.pvs-studio untuk caching, karena Buddy secara otomatis menyimpan semua file untuk peluncuran selanjutnya. Karena itu, hal terakhir yang tersisa adalah menyimpan login dan kata sandi untuk PVS-Studio di Buddy. Setelah menyimpan perubahan, kami akan kembali ke Pipeline. Kita perlu melanjutkan untuk mengatur variabel dan menambahkan login dan kunci untuk PVS-Studio:
Setelah itu, tampilan permintaan tarik baru atau komit akan memicu cek. Jika komit berisi kesalahan, maka Sobat akan menunjukkan ini pada halaman permintaan tarik.
Pengantar
Pengaturan AppVeyor mirip dengan Buddy, karena semuanya terjadi di antarmuka web dan tidak perlu menambahkan file * .yml ke repositori proyek.
Buka tab Pengaturan di ikhtisar proyek:
Gulir halaman ini ke bawah dan nyalakan penyimpanan cache untuk membuat permintaan tarikan:
Sekarang buka tab Lingkungan, di mana kita menentukan gambar untuk perakitan dan variabel lingkungan yang diperlukan:
Jika Anda membaca bagian sebelumnya, Anda sangat mengenal kedua variabel ini -
PVS_KEY dan
PVS_USERNAME . Jika tidak, maka saya mengingatkan Anda bahwa mereka diperlukan untuk memeriksa lisensi alat analisa PVS-Studio. Di masa depan, kita akan bertemu mereka lagi dalam skrip Bash.
Pada halaman yang sama di bawah ini kami menunjukkan folder untuk caching:
Jika tidak, maka kami akan menganalisis seluruh proyek alih-alih sepasang file, tetapi kami akan mendapatkan output dari file yang ditentukan. Oleh karena itu, penting untuk memasukkan nama direktori yang benar.
Sekarang saatnya skrip memeriksa. Buka tab Tes dan pilih Script:
Masukkan kode berikut ke dalam formulir ini:
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
Perhatikan bagian kode berikut:
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
Tugas yang agak spesifik dari nilai perintah pwd ke variabel yang seharusnya menyimpan nilai default ini tampak aneh pada pandangan pertama, namun, saya akan menjelaskan semuanya sekarang.
Saat mengkonfigurasi penganalisis di AppVeyor, saya menemukan perilaku penganalisa yang sangat aneh. Di satu sisi, semuanya bekerja dengan benar, tetapi analisisnya tidak dimulai. Saya menghabiskan banyak waktu untuk memperhatikan bahwa kita berada di direktori / home / appveyor / proyek / testcalc /, dan penganalisa yakin bahwa kita berada di / opt / appveyor / build-agent /. Kemudian saya menyadari bahwa variabel $ PWD berbohong sedikit. Untuk alasan ini, saya memperbarui nilainya secara manual sebelum memulai analisis.
Dan kemudian semuanya, seperti sebelumnya:
Sekarang pertimbangkan cuplikan berikut:
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"`
Di dalamnya, kita mendapatkan perbedaan antara cabang tempat permintaan tarik diumumkan. Untuk melakukan ini, kita memerlukan variabel lingkungan berikut:
- $ APPVEYOR_PULL_REQUEST_NUMBER - jumlah permintaan tarik;
- $ APPVEYOR_REPO_NAME - nama pengguna dan repositori proyek.
Kesimpulan
Tentu saja, kami tidak mempertimbangkan semua layanan yang memungkinkan untuk integrasi berkelanjutan, namun, semuanya memiliki kemiripan satu sama lain untuk pekerjaan tertentu. Dengan pengecualian caching, setiap layanan membuat "sepeda" sendiri, jadi semuanya selalu berbeda.
Di suatu tempat, seperti di Travis-CI, beberapa baris kode dan caching berfungsi dengan sempurna; di suatu tempat, seperti di AppVeyor, Anda hanya perlu menentukan folder di pengaturan; tetapi di suatu tempat Anda perlu membuat kunci unik dan mencoba meyakinkan sistem untuk memberi Anda kesempatan untuk menimpa fragmen yang di-cache. Oleh karena itu, jika Anda ingin mengonfigurasi analisis permintaan tarik pada layanan integrasi berkelanjutan, yang tidak dibahas di atas, pertama-tama pastikan bahwa Anda tidak akan mengalami masalah dengan caching.
Terima kasih atas perhatian anda Jika sesuatu tidak berhasil, jangan ragu untuk menulis surat kepada kami sebagai
dukungan . Kami akan meminta dan membantu.

Jika Anda ingin berbagi artikel ini dengan audiens yang berbahasa Inggris, silakan gunakan tautan ke terjemahan: Maxim Zvyagintsev.
Analisis komitmen dan tarik permintaan di Travis CI, Buddy, dan AppVeyor menggunakan PVS-Studio .