SonarQube系列-通过配置扫描分析范围,聚焦关键问题
在许多情况下,你可能不希望分析项目中每个源文件的各个方面。例如,项目可能包含生成的代码、库中的源代码或有意复制的代码。在这种情况下,跳过这些文件分析的部分或全部方面是有意义的,从而消除干扰并将焦点缩小到真正重要的问题上。
如果SonarQube的结果不相关,那么没有人会想要使用它。这就是为什么精确配置每个项目要分析的内容是非常重要的一步。
为了帮助缩小焦点,Sonar Qube提供了几个选项来精确配置将要分析的内容和方式。
- 完全忽略一些文件或目录
- 从问题中排除文件或目录,但分析所有其它方面
- 从重复性中排除文件或目录,但分析所有其它方面
- 从覆盖率中排除文件或目录,但分析其它所有方面
你可以在全局或项目级别配置它们。
定义分析范围的大多数属性都可以在Sonar Qube UI中定义。其他参数必须在scanner调用中或在适当的配置文件中明确设置,
设置初始分析范围
分析的初始范围由以下参数控制:
sonar.sources
定义了项目中非测试代码的初始分析范围。sonar.tests
定义了项目中测试代码的初始分析范围。
这些参数定义了分析范围调整的起点:
- 根本不会分析这些参数定义的范围之外的文件。
- 除非通过进一步调整(排除、包含等)排除,否则将分析这些参数定义范围内的文件。
此外,这些参数包括:
- 仅在项目级别设置。这些参数没有全局的、服务器级别的等效参数。
- 由Sonar Scanner自动设置,在配置文件中显式设置,或在调用Scanner命令行上设置。这些参数没有UI设置。
sonar-project.properties
- 显式设置,并且两者都接受逗号分隔的路径列表。不支持使用通配符的模式匹配。
测试/非测试代码的作用域是分开的
测试代码和非测试代码是有区别的,因为
- 对这两个类别应用了不同的分析规则。
- 这两个类别具有不同的指标
- 测试代码不计入许可证定义的代码行数限制。
- 测试代码不计入覆盖率(您不必测试测试代码)
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
示例
假设您的存储库看起来像这样,您的源代码和测试代码在顶层明确分离:
在这种情况下,您可以像这样设置:sonar.sources 和 sonar.tests
如果在文件中配置范围,它将如下所示: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 位置位于:(新旧版本位置会有细微差异
)
- 管理>配置>常规设置(用于全局设置)
- 项目设置>常规设置(适用于项目级设置)
在全局级别进行的任何设置都将应用于所有项目,除非在项目级别被覆盖(唯一的例外是上面讨论的全局排除参数)
特定文件的排除和包含
如果项目的目录结构没有在顶层将源代码
与测试代码
完全分开,则可能需要使用排除项和包含项来调整范围。
:::warning
包含项和排除项不应是初始分析配置的一部分。建议仅设置它们以解决问题。例如,当您注意到某个分析选取了您不想分析的文件时。
:::
全局级别设置
Administration > Configuration > General Settings > Analysis Scope > A. File Exclusions
项目级别设置
Project Settings > General Settings > Analysis Scope > A. File Exclusions
针对项目级配置,要进行如下参数配置:
- 在配置文件中设置它们
<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**
)进行解释的。
排除项 和 包含项 建立在上述范围基础上,仅仅充当筛选器得作用。它们只会减少可分析集中的文件数量,从不添加到分析集合范围中。
示例
假设您的代码库看起来像这样,您的测试代码与源代码混合在一起:
你可以这样定义你的,包括整个目录:sonar.sources = src/
然后将“源文件排除项(键)”设置为sonar.exclusions``=src/**/test/**/*
结果是要扫描的源文件集是减去每个子目录下的所有内容:src test
要定义测试文件,首先设置为整个目录:sonar.tests= src/
然后将“测试文件包含(键)”设置为sonar.test.inclusions =src/**/test/**/*
结果是要扫描的源文件集是下的所有内容_减去所有不是_子目录的内容:src test
如果在文件中配置范围,它将如下所示: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。
按文件类型设置范围
大多数语言都提供了一种将分析范围限制为与一组扩展名匹配的文件的方法。您可以为每种语言指定一个或多个后缀(文件扩展名)。
例如,对于 C 语言,.c 和 .h是默认设置
通过参数key设置时,可使用相应参数sonar.<LANGUAGE>.file.suffixes
重复的排除
Administration > General Settings > Analysis Scope > Duplications
用于从重复检测机制中排除某些源文件的模式。该值是相对于当前工作目录的路径匹配模式的逗号分隔列表。
忽略问题
可使用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
根据内容忽略文件中的问题
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 设置它。
从特定文件中排除特定规则
您可以通过组合由规则键模式** **和_文件路径模式_组成的一对或多对字符串来防止将特定规则应用于特定文件。
然而,该参数的关键是 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
进行检查
:::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 设置它。
示例
:::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_
参数指定源代码目录的范围 - 文件后缀:许多语言都提供了限制文件后缀名的的参数,’配置’–>’通用’–>’[语言]’,设置File suffixes属性
- 再从上述范围内选择指定文件,缩小关注的文件范围
_sonar.exclusions/sonar.test.exclusions_
设置分析除指定文件以外的所有文件_sonar.inclusions/sonar.test.inclusions_
设置仅仅分析指定的文件
- 针对具体的问题,再通过排除重复,忽略错误,实现更细粒度的控制
如下图所示,通过四种不同的方法可将分析范围缩小到与开发团队相关的源代码。
:::warning