SquiggleCop.Tool 1.0.13
dotnet tool install --global SquiggleCop.Tool --version 1.0.13
dotnet new tool-manifest # if you are setting up this repo dotnet tool install --local SquiggleCop.Tool --version 1.0.13
#tool dotnet:?package=SquiggleCop.Tool&version=1.0.13
nuke :add-package SquiggleCop.Tool --version 1.0.13
SquiggleCop
防止意外的 .NET (Roslyn) 分析器配置更改。
在 .NET 构建中对诊断警告和错误级别进行配置的方法有很多,而了解它们之间的相互作用并获得正确的配置可能很困难。.NET/MSBuild 支持所有这些机制(以及可能更多!)来配置启用哪些分析器以及它们的严重级别:
- 在 SDK 中提供的分析器(文档)
- 分析器 NuGet 包(示例)
.editorconfig
(文档).globalconfig
(文档).ruleset
(文档)WarningLevel
(文档)AnalysisLevel
(文档)TreatWarningsAsErrors
(文档)WarningsAsErrors
(文档)WarningsNotAsErrors
(文档)NoWarn
(文档)
这需要跟踪很多东西!
使用 SquiggleCop,任何对项目文件或构建脚本的更改都会生成一个易于理解(并diff!)的基线文件,显示更改的结果
<table> <tr> <th>代码更改</th> </tr> <tr> <td>
--- a/sample.csproj
+++ b/sample.csproj
@@ -3,7 +3,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
- <AnalysisLevel>5</AnalysisLevel>
+ <AnalysisLevel>6</AnalysisLevel>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</td> <tr> <th>基线文件diff</th> </tr> <tr> <td>
--- a/SquiggleCop.Baseline.yaml
+++ b/SquiggleCop.Baseline.yaml
@@ -57,8 +57,8 @@
- {Id: CA1401, Title: P/Invokes should not be visible, Category: Interoperability, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
- {Id: CA1416, Title: Validate platform compatibility, Category: Interoperability, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: false}
- {Id: CA1417, Title: Do not use 'OutAttribute' on string parameters for P/Invokes, Category: Interoperability, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: false}
-- {Id: CA1418, Title: Use valid platform string, Category: Interoperability, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [None], IsEverSuppressed: true}
-- {Id: CA1419, Title: Provide a parameterless constructor that is as visible as the containing type for concrete types derived from 'System.Runtime.InteropServices.SafeHandle', Category: Interoperability, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [None], IsEverSuppressed: true}
+- {Id: CA1418, Title: Use valid platform string, Category: Interoperability, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [Warning], IsEverSuppressed: false}
+- {Id: CA1419, Title: Provide a parameterless constructor that is as visible as the containing type for concrete types derived from 'System.Runtime.InteropServices.SafeHandle', Category: Interoperability, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [Note], IsEverSuppressed: false}
- {Id: CA1420, Title: 'Property, type, or attribute requires runtime marshalling', Category: Interoperability, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [None], IsEverSuppressed: true}
- {Id: CA1421, Title: This method uses runtime marshalling even when the 'DisableRuntimeMarshallingAttribute' is applied, Category: Interoperability, DefaultSeverity: Note, IsEnabledByDefault: true, EffectiveSeverities: [None], IsEverSuppressed: true}
- {Id: CA1422, Title: Validate platform compatibility, Category: Interoperability, DefaultSeverity: Warning, IsEnabledByDefault: true, EffectiveSeverities: [None], IsEverSuppressed: false}
</td> </tr> </table>
SquiggleCop 解析编译器输出,创建包含所有 .NET (Roslyn) 分析规则及其配置严重级别的基准文件。该基准文件应该纳入版本控制。在后续执行中,会将新的基准与现有文件进行比较。如果基准不匹配,则可能是意外更改了配置,应予以修复,或者应更新基准以记录新的预期配置。
SquiggleCop 以 MSBuild 任务和 CLI 工具形式提供,方便将其集成到现有的开发流程中。
入门
使用 SARIF 日志
SquiggleCop 使用 SARIF v2.1 文件来实现其功能。SquiggleCop 会在需要时自动启用 SARIF 日志,并将它们放在 obj/
文件夹中。如果您想要/需要自定义 SARIF 输出路径,请参阅 设置 SARIF 输出路径。
CLI 工具
CLI 工具旨在用于临时代码验证和与基准文件交互。通过运行以下命令安装 CLI 工具
dotnet tool install SquiggleCop.Tool
要生成或比较新的基准,运行 generate
命令,如下所示
Usage: dotnet squigglecop generate [--auto-baseline] [--output <String>] [--context <Int32>] [--help] sarif
Arguments:
0: sarif The SARIF log to generate a baseline for (Required)
Options:
-a, --auto-baseline Automatically update baseline if necessary
-o, --output <String> The output path for the baseline file
-c, --context <Int32> Number of context lines to use in the diff (Default: 3)
-h, --help Show help message
MSBuild 任务
Tasks 包会自动将 SquiggleCop 整合到 MSBuild 构建,旨在作为大型构建的一部分生成基准,并持续验证基准以防止构建发生意外更改。
按照这样添加 Tasks 包
dotnet add package SquiggleCop.Tasks
如果您使用集中式包管理 (CPM),则可以使用 GlobalPackageReference
将 SquiggleCop 自动添加到每个项目中。
<Project>
<ItemGroup>
<GlobalPackageReference Include="SquiggleCop.Tasks" Version="{{version}}" />
</ItemGroup>
</Project>
如果新的基准与现有文件不匹配,SquiggleCop 将发出 MSBuild 警告 SQ2000: 基准不匹配
。您可以使用 SquiggleCop CLI 创建新的基准,或者通过设置来启用自动基准
<Project>
<PropertyGroup>
<SquiggleCop_AutoBaseline>true</SquiggleCop_AutoBaseline>
</PropertyGroup>
</Project>
启用自动基准后,在提交代码之前请务必审查基准文件中的任何更改。
[!警示] 如果您启用自动基准,请确保在 CI 中将其关闭。否则 SquiggleCop 可能无法警告关于潜在问题!
基准文件的架构
基准文件是一个具有重复结构的 YAML 文件。以下是一个单独规则条目的示例
- Id: CA1000
Title: Do not declare static members on generic types
Category: Design
DefaultSeverity: Note
IsEnabledByDefault: true
EffectiveSeverities:
- Note
- None
IsEverSuppressed: true
ID
这是诊断的 ID。
标题
诊断的标题。请注意,某些诊断可能有多个针对单个 ID 的标题。例如,根据配置方式的不同,IDE0053
的标题可以是 "为 lambda 表达式使用块体" 或 "为 lambda 表达式使用表达式体"。
类别
诊断的类别。更多详细信息,请参阅 分析器配置。
默认严重性
诊断的默认严重性。
默认启用
如果诊断被默认启用。
有效严重性
在考虑所有选项(即规则集、.editorconfig、.globalconfig 等)后,诊断的严重性或严重性。一种常见的方法是使用不同的 .editorconfig 文件为代码库的各个部分使用不同的严重性。请注意,内联抑制将不会显示在这里,它们会在 IsEverSuppressed
中显示。
是否曾抑制
如果诊断在调用点被抑制,则为 true
。常见的做法是
using 指令
SupressMessage
<AnalysisLevel>
诊断基准不匹配
调试 CI 中发生但在本地未发生的基准不匹配的最简单方法是
- 上传构建中的 SARIF 文件
- 使用 SquiggleCop CLI 从 CI SARIF 文件生成新的基准,并将其与已签入的基准进行比较
上传 SARIF 报告
将您的SARIF报告作为管道工件上传,以便缩小问题范围。
GitHub Actions
- name: Upload SARIF logs
uses: actions/upload-artifact@v4
if: success() || failure() # Upload logs even if the build failed
with:
name: SARIF logs
path: ./artifacts/**/*.sarif # Modify as necessary to point to your sarif files
Azure DevOps
- task: CopyFiles@2
displayName: 'Copy SARIF files to Artifact Staging'
condition: succeededOrFailed() # Upload logs even if the build failed
inputs:
contents: 'artifacts\**\*.sarif' # Modify as necessary to point to your sarif files
targetFolder: '$(Build.ArtifactStagingDirectory)\sarif'
cleanTargetFolder: true
overWrite: true
- task: PublishPipelineArtifact@1
displayName: 'Publish SARIF files as Artifacts'
condition: succeededOrFailed() # Upload logs even if the build failed
inputs:
targetPath: '$(Build.ArtifactStagingDirectory)\sarif'
publishLocation: 'pipeline'
artifact: 'sarif'
基线不匹配的常见原因
- 本地与CI的MSBuild参数不同
- 检查设置是否基于
$(ContinuousIntegrationBuild)
属性,一些CI提供商会设置此属性
- 检查设置是否基于
- 不同的SDK版本
- 使用
global.json
在本地和CI中设置相同的SDK版本(查看详情) - 新的SDK功能版本可能引入新的分析器,因此我们建议将
rollForward
限制为补丁更新,或者完全禁用
- 使用
高级配置
设置SARIF输出路径
如果ErrorLog
属性未设置,SquiggleCop会在CoreCompile
目标之前将其设置。要设置自定义的SARIF输出路径,将属性设置为如下内容
<ErrorLog>$(MSBuildProjectFile).sarif,version=2.1</ErrorLog>
[!TIP] 我们建议您将
*.sarif
添加到您的.gitignore
文件中
或设置命令行属性以作为即兴验证的一部分
dotnet build -p:ErrorLog=diagnostics.sarif%2cversion=2.1
[!IMPORTANT] 日志路径中的逗号或分号字符必须进行XML转义
替代基线路径
默认情况下,SquiggleCop期望基线文件名为SquiggleCop.Baseline.yaml
,并位于项目文件旁边。要指定基线文件的自定义路径,向AdditionalFiles
中添加指向基线文件的条目
<Project>
<ItemGroup>
<AdditionalFiles Include="/path/to/SquiggleCop.Baseline.yaml" />
</ItemGroup>
</Project>
TreatWarningsAsErrors
通常,项目在CI构建中使用TreatWarningsAsErrors
来防止警告进入主分支。
但是,切换TreatWarningsAsErrors 也会改变分析器诊断的有效严重性,这可能导致基线文件中不必要的更改。如果您的项目或开发工作流在CI和本地开发之间切换TreatWarningsAsErrors,还应根据相同的逻辑切换SquiggleCop_Enabled
属性。
以下是一个示例,根据ContinuousIntegrationBuild
属性切换TreatWarningsAsErrors
<Project>
<PropertyGroup>
<PedanticMode Condition=" '$(PedanticMode)' == '' ">$([MSBuild]::ValueOrDefault('$(ContinuousIntegrationBuild)', 'false'))</PedanticMode>
<TreatWarningsAsErrors>$(PedanticMode)</TreatWarningsAsErrors>
<SquiggleCop_Enabled>$(PedanticMode)</SquiggleCop_Enabled>
</PropertyGroup>
</Project>
编码与换行符
基线文件以UTF-8编码编写,不带BOM。基线文件在所有平台上使用\n
换行符。SquiggleCop自己的差异算法忽略换行符差异,以避免不必要的麻烦,但是根据您的.gitattributes
设置,换行符可能被规范化为其他值。如果Git的换行符规范化导致问题,请考虑在您的.gitattributes
文件中设置以下内容
# Store SquiggleCop baselines as lf regardless of platform
SquiggleCop.Baseline.yaml text eol=lf
然后运行git add --renormalize .
以更新Git并用重新规范化的文件替换。
图标“分形”由Burmich Bohdan来自Noun Project提供(CC BY 3.0)(查看详情)
产品 | 版本 兼容的和额外的计算目标框架版本。 |
---|---|
.NET | net6.0兼容。 net6.0-android已计算。 net6.0-ios已计算。 net6.0-maccatalyst已计算。 net6.0-macos已计算。 net6.0-tvos已计算。 net6.0-windows已计算。 net7.0已计算。 net7.0-android已计算。 net7.0-ios已计算。 net7.0-maccatalyst已计算。 net7.0-macos已计算。 net7.0-tvos已计算。 net7.0-windows已计算。 net8.0已计算。 net8.0-android已计算。 net8.0-browser已计算。 net8.0-ios已计算。 net8.0-maccatalyst已计算。 net8.0-macos已计算。 net8.0-tvos已计算。 net8.0-windows已计算。 |
此包没有依赖项。