SonarScanner (C#) 不遵守代码内 StyleCop 警告抑制

SonarScanner (C#) not honoring in-code StyleCop warning suppression

我正在尝试使用 SonarQube 为我的组织进行静态代码分析。 我们所有的 C# 项目都已经启用了 StyleCop,这在代码可读性方面帮助了我们很多。现在我们想利用SonarQube进行静态代码分析。

我按照 here 提供的指南在本地成功托管了 SonarQube 服务器。当代码中没有警告抑制时,我能够 运行 成功分析并生成 sonarqube 报告。

问题:Sonarqube 不考虑代码内警告抑制和 msbuild 失败。

我创建了一个示例 C# 控制台应用程序项目来演示我面临的问题。

StyleCop 已启用(已安装的 nuget:StyleCop.Analyzers v1.1.118)并将警告转换为错误。 以下是规则集的片段

...
...
...
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers">
...
...
<Rule Id="SA1307" Action="Error" />
...
...

该项目有以下文件: 1. Program.cs

// <copyright file="Program.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>

namespace StyleCopSonarQubeIssue
{
    /// <summary>
    /// The program class.
    /// </summary>
    internal class Program
    {
        /// <summary>
        /// Defines the entry point of the application.
        /// </summary>
        /// <param name="args">The arguments.</param>
        public static void Main(string[] args)
        {
            // Method intentionally left empty.
        }
    }
}

  1. SystemInfo.cs
// <copyright file="SystemInfo.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>

namespace StyleCopSonarQubeIssue
{
    using System.Runtime.InteropServices;

    /// <summary>
    /// The sytem info enum.
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public struct SystemInfo
    {
        /// <summary>
        /// Oem Id.
        /// </summary>
        public uint dwOemId;

        /// <summary>
        /// Page size.
        /// </summary>
        public uint dwPageSize;
    }
}

  1. packages.config
<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="StyleCop.Analyzers" version="1.1.118" targetFramework="net452" developmentDependency="true" />
</packages>
  1. GlobalSuppressions.cs
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Native code.", Scope = "member", Target = "~F:StyleCopSonarQubeIssue.SystemInfo.dwPageSize")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Native code.", Scope = "member", Target = "~F:StyleCopSonarQubeIssue.SystemInfo.dwOemId")]
  1. App.config(默认 - 无变化)

构建项目 - 成功

按照 SonarQube 的指导分析上述项目。

  1. SonarScanner.MSBuild.exe 开始 /k:"StyleCopSonarQubeIssue" /d:sonar.host.url="http://localhost:9000" /d:sonar.login=""

  2. MsBuild.exe /t:重建 执行此语句后您将出现以下错误:

Microsoft (R) Build Engine version 14.0.27530.0
Copyright (C) Microsoft Corporation. All rights reserved.

Build started 2019-07-22 11:17:25 AM.
The target "RazorCoreCompile" listed in a BeforeTargets attribute at "C:\Users\bshah\Documents\Visual Studio 2015\Projects\StyleCopSonarQubeIssue\StyleCopSonarQubeIssue\.sonarqube\bin\targets\SonarQube.Integration.targets (453,49)" does not exist in the project, and will be ignored.
Project "C:\Users\bshah\Documents\Visual Studio 2015\Projects\StyleCopSonarQubeIssue\StyleCopSonarQubeIssue\StyleCopSonarQubeIssue.csproj" on node 1 (Rebuild target(s)).
CoreClean:
  Creating directory "obj\Debug\".
GenerateBindingRedirects:
  No suggested binding redirects from ResolveAssemblyReferences.
CreateProjectSpecificDirs:
  Creating directory "C:\Users\bshah\Documents\Visual Studio 2015\Projects\StyleCopSonarQubeIssue\StyleCopSonarQubeIssue\.sonarqube\conf[=15=]".
CoreCompile:
  C:\Program Files (x86)\MSBuild.0\bin\csc.exe /noconfig /nowarn:1701,1702 /nostdlib+ /platform:anycpu32bitpreferred /errorreport:prompt /warn:4 /define:DEBUG;TRACE /highentropyva+ /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2\Microsoft.CSharp.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2\mscorlib.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2\System.Core.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2\System.Data.DataSetExtensions.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2\System.Data.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2\System.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2\System.Net.Http.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2\System.Xml.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2\System.Xml.Linq.dll" /debug+ /debug:full /filealign:512 /optimize- /out:obj\Debug\StyleCopSonarQubeIssue.exe /ruleset:"C:\Users\bshah\Documents\Visual Studio 2015\Projects\StyleCopSonarQubeIssue\StyleCopSonarQubeIssue\.sonarqube\conf[=15=]\merged.ruleset" /errorlog:"C:\Users\bshah\Documents\Visual Studio 2015\Projects\StyleCopSonarQubeIssue\StyleCopSonarQubeIssue\bin\Debug\StyleCopSonarQubeIssue.exe.RoslynCA.json" /subsystemversion:6.00 /target:exe /warnaserror- /utf8output /analyzer:C:\Users\bshah\AppData\Local\Temp\.sonarqube\resources[=15=]\Google.Protobuf.dll /analyzer:C:\Users\bshah\AppData\Local\Temp\.sonarqube\resources[=15=]\SonarAnalyzer.CSharp.dll /analyzer:C:\Users\bshah\AppData\Local\Temp\.sonarqube\resources[=15=]\SonarAnalyzer.dll /analyzer:C:\Users\bshah\AppData\Local\Temp\.sonarqube\resources\Google.Protobuf.dll /analyzer:C:\Users\bshah\AppData\Local\Temp\.sonarqube\resources\SonarAnalyzer.dll /analyzer:C:\Users\bshah\AppData\Local\Temp\.sonarqube\resources\SonarAnalyzer.VisualBasic.dll /analyzer:..\packages\StyleCop.Analyzers.1.1.118\analyzers\dotnet\cs\StyleCop.Analyzers.CodeFixes.dll /analyzer:..\packages\StyleCop.Analyzers.1.1.118\analyzers\dotnet\cs\StyleCop.Analyzers.dll /additionalfile:"C:\Users\bshah\Documents\Visual Studio 2015\Projects\StyleCopSonarQubeIssue\StyleCopSonarQubeIssue\.sonarqube\conf\cs\SonarLint.xml" /additionalfile:"C:\Users\bshah\Documents\Visual Studio 2015\Projects\StyleCopSonarQubeIssue\StyleCopSonarQubeIssue\.sonarqube\conf[=15=]\ProjectOutFolderPath.txt" GlobalSuppressions.cs Program.cs Properties\AssemblyInfo.cs SystemInfo.cs "C:\Users\bshah\AppData\Local\Temp\.NETFramework,Version=v4.5.2.AssemblyAttributes.cs"
  Using shared compilation with compiler from directory: C:\Program Files (x86)\MSBuild.0\bin
Program.cs(10,20): warning S1118: Add a 'protected' constructor or the 'static' keyword to the class declaration. [C:\Users\bshah\Documents\Visual Studio 2015\Projects\StyleCopSonarQubeIssue\StyleCopSonarQubeIssue\StyleCopSonarQubeIssue.csproj]
_CopyAppConfigFile:
  Copying file from "App.config" to "bin\Debug\StyleCopSonarQubeIssue.exe.config".
C:\Program Files (x86)\MSBuild.0\bin\Microsoft.Common.CurrentVersion.targets(3813,5): error MSB3030: Could not copy the file "obj\Debug\StyleCopSonarQubeIssue.exe" because it was not found. [C:\Users\bshah\Documents\Visual Studio 2015\Projects\StyleCopSonarQubeIssue\StyleCopSonarQubeIssue\StyleCopSonarQubeIssue.csproj]
Done Building Project "C:\Users\bshah\Documents\Visual Studio 2015\Projects\StyleCopSonarQubeIssue\StyleCopSonarQubeIssue\StyleCopSonarQubeIssue.csproj" (Rebuild target(s)) -- FAILED.

Build FAILED.

"C:\Users\bshah\Documents\Visual Studio 2015\Projects\StyleCopSonarQubeIssue\StyleCopSonarQubeIssue\StyleCopSonarQubeIssue.csproj" (Rebuild target) (1) ->
(CoreCompile target) -> 
  Program.cs(10,20): warning S1118: Add a 'protected' constructor or the 'static' keyword to the class declaration. [C:\Users\bshah\Documents\Visual Studio 2015\Projects\StyleCopSonarQubeIssue\StyleCopSonarQubeIssue\StyleCopSonarQubeIssue.csproj]


"C:\Users\bshah\Documents\Visual Studio 2015\Projects\StyleCopSonarQubeIssue\StyleCopSonarQubeIssue\StyleCopSonarQubeIssue.csproj" (Rebuild target) (1) ->
(CopyFilesToOutputDirectory target) -> 
  C:\Program Files (x86)\MSBuild.0\bin\Microsoft.Common.CurrentVersion.targets(3813,5): error MSB3030: Could not copy the file "obj\Debug\StyleCopSonarQubeIssue.exe" because it was not found. [C:\Users\bshah\Documents\Visual Studio 2015\Projects\StyleCopSonarQubeIssue\StyleCopSonarQubeIssue\StyleCopSonarQubeIssue.csproj]

    1 Warning(s)
    1 Error(s)

Time Elapsed 00:00:00.96

检查详细的错误 \bin\Debug*.exe.RoslynCA.json 文件,您会看到 GlobalSuppression.cs 中被抑制的警告未被考虑。因此 C# 编译器不生成 .exe 并且 msbuild 失败。

有指点吗???

看起来像这样compiler bug

错误是在某些情况下要求编译器将分析问题写入文件会阻止编译器生成 .dll/.exe 文件。但是,编译器也不会发出任何错误。当 MSBuild 尝试复制 non-existent 文件时,构建会在后面的步骤中失败。

您可以通过执行以下操作来检查您是否受到此错误的影响:

  1. 禁用 SonarQube/SonarCloud 分析步骤。
  2. 执行构建并检查它是否成功完成
  3. 现在在 MSBuild 步骤中添加以下 MSBuild 参数:/p:ErrorLog=RoslynIssues.json 然后检查构建是否仍然成功完成。

如果 (2) 成功但 (3) 失败,那么您受到了编译器错误的影响。

Workarounds/solutions: 该错误已在 MSBuild 16.1 中修复,因此修复是升级到最新版本的编译器。如果这不可能,那么一个选项是通过编辑规则集将提出的问题的严重性从错误更改为警告。

(注:从this external thread复制的答案)