
喜歡 GitLab 但討厭錯誤?想要提高原始碼的品質嗎?那你來對地方了。今天我們將告訴您如何設定 PVS-Studio C# 分析器來檢查合併請求。擁有獨角獸心情,享受閱讀的樂趣。
— 是一款用於識別 C、C++、C# 和 Java 編寫的程式原始碼中的錯誤和潛在漏洞的工具。它可在 64 位元系統上運作。 Windows, Linux и macOS它可以分析面向 32 位元、64 位元和嵌入式 ARM 平台的程式碼。
順便說一下,我們發布了 PVS-Studio 7.08,在其中我們做了很多事情 。 例如:
- C# 分析器 Linux и macOS;
- Rider 外掛;
- 檢查文件列表的新模式。
文件列表檢查模式
以前,為了檢查某些文件,必須將包含文件清單的 .xml 傳遞給分析器。但由於這不是很方便,我們增加了傳輸.txt的功能,這使得生活變得更加輕鬆。
為了檢查特定文件,您需要指定一個標誌 —source文件 (-f) 並傳輸帶有檔案清單的.txt 檔案。它看起來像這樣:
pvs-studio-dotnet -t path/to/solution.sln -f fileList.txt -o project.json如果您有興趣自訂提交或拉取請求的審核,您也可以使用此模式來進行。差異在於獲取要分析的文件列表,並取決於您所使用的系統。
合併請求檢查的原理
檢查的重點是確保分析儀偵測到的問題不會落入合併 主 分支。我們也不想每次都分析整個專案。此外,合併分支時,我們會有一個修改文件的清單。因此,我建議添加合併請求的檢查。
在實作靜態分析器之前,合併請求是這樣的:

也就是說,分支中的所有錯誤 變化,將會移至 master 分支。因為我們不要這個,所以我們加入分析,現在圖表如下:

我們分析 變化2 如果沒有錯誤,我們接受合併請求,否則我們拒絕它。
順便說一句,如果你對分析 C/C++ 的提交和拉取請求感興趣,你可以閱讀 .
GitLab
— 一個基於 Web 的開源 DevOps 生命週期工具,為 Git 提供程式碼儲存庫管理系統,具有自己的 wiki、問題追蹤系統、CI/CD 管道和其他功能。
在開始實施合併請求分析之前,您需要註冊並上傳您的專案。如果你不知道怎麼做,我建議 我的同事。
注意。下面描述的設定環境的方法是可能的方法之一。目的是展示設定分析所需環境和運行分析器的步驟。也許,對您而言,將環境準備(新增儲存庫、安裝分析器)和分析階段分開會更加理想:例如,準備具有必要環境的 Docker 映像並使用它們,或使用其他方法。
為了更好地理解現在將要發生的事,我建議您看一下下面的圖表:

分析器需要 .NET Core SDK 3,因此在安裝分析器之前,您需要新增 Microsoft 儲存庫,分析器將從中安裝其相依性。為各種發行版新增 Microsoft 儲存庫 Linux .
要透過套件管理器安裝 PVS-Studio,您還需要新增 PVS-Studio 儲存庫。為不同的發行版添加存儲庫的更詳細描述見 .
此分析儀需要許可證密鑰才能運作。您可以在以下位置取得試用許可證 .
注意。請注意,所描述的操作模式(合併請求分析)需要企業許可證。因此,如果您想嘗試這種操作模式,請不要忘記在「訊息」欄位中註明您需要企業許可證。
如果發生合併請求,那麼我們只需要分析修改的文件列表,否則我們將分析所有文件。分析完之後,我們需要將日誌轉換成我們需要的格式。
現在,有了工作演算法,您就可以繼續編寫腳本了。為此,您需要更改文件 .gitlab-ci.yml 或者,如果不存在,則創建它。要建立它,您需要點擊項目名稱 -> 設定 CI/CD.

現在我們可以開始寫腳本了。讓我們先寫一些安裝分析器並輸入許可證的程式碼:
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由於安裝和啟動必須在所有其他腳本之前進行,因此我們使用特殊標籤 腳本之前。讓我稍微解釋一下這個片段。
分析儀安裝準備:
- 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_名稱 - 使用者名稱.
$PVS_KEY - 產品金鑰。
恢復專案依賴關係 $CI_專案目錄 – 專案目錄的完整路徑:
- dotnet restore "$CI_PROJECT_DIR"/Path/To/Solution.sln為了正確分析,專案必須成功建置且其相依性必須恢復(例如,必須下載所需的 NuGet 套件)。
您可以點擊來設定包含許可證資訊的環境變量 設置,然後 持續整合/持續交付.

在開啟的視窗中,找到該項目 變量,點擊右側的按鈕 拓展 並添加變數。結果應該如下:

現在我們可以繼續分析了。首先,讓我們新增一個腳本以進行全面分析。進入國旗 -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)" 文件 "".
在本例中,我們對所有包含 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剩下的就是在所有腳本運行後添加日誌轉換。讓我們使用標籤 腳本之後 和實用性 plog轉換器:
after_script:
- plog-converter -t html -o eLog ./PVS-Studio.json效用 — 是一個開源項目,用於將解析器錯誤報告轉換為各種形式,例如 HTML。 「Plog 轉換器實用程式」小節中提供了有關該實用程式的更詳細描述 .
順便說一句,如果你想在 IDE 中方便地本地處理 .json 報告,我建議使用我們的 適用於 IDE Rider。它的使用在 .
為了方便起見,這裡 .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 -> 管道 -> 運行。將開啟一個虛擬機器窗口,窗口末尾應顯示以下內容:

我們看到了 任務成功 ——成功,一切都很好。現在您可以測試您所做的事情了。
工作範例
為了說明這項工作,讓我們創建一個簡單的專案( 主) 中將包含多個文件。之後,在另一個分支中,我們將只更改一個檔案並嘗試發出合併請求。
讓我們考慮兩種情況:修改後的檔案包含錯誤的情況和不包含錯誤的情況。首先,一個有錯誤的例子。
假設 master 分支中有一個文件 程序.cs,其中不包含錯誤,而在另一個分支中開發人員添加了錯誤的程式碼並想要發出合併請求。他犯了什麼錯誤並不重要,重要的是這個錯誤確實存在。例如,操作員忘記了 扔 (是的, ):
void MyAwesomeMethod(String name)
{
if (name == null)
new ArgumentNullException(....);
// do something
....
}我們來看一下分析一個有錯誤的例子的結果。另外,為了確保只分析一個文件,我添加了一個標誌 -r 在 pvs-studio-dotnet 啟動行中:

我們看到分析器發現了一個錯誤並且不允許合併分支。
我們來檢查一下沒有錯誤的例子。修正代碼:
void MyAwesomeMethod(String name)
{
if (name == null)
throw new ArgumentNullException(....);
// do something
....
}合併請求分析的結果:

我們可以看到,沒有發現任何錯誤,任務成功執行,這正是我們想要檢查的。
結論
在合併分支之前清除壞程式碼非常方便且令人愉快。因此如果您正在使用 CI/CD,請嘗試整合靜態分析器進行檢查。而且,它做得相當簡單。
感謝您的關注。
如果您想與英語觀眾分享這篇文章,請使用翻譯連結:Nikolay Mironov。 .
來源: www.habr.com
