Анализа на обврски и барања за повлекување во Travis CI, Buddy и AppVeyor користејќи PVS-Studio

Анализа на обврски и барања за повлекување во Travis CI, Buddy и AppVeyor користејќи PVS-Studio
Во анализаторот PVS-Studio за јазиците C и C++ на Linux и macOS, почнувајќи од верзијата 7.04, се појави опција за тестирање за проверка на списокот со наведени датотеки. Користејќи го новиот режим, можете да го конфигурирате анализаторот да ги проверува обврските и да ги повлече барањата. Оваа статија ќе ви каже како да поставите проверка на списокот со променети датотеки на проектот GitHub во такви популарни системи CI (континуирана интеграција) како Travis CI, Buddy и AppVeyor.

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

ПВС-Студио е алатка за идентификување на грешки и потенцијални пропусти во изворниот код на програмите напишани во C, C++, C# и Java. Работи на 64-битни системи на Windows, Linux и macOS.

Во верзијата PVS-Studio 7.04 за Linux и macOS, се појави режим за проверка на списокот со изворни датотеки. Ова работи за проекти чиј систем за градење ви овозможува да генерирате датотека compile_commands.json. Потребно е анализаторот да извлече информации за компилацијата на наведените датотеки. Ако вашиот систем за изградба не поддржува генерирање на датотеката compile_commands.json, може да се обидете да генерирате таква датотека користејќи ја алатката Имајте.

Исто така, режимот за проверка на списокот со датотеки може да се користи заедно со дневникот за трага на траги на стартувањата на компајлерот (pvs-studio-analyzer trace). За да го направите ова, ќе треба прво да извршите целосна изградба на проектот и да го следите, така што анализаторот ќе собере целосни информации за параметрите за компилација на сите датотеки што се проверуваат.

Сепак, оваа опција има значителен недостаток - или ќе треба да извршите целосна изградба на трага на целиот проект секој пат кога ќе го извршите, што само по себе е во спротивност со идејата за брза проверка на извршување. Или, ако го кеширате самиот резултат на трага, последователните работи на анализаторот може да бидат нецелосни ако структурата на зависност на изворните датотеки се промени по трагата (на пример, нов #include се додава на една од изворните датотеки).

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

Списокот на изворни датотеки за анализа се зачувува во текстуална датотека и се пренесува до анализаторот користејќи го параметарот -S:

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

Оваа датотека одредува релативни или апсолутни патеки до датотеките и секоја нова датотека мора да биде на нова линија. Прифатливо е да се наведат не само имиња на датотеки за анализа, туку и различен текст. Анализаторот ќе види дека ова не е датотека и ќе ја игнорира линијата. Ова може да биде корисно за коментирање ако датотеките се наведени рачно. Сепак, честопати списокот на датотеки ќе се генерира за време на анализата во CI, на пример, тоа може да се датотеки од барање за задолжување или повлекување.

Сега, користејќи го овој режим, можете брзо да го проверите новиот код пред да влезе во главната развојна гранка. За да се осигура дека системот за скенирање реагира на предупредувањата на анализаторот, алатката лог-конвертор додадено знаме --покажи-предупредувања:

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

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

Забелешка. Кога првпат ќе започнете да анализирате список на датотеки, целиот проект ќе биде анализиран, бидејќи анализаторот треба да генерира датотека со зависности на изворните датотеки на проектот на датотеките за заглавие. Ова е карактеристика за анализа на датотеките C и C++. Во иднина, датотеката за зависност може да се кешира и таа автоматски ќе се ажурира од страна на анализаторот. Предноста на проверката на обврзниците при користење на режимот за проверка на списокот на датотеки во однос на користењето на режимот за постепена анализа е тоа што треба само да ја кеширате таа датотека, а не и објектните датотеки.

Општи принципи на анализа на барање за повлекување

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

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

Анализа на обврски и барања за повлекување во Travis CI, Buddy и AppVeyor користејќи PVS-Studio

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

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

Се разбира, би било можно да се провери целиот резултат од нивното спојување, но тоа би одземало премногу време и неоправдано, бидејќи само неколку датотеки се сменети. Затоа, поефикасно е да се анализираат само променетите.

За да го направите ова, ја добиваме разликата помеѓу гранките, кои се наоѓаат во HEAD на гранката од која сакаме да се споиме во господар:

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

$MERGE_BASE ќе го разгледаме подетално подоцна. Факт е дека не секоја услуга CI ги обезбедува потребните информации за базата на податоци за спојување, така што секој пат треба да смислите нови начини за да ги добиете овие податоци. Ова ќе биде детално опишано подолу во секоја од опишаните веб-услуги.

Значи, ја добивме разликата помеѓу гранките, поточно, списокот со имиња на датотеки што беа променети. Сега треба да ја дадеме датотеката .pvs-pr.листа (го пренасочивме излезот погоре кон него) до анализаторот:

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

По анализата, треба да ја конвертираме датотеката за евиденција (PVS-Studio.log) во лесно читлив формат:

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

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

Само сега треба не само да прикажуваме грешки, туку и да ја информираме нашата услуга за склопување и тестирање за присуството на проблеми. За таа цел, на конверторот беше додадено знаме -W (--покажи-предупредувања). Ако има барем едно предупредување од анализаторот, шифрата за враќање на услужната програма лог-конвертор ќе се смени во 2, што пак ќе ја информира CI услугата за присуството на потенцијални грешки во датотеките со барање за повлекување.

Тревис ЦИ

Конфигурацијата е направена како датотека .travis.yml. За погодност, ве советувам да ставите сè во посебна баш скрипта со функции што ќе бидат повикани од датотеката .travis.yml (bash script_name.sh функција_име).

Ќе го додадеме потребниот код во скриптата на баш, на овој начин ќе добиеме поголема функционалност. Во делот инсталира да го напишеме следново:

install:
  - bash .travis.sh travis_install

Ако сте имале инструкции, можете да ги пренесете во сценариото, отстранувајќи ги цртичките.

Ајде да ја отвориме датотеката .тревис.ш и додадете го дотерувањето на анализаторот на функцијата 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
}

Овој код треба да се изврши по изградбата на проектот, на пример, ако сте имале изградба на CMake:

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
}

Веројатно веќе сте ги забележале овие променливи на околината $TRAVIS_PULL_REQUEST и $TRAVIS_BRANCH. Тревис ЦИ ги изјавува независно:

  • $TRAVIS_PULL_REQUEST го зачувува бројот на барање за повлекување или лажни, ако ова е редовна гранка;
  • $TRAVIS_REPO_SLUG го складира името на складиштето на проектот.

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

Анализа на обврски и барања за повлекување во Travis CI, Buddy и AppVeyor користејќи PVS-Studio
Тревис CI одговара на шифрите за враќање, така што присуството на предупредувања ќе и каже на услугата да го означи извршувањето како да содржи грешки.

Сега да ја разгледаме подетално оваа линија на код:

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

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

Анализа на обврски и барања за повлекување во Travis CI, Buddy и AppVeyor користејќи PVS-Studio
Затоа анализираме A4и не Б3->А3. Поради оваа карактеристика, треба да ја пресметаме разликата со A3, што е токму врвот на гранката од потекло.

Остана уште еден важен детал - кеширање на зависностите на датотеките за заглавија на компајлирани преведувачки единици (*.c, *.cc, *.cpp, итн.). Анализаторот ги пресметува овие зависности кога првпат ќе се вклучи во режимот на проверка на список со датотеки и потоа ги зачувува во директориумот .PVS-Studio. Travis CI ви овозможува кеширање на папки, така што ќе ги зачуваме податоците од директориумот .ПВС-Студио/:

cache:
  directories:
    - .PVS-Studio/

Овој код треба да се додаде во датотеката .travis.yml. Овој директориум складира различни податоци собрани по анализата, што значително ќе ги забрза последователните циклуси на анализа на списокот со датотеки или постепена анализа. Ако ова не е направено, тогаш анализаторот всушност ќе ги анализира сите датотеки секој пат.

Бади

Како Тревис ЦИ, Бади обезбедува можност за автоматско градење и тестирање на проекти складирани на GitHub. За разлика од Travis CI, тој е конфигуриран во веб-интерфејсот (достапна е поддршка за bash), така што нема потреба да се складираат датотеките за конфигурација во проектот.

Пред сè, треба да додадеме ново дејство на склопувачката линија:

Анализа на обврски и барања за повлекување во Travis CI, Buddy и AppVeyor користејќи PVS-Studio
Да го посочиме компајлерот што се користел за изградба на проектот. Забележете го докерскиот контејнер што е инсталиран во оваа акција. На пример, постои посебен контејнер за GCC:

Анализа на обврски и барања за повлекување во Travis CI, Buddy и AppVeyor користејќи PVS-Studio
Сега ајде да инсталираме PVS-Studio и потребните комунални услуги:

Анализа на обврски и барања за повлекување во Travis CI, Buddy и AppVeyor користејќи 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

Сега да одиме во табулаторот Run (првата икона) и да го додадеме следниов код во соодветното поле за уредувач:

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

Ако го прочитате делот за Travs-CI, тогаш овој код веќе ви е познат, сепак, сега има нова фаза:

Анализа на обврски и барања за повлекување во Travis CI, Buddy и AppVeyor користејќи PVS-Studio
Факт е дека сега не го анализираме резултатот од спојувањето, туку ГЛАВАТА на гранката од која е направено барањето за повлекување:

Анализа на обврски и барања за повлекување во Travis CI, Buddy и AppVeyor користејќи PVS-Studio
Значи ние сме во условно обврзување 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 Ајде да го користиме GitHub API:

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

Ги користевме следните променливи што ги дава Бади:

  • $BUDDY_EXECUTION_PULL_REQEUST_NO — број на барање за повлекување;
  • $BUDDY_REPO_SLUG — комбинација од корисничко име и складиште (на пример макс/тест).

Сега да ги зачуваме промените користејќи го копчето подолу и да овозможиме анализа на барањето за повлекување:

Анализа на обврски и барања за повлекување во Travis CI, Buddy и AppVeyor користејќи PVS-Studio
За разлика од Travis CI, не треба да прецизираме .pvs-studio за кеширање, бидејќи Бади автоматски ги кешира сите датотеки за следните лансирања. Затоа, последното нешто што останува е да ги зачувате најавувањето и лозинката за PVS-Studio во Бади. Откако ќе ги зачуваме промените, ќе бидеме вратени на Pipeline. Треба да продолжиме со поставување на променливи и додавање најава и клуч за PVS-Studio:

Анализа на обврски и барања за повлекување во Travis CI, Buddy и AppVeyor користејќи PVS-Studio
По ова, појавата на ново барање за повлекување или извршување ќе го активира прегледот. Ако извршувањето содржи грешки, Бади ќе го покаже ова на страницата со барање за повлекување.

AppVeyor

Поставувањето на AppVeyor е слично на Бади, бидејќи сè се случува во веб-интерфејсот и нема потреба да се додава датотека *.yml во складиштето на проектот.

Ајде да одиме во јазичето Поставки во прегледот на проектот:

Анализа на обврски и барања за повлекување во Travis CI, Buddy и AppVeyor користејќи PVS-Studio
Ајде да се движиме надолу оваа страница и да овозможиме зачувување на кешот за собирање барања за повлекување:

Анализа на обврски и барања за повлекување во Travis CI, Buddy и AppVeyor користејќи PVS-Studio
Сега да одиме во табулаторот Environment, каде што ја одредуваме сликата за склопување и потребните променливи на животната средина:

Анализа на обврски и барања за повлекување во Travis CI, Buddy и AppVeyor користејќи PVS-Studio
Ако сте ги прочитале претходните делови, многу сте запознаени со овие две променливи − PVS_KEY и PVS_USERNAME. Ако не, дозволете ми да ве потсетам дека тие се неопходни за да се потврди лиценцата на анализаторот PVS-Studio. Ќе ги видиме повторно во скриптите на Bash во иднина.

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

Анализа на обврски и барања за повлекување во Travis CI, Buddy и AppVeyor користејќи PVS-Studio
Ако не го направиме ова, ќе го анализираме целиот проект наместо неколку датотеки, но ќе го добиеме излезот од наведените датотеки. Затоа, важно е да го внесете точното име на директориумот.

Сега е време за тестирање на сценариото. Отворете го јазичето Тестови и изберете Скрипта:

Анализа на обврски и барања за повлекување во Travis CI, Buddy и AppVeyor користејќи PVS-Studio
Треба да го залепите следниов код во оваа форма:

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

Прилично специфичното доделување на вредноста на командата pwd на променливата што треба да ја зачува оваа стандардна вредност изгледа чудно на прв поглед, сепак, сега ќе објаснам сè.

При поставувањето на анализаторот во AppVeyor, наидов на крајно чудно однесување на анализаторот. Од една страна, сè функционираше правилно, но анализата не започна. Поминав многу време забележувајќи дека сме во директориумот /home/appveyor/projects/testcalc/, а анализаторот е сигурен дека сме во /opt/appveyor/build-agent/. Тогаш сфатив дека променливата $PWD малку лажеше. Поради оваа причина, рачно ја ажурирав неговата вредност пред да ја започнам анализата.

И тогаш сè е како порано:

Анализа на обврски и барања за повлекување во Travis CI, Buddy и AppVeyor користејќи PVS-Studio
Сега разгледајте го следниот фрагмент:

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

Во него ја добиваме разликата помеѓу гранките над кои се декларира барањето за повлекување. За да го направите ова, потребни ни се следните променливи на околината:

  • $APPVEYOR_PULL_REQUEST_NUMBER — број на барање за повлекување;
  • $APPVEYOR_REPO_NAME - корисничко име и складиште на проектот.

Заклучок

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

Некаде, како во Travis-CI, неколку линии код и кеширање функционираат беспрекорно; некаде, како во AppVeyor, само треба да ја наведете папката во поставките; но некаде треба да креирате уникатни клучеви и да се обидете да го убедите системот да ви даде можност да го презапишете кешираниот фрагмент. Затоа, ако сакате да поставите анализа на барања за повлекување на услуга за континуирана интеграција што не беше дискутирана погоре, тогаш прво уверете се дека нема да имате проблеми со кеширањето.

Ви благодариме за вниманието. Ако нешто не успее, слободно пишете ни на поддршка. Ќе советуваме и помагаме.

Анализа на обврски и барања за повлекување во Travis CI, Buddy и AppVeyor користејќи PVS-Studio

Ако сакате да ја споделите оваа статија со публика што зборува англиски, ве молиме користете ја врската за превод: Максим Звјагинцев. Анализа на обврски и барања за повлекување во Travis CI, Buddy и AppVeyor користејќи PVS-Studio.

Извор: www.habr.com

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