C#์šฉ PVS-Studio๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ GitLab์—์„œ ๋ณ‘ํ•ฉ ์š”์ฒญ ๋ถ„์„

C#์šฉ PVS-Studio๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ GitLab์—์„œ ๋ณ‘ํ•ฉ ์š”์ฒญ ๋ถ„์„
GitLab์„ ์ข‹์•„ํ•˜๊ณ  ๋ฒ„๊ทธ๋ฅผ ์‹ซ์–ดํ•˜์‹œ๋‚˜์š”? ์†Œ์Šค ์ฝ”๋“œ์˜ ํ’ˆ์งˆ์„ ํ–ฅ์ƒ์‹œํ‚ค๊ณ  ์‹ถ์œผ์‹ญ๋‹ˆ๊นŒ? ๊ทธ๋ ‡๋‹ค๋ฉด ๋‹น์‹ ์€ ์˜ฌ๋ฐ”๋ฅธ ์žฅ์†Œ์— ์™”์Šต๋‹ˆ๋‹ค. ์˜ค๋Š˜์€ PVS-Studio C# ๋ถ„์„๊ธฐ๋ฅผ ๊ตฌ์„ฑํ•˜์—ฌ ๋ณ‘ํ•ฉ ์š”์ฒญ์„ ํ™•์ธํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ๋ ค๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค. ๋ชจ๋‘๋“ค ์œ ๋‹ˆ์ฝ˜ ๊ธฐ๋ถ„์„ ๊ฐ–๊ณ  ํ–‰๋ณตํ•œ ๋…์„œ๋ฅผ ํ•˜์„ธ์š”.

PVS-์ŠคํŠœ๋””์˜ค C, C++, C# ๋ฐ Java๋กœ ์ž‘์„ฑ๋œ ํ”„๋กœ๊ทธ๋žจ ์†Œ์Šค ์ฝ”๋“œ์˜ ์˜ค๋ฅ˜์™€ ์ž ์žฌ์ ์ธ ์ทจ์•ฝ์ ์„ ์‹๋ณ„ํ•˜๋Š” ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. Windows, Linux ๋ฐ macOS์˜ 64๋น„ํŠธ ์‹œ์Šคํ…œ์—์„œ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. 32๋น„ํŠธ, 64๋น„ํŠธ ๋ฐ ์ž„๋ฒ ๋””๋“œ ARM ํ”Œ๋žซํผ์šฉ์œผ๋กœ ์„ค๊ณ„๋œ ์ฝ”๋“œ๋ฅผ ๋ถ„์„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๊ฑด ๊ทธ๋ ‡๊ณ , ์šฐ๋ฆฌ๋Š” PVS-Studio 7.08์„ ์ถœ์‹œํ–ˆ๋Š”๋ฐ, ์—ฌ๊ธฐ์„œ ์šฐ๋ฆฌ๋Š” ๋งŽ์€ ์ผ์„ ํ–ˆ์Šต๋‹ˆ๋‹ค. ํฅ๋ฏธ๋กœ์šด. ์˜ˆ :

  • Linux ๋ฐ macOS์šฉ C# ๋ถ„์„๊ธฐ;
  • ๋ผ์ด๋”์šฉ ํ”Œ๋Ÿฌ๊ทธ์ธ;
  • ์ƒˆ๋กœ์šด ํŒŒ์ผ ๋ชฉ๋ก ํ™•์ธ ๋ชจ๋“œ.

ํŒŒ์ผ ๋ชฉ๋ก ํ™•์ธ ๋ชจ๋“œ

์ด์ „์—๋Š” ํŠน์ • ํŒŒ์ผ์„ ํ™•์ธํ•˜๋ ค๋ฉด ํŒŒ์ผ ๋ชฉ๋ก์ด ํฌํ•จ๋œ .xml์„ ๋ถ„์„๊ธฐ์— ์ „๋‹ฌํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Š” ๊ทธ๋‹ค์ง€ ํŽธ๋ฆฌํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— .txt๋ฅผ ์ „์†กํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜์—ฌ ์ƒํ™œ์„ ๋งค์šฐ ๋‹จ์ˆœํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

ํŠน์ • ํŒŒ์ผ์„ ํ™•์ธํ•˜๋ ค๋ฉด ํ”Œ๋ž˜๊ทธ๋ฅผ ์ง€์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. --sourceํŒŒ์ผ (-f) ํŒŒ์ผ ๋ชฉ๋ก๊ณผ ํ•จ๊ป˜ .txt๋ฅผ ์ „์†กํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

pvs-studio-dotnet -t path/to/solution.sln -f fileList.txt -o project.json

์ปค๋ฐ‹ ํ™•์ธ ๋˜๋Š” ํ’€ ์š”์ฒญ ์„ค์ •์— ๊ด€์‹ฌ์ด ์žˆ๋Š” ๊ฒฝ์šฐ ์ด ๋ชจ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๋‹น ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฐจ์ด์ ์€ ๋ถ„์„ํ•  ํŒŒ์ผ ๋ชฉ๋ก์„ ์–ป๋Š” ๋ฐ ์žˆ์œผ๋ฉฐ ์‚ฌ์šฉ ์ค‘์ธ ์‹œ์Šคํ…œ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค.

๋ณ‘ํ•ฉ ์š”์ฒญ ํ™•์ธ ์›์น™

๊ฒ€์‚ฌ์˜ ์ฃผ์š” ๋ณธ์งˆ์€ ๋ณ‘ํ•ฉ ์ค‘์— ๋ถ„์„๊ธฐ๊ฐ€ ๊ฐ์ง€ํ•œ ๋ฌธ์ œ๊ฐ€ ๋‹ค์Œ ๋‹จ๊ณ„์— ์†ํ•˜์ง€ ์•Š๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์„์‚ฌ ๋‚˜๋ญ‡๊ฐ€์ง€. ๋˜ํ•œ ์šฐ๋ฆฌ๋Š” ๋งค๋ฒˆ ์ „์ฒด ํ”„๋กœ์ ํŠธ๋ฅผ ๋ถ„์„ํ•˜๊ณ  ์‹ถ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ๋ธŒ๋žœ์น˜๋ฅผ ๋ณ‘ํ•ฉํ•˜๋ฉด ๋ณ€๊ฒฝ๋œ ํŒŒ์ผ ๋ชฉ๋ก์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ณ‘ํ•ฉ ์š”์ฒญ ํ™•์ธ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

์ •์  ๋ถ„์„๊ธฐ๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์ „์˜ ๋ณ‘ํ•ฉ ์š”์ฒญ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

C#์šฉ PVS-Studio๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ GitLab์—์„œ ๋ณ‘ํ•ฉ ์š”์ฒญ ๋ถ„์„
์ฆ‰, ๋ธŒ๋žœ์น˜์— ์žˆ๋˜ ๋ชจ๋“  ์˜ค๋ฅ˜๊ฐ€ ๋ณ€๊ฒฝ, ๋งˆ์Šคํ„ฐ ๋ธŒ๋žœ์น˜๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ด๊ฒƒ์„ ์›ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋ถ„์„์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ด์ œ ๋‹ค์ด์–ด๊ทธ๋žจ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

C#์šฉ PVS-Studio๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ GitLab์—์„œ ๋ณ‘ํ•ฉ ์š”์ฒญ ๋ถ„์„
๋ถ„์„ํ•˜๋Š” ๋ณ€ํ™”2 ์˜ค๋ฅ˜๊ฐ€ ์—†์œผ๋ฉด ๋ณ‘ํ•ฉ ์š”์ฒญ์„ ์ˆ˜๋ฝํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๊ฑฐ๋ถ€ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ C/C++์— ๋Œ€ํ•œ ์ปค๋ฐ‹ ๋ฐ ํ’€ ์š”์ฒญ ๋ถ„์„์— ๊ด€์‹ฌ์ด ์žˆ๋‹ค๋ฉด ์ด์— ๋Œ€ํ•ด ์ฝ์–ด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—.

GitLab

GitLab Git์šฉ ์ฝ”๋“œ ์ €์žฅ์†Œ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ๊ณผ ์ž์ฒด ์œ„ํ‚ค, ๋ฌธ์ œ ์ถ”์  ์‹œ์Šคํ…œ, CI/CD ํŒŒ์ดํ”„๋ผ์ธ ๋ฐ ๊ธฐํƒ€ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ์˜คํ”ˆ ์†Œ์Šค ์›น ๊ธฐ๋ฐ˜ DevOps ์ˆ˜๋ช… ์ฃผ๊ธฐ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.

๋ณ‘ํ•ฉ ์š”์ฒญ ๋ถ„์„์„ ์‹œ์ž‘ํ•˜๊ธฐ ์ „์— ํ”„๋กœ์ ํŠธ๋ฅผ ๋“ฑ๋กํ•˜๊ณ  ์—…๋กœ๋“œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ• ์ง€ ๋ชจ๋ฅด์‹ ๋‹ค๋ฉด ์ถ”์ฒœํ•ด๋“œ๋ ค์š” ัั‚ะฐั‚ัŒัŽ ๋‚ด ๋™๋ฃŒ.

์ฃผ์˜. ์•„๋ž˜์— ์„ค๋ช…๋œ ํ™˜๊ฒฝ ์„ค์ • ๋ฐฉ๋ฒ•์€ ๊ฐ€๋Šฅํ•œ ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. ๋ถ„์„์— ํ•„์š”ํ•œ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ณ  ๋ถ„์„๊ธฐ๋ฅผ ์‹œ์ž‘ํ•˜๋Š” ๋‹จ๊ณ„๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ๊ฒƒ์ด ๋ชฉํ‘œ์ž…๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ๊ท€ํ•˜์˜ ๊ฒฝ์šฐ ํ™˜๊ฒฝ ์ค€๋น„(๋ฆฌํฌ์ง€ํ† ๋ฆฌ ์ถ”๊ฐ€, ๋ถ„์„๊ธฐ ์„ค์น˜) ๋‹จ๊ณ„์™€ ๋ถ„์„ ๋‹จ๊ณ„๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ๋” ์ตœ์ ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ํ•„์š”ํ•œ ํ™˜๊ฒฝ์œผ๋กœ Docker ์ด๋ฏธ์ง€๋ฅผ ์ค€๋น„ํ•˜๊ณ  ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ง€๊ธˆ ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚ ์ง€ ๋” ์ž˜ ์ดํ•ดํ•˜๋ ค๋ฉด ๋‹ค์Œ ๋‹ค์ด์–ด๊ทธ๋žจ์„ ์‚ดํŽด๋ณด๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

C#์šฉ PVS-Studio๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ GitLab์—์„œ ๋ณ‘ํ•ฉ ์š”์ฒญ ๋ถ„์„
๋ถ„์„๊ธฐ๊ฐ€ ์ž‘๋™ํ•˜๋ ค๋ฉด .NET Core SDK 3์ด ํ•„์š”ํ•˜๋ฏ€๋กœ ๋ถ„์„๊ธฐ๋ฅผ ์„ค์น˜ํ•˜๊ธฐ ์ „์— ๋ถ„์„๊ธฐ์— ํ•„์š”ํ•œ ์ข…์†์„ฑ์„ ์„ค์น˜ํ•  Microsoft ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์–‘ํ•œ Linux ๋ฐฐํฌํŒ์„ ์œ„ํ•œ Microsoft ๋ฆฌํฌ์ง€ํ† ๋ฆฌ ์ถ”๊ฐ€ ํ•ด๋‹น ๋ฌธ์„œ์— ์„ค๋ช…๋˜์–ด ์žˆ์Œ.

ํŒจํ‚ค์ง€ ๊ด€๋ฆฌ์ž๋ฅผ ํ†ตํ•ด PVS-Studio๋ฅผ ์„ค์น˜ํ•˜๋ ค๋ฉด PVS-Studio ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์–‘ํ•œ ๋ฐฐํฌํŒ์— ๋Œ€ํ•œ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ ์ถ”๊ฐ€์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋ฌธ์„œ์˜ ๊ด€๋ จ ์„น์…˜.

๋ถ„์„๊ธฐ๋ฅผ ์ž‘๋™ํ•˜๋ ค๋ฉด ๋ผ์ด์„ผ์Šค ํ‚ค๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์—์„œ ํ‰๊ฐ€ํŒ ๋ผ์ด์„ผ์Šค๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ถ„์„๊ธฐ ๋‹ค์šด๋กœ๋“œ ํŽ˜์ด์ง€.

์ฃผ์˜. ์„ค๋ช…๋œ ์ž‘์—… ๋ชจ๋“œ(๋ณ‘ํ•ฉ ์š”์ฒญ ๋ถ„์„)์—๋Š” Enterprise ๋ผ์ด์„ผ์Šค๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด ์ž‘์—… ๋ชจ๋“œ๋ฅผ ์‹œ๋„ํ•˜๋ ค๋ฉด "๋ฉ”์‹œ์ง€" ํ•„๋“œ์— Enterprise ๋ผ์ด์„ผ์Šค๊ฐ€ ํ•„์š”ํ•จ์„ ํ‘œ์‹œํ•˜๋Š” ๊ฒƒ์„ ์žŠ์ง€ ๋งˆ์‹ญ์‹œ์˜ค.

๋ณ‘ํ•ฉ ์š”์ฒญ์ด ๋ฐœ์ƒํ•˜๋ฉด ๋ณ€๊ฒฝ๋œ ํŒŒ์ผ ๋ชฉ๋ก๋งŒ ๋ถ„์„ํ•˜๋ฉด ๋˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋ชจ๋“  ํŒŒ์ผ์„ ๋ถ„์„ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๋ถ„์„ ํ›„์—๋Š” ๋กœ๊ทธ๋ฅผ ํ•„์š”ํ•œ ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด์ œ ์ž‘์—… ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๋ˆˆ์•ž์— ๋‘๊ณ  ์Šคํฌ๋ฆฝํŠธ ์ž‘์„ฑ์œผ๋กœ ๋„˜์–ด๊ฐˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ ค๋ฉด ํŒŒ์ผ์„ ๋ณ€๊ฒฝํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. .gitlab-ci.yml ๋˜๋Š” ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ์ƒˆ๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์„ ์ƒ์„ฑํ•˜๋ ค๋ฉด ํ”„๋กœ์ ํŠธ ์ด๋ฆ„์„ ํด๋ฆญํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค -> CI/CD ์„ค์ •.

C#์šฉ PVS-Studio๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ GitLab์—์„œ ๋ณ‘ํ•ฉ ์š”์ฒญ ๋ถ„์„
์ด์ œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ž‘์„ฑํ•  ์ค€๋น„๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋จผ์ € ๋ถ„์„๊ธฐ๋ฅผ ์„ค์น˜ํ•˜๊ณ  ๋ผ์ด์„ผ์Šค๋ฅผ ์ž…๋ ฅํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

before_script:
  - apt-get update && apt-get -y install wget gnupg 

  - apt-get -y install git
  - wget https://packages.microsoft.com/config/debian/10/
packages-microsoft-prod.deb -O packages-microsoft-prod.deb
  - dpkg -i packages-microsoft-prod.deb
  - apt-get update
  - apt-get install apt-transport-https
  - apt-get update
  
  - 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-dotnet

  - pvs-studio-analyzer credentials $PVS_NAME $PVS_KEY
  - dotnet restore "$CI_PROJECT_DIR"/Test/Test.sln

์„ค์น˜์™€ ํ™œ์„ฑํ™”๋Š” ๋‹ค๋ฅธ ๋ชจ๋“  ์Šคํฌ๋ฆฝํŠธ๋ณด๋‹ค ๋จผ์ € ์ด๋ฃจ์–ด์ ธ์•ผ ํ•˜๋ฏ€๋กœ ํŠน์ˆ˜ ๋ผ๋ฒจ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. before_script. ์ด ๋ถ€๋ถ„์„ ์กฐ๊ธˆ ์„ค๋ช…ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๋ถ„์„๊ธฐ ์„ค์น˜ ์ค€๋น„:

  - wget https://packages.microsoft.com/config/debian/10/
packages-microsoft-prod.deb -O packages-microsoft-prod.deb
  - dpkg -i packages-microsoft-prod.deb
  - apt-get update
  - apt-get install apt-transport-https
  - apt-get update

PVS-Studio ์ €์žฅ์†Œ ๋ฐ ๋ถ„์„๊ธฐ ์ถ”๊ฐ€:

  - 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-dotnet

๋ผ์ด์„ผ์Šค ํ™œ์„ฑํ™”:

  - pvs-studio-analyzer credentials $PVS_NAME $PVS_KEY

$PVS_NAME - ์‚ฌ์šฉ์ž ์ด๋ฆ„.

$PVS_KEY - ์ œํ’ˆ ํ‚ค.

ํ”„๋กœ์ ํŠธ ์ข…์†์„ฑ์„ ๋ณต๊ตฌํ•˜๋Š” ์ค‘ $CI_PROJECT_DIR โ€“ ํ”„๋กœ์ ํŠธ ๋””๋ ‰ํ† ๋ฆฌ์˜ ์ „์ฒด ๊ฒฝ๋กœ:

  - dotnet restore "$CI_PROJECT_DIR"/Path/To/Solution.sln

์˜ฌ๋ฐ”๋ฅธ ๋ถ„์„์„ ์œ„ํ•ด์„œ๋Š” ํ”„๋กœ์ ํŠธ๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ๋นŒ๋“œ๋˜์–ด์•ผ ํ•˜๋ฉฐ ํ•ด๋‹น ์ข…์†์„ฑ์„ ๋ณต์›ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(์˜ˆ: ํ•„์š”ํ•œ NuGet ํŒจํ‚ค์ง€๋ฅผ ๋‹ค์šด๋กœ๋“œํ•ด์•ผ ํ•จ).

ํด๋ฆญํ•˜๋ฉด ๋ผ์ด์„ผ์Šค ์ •๋ณด๊ฐ€ ํฌํ•จ๋œ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ™˜๊ฒฝ, ๊ทธ๋ฆฌ๊ณ  ์ดํ›„ CI/CD.

C#์šฉ PVS-Studio๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ GitLab์—์„œ ๋ณ‘ํ•ฉ ์š”์ฒญ ๋ถ„์„
์—ด๋ฆฌ๋Š” ์ฐฝ์—์„œ ํ•ญ๋ชฉ์„ ์ฐพ์œผ์‹ญ์‹œ์˜ค. ๋ณ€์ˆ˜, ์˜ค๋ฅธ์ชฝ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜์„ธ์š” ํŽผ์น˜๊ธฐ ๊ทธ๋ฆฌ๊ณ  ๋ณ€์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.

C#์šฉ PVS-Studio๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ GitLab์—์„œ ๋ณ‘ํ•ฉ ์š”์ฒญ ๋ถ„์„
์ด์ œ ๋ถ„์„์œผ๋กœ ๋„˜์–ด๊ฐˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋จผ์ € ์™„์ „ํ•œ ๋ถ„์„์„ ์œ„ํ•ด ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ถ”๊ฐ€ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊นƒ๋ฐœ์— -t ํ”Œ๋ž˜๊ทธ์— ๋Œ€ํ•œ ์†”๋ฃจ์…˜ ๊ฒฝ๋กœ๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. -o ๋ถ„์„ ๊ฒฐ๊ณผ๊ฐ€ ๊ธฐ๋ก๋  ํŒŒ์ผ์˜ โ€‹โ€‹๊ฒฝ๋กœ๋ฅผ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋ฐ˜ํ™˜ ์ฝ”๋“œ์—๋„ ๊ด€์‹ฌ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ๋ถ„์„ ์ค‘์— ๊ฒฝ๊ณ ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค๋Š” ์ •๋ณด๊ฐ€ ๋ฐ˜ํ™˜ ์ฝ”๋“œ์— ํฌํ•จ๋˜๋ฉด ์ž‘์—…์ด ์ค‘์ง€๋˜๋Š” ๋ฐ ๊ด€์‹ฌ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์กฐ๊ฐ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

job:
  script:
  - exit_code=0
  - pvs-studio-dotnet -t "$CI_PROJECT_DIR"/Test/Test.sln -o 
PVS-Studio.json || exit_code=$?
  - exit_code=$((($exit_code & 8)/8))
  - if [[ $exit_code == 1 ]]; then exit 1; else exit 0; fi

๋ฐ˜ํ™˜ ์ฝ”๋“œ๋Š” ๋น„ํŠธ ๋งˆ์Šคํฌ ์›์น™์— ๋”ฐ๋ผ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋ถ„์„ ๊ฒฐ๊ณผ ๊ฒฝ๊ณ ๊ฐ€ ๋ฐœํ–‰๋œ ๊ฒฝ์šฐ ๋ฐ˜ํ™˜ ์ฝ”๋“œ๋Š” 8์ด ๋ฉ๋‹ˆ๋‹ค. ๋ผ์ด์„ผ์Šค๊ฐ€ ํ•œ ๋‹ฌ ์ด๋‚ด์— ๋งŒ๋ฃŒ๋˜๋ฉด ๋ฐ˜ํ™˜ ์ฝ”๋“œ๋Š” 4๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ๋ถ„์„ ์ค‘์— ์˜ค๋ฅ˜๊ฐ€ ๊ฐ์ง€๋œ ๊ฒฝ์šฐ ๋ผ์ด์„ผ์Šค๊ฐ€ ํ•œ ๋‹ฌ ์ด๋‚ด์— ๋งŒ๋ฃŒ๋˜๋ฉด ์ฝ”๋“œ๊ฐ€ ๋ฐ˜ํ™˜๋˜๊ณ  ๋‘ ๊ฐ’์ด ๋ชจ๋‘ ๊ธฐ๋ก๋ฉ๋‹ˆ๋‹ค. ์ˆซ์ž๋ฅผ ๋”ํ•˜๊ณ  ์ตœ์ข… ๋ฐ˜ํ™˜ ์ฝ”๋“œ์ธ 8+4=12๋ฅผ ์–ป์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํ•ด๋‹น ๋น„ํŠธ๋ฅผ ํ™•์ธํ•จ์œผ๋กœ์จ ๋ถ„์„ ์‹œ ๋‹ค์–‘ํ•œ ์ƒํƒœ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค. ๋ฐ˜ํ™˜ ์ฝ”๋“œ๋Š” ๋ฌธ์„œ์˜ "pvs-studio-dotnet(Linux/macOS) ๋ฐ˜ํ™˜ ์ฝ”๋“œ" ์„น์…˜์— ์ž์„ธํžˆ ์„ค๋ช…๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.PVS-Studio๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ช…๋ น์ค„์—์„œ Visual Studio/MSBuild/.NET Core ํ”„๋กœ์ ํŠธ ํ™•์ธ".

์ด ๊ฒฝ์šฐ 8์ด ๋‚˜ํƒ€๋‚˜๋Š” ๋ชจ๋“  ๋ฐ˜ํ™˜ ์ฝ”๋“œ์— ๊ด€์‹ฌ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  - exit_code=$((($exit_code & 8)/8))

๋ฐ˜ํ™˜ ์ฝ”๋“œ์— ์šฐ๋ฆฌ๊ฐ€ ๊ด€์‹ฌ ์žˆ๋Š” ์ˆซ์ž์˜ ๋น„ํŠธ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์œผ๋ฉด 1์„ ๋ฐ›๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด 0์„ ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ด์ œ ๋ณ‘ํ•ฉ ์š”์ฒญ ๋ถ„์„์„ ์ถ”๊ฐ€ํ•  ์ฐจ๋ก€์ž…๋‹ˆ๋‹ค. ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์ „์— ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์œ„ํ•œ ์žฅ์†Œ๋ฅผ ์ค€๋น„ํ•ฉ์‹œ๋‹ค. ๋ณ‘ํ•ฉ ์š”์ฒญ์ด ๋ฐœ์ƒํ•  ๋•Œ๋งŒ ์‹คํ–‰๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

merge:
  script:
  only:
  - merge_requests

์Šคํฌ๋ฆฝํŠธ ์ž์ฒด๋กœ ๋„˜์–ด ๊ฐ‘์‹œ๋‹ค. ๋‚˜๋Š” ๊ฐ€์ƒ ๋จธ์‹ ์ด ์•„๋ฌด๊ฒƒ๋„ ๋ชจ๋ฅธ๋‹ค๋Š” ์‚ฌ์‹ค์— ์ง๋ฉดํ–ˆ์Šต๋‹ˆ๋‹ค. ์›์‚ฐ์ง€ / ๋งˆ์Šคํ„ฐ. ๊ทธ๋Ÿฌ๋‹ˆ ๊ทธ๋…€๋ฅผ ์กฐ๊ธˆ ๋„์™€์ฃผ์ž:

  - git fetch origin

์ด์ œ ์šฐ๋ฆฌ๋Š” ๋ถ„๊ธฐ ๊ฐ„์˜ ์ฐจ์ด๋ฅผ ์–ป๊ณ  ๊ฒฐ๊ณผ๋ฅผ ๋‹ค์Œ ์œ„์น˜์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. TXT ํŒŒ์ผ:

  - git diff --name-only origin/master $CI_COMMIT_SHA > pvs-fl.txt

ะ“ะดะต $CI_COMMIT_SHA โ€“ ๋งˆ์ง€๋ง‰ ์ปค๋ฐ‹์˜ ํ•ด์‹œ์ž…๋‹ˆ๋‹ค.

๋‹ค์Œ์œผ๋กœ ํ”Œ๋ž˜๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŒŒ์ผ ๋ชฉ๋ก ๋ถ„์„์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. -f. ์ด์ „์— ๋ฐ›์€ .txt ํŒŒ์ผ์„ ์—ฌ๊ธฐ์— ์ „์†กํ•ฉ๋‹ˆ๋‹ค. ๊ธ€์Ž„์š”, ์ „์ฒด ๋ถ„์„๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ ๋ฐ˜ํ™˜ ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

  - exit_code=0
  - pvs-studio-dotnet -t "$CI_PROJECT_DIR"/Test/Test.sln -f 
pvs-fl.txt -o PVS-Studio.json || exit_code=$?
  - exit_code=$((($exit_code & 8)/8))
  - if [[ $exit_code == 1 ]]; then exit 1; else exit 0; fi

๋ณ‘ํ•ฉ ์š”์ฒญ์„ ํ™•์ธํ•˜๋Š” ์ „์ฒด ์Šคํฌ๋ฆฝํŠธ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

merge:
  script:
  - git fetch origin
  - git diff --name-only origin/master $CI_COMMIT_SHA > pvs-fl.txt
  - exit_code=0
  - pvs-studio-dotnet -t "$CI_PROJECT_DIR"/Test/Test.sln -f 
pvs-fl.txt -o PVS-Studio.json || exit_code=$?
  - exit_code=$((($exit_code & 8)/8))
  - if [[ $exit_code == 1 ]]; then exit 1; else exit 0; fi
  only:
  - merge_requests

๋‚จ์€ ๊ฒƒ์€ ๋ชจ๋“  ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ฒ˜๋ฆฌ๋œ ํ›„ ๋กœ๊ทธ ๋ณ€ํ™˜์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋ผ๋ฒจ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค after_script ์œ ํ‹ธ๋ฆฌํ‹ฐ ํ”Œ๋กœ๊ทธ ๋ณ€ํ™˜๊ธฐ:

after_script:
  - plog-converter -t html -o eLog ./PVS-Studio.json

๊ณต์ต ์‚ฌ์—… ํ”Œ๋กœ๊ทธ ๋ณ€ํ™˜๊ธฐ ํŒŒ์„œ ์˜ค๋ฅ˜ ๋ณด๊ณ ์„œ๋ฅผ HTML๊ณผ ๊ฐ™์€ ๋‹ค์–‘ํ•œ ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ์˜คํ”ˆ ์†Œ์Šค ํ”„๋กœ์ ํŠธ์ž…๋‹ˆ๋‹ค. ์œ ํ‹ธ๋ฆฌํ‹ฐ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์„ค๋ช…์€ "Plog ๋ณ€ํ™˜๊ธฐ ์œ ํ‹ธ๋ฆฌํ‹ฐ" ํ•˜์œ„ ์„น์…˜์— ๋‚˜์™€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ์„œ์˜ ๊ด€๋ จ ์„น์…˜.

๊ทธ๋Ÿฐ๋ฐ IDE์—์„œ ๋กœ์ปฌ๋กœ .json ๋ณด๊ณ ์„œ๋ฅผ ํŽธ๋ฆฌํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋‹ค์Œ์„ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค. ํ”Œ๋Ÿฌ๊ทธ์ธ IDE ๋ผ์ด๋”์šฉ. ๊ทธ ์‚ฌ์šฉ๋ฒ•์€ ๋‹ค์Œ ํ•ญ๋ชฉ์— ์ž์„ธํžˆ ์„ค๋ช…๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ด€๋ จ ๋ฌธ์„œ.

ํŽธ์˜์ƒ ์ด๋ ‡์Šต๋‹ˆ๋‹ค. .gitlab-ci.yml ์ „๋ถ€:

image: debian

before_script:
  - apt-get update && apt-get -y install wget gnupg 

  - apt-get -y install git
  - wget https://packages.microsoft.com/config/debian/10/
packages-microsoft-prod.deb -O packages-microsoft-prod.deb
  - dpkg -i packages-microsoft-prod.deb
  - apt-get update
  - apt-get install apt-transport-https
  - apt-get update
  
  - 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-dotnet

  - pvs-studio-analyzer credentials $PVS_NAME $PVS_KEY
  - dotnet restore "$CI_PROJECT_DIR"/Test/Test.sln

merge:
  script:
  - git fetch origin
  - git diff --name-only origin/master $CI_COMMIT_SHA > pvs-fl.txt
  - exit_code=0
  - pvs-studio-dotnet -t "$CI_PROJECT_DIR"/Test/Test.sln -f 
pvs-fl.txt -o PVS-Studio.json || exit_code=$?
  - exit_code=$((($exit_code & 8)/8))
  - if [[ $exit_code == 1 ]]; then exit 1; else exit 0; fi
  only:
  - merge_requests

job:
  script:
  - exit_code=0
  - pvs-studio-dotnet -t "$CI_PROJECT_DIR"/Test/Test.sln -o 
PVS-Studio.json || exit_code=$?
  - exit_code=$((($exit_code & 8)/8))
  - if [[ $exit_code == 1 ]]; then exit 1; else exit 0; fi
  
after_script:
  - plog-converter -t html -o eLog ./PVS-Studio.json

ํŒŒ์ผ์— ๋ชจ๋“  ๋‚ด์šฉ์„ ์ถ”๊ฐ€ํ•œ ํ›„ ๋‹ค์Œ์„ ํด๋ฆญํ•˜์„ธ์š”. ๋ณ€๊ฒฝ ์‚ฌํ•ญ ์ ์šฉ. ๋ชจ๋“  ๊ฒƒ์ด ์˜ฌ๋ฐ”๋ฅธ์ง€ ํ™•์ธํ•˜๋ ค๋ฉด ๋‹ค์Œ์œผ๋กœ ์ด๋™ํ•˜์‹ญ์‹œ์˜ค. CI / CD -> ํŒŒ์ดํ”„ ๋ผ์ธ -> ๋‹ฌ๋ฆฌ๋Š”. ๊ฐ€์ƒ ๋จธ์‹  ์ฐฝ์ด ์—ด๋ฆฌ๊ณ  ๋งˆ์ง€๋ง‰์—๋Š” ๋‹ค์Œ์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

C#์šฉ PVS-Studio๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ GitLab์—์„œ ๋ณ‘ํ•ฉ ์š”์ฒญ ๋ถ„์„
๋ดค๋‹ค ์ž‘์—… ์„ฑ๊ณต - ์„ฑ๊ณต, ๋ชจ๋“  ๊ฒƒ์ด ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค. ์ด์ œ ์ˆ˜ํ–‰ํ•œ ์ž‘์—…์„ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ž‘์—… ์˜ˆ

์ž‘์—…์˜ ์˜ˆ๋ฅผ ๋“ค์–ด ๊ฐ„๋‹จํ•œ ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค( ์„์‚ฌ)์—๋Š” ์—ฌ๋Ÿฌ ํŒŒ์ผ์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ๊ทธ ํ›„ ๋‹ค๋ฅธ ๋ธŒ๋žœ์น˜์—์„œ๋Š” ํŒŒ์ผ ํ•˜๋‚˜๋งŒ ๋ณ€๊ฒฝํ•˜๊ณ  ๋ณ‘ํ•ฉ ์š”์ฒญ์„ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค.

์ˆ˜์ •๋œ ํŒŒ์ผ์— ์˜ค๋ฅ˜๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ์™€ ์˜ค๋ฅ˜๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ์˜ ๋‘ ๊ฐ€์ง€ ๊ฒฝ์šฐ๋ฅผ ๊ณ ๋ คํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋จผ์ € ์˜ค๋ฅ˜๊ฐ€ ์žˆ๋Š” ์˜ˆ์ž…๋‹ˆ๋‹ค.

๋งˆ์Šคํ„ฐ ๋ธŒ๋žœ์น˜์— ํŒŒ์ผ์ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ํ”„๋กœ๊ทธ๋žจ.cs, ์—ฌ๊ธฐ์—๋Š” ์˜ค๋ฅ˜๊ฐ€ ์—†์ง€๋งŒ ๋‹ค๋ฅธ ๋ธŒ๋žœ์น˜์—์„œ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ž˜๋ชป๋œ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ๋ณ‘ํ•ฉ ์š”์ฒญ์„ ํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๊ฐ€ ์–ด๋–ค ์ข…๋ฅ˜์˜ ์‹ค์ˆ˜๋ฅผ ์ €์งˆ๋ €๋Š”์ง€๋Š” ๊ทธ๋‹ค์ง€ ์ค‘์š”ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฒƒ์€ ๊ทธ๊ฒƒ์ด ์กด์žฌํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๊ตํ™˜์›์ด ์žŠ์–ด๋ฒ„๋ ธ์–ด์š” ๋˜์ ธ (์˜ˆ, ์ •๋ง ํ‹€๋ ธ์–ด):

void MyAwesomeMethod(String name)
{
  if (name == null)
    new ArgumentNullException(....);
  // do something
  ....
}

์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ ์˜ˆ์ œ๋ฅผ ๋ถ„์„ํ•œ ๊ฒฐ๊ณผ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ํ•˜๋‚˜์˜ ํŒŒ์ผ๋งŒ ๊ตฌ๋ฌธ ๋ถ„์„๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ํ”Œ๋ž˜๊ทธ๋ฅผ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. -r pvs-studio-dotnet ์ถœ์‹œ ๋ผ์ธ:

C#์šฉ PVS-Studio๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ GitLab์—์„œ ๋ณ‘ํ•ฉ ์š”์ฒญ ๋ถ„์„
๋ถ„์„๊ธฐ๊ฐ€ ์˜ค๋ฅ˜๋ฅผ ๋ฐœ๊ฒฌํ•˜์—ฌ ๋ธŒ๋žœ์น˜ ๋ณ‘ํ•ฉ์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š์€ ๊ฒƒ์„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค.

์˜ค๋ฅ˜ ์—†์ด ์˜ˆ์ œ๋ฅผ ํ™•์ธํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ ์ˆ˜์ •:

void MyAwesomeMethod(String name)
{
  if (name == null)
    throw new ArgumentNullException(....);
  // do something
  ....
}

๋ณ‘ํ•ฉ ์š”์ฒญ ๋ถ„์„ ๊ฒฐ๊ณผ:

C#์šฉ PVS-Studio๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ GitLab์—์„œ ๋ณ‘ํ•ฉ ์š”์ฒญ ๋ถ„์„
๋ณด์‹œ๋‹ค์‹œํ”ผ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ๊ฒฌ๋˜์ง€ ์•Š์•˜์œผ๋ฉฐ ์ž‘์—… ์‹คํ–‰์ด ์„ฑ๊ณตํ–ˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค.

๊ฒฐ๋ก 

๋ธŒ๋žœ์น˜๋ฅผ ๋ณ‘ํ•ฉํ•˜๊ธฐ ์ „์— ์ž˜๋ชป๋œ ์ฝ”๋“œ๋ฅผ ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ์€ ๋งค์šฐ ํŽธ๋ฆฌํ•˜๊ณ  ์ฆ๊ฒ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ CI/CD๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์ •์  ๋ถ„์„๊ธฐ๋ฅผ ๋‚ด์žฅํ•˜์—ฌ ํ™•์ธํ•ด๋ณด์„ธ์š”. ๋˜ํ•œ ์ด๊ฒƒ์€ ๋งค์šฐ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค.

๊ด€์‹ฌ์„ ๊ฐ€์ ธ ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

C#์šฉ PVS-Studio๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ GitLab์—์„œ ๋ณ‘ํ•ฉ ์š”์ฒญ ๋ถ„์„
์ด ๊ธฐ์‚ฌ๋ฅผ ์˜์–ด๊ถŒ ์ฒญ์ค‘๊ณผ ๊ณต์œ ํ•˜๋ ค๋ฉด ๋ฒˆ์—ญ ๋งํฌ์ธ Nikolay Mironov๋ฅผ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค. C#์šฉ PVS-Studio๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ GitLab์—์„œ ๋ณ‘ํ•ฉ ์š”์ฒญ ๋ถ„์„.

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€