Анализа урезивања и повлачења захтева у Травис ЦИ, Будди и АппВеиор користећи ПВС-Студио

Анализа урезивања и повлачења захтева у Травис ЦИ, Будди и АппВеиор користећи ПВС-Студио
У анализатору ПВС-Студио за језике Ц и Ц++ на Линук-у и мацОС-у, почевши од верзије 7.04, појавила се тестна опција за проверу листе наведених датотека. Користећи нови режим, можете да конфигуришете анализатор да проверава урезивање и повлачење захтева. Овај чланак ће вам рећи како да подесите проверу листе промењених датотека ГитХуб пројекта у тако популарним ЦИ (континуирана интеграција) системима као што су Травис ЦИ, Будди и АппВеиор.

Режим провере листе датотека

ПВС-Студио је алат за идентификацију грешака и потенцијалних рањивости у изворном коду програма написаних у Ц, Ц++, Ц# и Јави. Ради на 64-битним системима на Виндовс, Линук и мацОС.

У верзији ПВС-Студио 7.04 за Линук и мацОС појавио се режим за проверу листе изворних датотека. Ово ради за пројекте чији систем изградње вам омогућава да генеришете датотеку цомпиле_цоммандс.јсон. Потребно је да анализатор издвоји информације о компилацији наведених датотека. Ако ваш систем изградње не подржава генерисање датотеке цомпиле_цоммандс.јсон, можете покушати да генеришете такву датотеку помоћу услужног програма Медвед.

Такође, режим провере листе датотека може се користити заједно са евиденцијом праћења покретања компајлера (пвс-студио-анализер траце). Да бисте то урадили, прво ћете морати да извршите комплетну изградњу пројекта и да га пратите тако да анализатор прикупи потпуне информације о параметрима компилације свих датотека које се проверавају.

Међутим, ова опција има значајан недостатак - или ћете морати да извршите потпуни траг изградње целог пројекта сваки пут када га покренете, што је само по себи у супротности са идејом брзе провере урезивања. Или, ако кеширате сам резултат праћења, наредна покретања анализатора могу бити непотпуна ако се структура зависности изворних датотека промени након праћења (на пример, нови #инцлуде се додаје једној од изворних датотека).

Због тога не препоручујемо коришћење режима провере листе датотека са евиденцијом праћења за проверу урезивања или захтева за повлачењем. У случају да можете да направите инкременталну изградњу када проверавате урезивање, размислите о коришћењу режима инкрементална анализа.

Листа изворних датотека за анализу се чува у текстуалној датотеци и прослеђује анализатору помоћу параметра -S:

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

Ова датотека наводи релативне или апсолутне путање до датотека, а свака нова датотека мора бити на новом реду. Прихватљиво је навести не само називе датотека за анализу, већ и различите текстове. Анализатор ће видети да ово није датотека и игнорисаће линију. Ово може бити корисно за коментарисање ако су датотеке специфициране ручно. Међутим, често ће се током анализе у ЦИ генерисати листа датотека, на пример, то могу бити датотеке из захтева за урезивање или повлачење.

Сада, користећи овај режим, можете брзо да проверите нови код пре него што уђе у главну развојну грану. Да би се осигурало да систем за скенирање реагује на упозорења анализатора, услужни програм плог-конвертер додата застава --индицате-варнингс:

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

Са овом заставицом, претварач ће вратити код који није нула ако постоје упозорења у извештају анализатора. Користећи повратни код, можете блокирати закачицу пре урезивања, урезивање или захтев за повлачење, а генерисани извештај анализатора може да се прикаже, дели или пошаље е-поштом.

Белешка. Када први пут почнете да анализирате листу датотека, цео пројекат ће бити анализиран, јер анализатор треба да генерише датотеку зависности изворних датотека пројекта од датотека заглавља. Ово је карактеристика анализе Ц и Ц++ датотека. У будућности, датотека зависности може бити кеширана и анализатор ће је аутоматски ажурирати. Предност провере урезивања када се користи режим провере листе датотека у односу на режим инкременталне анализе је у томе што треба да кеширате само ту датотеку, а не објектне датотеке.

Општи принципи анализе захтева за повлачењем

Анализа целог пројекта одузима доста времена, тако да има смисла проверити само одређени део. Проблем је у томе што морате да одвојите нове датотеке од осталих датотека пројекта.

Погледајмо пример стабла урезивања са две гране:

Анализа урезивања и повлачења захтева у Травис ЦИ, Будди и АппВеиор користећи ПВС-Студио

Замислимо ту обавезу A1 садржи прилично велику количину кода који је већ тестиран. Мало раније смо направили грану од комита A1 и променио неке датотеке.

Ви сте, наравно, то приметили после A1 догодила су се још два обавезивања, али су то била и спајања других филијала, јер се не обавезујемо мајстор. А сада је дошло време када хотфик спреман. Због тога се појавио пулл захтев за спајање B3 и A3.

Наравно, било би могуће проверити цео резултат њиховог спајања, али то би било превише дуготрајно и неоправдано, пошто је промењено само неколико фајлова. Зато је ефикасније анализирати само оне измењене.

Да бисмо то урадили, добијамо разлику између грана, која се налази у ГЛАВИ гране из које желимо да се спојимо у мастер:

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

$МЕРГЕ_БАСЕ касније ћемо га детаљно размотрити. Чињеница је да сваки ЦИ сервис не пружа потребне информације о бази података за спајање, тако да сваки пут морате смислити нове начине за добијање ових података. Ово ће бити детаљно описано у наставку у свакој од описаних веб услуга.

Дакле, добили смо разлику између грана, тачније, листу имена датотека које су промењене. Сада треба да дамо фајл .пвс-пр.лист (преусмерили смо излаз изнад на њега) у анализатор:

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

Након анализе, треба да конвертујемо датотеку евиденције (ПВС-Студио.лог) у формат који је лак за читање:

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

Ова команда ће навести грешке у стдерр (стандардни излаз поруке о грешци).

Тек сада морамо не само да прикажемо грешке, већ и обавестимо нашу службу за монтажу и тестирање о присуству проблема. У ту сврху конвертору је додата заставица -W (--индицате-варнингс). Ако постоји бар једно упозорење анализатора, повратни код услужног програма плог-конвертер ће се променити на 2, што ће заузврат обавестити ЦИ услугу о присуству потенцијалних грешака у датотекама захтева за повлачење.

Травис ЦИ

Конфигурација је направљена као датотека .травис.имл. Ради практичности, саветујем вам да све ставите у засебну басх скрипту са функцијама које ће бити позване из датотеке .травис.имл (басх име_скрипте.сх име_функције).

Додаћемо потребан код у скрипту на треснути, на овај начин ћемо добити више функционалности. У одељку инсталирати хајде да напишемо следеће:

install:
  - bash .travis.sh 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 
}

Сада додајмо у одељак скрипта покрените анализу:

script:
  - bash .travis.sh travis_script

И у басх скрипти:

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
}

Овај код треба да се покрене након изградње пројекта, на пример, ако сте имали изградњу на ЦМаке:

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

Испоставиће се овако:

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
}

Вероватно сте већ приметили ове променљиве окружења $ТРАВИС_ПУЛЛ_РЕКУЕСТ и $ТРАВИС_БРАНЦХ. Травис ЦИ их независно проглашава:

  • $ТРАВИС_ПУЛЛ_РЕКУЕСТ чува број захтева за повлачење или лажан, ако је ово редовна грана;
  • $ТРАВИС_РЕПО_СЛУГ чува назив репозиторијума пројекта.

Алгоритам за ову функцију:

Анализа урезивања и повлачења захтева у Травис ЦИ, Будди и АппВеиор користећи ПВС-Студио
Травис ЦИ одговара на повратне кодове, тако да ће присуство упозорења рећи сервису да означи урезивање као да садржи грешке.

Сада погледајмо ближе ову линију кода:

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

Чињеница је да Травис ЦИ аутоматски спаја гране док анализира захтев за повлачење:

Анализа урезивања и повлачења захтева у Травис ЦИ, Будди и АппВеиор користећи ПВС-Студио
Стога анализирамо A4И не Б3->А3. Због ове карактеристике морамо израчунати разлику са АКСНУМКС, што је управо врх огранка из порекло.

Остао је још један важан детаљ - кеширање зависности датотека заглавља од компајлираних преводилачких јединица (*.ц, *.цц, *.цпп, итд.). Анализатор израчунава ове зависности када се први пут покрене у режиму провере листе датотека, а затим их чува у директоријуму .ПВС-Студио. Травис ЦИ вам омогућава да кеширате фасцикле, тако да ћемо сачувати податке директоријума .ПВС-Студио/:

cache:
  directories:
    - .PVS-Studio/

Овај код треба додати у датотеку .травис.имл. У овом директоријуму се чувају различити подаци прикупљени након анализе, што ће значајно убрзати наредна извођења анализе листе датотека или инкременталне анализе. Ако се то не уради, онда ће анализатор заправо сваки пут анализирати све датотеке.

Пријатељ

Као Травис ЦИ, Пријатељ пружа могућност аутоматског прављења и тестирања пројеката ускладиштених на ГитХуб-у. За разлику од Травис ЦИ, он је конфигурисан у веб интерфејсу (доступна је подршка за басх), тако да нема потребе да се конфигурационе датотеке чувају у пројекту.

Пре свега, морамо да додамо нову акцију на монтажну линију:

Анализа урезивања и повлачења захтева у Травис ЦИ, Будди и АппВеиор користећи ПВС-Студио
Хајде да означимо компајлер који је коришћен за изградњу пројекта. Обратите пажњу на доцкер контејнер који је инсталиран у овој радњи. На пример, постоји посебан контејнер за ГЦЦ:

Анализа урезивања и повлачења захтева у Травис ЦИ, Будди и АппВеиор користећи ПВС-Студио
Сада инсталирајмо ПВС-Студио и потребне услужне програме:

Анализа урезивања и повлачења захтева у Травис ЦИ, Будди и АппВеиор користећи ПВС-Студио
Хајде да додамо следеће редове у едитор:

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

Сада идемо на картицу Покрени (прва икона) и додамо следећи код у одговарајуће поље уређивача:

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

Ако прочитате одељак о Травс-ЦИ, онда вам је овај код већ познат, међутим, сада постоји нова фаза:

Анализа урезивања и повлачења захтева у Травис ЦИ, Будди и АппВеиор користећи ПВС-Студио
Чињеница је да сада не анализирамо резултат стапања, већ ГЛАВУ гране из које је направљен захтев за повлачење:

Анализа урезивања и повлачења захтева у Травис ЦИ, Будди и АппВеиор користећи ПВС-Студио
Дакле, ми смо у условној обавези B3 и треба да добијемо разлику од 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

Да би одредили A3 Хајде да користимо ГитХуб АПИ:

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

Користили смо следеће променљиве које Бади пружа:

  • $БУДДИ_ЕКСЕЦУТИОН_ПУЛЛ_РЕКЕУСТ_НО — број захтева за повлачење;
  • $БУДДИ_РЕПО_СЛУГ — комбинација корисничког имена и спремишта (на пример мак/тест).

Хајде сада да сачувамо промене помоћу дугмета испод и омогућимо анализу захтева за повлачење:

Анализа урезивања и повлачења захтева у Травис ЦИ, Будди и АппВеиор користећи ПВС-Студио
За разлику од Травис ЦИ, не морамо да прецизирамо .пвс-студио за кеширање, пошто Будди аутоматски кешује све датотеке за наредна покретања. Дакле, последња ствар која је преостала је да сачувате корисничко име и лозинку за ПВС-Студио у Будди. Након што сачувамо промене, бићемо враћени на Пипелине. Морамо да пређемо на подешавање променљивих и додавање корисничког имена и кључа за ПВС-Студио:

Анализа урезивања и повлачења захтева у Травис ЦИ, Будди и АппВеиор користећи ПВС-Студио
Након овога, појављивање новог захтева за повлачење или урезивања ће покренути преглед. Ако урезивање садржи грешке, Будди ће то назначити на страници са захтевом за повлачење.

АппВеиор

Подешавање АппВеиор-а је слично Будди-ју, пошто се све дешава у веб интерфејсу и нема потребе за додавањем *.имл датотеке у репозиторијум пројекта.

Идемо на картицу Подешавања у прегледу пројекта:

Анализа урезивања и повлачења захтева у Травис ЦИ, Будди и АппВеиор користећи ПВС-Студио
Хајде да померимо ову страницу надоле и омогућимо чување кеша за прикупљање захтева за повлачење:

Анализа урезивања и повлачења захтева у Травис ЦИ, Будди и АппВеиор користећи ПВС-Студио
Сада идемо на картицу Околина, где наводимо слику за склапање и потребне променљиве окружења:

Анализа урезивања и повлачења захтева у Травис ЦИ, Будди и АппВеиор користећи ПВС-Студио
Ако сте прочитали претходне одељке, веома сте упознати са ове две варијабле − ПВС_КЕИ и ПВС_УСЕРНАМЕ. Ако нису, да вас подсетим да су они неопходни за верификацију лиценце за ПВС-Студио анализатор. Видећемо их поново у Басх скриптама у будућности.

На истој страници испод означавамо фасциклу за кеширање:

Анализа урезивања и повлачења захтева у Травис ЦИ, Будди и АппВеиор користећи ПВС-Студио
Ако то не урадимо, анализираћемо цео пројекат уместо неколико датотека, али ћемо добити излаз из наведених датотека. Због тога је важно да унесете тачан назив директоријума.

Сада је време да се скрипта тестира. Отворите картицу Тестови и изаберите Скрипта:

Анализа урезивања и повлачења захтева у Травис ЦИ, Будди и АппВеиор користећи ПВС-Студио
Морате да налепите следећи код у овај образац:

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

Обратимо пажњу на следећи део кода:

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

Прилично специфично додељивање вредности команде пвд променљивој која треба да чува ову подразумевану вредност на први поглед делује чудно, међутим, сада ћу све објаснити.

Приликом подешавања анализатора у АппВеиор-у, наишао сам на изузетно чудно понашање анализатора. С једне стране, све је функционисало како треба, али анализа није почела. Провео сам доста времена приметивши да се налазимо у директоријуму /хоме/аппвеиор/пројецтс/тестцалц/, а анализатор је сигуран да се налазимо у /опт/аппвеиор/буилд-агент/. Онда сам схватио да променљива $ПВД мало лаже. Из тог разлога сам ручно ажурирао његову вредност пре почетка анализе.

А онда је све као пре:

Анализа урезивања и повлачења захтева у Травис ЦИ, Будди и АппВеиор користећи ПВС-Студио
Сада размотрите следећи фрагмент:

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

У њему добијамо разлику између грана преко којих је декларисан захтев за повлачење. Да бисмо то урадили, потребне су нам следеће променљиве окружења:

  • $АППВЕИОР_ПУЛЛ_РЕКУЕСТ_НУМБЕР — број захтева за повлачење;
  • $АППВЕИОР_РЕПО_НАМЕ - корисничко име и спремиште пројекта.

Закључак

Наравно, нисмо узели у обзир све могуће услуге континуиране интеграције, али све оне имају изузетно сличне оперативне специфичности једна другој. Са изузетком кеширања, сваки сервис прави свој „бицикл“, тако да је све увек другачије.

Негде, као у Травис-ЦИ, пар линија кода и кеширање раде беспрекорно; негде, као у АппВеиор-у, само треба да наведете фасциклу у подешавањима; али негде треба да креирате јединствене кључеве и покушате да убедите систем да вам пружи прилику да препишете кеширани фрагмент. Стога, ако желите да подесите анализу захтева за повлачењем на сервису за континуирану интеграцију о којој горе није било речи, прво се уверите да нећете имати проблема са кеширањем.

Хвала на пажњи. Ако нешто не успе, слободно нам пишите на подршка. Ми ћемо саветовати и помоћи.

Анализа урезивања и повлачења захтева у Травис ЦИ, Будди и АппВеиор користећи ПВС-Студио

Ако желите да поделите овај чланак са публиком која говори енглески, користите линк за превод: Максим Звјагинцев. Анализа урезивања и повлачења захтева у Травис ЦИ, Будди и АппВеиор користећи ПВС-Студио.

Извор: ввв.хабр.цом

Додај коментар