在寫在 CI 流程中忽略 SonarQube 的特定分析規則這篇文章的時候,發現了一個有趣的資訊,SonarQube Scanner for MSBuild v2.0 這個版本支援第三方 Roslyn 分析器,這對於我們來說是一個很好的消息,因為這樣我們就可以在 SonarQube 上使用第三方的 Roslyn 分析器。

緣由是這樣的,當我在查看某專案的分析結果,在透過 Why is this an issue 的時候,像是 roslyn:CA1822 這個 Roslyn 所提出的建議中,在詳細說明中沒有提供規則連結,也就是像下圖 csharpsquid:S3776 規則旁邊的連結符號。

csharpsquid:S3776

roslyn:CA1822

因此就納悶這個分析規則是怎麼來的,才發覺有一些分析規則是來自於第三方的 Roslyn 分析器,而這些 Roslyn 分析器如何判斷的作法也放在 dotnet/roslyn-analyzers GitHub 上,有興趣的人可以去看看。

由於這些規則不是 SonarQube 平台上的內建規則,而是從 SonarQube Scanner 中透過第三方的 Roslyn 分析器來提供建議,因此這些分析規則無法在 SonarQube 上直接關閉,因此若要調整所提供的建議,則需要自己製作 Roslyn plugin 來微調,詳細資訊參考 SonarSource/sonarqube-roslyn-sdk - Customizing the rules.xml fileSonarQube Scanner for MSBuild v2.0 released: support for third-party Roslyn analyzers 這篇的介紹。

後記

後來再查 Microsoft 的 Code Analysis 文件的時候,發現了 CA1822: Mark members as static 這個規則文件中有提到如何忽略這項警告,這邊列出 3 種比較有機會用到的方式。

第一種,當要抑制警告的範圍很小,只有在特定檔案或是只有幾行程式碼了話,可以使用前置處理器指示詞 (preprocessor directive) 的方式處理,如下範例中的 #pragma warning disable CA1822

    try { ... }
    catch (Exception e)
    {
#pragma warning disable CA2200 // Rethrow to preserve stack details
        throw e;
#pragma warning restore CA2200 // Rethrow to preserve stack details
    }

第二種,範圍很大,需要在整個專案中忽略這個警告,可以使用 SuppressMessageAttribute 的方式來隱藏專案或檔案特定部分的警告,此方法的詳細作法請參考官方文件

第三種是我比較喜歡的做法,同樣是處理範圍很大,需要在整個專案中忽略這個警告,我們可以使用 EditorConfig 或 AnalyzerConfig 設定檔來將該 Roslyn Analyzers 規則做調整,這樣除了不用在程式碼中加入額外的註解,也可以將規則集中在一個設定檔中管理。

使用 EditorConfig 設定檔的作法很簡單,只要在專案資料夾中(就是包含 .csproj 專案檔的資料夾中),新增一個 .editorconfig 檔案,並加入以下設定寫法:

[*.{cs,vb}]
dotnet_diagnostic.<rule-ID>.severity = none

此設定會針對 .cs.vb 檔案(可以根據你的需求做調整),將 <rule-ID> 的規則設定為 none,這樣就可以在整個專案中忽略這個警告,例如我要忽略 CA1822 這個規則,可以這樣寫:

[*.{cs,vb}]
dotnet_diagnostic.CA1822.severity = none

不過一般來說,EditorConfig 主要是會用在編輯版面的通用配置,因此如果是針對特定的分析器規則,我會更推薦建議使用 AnalyzerConfig 設定檔,他的設定方式和 EditorConfig 大致相同。

使用 AnalyzerConfig 設定檔,只要在專案資料夾或是方案資料夾中(就是包含 .csproj 專案檔或是 .sln 方案檔的資料夾中),新增一個 .globalconfig 檔案,並加入以下設定寫法:

is_global = true
<option_name> = <option_value>

is_global 的設定值,顧名思義就是套用至整個專案,接著設定規則的部分和 EditorConfig 一樣,例如我要忽略 CA1822 這個規則,可以這樣寫:

is_global = true
dotnet_diagnostic.CA1822.severity = none

如此一來,就可以忽略 Roslyn Analyzers 所提出的 CA1822 警告了,而且這樣的設定方式除了可以集中管理規則,SonarQube 也會讀取這些設定檔,因此在 SonarQube 上也不會再看到這些警告了。


參考資料:


Poy Chang

Trial and Error