SonarQube系列-透過配置掃描分析範圍,聚焦關鍵問題

DevOps在路上發表於2023-10-12

在許多情況下,你可能不希望分析專案中每個原始檔的各個方面。例如,專案可能包含生成的程式碼、庫中的原始碼或有意複製的程式碼。在這種情況下,跳過這些檔案分析的部分或全部方面是有意義的,從而消除干擾並將焦點縮小到真正重要的問題上。

如果SonarQube的結果不相關,那麼沒有人會想要使用它。這就是為什麼精確配置每個專案要分析的內容是非常重要的一步。
為了幫助縮小焦點,Sonar Qube提供了幾個選項來精確配置將要分析的內容和方式。

  • 完全忽略一些檔案或目錄
  • 從問題中排除檔案或目錄,但分析所有其它方面
  • 從重複性中排除檔案或目錄,但分析所有其它方面
  • 從覆蓋率中排除檔案或目錄,但分析其它所有方面

你可以在全域性或專案級別配置它們。
定義分析範圍的大多數屬性都可以在Sonar Qube UI中定義。其他引數必須在scanner呼叫中或在適當的配置檔案中明確設定,

設定初始分析範圍

分析的初始範圍由以下引數控制:

  • sonar.sources定義了專案中非測試程式碼的初始分析範圍。
  • sonar.tests定義了專案中測試程式碼的初始分析範圍。

這些引數定義了分析範圍調整的起點:

  • 根本不會分析這些引數定義的範圍之外的檔案。
  • 除非透過進一步調整(排除、包含等)排除,否則將分析這些引數定義範圍內的檔案。

此外,這些引數包括:

  • 僅在專案級別設定。這些引數沒有全域性的、伺服器級別的等效引數。
  • 由Sonar Scanner自動設定,在配置檔案中顯式設定,或在呼叫Scanner命令列上設定。這些引數沒有UI設定。sonar-project.properties
  • 顯式設定,並且兩者都接受逗號分隔的路徑列表。不支援使用萬用字元的模式匹配。

測試/非測試程式碼的作用域是分開的

測試程式碼和非測試程式碼是有區別的,因為

  • 對這兩個類別應用了不同的分析規則。
  • 這兩個類別具有不同的指標
  • 測試程式碼不計入許可證定義的程式碼行數限制。
  • 測試程式碼不計入覆蓋率(您不必測試測試程式碼)

image.png

Maven、Gradle和.NET的自動設定

如果使用 SonarScanner for Maven、SonarScanner for Gradle 或 SonarScanner for .NET 分析程式碼,則會根據專案配置中的資訊自動確定引數,不必顯式設定引數。
如果您確實顯式設定了引數(例如,在 Maven 的情況下,這將覆蓋自動pom.xml 中的 sonar.sources, sonar.tests

其他場景的預設設定

如果您沒有使用Maven、Gradle或。NET

  • 預設情況下,設定為當前工作目錄(路徑)sonar.sources
  • 預設情況下,未設定 sonar.tests

顯式設定

如果預設值不合適(例如_,如果您有測試_程式碼),則必須在掃描程式呼叫或相應的配置檔案中顯式設定引數(請參閱分析引數)。
顯式設定時,兩者兼而有之,並採用逗號分隔的目錄或檔案列表。sonar.sourcessonar.tests

  • 列表中的條目是簡單路徑。不允許使用萬用字元(、 和 )***?
  • 列表中的目錄意味著包含所有可分析的檔案和其下方的目錄遞迴。列表中的單個檔案表示包含該檔案。
  • 路徑是相對於專案基目錄進行解釋的。基目錄由您正在使用的掃描程式定義。在大多數情況下,這是專案的根目錄。如果您使用的是SonarScanner CLI,則基目錄將是呼叫該工具的當前目錄(儘管可以使用引數將其覆蓋)。sonar.projectBaseDir

示例

假設您的儲存庫看起來像這樣,您的原始碼和測試程式碼在頂層明確分離:
image.png

在這種情況下,您可以像這樣設定:sonar.sources 和 sonar.tests
image.pngimage.png
如果在檔案中配置範圍,它將如下所示:sonar-project.properties, 無需進一步微調

# Define separate root directories for sources and tests
sonar.sources = src/
sonar.tests = test/

萬用字元模式

SonarQube中可以使用以下萬用字元, 下面討論的大多數引數都使用萬用字元模式

符號 匹配
* 匹配一個或多個字元 (不包括目錄分隔符 )
** 匹配一個或多個目錄
? 匹配一個字元 (不包括目錄分隔符 )

:::info

  • The pattern **/*.css
    • matches anyDirectory/anyFile.css
    • doesn't match org/sonar.api/MyBean.java
  • The pattern **/*Bean.java
    • matches org/sonar.api/MyBean.java
    • doesn't match org/sonar/util/MyDTO.java
  • The pattern **/*Bean?.java
    • matches org/sonar/util/MyOtherBean1.java
    • doesn't match org/sonar/util/MyOtherBean.java
  • The pattern org/sonar/*
    • matches org/sonar/MyClass.java
    • doesn't match org/sonar/util/MyClassUtil.java
  • The pattern org/sonar/**/*
    • matches org/sonar/MyClass.java
    • doesn't match org/radar/MyClass.java
      :::

透過UI設定分析過濾範圍

除非另有說明,否則以下所有引數均可在全域性和專案級別設定。設定的 UI 位置位於:(新舊版本位置會有細微差異

  • 管理>配置>常規設定(用於全域性設定)
  • 專案設定>常規設定(適用於專案級設定)

在全域性級別進行的任何設定都將應用於所有專案,除非在專案級別被覆蓋(唯一的例外是上面討論的全域性排除引數)
image.png

特定檔案的排除和包含

如果專案的目錄結構沒有在頂層將原始碼測試程式碼完全分開,則可能需要使用排除項和包含項來調整範圍。
:::warning
包含項和排除項不應是初始分析配置的一部分。建議僅設定它們以解決問題。例如,當您注意到某個分析選取了您不想分析的檔案時。
:::

全域性級別設定

Administration > Configuration > General Settings > Analysis Scope > A. File Exclusions
image.png
image.png

專案級別設定

Project Settings > General Settings > Analysis Scope > A. File Exclusions
image.png
針對專案級配置,要進行如下引數配置:

  • 在配置檔案中設定它們<YOUR_PROJECT>/sonar-project.properties
<properties>
  <!-- 找到pom檔案的properties標籤,在裡面新增如下配置 -->
  <!-- Sonar掃描需要排除的包、類 多個用英文 , 隔開 -->
  <sonar.exclusions>
    <!-- 指定需要排除的包 -->
    src/main/java/com/zhibo/**/model/**,
    src/main/java/com/zhibo/**/vo/**,
    <!-- 排除以Enum結尾的類 -->
    src/main/java/com/zhibo/**/*Enum.*
  </sonar.exclusions>
</properties>
  • 呼叫掃描程式時,在命令列上設定它們。
  • 對於 Maven、Gradle 或 .NET 專案,請在相應的特定於框架的配置檔案中設定它們。
# 排除所有Bean結尾的類
# 匹配org/sonar.api/MyBean.java, org/sonar/util/MyOtherBean.java, org/sonar/util/MyDTO.java等
sonar.exclusions=**/*Bean.java,**/*DTO.java

# 排除src/main/java/org/sonar目錄下所有檔案
# 但不包括其子目錄下的檔案
sonar.exclusions=src/main/java/org/sonar/*

# 排除bank目錄及其子目錄下的所有檔案
sonar.exclusions=bank/**/*

# 排除bank目錄及其子目錄下的所有.cs檔案
sonar.exclusions=bank/**/*.cs

注意:萬用字元模式是相對於專案基目錄(**sonar.sources sonar.tests**)進行解釋的。
排除項 和 包含項 建立在上述範圍基礎上,僅僅充當篩選器得作用。它們只會減少可分析集中的檔案數量,從不新增到分析集合範圍中。

示例

假設您的程式碼庫看起來像這樣,您的測試程式碼與原始碼混合在一起:
image.png
你可以這樣定義你的,包括整個目錄:sonar.sources = src/
image.png
然後將“原始檔排除項(鍵)”設定為sonar.exclusions``=src/**/test/**/*
結果是要掃描的原始檔集是減去每個子目錄下的所有內容:src test
image.png
要定義測試檔案,首先設定為整個目錄:sonar.tests= src/
image.png
然後將“測試檔案包含(鍵)”設定為sonar.test.inclusions =src/**/test/**/*
結果是要掃描的原始檔集是下的所有內容_減去所有不是_子目錄的內容:src test
image.png
如果在檔案中配置範圍,它將如下所示:sonar-project.properties

# Define the same root directory for sources and tests
sonar.sources = src/
sonar.tests = src/

# Include test subdirectories in test scope
sonar.test.inclusions = src/**/test/**/*

# Exclude test subdirectories from source scope
sonar.exclusions = src/**/test/**/*

程式碼覆蓋率的排除

配置不應該檢測程式碼覆蓋率的檔案。引數的值是相對於當前工作目錄的路徑匹配模式的逗號分隔列表
Administration > General Settings > Analysis Scope > Code Coverage > Coverage Exclusions。
image.png

按檔案型別設定範圍

大多數語言都提供了一種將分析範圍限制為與一組副檔名匹配的檔案的方法。您可以為每種語言指定一個或多個字尾(副檔名)。
例如,對於 C 語言,.c 和 .h是預設設定
透過引數key設定時,可使用相應引數sonar.<LANGUAGE>.file.suffixes
image.png

重複的排除

Administration > General Settings > Analysis Scope > Duplications
用於從重複檢測機制中排除某些原始檔的模式。該值是相對於當前工作目錄的路徑匹配模式的逗號分隔列表。
image.png

忽略問題

可使用SonarQube忽略某些元件和某些編碼規則的問題。Administration > General Settings > Analysis Scope > Issues。
請注意,以下屬性只能透過Web介面設定,因為它們是多值的。

  • Ignore Issues on Files
  • Ignore Issues in Blocks
  • Ignore Issues on Multiple Criteria
  • Restrict Scope of Coding Rules

image.png

根據內容忽略檔案中的問題

Analysis Scope > D. Issue Exclusions > Ignore Issues on Files
可以忽略包含與給定正規表示式匹配的程式碼塊的檔案。這些檔案中的所有問題以及安全熱點都將被忽略。在此設定中,可以輸入一個或多個正規表示式模式。任何至少包含一種指定模式的檔案都將被忽略。
例如,假設您在 Java 專案中生成了希望排除的類檔案。這些檔案看起來像這樣:

@Generated("com.example.generated")
public class GeneratedClass extends AnotherClass {
    // Some generated code
}

要排除所有此類檔案,您可以將此引數設定為:

@Generated\(".*"\)
#如果在檔案中找到此正規表示式,則會忽略整個檔案

請注意,由於該值是正規表示式,因此您需要轉義()括號字元並使用表示式 .* 匹配這些括號之間的字串。
然而,該引數的關鍵是 sonar.issue.ignore.allfile,因為它是一個多值屬性,所以我們建議僅透過 UI 設定它。

忽略檔案中的塊

Analysis Scope > D. Issue Exclusions > Ignore Issues on Blocks
您可以忽略檔案中的特定程式碼塊,同時繼續掃描檔案的其餘部分。要忽略的塊在檔案內由開始結束字串分隔。您可以透過正規表示式指定這些開始和結束字串。這些塊內的所有問題以及安全熱點都將被忽略。您可以輸入一對或多對正規表示式模式。任何檔案中位於起始模式與其相應的結束模式之間的任何程式碼都將被忽略
注意:

  • 如果找到第一個正規表示式但未找到第二個正規表示式,則檔案末尾被視為塊的末尾。
  • 正規表示式不匹配多行。

例如,假設想忽略方法 doSomethingElse 中使用塊分隔符的程式碼,如下所示:

public class MyClass {
    public MyClass() {
        ...
    }

    public void doSomething() {
        ...
    }

    // BEGIN-NOSCAN
    public void doSomethingElse()
    {
        ...
    }
    // END-NOSCAN
}

您可以指定以下正規表示式:
塊的開始 \s*//\s*START-NOSCAN
塊結束:** **\s*//\s*END-NOSCAN
這些正規表示式可確保無論行註釋字元 ( ) 周圍的空格數量如何,都可以識別起始塊分隔符和結束塊分隔符//
該引數的關鍵是 sonar.issue.ignore.block. 但是,由於它是一個多值屬性,因此我們建議僅透過 UI 設定它。
image.png

從特定檔案中排除特定規則

您可以透過組合由規則鍵模式** **和_檔案路徑模式_組成的一對或多對字串來防止將特定規則應用於特定檔案。
然而,該引數的關鍵是 sonar.issue.ignore.multicriteria,,因為它是一個多值屬性,所以我們建議僅透過 UI 設定。

規則鍵模式

規則鍵模式由規則儲存庫名稱、後跟冒號、規則鍵或規則名稱通配模式組成。
例如:

  • java:S195與java規則庫中的規則 rule S1195完全匹配。
  • java:Naming匹配java儲存庫中規則名稱中包含字串Naming的所有規則。

您可以在規則定義中找到規則定義的完全限定規則 ID 和規則名稱。
例如,對於 此規則

  • 規則ID: css:S4655
  • 規則名稱: "!important" should not be used on "keyframes"

檔案路徑模式

檔案路徑模式使用上述路徑匹配格式來指定一組目錄或檔案。

示例

如下圖所示,這個配置將忽略所有檔案的 針對規則 java:S2259 進行檢查
image.png
:::success

  • 忽略所有檔案中的所有問題:
    • 規則關鍵模式: *
    • 檔案路徑模式: */
  • 忽略檔案中的所有問題 bank/ZTR00021.cbl:
    • 規則關鍵模式: *
    • 檔案路徑模式: bank/ZTR00021.cbl
  • 忽略直接位於 Java 包中 com.foo但不位於其子包中的檔案中的所有問題:
    • 規則關鍵模式: *
    • 檔案路徑模式: com/foo/*
  • cpp:Union 忽略目錄 object 及其子目錄 中檔案中所有違反編碼規則的問題 :
    • 規則關鍵模式: cpp:Union
    • 檔案路徑模式: object/**/*
      :::

將特定規則應用於特定檔案

  • Global level: Administration > Configuration > General Settings > Analysis Scope > D. Issue Exclusions > Restrict Scope of Coding Rules
  • Project level: Project Settings > General Settings > Analysis Scope > D. Issue Exclusions > Restrict Scope of Coding Rules

設定這些引數的機制與上面的 sonar.issue.**ignore**.multicriteria相同:每個條目都包含一個規則鍵模式和一個檔案路徑模式。
不同的是,在這種情況下,這意味著指定的規則將僅應用於指定的檔案集。
該引數的關鍵是 sonar.issue.**enforce**.multicriteria. 但是,由於它是一個多值屬性,因此我們建議僅透過 UI 設定它。
image.png

示例

:::success

  • 只檢查“Bean”物件上的“Magic Number”規則,而不檢查其他任何東西:
    • 規則鍵模式:checkstyle:com.puppycrawl.tools.checkstyle.checks.coding.MagicNumberCheck
    • 檔案路徑模式:**/*Bean.java
  • 僅檢查規則_Prevent GO TO statement from transferring control outside current module on COBOL programs_ in the directories:bank/creditcardbank/bankcard
    • 規則鍵模式 1:cobol:COBOL.GotoTransferControlOutsideCurrentModuleCheck
    • 檔案路徑模式 1:bank/creditcard/**/*
    • 規則鍵模式 2:cobol:COBOL.GotoTransferControlOutsideCurrentModuleCheck
    • 檔案路徑模式 2:bank/bankcard/**/*
      :::

總結

有以下幾種方式來縮小要分析原始碼的範圍,如下:

  1. 首先設定初始化分析範圍:設定_sonar.sources_引數指定原始碼目錄的範圍
  2. 檔案字尾:許多語言都提供了限制檔案字尾名的的引數,’配置’–>’通用’–>’[語言]’,設定File suffixes屬性
  3. 再從上述範圍內選擇指定檔案,縮小關注的檔案範圍
    • _sonar.exclusions/sonar.test.exclusions_ 設定分析除指定檔案以外的所有檔案
    • _sonar.inclusions/sonar.test.inclusions_ 設定僅僅分析指定的檔案
  4. 針對具體的問題,再透過排除重複,忽略錯誤,實現更細粒度的控制

如下圖所示,透過四種不同的方法可將分析範圍縮小到與開發團隊相關的原始碼。
:::warning

  • 源目錄(Source Directories)
  • 檔案字尾(File Suffixes)
  • 選擇檔案(Choosing Files)
    • 原始檔排除(Source File Exclusions)
    • 測試檔案排除(Test File Exclusions)
    • 原始檔包含(Source File Inclusions)
    • 測試檔案包含(Test File Inclusions)
      :::
      image.pngimage.png

相關文章