使用 PVS-Studio for C# 分析 GitLab 中的合併請求

使用 PVS-Studio for C# 分析 GitLab 中的合併請求
喜歡 GitLab 但討厭 bug? 想要提高原始碼的品質嗎? 那麼您就來對地方了。 今天我們將告訴您如何設定PVS-Studio C#分析器來檢查合併請求。 祝大家有獨角獸心情,快樂閱讀。

PVS工作室 是一種用於識別用 C、C++、C# 和 Java 編寫的程式原始碼中的錯誤和潛在漏洞的工具。 適用於 Windows、Linux 和 macOS 上的 64 位元系統。 可以分析為 32 位元、64 位元和嵌入式 ARM 平台設計的程式碼。

順便說一句,我們發布了PVS-Studio 7.08,其中我們做了很多事情 有趣的。 例如:

  • 適用於 Linux 和 macOS 的 C# 分析器;
  • Rider 外掛;
  • 新的文件列表檢查模式。

文件列表檢查模式

以前,為了檢查某些文件,需要將包含文件清單的 .xml 傳遞給分析器。 但由於這不是很方便,我們添加了傳輸 .txt 的功能,這使生活變得非常簡單。

為了檢查特定文件,您必須指定標誌 --原始檔 (-f)並傳輸 .txt 和檔案清單。 它看起來像這樣:

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

如果您有興趣設定提交檢查或拉取請求,您也可以使用此模式來執行此操作。 區別在於獲取要分析的文件列表,並且取決於您使用的系統。

檢查合併請求的原理

檢查的主要本質是確保分析器在合併過程中偵測到的問題不會落入 分支。 我們也不想每次都分析整個專案。 此外,當合併分支時,我們有一個已更改文件的清單。 因此,我建議新增合併請求檢查。

這是實作靜態分析器之前合併請求的樣子:

使用 PVS-Studio for C# 分析 GitLab 中的合併請求
也就是說,分支中的所有錯誤 變化,將移動到 master 分支。 由於我們不希望出現這種情況,因此我們添加了分析,現在該圖如下所示:

使用 PVS-Studio for C# 分析 GitLab 中的合併請求
分析 變化2 如果沒有錯誤,我們接受合併請求,否則我們拒絕它。

順便說一句,如果您有興趣分析 C/C++ 的提交和拉取請求,那麼您可以閱讀相關內容 這裡.

GitLab

GitLab 是一個基於 Web 的開源 DevOps 生命週期工具,它為 Git 提供程式碼儲存庫管理系統,具有自己的 wiki、問題追蹤系統、CI/CD 管道和其他功能。

在開始分析合併請求之前,您需要註冊並上傳您的專案。 如果您不知道如何執行此操作,那麼我建議 一篇文章 我的同事。

注意。 下面描述的設定環境的方法是可能的方法之一。 目標是展示設定分析所需環境和啟動分析器的步驟。 也許在您的情況下,將環境準備階段(新增儲存庫、安裝分析器)和分析階段分開會更理想:例如,使用必要的環境準備 Docker 映像並使用它們,或使用其他方法。

為了更好地理解現在會發生什麼,我建議查看下圖:

使用 PVS-Studio for C# 分析 GitLab 中的合併請求
此分析器需要 .NET Core SDK 3 才能運作,因此在安裝分析器之前,您需要新增 Microsoft 儲存庫,從中安裝分析器所需的依賴項。 為各種 Linux 發行版新增 Microsoft 儲存庫 對應文檔中描述.

要透過套件管理器安裝 PVS-Studio,您還需要新增 PVS-Studio 儲存庫。 為不同的發行版新增儲存庫有更詳細的描述 文件的相關部分.

分析儀需要許可證密鑰才能運作。 您可以在以下位置取得試用許可證 分析儀下載頁面.

注意。 請注意,所描述的操作模式(合併請求分析)需要企業許可證。 因此,如果您想嘗試這種操作模式,請不要忘記在「訊息」欄位中註明您需要企業許可證。

如果發生合併請求,那麼我們只需要分析更改的文件列表,否則我們分析所有文件。 分析完之後,我們需要將日誌轉換成我們需要的格式。

現在,工作演算法就在眼前,您可以繼續編寫腳本了。 為此,您需要更改文件 .gitlab-ci.yml 或者,如果它不存在,則創建它。 要建立它,您需要點擊項目名稱 -> 設定 CI/CD.

使用 PVS-Studio for C# 分析 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

由於安裝和啟動必須在所有其他腳本之前發生,因此我們使用特殊的標籤 之前的腳本。 讓我稍微解釋一下這個片段。

準備安裝分析儀:

  - 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 套件)。

您可以透過點擊設定包含許可證資訊的環境變量 設置,以及之後的 持續整合/持續交付.

使用 PVS-Studio for C# 分析 GitLab 中的合併請求
在開啟的視窗中找到該項目 變量,點擊右側按鈕 擴大 並添加變數。 結果應該是這樣的:

使用 PVS-Studio for C# 分析 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

剩下的就是在處理完所有腳本後新增日誌轉換。 我們使用標籤 後腳本 和效用 plog轉換器:

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

效用 plog轉換器 是一個開源項目,用於將解析器錯誤報告轉換為各種形式,例如 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 -> 管道 -> 運行。 將開啟一個虛擬機器窗口,其末尾應有以下內容:

使用 PVS-Studio for C# 分析 GitLab 中的合併請求
作業成功 ——成功了,一切都好。 現在您可以測試您所做的事情。

工作示例

作為工作範例,讓我們創建一個簡單的專案(在 )其中將包含多個文件。 之後,在另一個分支中,我們將只更改一個檔案並嘗試發出合併請求。

讓我們考慮兩種情況:修改後的檔案包含錯誤時和不包含錯誤時。 首先,舉一個有錯誤的例子。

假設master分支中有一個文件 程序.cs,它不包含錯誤,但在另一個分支中,開發人員添加了錯誤代碼並想要發出合併請求。 他犯了什麼錯誤並不重要,重要的是它確實存在。 例如,操作員忘記了 (是的, 大錯特錯):

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

我們來看一個有錯誤的例子的分析結果。 另外為了確保只解析一個文件,我添加了標誌 -r 到 pvs-studio-dotnet 啟動線:

使用 PVS-Studio for C# 分析 GitLab 中的合併請求
我們看到分析器發現了錯誤並且不允許合併分支。

讓我們檢查一下範例是否有錯誤。 更正代碼:

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

合併請求分析結果:

使用 PVS-Studio for C# 分析 GitLab 中的合併請求
可以看到,沒有發現錯誤,任務執行成功,這正是我們想要檢查的。

結論

在合併分支之前清除壞程式碼是非常方便和愉快的。 因此,如果您使用 CI/CD,請嘗試嵌入靜態分析器進行檢查。 而且,這非常簡單。

感謝您的關注。

使用 PVS-Studio for C# 分析 GitLab 中的合併請求
如果您想與英語讀者分享這篇文章,請使用翻譯連結:Nikolay Mironov。 使用 PVS-Studio for C# 分析 GitLab 中的合併請求.

來源: www.habr.com

添加評論