Analiz de komèt ak demann rale nan Travis CI, Buddy ak AppVeyor lè l sèvi avèk PVS-Studio

Analiz de komèt ak demann rale nan Travis CI, Buddy ak AppVeyor lè l sèvi avèk PVS-Studio
Nan analizeur PVS-Studio pou lang C ak C++ sou Linux ak macOS, apati vèsyon 7.04, yon opsyon tès parèt pou tcheke lis fichye espesifye yo. Sèvi ak nouvo mòd la, ou ka configured analizè a pou tcheke komèt ak demann rale. Atik sa a pral di w ki jan yo mete kanpe tcheke lis dosye ki chanje nan yon pwojè GitHub nan sistèm popilè CI (Entegrasyon Kontinyèl) tankou Travis CI, Buddy ak AppVeyor.

Mòd tcheke lis dosye

PVS-estidyo se yon zouti pou idantifye erè ak frajilite potansyèl nan kòd sous pwogram ki ekri nan C, C++, C# ak Java. Travay sou sistèm 64-bit sou Windows, Linux ak macOS.

Nan vèsyon PVS-Studio 7.04 pou Linux ak macOS, yon mòd pou tcheke lis dosye sous te parèt. Sa a travay pou pwojè ki gen sistèm bati pèmèt ou jenere yon dosye compile_commands.json. Li nesesè pou analizè a ekstrè enfòmasyon sou konpilasyon dosye yo espesifye. Si sistèm bati ou a pa sipòte jenere fichye compile_commands.json la, ou ka eseye jenere yon fichye konsa lè l sèvi avèk sèvis piblik la. Vire a.

Epitou, mòd tcheke lis fichye a ka itilize ansanm ak boutèy demi lit trase nan lanse konpilatè (pvs-studio-analyzer tras). Pou fè sa, w ap bezwen premye fè yon bati konplè nan pwojè a epi swiv li pou ke analizè a kolekte enfòmasyon konplè sou paramèt yo konpilasyon nan tout dosye yo te tcheke.

Sepandan, opsyon sa a gen yon dezavantaj enpòtan - ou pral swa bezwen fè yon tras bati konplè nan tout pwojè a chak fwa ou kouri li, ki nan tèt li kontredi lide nan byen vit tcheke yon komèt. Oswa, si ou kache rezilta tras la tèt li, kouri ki vin apre nan analizè a ka enkonplè si estrikti depandans nan dosye sous yo chanje apre tras la (pa egzanp, yo ajoute yon nouvo #include nan youn nan dosye sous yo).

Se poutèt sa, nou pa rekòmande pou w sèvi ak mòd chèk lis fichye a ak boutèy demi lit la pou tcheke komèt oswa demann rale. Nan ka ou ka fè yon bati incrémentielle lè tcheke yon komèt, konsidere itilize mòd la analiz incrémentielle.

Lis fichye sous pou analiz yo sove nan yon dosye tèks epi yo pase nan analizè a lè l sèvi avèk paramèt la -S:

pvs-studio-analyzer analyze ... -f build/compile_commands.json -S check-list.txt

Fichye sa a presize chemen relatif oswa absoli nan dosye, epi chak nouvo dosye dwe sou yon nouvo liy. Li akseptab pou presize non sèlman dosye pou analiz, men tou divès kalite tèks. Analizè a pral wè ke sa a se pa yon dosye epi li pral inyore liy lan. Sa a ka itil pou fè kòmantè si yo espesifye dosye yo manyèlman. Sepandan, souvan yo pral pwodwi yon lis dosye pandan analiz nan CI, pou egzanp, sa yo ta ka fichye ki soti nan yon demann komèt oswa rale.

Koulye a, lè l sèvi avèk mòd sa a, ou ka byen vit tcheke nouvo kòd anvan li vin nan branch devlopman prensipal la. Pou asire ke sistèm nan optik reponn a avètisman analizeur, sèvis piblik la plog-konvètè drapo te ajoute --indike-avètisman:

plog-converter ... --indicate-warnings ... -o /path/to/report.tasks ...

Avèk drapo sa a, konvètisè a pral retounen yon kòd ki pa zewo si gen avètisman nan rapò analizè a. Sèvi ak kòd retou a, ou ka bloke yon zen precommit, komèt, oswa demann rale, epi yo ka parèt, pataje, oswa voye pa imèl rapò analizè pwodwi a.

Remak. Lè ou premye kòmanse analize yon lis dosye, yo pral analize tout pwojè a, paske analizeur a bezwen jenere yon dosye depandans nan dosye sous pwojè yo sou dosye yo header. Sa a se yon karakteristik analize C ak C++ dosye. Nan tan kap vini an, dosye a depandans ka kach epi li pral mete ajou otomatikman pa analizè a. Avantaj nan tcheke komèt lè w ap itilize mòd tcheke lis dosye sou lè l sèvi avèk mòd analiz incrémentielle se ke ou sèlman bezwen nan kachèt fichye sa a epi yo pa fichye objè yo.

Prensip jeneral nan analiz demann rale

Analize tout pwojè a pran anpil tan, kidonk li fè sans pou tcheke sèlman yon sèten pati nan li. Pwoblèm lan se ke ou bezwen separe nouvo dosye yo soti nan rès dosye pwojè yo.

Ann gade yon egzanp yon pye bwa komèt ki gen de branch:

Analiz de komèt ak demann rale nan Travis CI, Buddy ak AppVeyor lè l sèvi avèk PVS-Studio

Ann imajine ke komèt A1 gen yon kantite lajan jistis gwo nan kòd ki te deja teste. Yon ti kras pi bonè nou te fè yon branch nan komèt la A1 epi chanje kèk dosye.

Ou, nan kou, remake sa apre A1 de plis komèt ki te fèt, men sa yo te tou fusions nan lòt branch, paske nou pa komèt mèt. Epi kounyeya lè a rive lè Hotfix pare. Se poutèt sa yon demann rale pou fizyon an parèt B3 и A3.

Natirèlman, li ta posib yo tcheke rezilta a tout antye nan fizyon yo, men sa a ta dwe twò konsome tan ak enjustifye, paske se sèlman kèk dosye yo te chanje. Se poutèt sa, li pi efikas analize sèlman sa yo chanje.

Pou fè sa, nou jwenn diferans ki genyen ant branch yo, yo te nan TÈT la nan branch ki soti nan ki nou vle rantre nan mèt:

git diff --name-only HEAD origin/$MERGE_BASE > .pvs-pr.list

$MERGE_BASE nou pral gade li an detay pita. Reyalite a se ke se pa tout sèvis CI bay enfòmasyon ki nesesè sou baz done a pou fusion, kidonk chak fwa ou gen vini ak nouvo fason yo jwenn done sa yo. Sa a pral dekri an detay anba a nan chak nan sèvis entènèt ki dekri yo.

Se konsa, nou te resevwa diferans ki genyen ant branch yo, oswa pito, yon lis non dosye ki te chanje. Koulye a, nou bezwen bay dosye a .pvs-pr.list (nou redireksyon pwodiksyon an pi wo a sou li) nan analizè a:

pvs-studio-analyzer analyze -j8 
                            -o PVS-Studio.log 
                            -S .pvs-pr.list

Apre analiz, nou bezwen konvèti dosye log (PVS-Studio.log) nan yon fòma ki fasil pou li:

plog-converter -t errorfile PVS-Studio.log --cerr -w

Kòmand sa a pral lis erè yo nan stderr (estanda mesaj erè pwodiksyon).

Se sèlman kounye a nou bezwen pa sèlman montre erè, men tou, enfòme sèvis nou an pou asanble ak tès sou prezans nan pwoblèm. Pou rezon sa a, yo te ajoute yon drapo nan konvètisè a -W (--indike-avètisman). Si gen omwen yon avètisman analizè, kòd retounen sèvis piblik la plog-konvètè pral chanje nan 2, ki an vire pral enfòme sèvis la CI sou prezans nan erè potansyèl nan dosye yo demann rale.

Travis C.I.

Konfigirasyon an fèt kòm yon dosye .travis.yml. Pou konvenyans, mwen konseye w mete tout bagay nan yon script bash separe ak fonksyon yo pral rele nan dosye a. .travis.yml (bash script_name.sh function_name).

Nou pral ajoute kòd ki nesesè nan script la nan frape, fason sa a nou pral jwenn plis fonctionnalités. Nan seksyon enstale ann ekri sa ki annapre yo:

install:
  - bash .travis.sh travis_install

Si ou te gen nenpòt enstriksyon, ou ka transfere yo nan script la, retire tire yo.

Ann louvri dosye a .travis.sh epi ajoute anviwònman analizè a nan fonksyon an 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 
}

Koulye a, ann ajoute nan seksyon an script kouri analiz:

script:
  - bash .travis.sh travis_script

Ak nan script la 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
}

Kòd sa a bezwen kouri apre bati pwojè a, pou egzanp, si ou te gen yon bati sou CMake:

travis_script() {
  CMAKE_ARGS="-DCMAKE_EXPORT_COMPILE_COMMANDS=On ${CMAKE_ARGS}"
  cmake $CMAKE_ARGS CMakeLists.txt
  make -j8
}

Li pral tounen tankou sa a:

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
}

Ou te pwobableman deja remake varyab anviwònman sa yo $TRAVIS_PULL_REQUEST и $TRAVIS_BRANCH. Travis CI deklare yo poukont yo:

  • $TRAVIS_PULL_REQUEST magazen nimewo demann rale a oswa fo, si sa a se yon branch regilye;
  • $TRAVIS_REPO_SLUG estoke non depo pwojè a.

Algorithm pou fonksyon sa a:

Analiz de komèt ak demann rale nan Travis CI, Buddy ak AppVeyor lè l sèvi avèk PVS-Studio
Travis CI reponn a kòd retounen yo, kidonk prezans avètisman yo pral di sèvis la make komèt la kòm ki gen erè.

Koulye a, ann pran yon gade pi pre nan liy sa a nan kòd:

git diff --name-only origin/HEAD > .pvs-pr.list

Reyalite a se ke Travis CI otomatikman fusion branch pandan analize yon demann rale:

Analiz de komèt ak demann rale nan Travis CI, Buddy ak AppVeyor lè l sèvi avèk PVS-Studio
Se poutèt sa nou analize A4men se pa B3->A3. Akòz karakteristik sa a, nou bezwen kalkile diferans lan ak A3, ki se jisteman tèt branch lan soti nan orijin.

Gen yon sèl detay enpòtan ki rete - kachèt depandans yo nan dosye header sou inite tradiksyon konpile (*.c, *.cc, *.cpp, elatriye). Analizatè a kalkile depandans sa yo lè li premye te lanse nan mòd tcheke yon lis fichye epi li sove yo nan anyè .PVS-Studio. Travis CI pèmèt ou kachèt dosye, kidonk nou pral sove done yo anyè .PVS-Studio/:

cache:
  directories:
    - .PVS-Studio/

Kòd sa a bezwen ajoute nan dosye a .travis.yml. Anyè sa a estoke done divès kalite kolekte apre analiz, ki pral siyifikativman akselere kouri ki vin apre nan analiz lis dosye oswa analiz incrémentielle. Si sa a pa fè, Lè sa a, analizeur a pral aktyèlman analize tout dosye chak fwa.

Buddy

Tankou Travis CI, Buddy bay kapasite pou otomatikman bati ak teste pwojè ki estoke sou GitHub. Kontrèman ak Travis CI, li se configuré nan koòdone entènèt la (sipò bash ki disponib), kidonk pa gen okenn bezwen nan magazen fichye konfigirasyon nan pwojè a.

Premye a tout, nou bezwen ajoute yon nouvo aksyon nan liy asanble a:

Analiz de komèt ak demann rale nan Travis CI, Buddy ak AppVeyor lè l sèvi avèk PVS-Studio
Ann endike du ki te itilize pou konstwi pwojè a. Remake veso docker ki enstale nan aksyon sa a. Pou egzanp, gen yon veso espesyal pou GCC:

Analiz de komèt ak demann rale nan Travis CI, Buddy ak AppVeyor lè l sèvi avèk PVS-Studio
Koulye a, ann enstale PVS-Studio ak sèvis piblik ki nesesè yo:

Analiz de komèt ak demann rale nan Travis CI, Buddy ak AppVeyor lè l sèvi avèk PVS-Studio
Ann ajoute liy sa yo nan editè a:

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

Koulye a, ann ale nan tab la Kouri (premye icon) epi ajoute kòd sa a nan jaden editè ki koresponn lan:

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

Si ou li seksyon an sou Travs-CI, Lè sa a, kòd sa a deja abitye pou ou, sepandan, kounye a gen yon nouvo etap:

Analiz de komèt ak demann rale nan Travis CI, Buddy ak AppVeyor lè l sèvi avèk PVS-Studio
Reyalite a se ke kounye a nou analize pa rezilta a nan fizyon an, men TÈT la nan branch ki soti nan ki demann lan te fè:

Analiz de komèt ak demann rale nan Travis CI, Buddy ak AppVeyor lè l sèvi avèk PVS-Studio
Se konsa, nou nan yon komite kondisyonèl B3 epi nou bezwen jwenn diferans lan 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

Pou detèmine A3 Ann sèvi ak API GitHub:

https://api.github.com/repos/${USERNAME}/${REPO}/pulls/${PULL_REQUEST_ID}

Nou itilize varyab sa yo ke Buddy bay:

  • $BUDDY_EXECUTION_PULL_REQEUST_NO — rale nimewo demann;
  • $BUDDY_REPO_SLUG — yon konbinezon non itilizatè ak depo (pa egzanp max/tès).

Koulye a, ann sove chanjman yo lè l sèvi avèk bouton ki anba a epi pèmèt analiz demann rale a:

Analiz de komèt ak demann rale nan Travis CI, Buddy ak AppVeyor lè l sèvi avèk PVS-Studio
Kontrèman ak Travis CI, nou pa bezwen presize .pvs-studio pou kachèt, depi Buddy otomatikman kach tout dosye pou lansman ki vin apre yo. Se poutèt sa, dènye bagay ki rete a se sove login ak modpas pou PVS-Studio nan Buddy. Apre yo fin sove chanjman yo, nou pral tounen nan Pipeline. Nou bezwen ale nan mete kanpe varyab epi ajoute yon login ak kle pou PVS-Studio:

Analiz de komèt ak demann rale nan Travis CI, Buddy ak AppVeyor lè l sèvi avèk PVS-Studio
Apre sa, aparans nan yon nouvo demann rale oswa komèt pral deklanche revizyon an. Si yon komèt gen erè, Buddy pral endike sa sou paj demann pou rale a.

AppVeyor

Mete kanpe AppVeyor se menm jan ak Buddy, paske tout bagay k ap pase nan koòdone entènèt la epi pa gen okenn bezwen ajoute yon dosye *.yml nan depo pwojè a.

Ann ale nan tab la Anviwònman nan BECA pwojè a:

Analiz de komèt ak demann rale nan Travis CI, Buddy ak AppVeyor lè l sèvi avèk PVS-Studio
Ann desann paj sa a epi pèmèt ekonomize kachèt pou kolekte demann rale:

Analiz de komèt ak demann rale nan Travis CI, Buddy ak AppVeyor lè l sèvi avèk PVS-Studio
Koulye a, ann ale nan tab Anviwònman an, kote nou presize imaj la pou asanble ak varyab anviwònman ki nesesè yo:

Analiz de komèt ak demann rale nan Travis CI, Buddy ak AppVeyor lè l sèvi avèk PVS-Studio
Si ou te li seksyon anvan yo, ou trè abitye ak de varyab sa yo - PVS_KEY и PVS_USERNAME. Si ou pa, kite m fè w sonje ke yo nesesè pou verifye lisans analizeur PVS-Studio la. Nou pral wè yo ankò nan scripts Bash nan tan kap vini an.

Nan menm paj anba a nou endike katab la pou kachèt:

Analiz de komèt ak demann rale nan Travis CI, Buddy ak AppVeyor lè l sèvi avèk PVS-Studio
Si nou pa fè sa, nou pral analize pwojè a tout antye olye de yon pè nan dosye, men nou pral jwenn pwodiksyon an nan dosye yo espesifye. Se poutèt sa, li enpòtan pou antre kòrèk non anyè.

Kounye a li lè pou script la teste. Louvri tab Tès la epi chwazi Script:

Analiz de komèt ak demann rale nan Travis CI, Buddy ak AppVeyor lè l sèvi avèk PVS-Studio
Ou bezwen kole kòd sa a nan fòm sa a:

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

Ann peye atansyon sou pati sa a nan kòd la:

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

Plasman an olye espesifik nan valè a nan lòd la pwd nan yon varyab ki ta dwe estoke valè default sa a sanble etranj nan premye gade, sepandan, mwen pral eksplike tout bagay kounye a.

Pandan m te mete analizè a nan AppVeyor, mwen te rankontre yon konpòtman trè etranj nan analizè a. Sou yon bò, tout bagay te travay kòrèkteman, men analiz la pa t kòmanse. Mwen te pase anpil tan remake ke nou nan /home/appveyor/projects/testcalc/ anyè, epi analizè a asire w ke nou nan /opt/appveyor/build-agent/. Lè sa a, mwen reyalize ke $PWD varyab la te bay manti yon ti kras. Pou rezon sa a, mwen manyèlman mete ajou valè li yo anvan yo kòmanse analiz la.

Lè sa a, tout bagay se tankou anvan:

Analiz de komèt ak demann rale nan Travis CI, Buddy ak AppVeyor lè l sèvi avèk PVS-Studio
Koulye a, konsidere fragman sa a:

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"`

Nan li nou jwenn diferans ki genyen ant branch yo sou ki demann lan te deklare. Pou fè sa nou bezwen varyab anviwònman sa yo:

  • $APPVEYOR_PULL_REQUEST_NUMBER — rale nimewo demann;
  • $APPVEYOR_REPO_NAME - non itilizatè ak depo pwojè.

Konklizyon

Natirèlman, nou pa te konsidere tout sèvis posib entegrasyon kontinyèl yo, sepandan, yo tout gen spesifik fonksyònman trè menm jan youn ak lòt. Ak eksepsyon nan kachèt, chak sèvis fè pwòp "bisiklèt", kidonk tout bagay toujou diferan.

Yon kote, tankou nan Travis-CI, yon koup nan liy nan kòd ak kachèt travay parfètman; yon kote, tankou nan AppVeyor, ou jis bezwen presize katab la nan anviwònman yo; men yon kote ou bezwen kreye kle inik epi eseye konvenk sistèm nan ba ou opòtinite pou ranplase fragman nan kachèt. Se poutèt sa, si ou vle mete kanpe analiz de demann rale sou yon sèvis entegrasyon kontinyèl ki pa te diskite pi wo a, Lè sa a, premye asire w ke ou pa pral gen pwoblèm ak kachèt.

Mèsi pou atansyon ou. Si yon bagay pa mache, ou lib pou ekri nou nan sipò. Nou pral konseye ak ede.

Analiz de komèt ak demann rale nan Travis CI, Buddy ak AppVeyor lè l sèvi avèk PVS-Studio

Si ou vle pataje atik sa a ak yon odyans ki pale angle, tanpri itilize lyen tradiksyon an: Maxim Zvyagintsev. Analiz de komèt ak demann rale nan Travis CI, Buddy ak AppVeyor lè l sèvi avèk PVS-Studio.

Sous: www.habr.com

Add nouvo kòmantè