Linux ๋ฐ macOS์ C ๋ฐ C++ ์ธ์ด์ฉ PVS-Studio ๋ถ์๊ธฐ ๋ฒ์ 7.04๋ถํฐ ์ง์ ๋ ํ์ผ ๋ชฉ๋ก์ ํ์ธํ๋ ํ
์คํธ ์ต์
์ด ๋ํ๋ฌ์ต๋๋ค. ์ ๋ชจ๋๋ฅผ ์ฌ์ฉํ๋ฉด ์ปค๋ฐ๊ณผ ํ ์์ฒญ์ ํ์ธํ๋๋ก ๋ถ์๊ธฐ๋ฅผ ๊ตฌ์ฑํ ์ ์์ต๋๋ค. ์ด ๊ธฐ์ฌ์์๋ Travis CI, Buddy ๋ฐ AppVeyor์ ๊ฐ์ ๋๋ฆฌ ์ฌ์ฉ๋๋ CI(์ง์์ ํตํฉ) ์์คํ
์์ GitHub ํ๋ก์ ํธ์ ๋ณ๊ฒฝ๋ ํ์ผ ๋ชฉ๋ก ํ์ธ์ ์ค์ ํ๋ ๋ฐฉ๋ฒ์ ์ค๋ช
ํฉ๋๋ค.
ํ์ผ ๋ชฉ๋ก ํ์ธ ๋ชจ๋
Linux ๋ฐ macOS์ฉ PVS-Studio 7.04 ๋ฒ์ ์๋ ์์ค ํ์ผ ๋ชฉ๋ก์ ํ์ธํ๋ ๋ชจ๋๊ฐ ๋ํ๋ฌ์ต๋๋ค. ์ด๋ ๋น๋ ์์คํ
์ ํตํด ํ์ผ์ ์์ฑํ ์ ์๋ ํ๋ก์ ํธ์ ์ ์ฉ๋ฉ๋๋ค.
๋ํ ํ์ผ ๋ชฉ๋ก ํ์ธ ๋ชจ๋๋ ์ปดํ์ผ๋ฌ ์คํ์ strace ์ถ์ ๋ก๊ทธ(pvs-studio-analyzer ์ถ์ )์ ํจ๊ป ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ด๋ ๊ฒ ํ๋ ค๋ฉด ๋จผ์ ํ๋ก์ ํธ์ ์ ์ฒด ๋น๋๋ฅผ ์ํํ๊ณ ์ด๋ฅผ ์ถ์ ํ์ฌ ๋ถ์๊ธฐ๊ฐ ๊ฒ์ฌ ์ค์ธ ๋ชจ๋ ํ์ผ์ ์ปดํ์ผ ๋งค๊ฐ๋ณ์์ ๋ํ ์ ์ฒด ์ ๋ณด๋ฅผ ์์งํ๋๋ก ํด์ผ ํฉ๋๋ค.
๊ทธ๋ฌ๋ ์ด ์ต์ ์๋ ์ฌ๊ฐํ ๋จ์ ์ด ์์ต๋๋ค. ์คํํ ๋๋ง๋ค ์ ์ฒด ํ๋ก์ ํธ์ ์ ์ฒด ๋น๋ ์ถ์ ์ ์ํํด์ผ ํ๋ฉฐ, ์ด๋ ๊ทธ ์์ฒด๋ก ์ปค๋ฐ์ ๋น ๋ฅด๊ฒ ํ์ธํ๋ค๋ ์์ด๋์ด์ ๋ชจ์๋ฉ๋๋ค. ๋๋ ์ถ์ ๊ฒฐ๊ณผ ์์ฒด๋ฅผ ์บ์ํ๋ ๊ฒฝ์ฐ ์ถ์ ํ ์์ค ํ์ผ์ ์ข ์์ฑ ๊ตฌ์กฐ๊ฐ ๋ณ๊ฒฝ๋๋ฉด ๋ถ์๊ธฐ์ ํ์ ์คํ์ด ์๋ฃ๋์ง ์์ ์ ์์ต๋๋ค(์: ์์ค ํ์ผ ์ค ํ๋์ ์๋ก์ด #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 ...
์ด ํ๋๊ทธ๋ฅผ ์ฌ์ฉํ๋ฉด ๋ถ์๊ธฐ ๋ณด๊ณ ์์ ๊ฒฝ๊ณ ๊ฐ ์๋ ๊ฒฝ์ฐ ๋ณํ๊ธฐ๊ฐ XNUMX์ด ์๋ ์ฝ๋๋ฅผ ๋ฐํํฉ๋๋ค. ๋ฐํ ์ฝ๋๋ฅผ ์ฌ์ฉํ๋ฉด ์ฌ์ ์ปค๋ฐ ํํฌ, ์ปค๋ฐ ๋๋ ๋์ด์ค๊ธฐ ์์ฒญ์ ์ฐจ๋จํ ์ ์์ผ๋ฉฐ ์์ฑ๋ ๋ถ์๊ธฐ ๋ณด๊ณ ์๋ฅผ ํ์, ๊ณต์ ํ๊ฑฐ๋ ์ด๋ฉ์ผ๋ก ๋ณด๋ผ ์ ์์ต๋๋ค.
๋ฉ๋ชจ. ์ฒ์ ํ์ผ ๋ชฉ๋ก ๋ถ์์ ์์ํ๋ฉด ์ ์ฒด ํ๋ก์ ํธ๊ฐ ๋ถ์๋ฉ๋๋ค. ๋ถ์๊ธฐ๋ ํค๋ ํ์ผ์ ๋ํ ํ๋ก์ ํธ ์์ค ํ์ผ์ ์ข ์์ฑ ํ์ผ์ ์์ฑํด์ผ ํฉ๋๋ค. C, C++ ํ์ผ์ ๋ถ์ํ๋ ๊ธฐ๋ฅ์ ๋๋ค. ์์ผ๋ก๋ ์ข ์์ฑ ํ์ผ์ ์บ์ํ ์ ์์ผ๋ฉฐ ๋ถ์๊ธฐ์ ์ํด ์๋์ผ๋ก ์ ๋ฐ์ดํธ๋ฉ๋๋ค. ์ฆ๋ถ ๋ถ์ ๋ชจ๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒ๋ณด๋ค ํ์ผ ๋ชฉ๋ก ๊ฒ์ฌ ๋ชจ๋๋ฅผ ์ฌ์ฉํ ๋ ์ปค๋ฐ์ ๊ฒ์ฌํ๋ฉด ๊ฐ์ฒด ํ์ผ์ด ์๋ ํด๋น ํ์ผ๋ง ์บ์ํ๋ฉด ๋๋ค๋ ์ด์ ์ด ์์ต๋๋ค.
ํ ์์ฒญ ๋ถ์์ ์ผ๋ฐ ์์น
์ ์ฒด ํ๋ก์ ํธ๋ฅผ ๋ถ์ํ๋ ค๋ฉด ์๊ฐ์ด ๋ง์ด ๊ฑธ๋ฆฌ๋ฏ๋ก ํน์ ๋ถ๋ถ๋ง ํ์ธํ๋ ๊ฒ์ด ํฉ๋ฆฌ์ ์ ๋๋ค. ๋ฌธ์ ๋ ์ ํ์ผ์ ๋๋จธ์ง ํ๋ก์ ํธ ํ์ผ๊ณผ ๋ถ๋ฆฌํด์ผ ํ๋ค๋ ๊ฒ์ ๋๋ค.
๋ ๊ฐ์ ๋ถ๊ธฐ๊ฐ ์๋ ์ปค๋ฐ ํธ๋ฆฌ์ ์๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
์ปค๋ฐ์ ์์ํด ๋ด ์๋ค A1 ์ด๋ฏธ ํ ์คํธ๋ ์๋นํ ๋ง์ ์์ ์ฝ๋๊ฐ ํฌํจ๋์ด ์์ต๋๋ค. ์กฐ๊ธ ๋ ์ผ์ฐ ์ปค๋ฐ์์ ๋ธ๋์น๋ฅผ ๋ง๋ค์์ต๋๋ค. A1 ์ผ๋ถ ํ์ผ์ ๋ณ๊ฒฝํ์ต๋๋ค.
๋ฌผ๋ก ๋น์ ์ ๊ทธ ํ์ A1 ๋ ๊ฐ์ ์ปค๋ฐ์ด ๋ ๋ฐ์ํ์ง๋ง ์ด๊ฒ๋ ๋ค๋ฅธ ๋ธ๋์น์ ํฉ๋ณ์ด์์ต๋๋ค. ์์ฌ. ๊ทธ๋ฆฌ๊ณ ์ด์ ๋๊ฐ ์์ต๋๋ค. ํซํฝ์ค ์ค๋น๊ฐ ๋. ๊ทธ๋์ ํฉ๋ณ ์์ฒญ์ด ๋ํ๋ฌ์ต๋๋ค B3 ะธ A3.
๋ฌผ๋ก ํฉ๋ณ ๊ฒฐ๊ณผ ์ ์ฒด๋ฅผ ํ์ธํ๋ ๊ฒ๋ ๊ฐ๋ฅํ๊ฒ ์ง๋ง, ๋ณ๊ฒฝ๋ ํ์ผ์ด ๋ช ๊ฐ์ ๋ถ๊ณผํ๊ธฐ ๋๋ฌธ์ ์๊ฐ์ด ๋๋ฌด ๋ง์ด ๊ฑธ๋ฆฌ๊ณ ์ ๋นํ์ง ์์ต๋๋ค. ๋ฐ๋ผ์ ๋ณ๊ฒฝ๋ ๊ฒ๋ง ๋ถ์ํ๋ ๊ฒ์ด ๋ ํจ์จ์ ์ด๋ค.
์ด๋ฅผ ์ํด ๋ง์คํฐ๋ก ๋ณํฉํ๋ ค๋ ๋ธ๋์น์ HEAD์ ์๋ ๋ธ๋์น ๊ฐ์ ์ฐจ์ด์ ์ ์ป์ต๋๋ค.
git diff --name-only HEAD origin/$MERGE_BASE > .pvs-pr.list
$MERGE_BASE ๋์ค์ ์์ธํ ์ดํด๋ณด๊ฒ ์ต๋๋ค. ์ฌ์ค ๋ชจ๋ CI ์๋น์ค๊ฐ ๋ณํฉ์ ํ์ํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ ๊ฒ์ ์๋๋ฏ๋ก ๋งค๋ฒ ์ด ๋ฐ์ดํฐ๋ฅผ ์ป๊ธฐ ์ํ ์๋ก์ด ๋ฐฉ๋ฒ์ ์ฐพ์์ผ ํฉ๋๋ค. ์ด์ ๋ํด์๋ ์๋์์ ์ค๋ช ํ๋ ๊ฐ ์น ์๋น์ค์์ ์์ธํ ์ค๋ช ํฉ๋๋ค.
๊ทธ๋์ ์ฐ๋ฆฌ๋ ๋ธ๋์น ๊ฐ์ ์ฐจ์ด์ , ๋๋ ๋ณ๊ฒฝ๋ ํ์ผ ์ด๋ฆ ๋ชฉ๋ก์ ์ป์์ต๋๋ค. ์ด์ ํ์ผ์ ์ฃผ์ด์ผ ํฉ๋๋ค .pvs-pr.list (์์ ์ถ๋ ฅ์ ์ฌ๊ธฐ๋ก ๋ฆฌ๋๋ ์ ํ์ต๋๋ค) ๋ถ์๊ธฐ๋ก:
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 ์๋น์ค์ ํ ์์ฒญ ํ์ผ์ ์ ์ฌ์ ์ธ ์ค๋ฅ๊ฐ ์์์ ์๋ฆฝ๋๋ค.
ํธ๋๋น์ค CI
๊ตฌ์ฑ์ ํ์ผ๋ก ์ด๋ฃจ์ด์ง๋๋ค. .travis.yml. ํธ์๋ฅผ ์ํด ํ์ผ์์ ํธ์ถ๋ ํจ์๊ฐ ํฌํจ๋ ๋ณ๋์ bash ์คํฌ๋ฆฝํธ์ ๋ชจ๋ ๊ฒ์ ๋ฃ๋ ๊ฒ์ด ์ข์ต๋๋ค. .travis.yml (bash ์คํฌ๋ฆฝํธ_์ด๋ฆ.sh ํจ์_์ด๋ฆ).
์คํฌ๋ฆฝํธ์ ํ์ํ ์ฝ๋๋ฅผ ์ถ๊ฐํ๊ฒ ์ต๋๋ค. ์ธ๊ฒ ๋๋ฆฌ๋ค, ์ด๋ ๊ฒ ํ๋ฉด ๋ ๋ง์ ๊ธฐ๋ฅ์ ์ป์ ์ ์์ต๋๋ค. ์น์ ์์ ์ค์น ๋ค์์ ์์ฑํด ๋ด ์๋ค:
install:
- bash .travis.sh travis_install
์ง์นจ์ด ์๋ ๊ฒฝ์ฐ ํ์ดํ์ ์ ๊ฑฐํ์ฌ ํด๋น ์ง์นจ์ ์คํฌ๋ฆฝํธ๋ก ์ ์กํ ์ ์์ต๋๋ค.
ํ์ผ์ ์ด์ด๋ณด์ .travis.sh ํจ์์ ๋ถ์๊ธฐ ์ค์ ์ ์ถ๊ฐํฉ๋๋ค. ํธ๋๋น์ค_์ค์น():
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
๊ทธ๋ฆฌ๊ณ 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
}
์๋ฅผ ๋ค์ด 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 CI๋ ์ด๋ฅผ ๋ ๋ฆฝ์ ์ผ๋ก ์ ์ธํฉ๋๋ค.
- $TRAVIS_PULL_REQUEST ํ ์์ฒญ ๋ฒํธ๋ฅผ ์ ์ฅํ๊ฑฐ๋ ๊ทธ๋ฆ๋, ์ด๊ฒ์ด ์ผ๋ฐ ์ง์ ์ธ ๊ฒฝ์ฐ;
- $TRAVIS_REPO_SLUG ํ๋ก์ ํธ ์ ์ฅ์์ ์ด๋ฆ์ ์ ์ฅํฉ๋๋ค.
์ด ํจ์์ ์๊ณ ๋ฆฌ์ฆ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
Travis CI๋ ๋ฐํ ์ฝ๋์ ์๋ตํ๋ฏ๋ก ๊ฒฝ๊ณ ๊ฐ ์์ผ๋ฉด ์๋น์ค๊ฐ ์ปค๋ฐ์ ์ค๋ฅ๊ฐ ํฌํจ๋ ๊ฒ์ผ๋ก ํ์ํ๋๋ก ์ง์ํฉ๋๋ค.
์ด์ ์ด ์ฝ๋ ์ค์ ์์ธํ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
git diff --name-only origin/HEAD > .pvs-pr.list
์ฌ์ค Travis CI๋ ํ ์์ฒญ์ ๋ถ์ํ๋ ๋์ ์๋์ผ๋ก ๋ธ๋์น๋ฅผ ๋ณํฉํฉ๋๋ค.
๊ทธ๋ฌ๋ฏ๋ก ์ฐ๋ฆฌ๋ ๋ถ์ํ๋ค A4์๋๋ผ B3->A3. ์ด ๊ธฐ๋ฅ์ผ๋ก ์ธํด ๋ค์๊ณผ์ ์ฐจ์ด๋ฅผ ๊ณ์ฐํด์ผ ํฉ๋๋ค. A3, ์ด๋ ์ ํํ ์์ ๋ถ๊ธฐ์ ์๋จ์
๋๋ค. ์ถ๋ฐ์ง.
ํ ๊ฐ์ง ์ค์ํ ์ธ๋ถ ์ฌํญ์ด ๋จ์ ์์ต๋๋ค. ์ปดํ์ผ๋ ๋ฒ์ญ ๋จ์(*.c, *.cc, *.cpp ๋ฑ)์ ๋ํ ํค๋ ํ์ผ์ ์ข ์์ฑ์ ์บ์ฑํ๋ ๊ฒ์ ๋๋ค. ๋ถ์๊ธฐ๋ ํ์ผ ๋ชฉ๋ก์ ํ์ธํ๋ ๋ชจ๋๋ก ์ฒ์ ์คํ๋ ๋ ์ด๋ฌํ ์ข ์์ฑ์ ๊ณ์ฐํ ๋ค์ ์ด๋ฅผ .PVS-Studio ๋๋ ํฐ๋ฆฌ์ ์ ์ฅํฉ๋๋ค. Travis CI๋ฅผ ์ฌ์ฉํ๋ฉด ํด๋๋ฅผ ์บ์ํ ์ ์์ผ๋ฏ๋ก ๋๋ ํฐ๋ฆฌ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํฉ๋๋ค. .PVS-์คํ๋์ค/:
cache:
directories:
- .PVS-Studio/
์ด ์ฝ๋๋ฅผ ํ์ผ์ ์ถ๊ฐํด์ผ ํฉ๋๋ค. .travis.yml. ์ด ๋๋ ํฐ๋ฆฌ๋ ๋ถ์ ํ ์์ง๋ ๋ค์ํ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ฏ๋ก ํ์ ํ์ผ ๋ชฉ๋ก ๋ถ์ ๋๋ ์ฆ๋ถ ๋ถ์ ์คํ ์๋๊ฐ ํฌ๊ฒ ํฅ์๋ฉ๋๋ค. ์ด๊ฒ์ด ์๋ฃ๋์ง ์์ผ๋ฉด ๋ถ์๊ธฐ๋ ์ค์ ๋ก ๋งค๋ฒ ๋ชจ๋ ํ์ผ์ ๋ถ์ํฉ๋๋ค.
๋๋ฃ
ํธ๋๋น์ค CI์ฒ๋ผ,
์ฐ์ , ์กฐ๋ฆฝ ๋ผ์ธ์ ์๋ก์ด ์์ ์ ์ถ๊ฐํด์ผ ํฉ๋๋ค.
ํ๋ก์ ํธ๋ฅผ ๋น๋ํ๋ ๋ฐ ์ฌ์ฉ๋ ์ปดํ์ผ๋ฌ๋ฅผ ์ง์ ํด ๋ณด๊ฒ ์ต๋๋ค. ์ด ์์
์ ์ค์น๋ Docker ์ปจํ
์ด๋๋ฅผ ํ์ธํ์ธ์. ์๋ฅผ ๋ค์ด, GCC๋ฅผ ์ํ ํน๋ณํ ์ปจํ
์ด๋๊ฐ ์์ต๋๋ค:
์ด์ 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
Travs-CI ์น์ ์ ์ฝ์๋ค๋ฉด ์ด ์ฝ๋๋ ์ด๋ฏธ ์ต์ํ ๊ฒ์ ๋๋ค. ๊ทธ๋ฌ๋ ์ด์ ์๋ก์ด ๋จ๊ณ๊ฐ ์์ต๋๋ค.
์ฌ์ค ์ด์ ์ฐ๋ฆฌ๋ ๋ณํฉ ๊ฒฐ๊ณผ๊ฐ ์๋๋ผ ํ ์์ฒญ์ด ์ด๋ฃจ์ด์ง ๋ธ๋์น์ HEAD๋ฅผ ๋ถ์ํฉ๋๋ค.
๊ทธ๋์ ์ฐ๋ฆฌ๋ ์กฐ๊ฑด๋ถ ์ปค๋ฐ์ ํ๊ณ ์์ต๋๋ค. 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๊ฐ ์ ๊ณตํ๋ ๋ค์ ๋ณ์๋ฅผ ์ฌ์ฉํ์ต๋๋ค.
- $BUDDY_EXECUTION_PULL_REQEUST_NO โ ํ ์์ฒญ ๋ฒํธ
- $BUDDY_REPO_SLUG โ ์ฌ์ฉ์ ์ด๋ฆ๊ณผ ์ ์ฅ์์ ์กฐํฉ(์: max/test)
์ด์ ์๋ ๋ฒํผ์ ์ฌ์ฉํ์ฌ ๋ณ๊ฒฝ ์ฌํญ์ ์ ์ฅํ๊ณ ํ ์์ฒญ ๋ถ์์ ํ์ฑํํ๊ฒ ์ต๋๋ค.
Travis CI์ ๋ฌ๋ฆฌ ์ง์ ํ ํ์๊ฐ ์์ต๋๋ค. .pvs-์คํ๋์ค ์บ์ฑ์ ์ํด Buddy๋ ํ์ ์คํ์ ์ํด ๋ชจ๋ ํ์ผ์ ์๋์ผ๋ก ์บ์ํ๊ธฐ ๋๋ฌธ์
๋๋ค. ๋ฐ๋ผ์ ๋ง์ง๋ง์ผ๋ก PVS-Studio์ ๋ก๊ทธ์ธ๊ณผ ๋น๋ฐ๋ฒํธ๋ฅผ Buddy์ ์ ์ฅํ๋ ์ผ๋ง ๋จ์์ต๋๋ค. ๋ณ๊ฒฝ ์ฌํญ์ ์ ์ฅํ ํ ํ์ดํ๋ผ์ธ์ผ๋ก ๋์๊ฐ๋๋ค. ๋ณ์๋ฅผ ์ค์ ํ๊ณ PVS-Studio์ ๋ํ ๋ก๊ทธ์ธ ๋ฐ ํค๋ฅผ ์ถ๊ฐํด์ผ ํฉ๋๋ค.
๊ทธ ํ ์๋ก์ด ํ ์์ฒญ์ด๋ ์ปค๋ฐ์ด ๋ํ๋๋ฉด ๊ฒํ ๊ฐ ์์๋ฉ๋๋ค. ์ปค๋ฐ์ ์ค๋ฅ๊ฐ ์์ผ๋ฉด Buddy๋ ํ ์์ฒญ ํ์ด์ง์ ์ด๋ฅผ ํ์ํฉ๋๋ค.
์ฑ๋ฒ ์ด์ด
AppVeyor ์ค์ ์ ๋ชจ๋ ๊ฒ์ด ์น ์ธํฐํ์ด์ค์์ ์ด๋ฃจ์ด์ง๊ณ ํ๋ก์ ํธ ์ ์ฅ์์ *.yml ํ์ผ์ ์ถ๊ฐํ ํ์๊ฐ ์๊ธฐ ๋๋ฌธ์ Buddy์ ์ ์ฌํฉ๋๋ค.
ํ๋ก์ ํธ ๊ฐ์์ ์ค์ ํญ์ผ๋ก ์ด๋ํด ๋ณด๊ฒ ์ต๋๋ค.
์ด ํ์ด์ง๋ฅผ ์๋๋ก ์คํฌ๋กคํ์ฌ ํ ์์ฒญ ์์ง์ ์ํ ์บ์ ์ ์ฅ์ ํ์ฑํํด ๋ณด๊ฒ ์ต๋๋ค.
์ด์ ์ด์
๋ธ๋ฆฌ์ฉ ์ด๋ฏธ์ง์ ํ์ํ ํ๊ฒฝ ๋ณ์๋ฅผ ์ง์ ํ๋ ํ๊ฒฝ ํญ์ผ๋ก ์ด๋ํ๊ฒ ์ต๋๋ค.
์ด์ ์น์
์ ์ฝ์๋ค๋ฉด ๋ค์ ๋ ๋ณ์์ ๋ํด ๋งค์ฐ ์ ์๊ณ ์์ ๊ฒ์
๋๋ค. PVS_KEY ะธ PVS_USERNAME. ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ PVS-Studio ๋ถ์๊ธฐ์ ๋ผ์ด์ผ์ค๋ฅผ ํ์ธํ๋ ๋ฐ ํ์ํจ์ ์๋ ค๋๋ฆฝ๋๋ค. ๋์ค์ Bash ์คํฌ๋ฆฝํธ์์ ๋ค์ ๋ณด๊ฒ ๋ ๊ฒ์
๋๋ค.
์๋ ๊ฐ์ ํ์ด์ง์ ์บ์ฑ ํด๋๊ฐ ํ์๋์ด ์์ต๋๋ค.
์ด๋ ๊ฒ ํ์ง ์์ผ๋ฉด ๋ช ๊ฐ์ ํ์ผ ๋์ ์ ์ฒด ํ๋ก์ ํธ๋ฅผ ๋ถ์ํ์ง๋ง ์ง์ ๋ ํ์ผ์์ ์ถ๋ ฅ์ ์ป๊ฒ ๋ฉ๋๋ค. ๋ฐ๋ผ์ ์ฌ๋ฐ๋ฅธ ๋๋ ํฐ๋ฆฌ ์ด๋ฆ์ ์
๋ ฅํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
์ด์ ์คํฌ๋ฆฝํธ๋ฅผ ํ ์คํธํ ์ฐจ๋ก์ ๋๋ค. ํ ์คํธ ํญ์ ์ด๊ณ ์คํฌ๋ฆฝํธ๋ฅผ ์ ํํฉ๋๋ค.
์ด ์์์ ๋ค์ ์ฝ๋๋ฅผ ๋ถ์ฌ๋ฃ์ด์ผ ํฉ๋๋ค.
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 ๋ณ์๊ฐ ์ฝ๊ฐ ๊ฑฐ์ง๋ง์ ํ๊ณ ์๋ค๋ ๊ฒ์ ๊นจ๋ฌ์์ต๋๋ค. ์ด๋ฌํ ์ด์ ๋ก ๋ถ์์ ์์ํ๊ธฐ ์ ์ ํด๋น ๊ฐ์ ์๋์ผ๋ก ์ ๋ฐ์ดํธํ์ต๋๋ค.
๊ทธ๋ฌ๋ฉด ๋ชจ๋ ๊ฒ์ด ์ด์ ๊ณผ ๊ฐ์ต๋๋ค.
์ด์ ๋ค์ ๋ถ๋ถ์ ๊ณ ๋ คํด๋ณด์ธ์.
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์ ๊ฐ์ ๊ณณ์์๋ ์ค์ ์์ ํด๋๋ฅผ ์ง์ ํ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค. ํ์ง๋ง ์ด๋๊ฐ์์ ๊ณ ์ ํ ํค๋ฅผ ์์ฑํ๊ณ ์บ์๋ ์กฐ๊ฐ์ ๋ฎ์ด์ธ ์ ์๋ ๊ธฐํ๋ฅผ ์ ๊ณตํ๋๋ก ์์คํ ์ ์ค๋ํด์ผ ํฉ๋๋ค. ๋ฐ๋ผ์ ์์์ ๋ ผ์๋์ง ์์ ์ง์์ ์ธ ํตํฉ ์๋น์ค์ ๋ํ ํ ์์ฒญ ๋ถ์์ ์ค์ ํ๋ ค๋ฉด ๋จผ์ ์บ์ฑ์ ๋ฌธ์ ๊ฐ ์๋์ง ํ์ธํ์ญ์์ค.
๊ด์ฌ์ ๊ฐ์ ธ์ฃผ์
์ ๊ฐ์ฌํฉ๋๋ค. ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋์ง ์์ผ๋ฉด ์ธ์ ๋ ์ง ๋ค์ ์ฃผ์๋ก ๋ฌธ์ํด ์ฃผ์ธ์.
์ด ๊ธฐ์ฌ๋ฅผ ์์ด๊ถ ์ฒญ์ค๊ณผ ๊ณต์ ํ๋ ค๋ฉด ๋ฒ์ญ ๋งํฌ์ธ Maxim Zvyagintsev๋ฅผ ์ฌ์ฉํ์ญ์์ค.
์ถ์ฒ : habr.com