PVS-Studio๋Š” ์ด์ œ Chocolatey์— ์žˆ์Šต๋‹ˆ๋‹ค. Azure DevOps์—์„œ Chocolatey๋ฅผ ํ™•์ธํ•˜์„ธ์š”.

PVS-Studio๋Š” ์ด์ œ Chocolatey์— ์žˆ์Šต๋‹ˆ๋‹ค. Azure DevOps์—์„œ Chocolatey๋ฅผ ํ™•์ธํ•˜์„ธ์š”.
์šฐ๋ฆฌ๋Š” PVS-Studio๋ฅผ ๋”์šฑ ํŽธ๋ฆฌํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ณ„์†ํ•ด์„œ ๋…ธ๋ ฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ Windows์šฉ ํŒจํ‚ค์ง€ ๊ด€๋ฆฌ์ž์ธ Chocolatey์—์„œ ๋ถ„์„๊ธฐ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ด๊ฒƒ์ด ํŠนํžˆ ํด๋ผ์šฐ๋“œ ์„œ๋น„์Šค์—์„œ PVS-Studio์˜ ๋ฐฐํฌ๋ฅผ ์ด‰์ง„ํ•  ๊ฒƒ์ด๋ผ๊ณ  ๋ฏฟ์Šต๋‹ˆ๋‹ค. ๋ฉ€๋ฆฌ ๊ฐ€์ง€ ์•Š๊ธฐ ์œ„ํ•ด ๋™์ผํ•œ Chocolatey์˜ ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ํ™•์ธํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. Azure DevOps๋Š” CI ์‹œ์Šคํ…œ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ์€ ํด๋ผ์šฐ๋“œ ์‹œ์Šคํ…œ๊ณผ์˜ ํ†ตํ•ฉ ์ฃผ์ œ์— ๊ด€ํ•œ ๋‹ค๋ฅธ ๊ธฐ์‚ฌ ๋ชฉ๋ก์ž…๋‹ˆ๋‹ค.

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

๊ทธ๋ž˜์„œ ์ด ๊ธ€์˜ ์ฃผ์ธ๊ณต์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

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

์• ์ € ๋ฐ๋ธŒ์˜ต์Šค โ€” ์ „์ฒด ๊ฐœ๋ฐœ ํ”„๋กœ์„ธ์Šค๋ฅผ ๊ณต๋™์œผ๋กœ ๋‹ค๋ฃจ๋Š” ์ผ๋ จ์˜ ํด๋ผ์šฐ๋“œ ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค. ์ด ํ”Œ๋žซํผ์—๋Š” Azure Pipelines, Azure Boards, Azure Artifacts, Azure Repos, Azure Test Plans์™€ ๊ฐ™์€ ๋„๊ตฌ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์–ด ์†Œํ”„ํŠธ์›จ์–ด ์ƒ์„ฑ ํ”„๋กœ์„ธ์Šค ์†๋„๋ฅผ ๋†’์ด๊ณ  ํ’ˆ์งˆ์„ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ดˆ์ฝœ๋ฆฟ Windows์šฉ ์˜คํ”ˆ ์†Œ์Šค ํŒจํ‚ค์ง€ ๊ด€๋ฆฌ์ž์ž…๋‹ˆ๋‹ค. ์ด ํ”„๋กœ์ ํŠธ์˜ ๋ชฉํ‘œ๋Š” Windows ์šด์˜ ์ฒด์ œ์˜ ์„ค์น˜๋ถ€ํ„ฐ ์—…๋ฐ์ดํŠธ ๋ฐ ์ œ๊ฑฐ๊นŒ์ง€ ์ „์ฒด ์†Œํ”„ํŠธ์›จ์–ด ์ˆ˜๋ช…์ฃผ๊ธฐ๋ฅผ ์ž๋™ํ™”ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Chocolatey ์‚ฌ์šฉ์— ๋Œ€ํ•ด

์—ฌ๊ธฐ์—์„œ ํŒจํ‚ค์ง€ ๊ด€๋ฆฌ์ž ์ž์ฒด๋ฅผ ์„ค์น˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งํฌ. ๋ถ„์„๊ธฐ ์„ค์น˜์— ๋Œ€ํ•œ ์ „์ฒด ์„ค๋ช…์„œ๋Š” ๋‹ค์Œ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งํฌ Chocolatey ํŒจํ‚ค์ง€ ๊ด€๋ฆฌ์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„ค์น˜ ์„น์…˜์„ ์ฐธ์กฐํ•˜์„ธ์š”. ๊ฑฐ๊ธฐ์—์„œ ๋ช‡ ๊ฐ€์ง€ ์š”์ ์„ ๊ฐ„๋žตํ•˜๊ฒŒ ๋ฐ˜๋ณตํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์ตœ์‹  ๋ฒ„์ „์˜ ๋ถ„์„๊ธฐ๋ฅผ ์„ค์น˜ํ•˜๋Š” ๋ช…๋ น:

choco install pvs-studio

PVS-Studio ํŒจํ‚ค์ง€์˜ ํŠน์ • ๋ฒ„์ „์„ ์„ค์น˜ํ•˜๋Š” ๋ช…๋ น:

choco install pvs-studio --version=7.05.35617.2075

๊ธฐ๋ณธ์ ์œผ๋กœ ๋ถ„์„๊ธฐ์˜ ํ•ต์‹ฌ์ธ Core ๊ตฌ์„ฑ ์š”์†Œ๋งŒ ์„ค์น˜๋ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๋ชจ๋“  ํ”Œ๋ž˜๊ทธ(Standalone, JavaCore, IDEA, MSVS2010, MSVS2012, MSVS2013, MSVS2015, MSVS2017, MSVS2019)๋Š” --package-parameters๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Visual Studio 2019์šฉ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ถ„์„๊ธฐ๋ฅผ ์„ค์น˜ํ•˜๋Š” ๋ช…๋ น์˜ ์˜ˆ:

choco install pvs-studio --package-parameters="'/MSVS2019'"

์ด์ œ Azure DevOps์—์„œ ๋ถ„์„๊ธฐ๋ฅผ ํŽธ๋ฆฌํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๋Š” ์˜ˆ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์กฐ์ •

๊ณ„์ • ๋“ฑ๋ก, ๋นŒ๋“œ ํŒŒ์ดํ”„๋ผ์ธ ์ƒ์„ฑ, ๊ณ„์ •์„ GitHub ์ €์žฅ์†Œ์— ์žˆ๋Š” ํ”„๋กœ์ ํŠธ์™€ ๋™๊ธฐํ™”์™€ ๊ฐ™์€ ๋ฌธ์ œ์— ๋Œ€ํ•œ ๋ณ„๋„์˜ ์„น์…˜์ด ์žˆ๋‹ค๋Š” ์ ์„ ์ƒ๊ธฐ์‹œ์ผœ ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ธฐ์‚ฌ. ๊ตฌ์„ฑ ํŒŒ์ผ์„ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์„ค์ •์ด ์ฆ‰์‹œ ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค.

๋จผ์ € ์‹œ์ž‘ ํŠธ๋ฆฌ๊ฑฐ๋ฅผ ์„ค์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์žˆ์„ ๋•Œ๋งŒ ์‹œ์ž‘ํ•จ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ์„์‚ฌ ๋‚˜๋ญ‡๊ฐ€์ง€:

trigger:
- master

๋‹ค์Œ์œผ๋กœ ๊ฐ€์ƒ ๋จธ์‹ ์„ ์„ ํƒํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ๋Š” Windows Server 2019 ๋ฐ Visual Studio 2019๋ฅผ ์‚ฌ์šฉํ•˜๋Š” Microsoft ํ˜ธ์ŠคํŒ… ์—์ด์ „ํŠธ์ž…๋‹ˆ๋‹ค.

pool:
  vmImage: 'windows-latest'

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

PVS-Studio๋Š” ์ด์ œ Chocolatey์— ์žˆ์Šต๋‹ˆ๋‹ค. Azure DevOps์—์„œ Chocolatey๋ฅผ ํ™•์ธํ•˜์„ธ์š”.

์—ฌ๊ธฐ์„œ ํ™•์žฅ์„ ์ถ”๊ฐ€ํ•  ์œ„์น˜๋ฅผ ์„ ํƒํ•˜๊ณ  ๋ฒ„ํŠผ์„ ํด๋ฆญํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์„ค์น˜.

PVS-Studio๋Š” ์ด์ œ Chocolatey์— ์žˆ์Šต๋‹ˆ๋‹ค. Azure DevOps์—์„œ Chocolatey๋ฅผ ํ™•์ธํ•˜์„ธ์š”.

์„ฑ๊ณต์ ์œผ๋กœ ์„ค์น˜๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด ๋‹ค์Œ์„ ํด๋ฆญํ•˜์„ธ์š”. ์กฐ์ง์œผ๋กœ ์ง„ํ–‰:

PVS-Studio๋Š” ์ด์ œ Chocolatey์— ์žˆ์Šต๋‹ˆ๋‹ค. Azure DevOps์—์„œ Chocolatey๋ฅผ ํ™•์ธํ•˜์„ธ์š”.

์ด์ œ ์ฐฝ์—์„œ Chocolatey ์ž‘์—…์— ๋Œ€ํ•œ ํ…œํ”Œ๋ฆฟ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž‘์—… ๊ตฌ์„ฑ ํŒŒ์ผ์„ ํŽธ์ง‘ํ•  ๋•Œ Azure-ํŒŒ์ดํ”„๋ผ์ธ.yml:

PVS-Studio๋Š” ์ด์ œ Chocolatey์— ์žˆ์Šต๋‹ˆ๋‹ค. Azure DevOps์—์„œ Chocolatey๋ฅผ ํ™•์ธํ•˜์„ธ์š”.

Chocolatey๋ฅผ ํด๋ฆญํ•˜๊ณ  ํ•„๋“œ ๋ชฉ๋ก์„ ํ™•์ธํ•˜์„ธ์š”.

PVS-Studio๋Š” ์ด์ œ Chocolatey์— ์žˆ์Šต๋‹ˆ๋‹ค. Azure DevOps์—์„œ Chocolatey๋ฅผ ํ™•์ธํ•˜์„ธ์š”.

์—ฌ๊ธฐ์„œ๋Š” ์„ ํƒํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์„ค์น˜ ํ˜„์žฅ์—์„œ ํŒ€๊ณผ ํ•จ๊ป˜. ์•ˆ์— Nuspec ํŒŒ์ผ ์ด๋ฆ„ ํ•„์š”ํ•œ ํŒจํ‚ค์ง€์˜ ์ด๋ฆ„(pvs-studio)์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ๋ฒ„์ „์„ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ์šฐ๋ฆฌ์—๊ฒŒ ๋”ฑ ๋งž๋Š” ์ตœ์‹  ๋ฒ„์ „์ด ์„ค์น˜๋ฉ๋‹ˆ๋‹ค. ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ๋ณด์ž ๋”ํ•˜๋‹ค ๊ตฌ์„ฑ ํŒŒ์ผ์—์„œ ์ƒ์„ฑ๋œ ์ž‘์—…์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

steps:
- task: ChocolateyCommand@0
  inputs:
    command: 'install'
    installPackageId: 'pvs-studio'

๋‹ค์Œ์œผ๋กœ ํŒŒ์ผ์˜ ์ฃผ์š” ๋ถ€๋ถ„์œผ๋กœ ์ด๋™ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

- task: CmdLine@2
  inputs:
    script: 

์ด์ œ ๋ถ„์„๊ธฐ ๋ผ์ด์„ผ์Šค๊ฐ€ ํฌํ•จ๋œ ํŒŒ์ผ์„ ์ƒ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ PVS์ด๋ฆ„ ะธ PVSKEY โ€“ ์„ค์ •์—์„œ ๊ฐ’์„ ์ง€์ •ํ•˜๋Š” ๋ณ€์ˆ˜์˜ ์ด๋ฆ„. PVS-Studio ๋กœ๊ทธ์ธ ๋ฐ ๋ผ์ด์„ผ์Šค ํ‚ค๊ฐ€ ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. ๊ฐ’์„ ์„ค์ •ํ•˜๋ ค๋ฉด ๋ฉ”๋‰ด๋ฅผ ์—ฝ๋‹ˆ๋‹ค. ๋ณ€์ˆ˜->์ƒˆ ๋ณ€์ˆ˜. ๋ณ€์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด๋ณด์ž PVS์ด๋ฆ„ ๋กœ๊ทธ์ธ ๋ฐ PVSKEY ๋ถ„์„๊ธฐ ํ‚ค์˜ ๊ฒฝ์šฐ. ํ™•์ธ๋ž€์„ ์„ ํƒํ•˜๋Š” ๊ฒƒ์„ ์žŠ์ง€ ๋งˆ์„ธ์š”. ์ด ๊ฐ’์„ ๋น„๋ฐ€๋กœ ์œ ์ง€ํ•˜์„ธ์š” ์— PVSKEY. ๋ช…๋ น ์ฝ”๋“œ:

ัall "C:Program Files (x86)PVS-StudioPVS-Studio_Cmd.exe" credentials 
โ€“u $(PVSNAME) โ€“n $(PVSKEY)

์ €์žฅ์†Œ์— ์žˆ๋Š” bat ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜์—ฌ ํ”„๋กœ์ ํŠธ๋ฅผ ๋นŒ๋“œํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

ัall build.bat

๋ถ„์„๊ธฐ ๊ฒฐ๊ณผ๊ฐ€ ํฌํ•จ๋œ ํŒŒ์ผ์ด ์ €์žฅ๋  ํด๋”๋ฅผ ๋งŒ๋“ค์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

ัall mkdir PVSTestResults

ํ”„๋กœ์ ํŠธ ๋ถ„์„์„ ์‹œ์ž‘ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

ัall "C:Program Files (x86)PVS-StudioPVS-Studio_Cmd.exe" 
โ€“t .srcchocolatey.sln โ€“o .PVSTestResultsChoco.plog 

Plogะกonverter ์œ ํ‹ธ๋ฆฌํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ณด๊ณ ์„œ๋ฅผ html ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

ัall "C:Program Files (x86)PVS-StudioPlogConverter.exe" 
โ€“t html โ€“o PVSTestResults .PVSTestResultsChoco.plog

์ด์ œ ๋ณด๊ณ ์„œ๋ฅผ ์—…๋กœ๋“œํ•  ์ˆ˜ ์žˆ๋„๋ก ์ž‘์—…์„ ์ƒ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

- task: PublishBuildArtifacts@1
  inputs:
    pathToPublish: PVSTestResults
    artifactName: PVSTestResults
    condition: always()

์ „์ฒด ๊ตฌ์„ฑ ํŒŒ์ผ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

trigger:
- master

pool:
  vmImage: 'windows-latest'

steps:
- task: ChocolateyCommand@0
  inputs:
    command: 'install'
    installPackageId: 'pvs-studio'

- task: CmdLine@2
  inputs:
    script: |
      call "C:Program Files (x86)PVS-StudioPVS-Studio_Cmd.exe" 
      credentials โ€“u $(PVSNAME) โ€“n $(PVSKEY)
      call build.bat
      call mkdir PVSTestResults
      call "C:Program Files (x86)PVS-StudioPVS-Studio_Cmd.exe" 
      โ€“t .srcchocolatey.sln โ€“o .PVSTestResultsChoco.plog
      call "C:Program Files (x86)PVS-StudioPlogConverter.exe" 
      โ€“t html โ€“o .PVSTestResults .PVSTestResultsChoco.plog

- task: PublishBuildArtifacts@1
  inputs:
    pathToPublish: PVSTestResults
    artifactName: PVSTestResults
    condition: always()

ํด๋ฆญํ•ด๋ณด์ž ์ €์žฅ->์ €์žฅ->์‹คํ–‰ ์ž‘์—…์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ž‘์—… ํƒญ์œผ๋กœ ์ด๋™ํ•˜์—ฌ ๋ณด๊ณ ์„œ๋ฅผ ๋‹ค์šด๋กœ๋“œํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

PVS-Studio๋Š” ์ด์ œ Chocolatey์— ์žˆ์Šต๋‹ˆ๋‹ค. Azure DevOps์—์„œ Chocolatey๋ฅผ ํ™•์ธํ•˜์„ธ์š”.

Chocolatey ํ”„๋กœ์ ํŠธ์—๋Š” 37615์ค„์˜ C# ์ฝ”๋“œ๋งŒ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐœ๊ฒฌ๋œ ์˜ค๋ฅ˜ ์ค‘ ์ผ๋ถ€๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์‹œํ—˜ ๊ฒฐ๊ณผ

๊ฒฝ๊ณ  N1

๋ถ„์„๊ธฐ ๊ฒฝ๊ณ : V3005 'Provider' ๋ณ€์ˆ˜๋Š” ์ž์‹ ์—๊ฒŒ ํ• ๋‹น๋ฉ๋‹ˆ๋‹ค. CrytpoHashProviderSpecs.cs 38

public abstract class CrytpoHashProviderSpecsBase : TinySpec
{
  ....
  protected CryptoHashProvider Provider;
  ....
  public override void Context()
  {
    Provider = Provider = new CryptoHashProvider(FileSystem.Object);
  }
}

๋ถ„์„๊ธฐ๊ฐ€ ๋ณ€์ˆ˜ ์ž์ฒด์— ๋Œ€ํ•œ ํ• ๋‹น์„ ๊ฐ์ง€ํ–ˆ๋Š”๋ฐ ์ด๋Š” ์˜๋ฏธ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ์ด๋Ÿฌํ•œ ๋ณ€์ˆ˜ ์ค‘ ํ•˜๋‚˜ ๋Œ€์‹  ๋‹ค๋ฅธ ๋ณ€์ˆ˜๊ฐ€ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ธ€์Ž„, ์•„๋‹ˆ๋ฉด ์ด๊ฒƒ์€ ์˜คํƒ€์ด๋ฏ€๋กœ ์ถ”๊ฐ€ ํ• ๋‹น์€ ๊ฐ„๋‹จํžˆ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฒฝ๊ณ  N2

๋ถ„์„๊ธฐ ๊ฒฝ๊ณ : V3093 [CWE-480] '&' ์—ฐ์‚ฐ์ž๋Š” ๋‘ ํ”ผ์—ฐ์‚ฐ์ž๋ฅผ ๋ชจ๋‘ ํ‰๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ๋‹จ๋ฝ '&&' ์—ฐ์‚ฐ์ž๋ฅผ ๋Œ€์‹  ์‚ฌ์šฉํ•ด์•ผ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. Platform.cs 64

public static PlatformType get_platform()
{
  switch (Environment.OSVersion.Platform)
  {
    case PlatformID.MacOSX:
    {
      ....
    }
    case PlatformID.Unix:
    if(file_system.directory_exists("/Applications")
      & file_system.directory_exists("/System")
      & file_system.directory_exists("/Users")
      & file_system.directory_exists("/Volumes"))
      {
        return PlatformType.Mac;
      }
        else
          return PlatformType.Linux;
    default:
      return PlatformType.Windows;
  }
}

์—ฐ์‚ฐ์ž ์ฐจ์ด & ์šด์˜์ž๋กœ๋ถ€ํ„ฐ && ํ‘œํ˜„์‹์˜ ์™ผ์ชฝ์ด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค๋ฉด ๊ทธ๋ฆ‡๋œ, ๊ทธ๋Ÿฌ๋ฉด ์˜ค๋ฅธ์ชฝ์ด ๊ณ„์† ๊ณ„์‚ฐ๋˜๋ฉฐ, ์ด ๊ฒฝ์šฐ ๋ถˆํ•„์š”ํ•œ ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. system.directory_exists.

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

if ((k < nct) & (s[k] != 0.0))

์ง€์ˆ˜๋ผ๊ณ  ํ•ด๋„ k ์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š์œผ๋ฉด ๋ฐฐ์—ด ์š”์†Œ์— ์•ก์„ธ์Šคํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. IndexOutOfRangeException.

๊ฒฝ๊ณ  N3, N4

๋ถ„์„๊ธฐ ๊ฒฝ๊ณ : V3022 [CWE-571] 'shortPrompt' ํ‘œํ˜„์€ ํ•ญ์ƒ ์ฐธ์ž…๋‹ˆ๋‹ค. InteractivePrompt.cs 101
๋ถ„์„๊ธฐ ๊ฒฝ๊ณ : V3022 [CWE-571] 'shortPrompt' ํ‘œํ˜„์€ ํ•ญ์ƒ ์ฐธ์ž…๋‹ˆ๋‹ค. InteractivePrompt.cs 105

public static string 
prompt_for_confirmation(.... bool shortPrompt = false, ....)
{
  ....
  if (shortPrompt)
  {
    var choicePrompt = choice.is_equal_to(defaultChoice) //1
    ?
    shortPrompt //2
    ?
    "[[{0}]{1}]".format_with(choice.Substring(0, 1).ToUpperInvariant(), //3
    choice.Substring(1,choice.Length - 1))
    :
    "[{0}]".format_with(choice.ToUpperInvariant()) //0
    : 
    shortPrompt //4
    ? 
    "[{0}]{1}".format_with(choice.Substring(0,1).ToUpperInvariant(), //5
    choice.Substring(1,choice.Length - 1)) 
    :
    choice; //0
    ....
  }
  ....
}

์ด ๊ฒฝ์šฐ ์‚ผํ•ญ ์—ฐ์‚ฐ์ž์˜ ์—ฐ์‚ฐ ๋’ค์—๋Š” ์ด์ƒํ•œ ๋…ผ๋ฆฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ข€ ๋” ์ž์„ธํžˆ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. 1๋ฒˆ์œผ๋กœ ํ‘œ์‹œํ•œ ์กฐ๊ฑด์ด ์ถฉ์กฑ๋˜๋ฉด ์กฐ๊ฑด 2๋กœ โ€‹โ€‹๋„˜์–ด๊ฐ‘๋‹ˆ๋‹ค. ์ฐธ๋œ, ์ด๋Š” 3ํ–‰์ด ์‹คํ–‰๋จ์„ ์˜๋ฏธํ•˜๋ฉฐ, ์กฐ๊ฑด 1์ด ๊ฑฐ์ง“์œผ๋กœ ํŒ๋ช…๋˜๋ฉด 4๋ฒˆ ํ–‰์œผ๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค. ์ฐธ๋œ, ์ด๋Š” ๋ผ์ธ 5๊ฐ€ ์‹คํ–‰๋จ์„ ์˜๋ฏธํ•˜๋ฏ€๋กœ ์ฃผ์„ 0์œผ๋กœ ํ‘œ์‹œ๋œ ์กฐ๊ฑด์€ ๊ฒฐ์ฝ” ์ถฉ์กฑ๋˜์ง€ ์•Š์œผ๋ฉฐ ์ด๋Š” ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ๊ธฐ๋Œ€ํ•œ ์—ฐ์‚ฐ ๋…ผ๋ฆฌ์™€ ์ •ํ™•ํžˆ ์ผ์น˜ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฒฝ๊ณ  N5

๋ถ„์„๊ธฐ ๊ฒฝ๊ณ : V3123 [CWE-783] ์•„๋งˆ๋„ '?:' ์—ฐ์‚ฐ์ž๊ฐ€ ์˜ˆ์ƒํ–ˆ๋˜ ๊ฒƒ๊ณผ ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ์ž‘๋™ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•ด๋‹น ์กฐ๊ฑด์˜ ๋‹ค๋ฅธ ์—ฐ์‚ฐ์ž๋ณด๋‹ค ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋‚ฎ์Šต๋‹ˆ๋‹ค. ์˜ต์…˜.cs 1019

private static string GetArgumentName (...., string description)
{
  string[] nameStart;
  if (maxIndex == 1)
  {
    nameStart = new string[]{"{0:", "{"};
  }
  else
  {
    nameStart = new string[]{"{" + index + ":"};
  }
  for (int i = 0; i < nameStart.Length; ++i) 
  {
    int start, j = 0;
    do 
    {
      start = description.IndexOf (nameStart [i], j);
    } 
    while (start >= 0 && j != 0 ? description [j++ - 1] == '{' : false);
    ....
    return maxIndex == 1 ? "VALUE" : "VALUE" + (index + 1);
  }
}

์ง„๋‹จ์€ ๋‹ค์Œ ๋ผ์ธ์— ๋Œ€ํ•ด ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค.

while (start >= 0 && j != 0 ? description [j++ - 1] == '{' : false)

๋ณ€์ˆ˜๋ถ€ํ„ฐ j ์œ„์˜ ๋ช‡ ์ค„์€ XNUMX์œผ๋กœ ์ดˆ๊ธฐํ™”๋˜๊ณ  ์‚ผํ•ญ ์—ฐ์‚ฐ์ž๋Š” ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆ‡๋œ. ์ด ์กฐ๊ฑด์œผ๋กœ ์ธํ•ด ๋ฃจํ”„ ๋ณธ๋ฌธ์€ ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ œ๊ฐ€ ๋ณด๊ธฐ์—” ์ด ์ฝ”๋“œ ์กฐ๊ฐ์€ ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์˜๋„ํ•œ ๋Œ€๋กœ ์ „ํ˜€ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๊ฒฝ๊ณ  N6

๋ถ„์„๊ธฐ ๊ฒฝ๊ณ : V3022 [CWE-571] 'installedPackageVersions.Count != 1' ํ‘œํ˜„์‹์€ ํ•ญ์ƒ ์ฐธ์ž…๋‹ˆ๋‹ค. NugetService.cs 1405

private void remove_nuget_cache_for_package(....)
{
  if (!config.AllVersions && installedPackageVersions.Count > 1)
  {
    const string allVersionsChoice = "All versions";
    if (installedPackageVersions.Count != 1)
    {
      choices.Add(allVersionsChoice);
    }
    ....
  }
  ....
}

์—ฌ๊ธฐ์—๋Š” ์ด์ƒํ•œ ์ค‘์ฒฉ ์กฐ๊ฑด์ด ์žˆ์Šต๋‹ˆ๋‹ค. installPackageVersions.Count != 1ํ•ญ์ƒ ๊ทธ๋Ÿด ๊ฒƒ์ด๋‹ค ์ฐธ๋œ. ์ด๋Ÿฌํ•œ ๊ฒฝ๊ณ ๋Š” ์ฝ”๋“œ์˜ ๋…ผ๋ฆฌ์  ์˜ค๋ฅ˜๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์œผ๋ฉฐ, ๋‹ค๋ฅธ ๊ฒฝ์šฐ์—๋Š” ๋‹จ์ˆœํžˆ ์ค‘๋ณต ๊ฒ€์‚ฌ๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

๊ฒฝ๊ณ  N7

๋ถ„์„๊ธฐ ๊ฒฝ๊ณ : V3001 '||' ์™ผ์ชฝ๊ณผ ์˜ค๋ฅธ์ชฝ์— ๋™์ผํ•œ ํ•˜์œ„ ํ‘œํ˜„์‹ 'commandArguments.contains("-apikey")'๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์šด์˜์ž. ArgumentsUtility.cs 42

public static bool arguments_contain_sensitive_information(string
 commandArguments)
{
  return commandArguments.contains("-install-arguments-sensitive")
  || commandArguments.contains("-package-parameters-sensitive")
  || commandArguments.contains("apikey ")
  || commandArguments.contains("config ")
  || commandArguments.contains("push ")
  || commandArguments.contains("-p ")
  || commandArguments.contains("-p=")
  || commandArguments.contains("-password")
  || commandArguments.contains("-cp ")
  || commandArguments.contains("-cp=")
  || commandArguments.contains("-certpassword")
  || commandArguments.contains("-k ")
  || commandArguments.contains("-k=")
  || commandArguments.contains("-key ")
  || commandArguments.contains("-key=")
  || commandArguments.contains("-apikey")
  || commandArguments.contains("-api-key")
  || commandArguments.contains("-apikey")
  || commandArguments.contains("-api-key");
}

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

commandArguments.contains("-apikey=");
commandArguments.contains("-api-key=");

๋ณต์‚ฌ-๋ถ™์—ฌ๋„ฃ๊ธฐ ์˜ค๋ฅ˜๋Š” ์†Œ์Šค ์ฝ”๋“œ๊ฐ€ ๋งŽ์€ ํ”„๋กœ์ ํŠธ์—์„œ ์กฐ๋งŒ๊ฐ„ ๋‚˜ํƒ€๋‚  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์œผ๋ฉฐ, ์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๋Š” ๊ฐ€์žฅ ์ข‹์€ ๋„๊ตฌ ์ค‘ ํ•˜๋‚˜๋Š” ์ •์  ๋ถ„์„์ž…๋‹ˆ๋‹ค.

PS ๊ทธ๋ฆฌ๊ณ  ํ•ญ์ƒ ๊ทธ๋ ‡๋“ฏ์ด ์ด ์˜ค๋ฅ˜๋Š” ์—ฌ๋Ÿฌ ์ค„๋กœ ๊ตฌ์„ฑ๋œ ์กฐ๊ฑด์˜ ๋์— ๋‚˜ํƒ€๋‚˜๋Š” ๊ฒฝํ–ฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค :). ์ถœํŒ๋ฌผ ์ฐธ์กฐ "๋งˆ์ง€๋ง‰ ์ค„ ํšจ๊ณผ".

๊ฒฝ๊ณ  N8

๋ถ„์„๊ธฐ ๊ฒฝ๊ณ : V3095 [CWE-476] 'installedPackage' ๊ฐœ์ฒด๊ฐ€ null์— ๋Œ€ํ•ด ํ™•์ธ๋˜๊ธฐ ์ „์— ์‚ฌ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ค„ ํ™•์ธ: 910, 917. NugetService.cs 910

public virtual ConcurrentDictionary<string, PackageResult> get_outdated(....)
{
  ....
  var pinnedPackageResult = outdatedPackages.GetOrAdd(
    packageName, 
    new PackageResult(installedPackage, 
                      _fileSystem.combine_paths(
                        ApplicationParameters.PackagesLocation, 
                        installedPackage.Id)));
  ....
  if (   installedPackage != null
      && !string.IsNullOrWhiteSpace(installedPackage.Version.SpecialVersion) 
      && !config.UpgradeCommand.ExcludePrerelease)
  {
    ....
  }
  ....
}

์ „ํ˜•์ ์ธ ์‹ค์ˆ˜: ๊ฐ์ฒด ์šฐ์„  ์„ค์น˜๋œํŒจํ‚ค์ง€ ์‚ฌ์šฉ๋œ ํ›„ ํ™•์ธ๋ฉ๋‹ˆ๋‹ค. null๋กœ. ์ด ์ง„๋‹จ์€ ํ”„๋กœ๊ทธ๋žจ์˜ ๋‘ ๊ฐ€์ง€ ๋ฌธ์ œ ์ค‘ ํ•˜๋‚˜์— ๋Œ€ํ•ด ์•Œ๋ ค์ค๋‹ˆ๋‹ค. ์„ค์น˜๋œํŒจํ‚ค์ง€ ๊ฒฐ์ฝ” ๊ฐ™์ง€ ์•Š๋‹ค null๋กœ, ์ด๋Š” ์˜์‹ฌ์Šค๋Ÿฝ๊ณ  ๊ฒ€์‚ฌ๊ฐ€ ์ค‘๋ณต๋˜๊ฑฐ๋‚˜ ์ž ์žฌ์ ์œผ๋กœ ์ฝ”๋“œ์—์„œ null ์ฐธ์กฐ์— ์•ก์„ธ์Šคํ•˜๋ ค๋Š” ์‹œ๋„๋กœ ์ธํ•ด ์‹ฌ๊ฐํ•œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฒฐ๋ก 

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

์šฐ๋ฆฌ๋Š” ์ดˆ๋Œ€ ๋‹ค์šด๋กœ๋“œ PVS-Studio๋ฅผ ์‚ฌ์šฉํ•ด ๋ณด์„ธ์š”. ์ •์  ๋ถ„์„๊ธฐ๋ฅผ ์ •๊ธฐ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋ฉด ํŒ€์ด ๊ฐœ๋ฐœํ•˜๋Š” ์ฝ”๋“œ์˜ ํ’ˆ์งˆ๊ณผ ์•ˆ์ •์„ฑ์ด ํ–ฅ์ƒ๋˜๊ณ  ๋งŽ์€ ๋ฌธ์ œ๋ฅผ ์˜ˆ๋ฐฉํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. ์ œ๋กœ๋ฐ์ด ์ทจ์•ฝ์ .

PS

์ถœํŒํ•˜๊ธฐ ์ „์— ์šฐ๋ฆฌ๋Š” Chocolatey ๊ฐœ๋ฐœ์ž๋“ค์—๊ฒŒ ๊ธฐ์‚ฌ๋ฅผ ๋ณด๋ƒˆ๊ณ  ๊ทธ๋“ค์€ ์ข‹์€ ๋ฐ˜์‘์„ ์–ป์—ˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ค‘์š”ํ•œ ๊ฒƒ์„ ์ฐพ์ง€ ๋ชปํ–ˆ์ง€๋งŒ ์˜ˆ๋ฅผ ๋“ค์–ด "api-key" ํ‚ค์™€ ๊ด€๋ จํ•˜์—ฌ ๋ฐœ๊ฒฌํ•œ ๋ฒ„๊ทธ๋ฅผ ์ข‹์•„ํ–ˆ์Šต๋‹ˆ๋‹ค.

PVS-Studio๋Š” ์ด์ œ Chocolatey์— ์žˆ์Šต๋‹ˆ๋‹ค. Azure DevOps์—์„œ Chocolatey๋ฅผ ํ™•์ธํ•˜์„ธ์š”.

์ด ๊ธฐ์‚ฌ๋ฅผ ์˜์–ด๊ถŒ ์ฒญ์ค‘๊ณผ ๊ณต์œ ํ•˜๋ ค๋ฉด ๋ฒˆ์—ญ ๋งํฌ์ธ Vladislav Stolyarov๋ฅผ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค. PVS-Studio๋Š” ์ด์ œ Chocolatey์— ์žˆ์Šต๋‹ˆ๋‹ค: Azure DevOps์—์„œ Chocolatey ํ™•์ธ.

์ถœ์ฒ˜ : habr.com

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