c# - 防止 TeamCity 将 ReSharper 代码检查建议(和提示)报告为警告?

标签 c# visual-studio-2010 resharper-7.1 teamcity-8.0 code-inspection

我已将 Inspections (.NET) 构建步骤添加到 TeamCity (v8) 项目,该项目由针对单个虚拟 C# 类的 Visual Studio 2010 解决方案构建步骤组成。

如果我收到任何检查错误或警告,构建步骤会设置失败条件。

我的虚拟类只生成 2 个建议,但构建声明失败

"Build failure on metric change: Number of inspection warnings is too large: 3".

有没有办法让 TeamCity 步骤忽略建议?

我启用了调试输出,并且该步骤中肯定没有警告:

<!-- Generated by InspectCode 2.0.0.0 -->
<Report ToolsVersion="2.0">
<Information>
 <Solution>Demo.sln</Solution>
 <InspectionScope><Element>Solution</Element></InspectionScope>
</Information>
<IssueTypes><IssueType Id="InconsistentNaming" Category="Constraints Violations" Description="Inconsistent Naming" Severity="SUGGESTION"/>
 <IssueType Id="UnusedMember.Global" Category="Redundancies in Symbol Declarations" Description="Type or type member is never used: Non-private accessibility" Severity="SUGGESTION"/>
</IssueTypes>
<Issues>
 <Project Name="Demo">
  <Issue TypeId="UnusedMember.Global" File="Demo\Class1.cs" Offset="36-42" Line="3" Message="Class 'Class1' is never used"/>
  <Issue TypeId="UnusedMember.Global" File="Demo\Class1.cs" Offset="71-76" Line="5" Message="Field 'maybe' is never used"/>
  <Issue TypeId="InconsistentNaming" File="Demo\Class1.cs" Offset="71-76" Line="5" Message="Name 'maybe' does not match rule 'Fields (not private)'. Suggested name is 'Maybe'."/>
 </Project>
</Issues>
</Report>

虚拟类如下:

namespace Demo
{
    public class Class1
    {
        public bool maybe = true;
    }
}

请注意,我仍然希望在 Visual Studio 中报告建议和提示,因此在 ReSharper 设置中将所有非警告和错误更改为不报告不是一个选项(或创建和维护此类设置文件仅供 TeamCity 使用) .

最佳答案

previous suggested technique 之后我编写了一个运行 InspectCode 的 PowerShell 脚本,然后对输出文件执行 XSLT 转换并将结果导入 TeamCity。您可以将其作为 PowerShell 构建步骤运行,将解决方案文件名作为第一个脚本参数传递,将变量 %system.teamcity.build.tempDir% 作为第二个参数传递。

转换结果.xslt:

(这应该与 PowerShell 脚本位于同一文件夹中)

<xsl:stylesheet
            xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
            version="1.0">
  <xsl:output method="xml" omit-xml-declaration="yes" indent="yes" />
  <xsl:strip-space elements="*"/>

  <xsl:key name="issueType" match="IssueTypes/IssueType" use="@Id" />

  <!--
  Template to strip out issues where the severity is HINT or SUGGESTION
  -->
  <xsl:template match="Issues//Issue">
    <xsl:choose>
      <xsl:when test="not(contains('HINT SUGGESTION', key('issueType', @TypeId)/@Severity))" >
        <xsl:copy>
          <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
      </xsl:when>
    </xsl:choose>
  </xsl:template>

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

运行检查代码.ps1:

param( 
    [Parameter(Mandatory = $true)][string]$solutionFile, 
    [Parameter(Mandatory = $true)][string]$buildTempDir)

# Runs the Jetbrains Resharper code inspection utility (InspectCode)
# - see https://confluence.jetbrains.com/display/NETCOM/Introducing+InspectCode
# We don't want to use the built-in TeamCity inspection plugin because it reports
# HINT and SUGGESTION issues, which we don't want to make mandatory.
# Basically we run InspectCode to generate an intermediate XML report, then we 
# transform that report via XSLT to strip out the issues we don't want to see.

$ErrorActionPreference = "Stop"

# Required if Powershell < 3.0
#$PSScriptRoot = Split-Path $script:MyInvocation.MyCommand.Path

# General-purpose function to transform XML
function Transform-Xml {
    param([string]$stylesheetPath=$(throw '$stylesheetPath is required'),
        [string[]]$xmlPath)

    begin {
        # Compile the stylesheet
        $compiledXslt = New-Object System.Xml.Xsl.XslCompiledTransform
        $compiledXslt.Load($stylesheetPath)

        function transformXmlDoc {
            param([xml]$xml, [System.Xml.Xsl.XslCompiledTransform]$xslt = $(throw '$xslt param is required'))

            $output = New-Object System.IO.MemoryStream
            $arglist = new-object System.Xml.Xsl.XsltArgumentList
            $outputReader = new-object System.IO.StreamReader($output)

            $xmlReader = New-Object System.Xml.XmlNodeReader($xml)
            $xslt.Transform($xmlReader, $arglist, $output)
            $output.position = 0

            $transformed = [string]$outputReader.ReadToEnd()
            $outputReader.Close()
            return $transformed
        }
        function applyStylesheetToXml([xml]$xml) {
            $result = transformXmlDoc $xml $compiledXslt
            [string]::join([environment]::newline, $result)
        }
        function applyStylesheetToXmlFile($sourcePath) {
            $rpath = resolve-path $sourcePath
            [xml]$xml = Get-Content $rpath
            $result = transformXmlDoc $xml $compiledXslt
            [string]::join([environment]::newline, $result)
        }
    }

    process {
        if ($_) {
            if ($_ -is [xml]) {
                applyStylesheetToXml $_
            }
            elseif ($_ -is [IO.FileInfo]) {
                applyStylesheetToXmlFile $_.FullName
            }
            elseif ($_ -is [string]) {
                if (test-path -type Leaf $_) {
                    applyStylesheetToXmlFile $_
                }
                else {
                    applyStylesheetToXml $_
                }
            }
            else {
                throw "Pipeline input type must be one of: [xml], [string] or [IO.FileInfo]"
            }
        }
    }

    end {
        if ($xmlPath) {
            foreach ($path in $xmlPath) {
                applyStylesheetToXmlFile $path
            }
        }
    }
}

$solutionPath = Resolve-Path $solutionFile
$tempDir = Resolve-Path $buildTempDir

# Locate inspectcode
if (-Not (Test-Path Env:\RESHARPER_TOOLS_PATH)) {
    throw 'RESHARPER_TOOLS_PATH environment variable not set'
}

$inspectcode = Join-Path $env:RESHARPER_TOOLS_PATH 'inspectcode.exe'
if (-Not (Test-Path -type Leaf $inspectcode)) {
    throw 'InpectCode executable not found'
}

# Path to XSLT transformation file
$fullXsltPath = Resolve-Path (Join-Path $PSScriptRoot 'TransformResults.xslt')

# Names of intermediate and final output files
$intermediateOutput = Join-Path $tempDir 'inspectcode-intermediate.xml'
$outputPath = Join-Path $tempDir 'inspectcode-final.xml'

# Run InspectCode 
& $inspectcode "/o=$intermediateOutput" $solutionPath

# Transform the inspection output to remove HINT and SUGGESTION
$transformed = Transform-Xml $fullXsltPath @($intermediateOutput)

# The PowerShell Out-File cmdlet always adds a UTF8 Byte Order Marker so we need to take steps to
# ensure this is not emitted, as the TeamCity XML importer will choke on it
$encoding = New-Object System.Text.UTF8Encoding($false)
[System.IO.File]::WriteAllLines($outputPath, $transformed, $encoding)

# When PowerShell is started through TeamCity's Command Runner, the standard
# output will be wrapped at column 80 (a default). This has a negative impact
# on service messages, as TeamCity quite naturally fails parsing a wrapped
# message. The solution is to set a new, much wider output width. It will
# only be set if TEAMCITY_VERSION exists, i.e., if started by TeamCity.
$host.UI.RawUI.BufferSize = New-Object System.Management.Automation.Host.Size(8192,50)

Write-Output "##teamcity[importData type='ReSharperInspectCode' path='$outputPath']"

关于c# - 防止 TeamCity 将 ReSharper 代码检查建议(和提示)报告为警告?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21032773/

相关文章:

C# + 信息权限管理

c# - 如何确定一个进程是否在 C# 中被管理?

c++ - visual c++ 2010 可再发行

c# - 从 Resharper 的检查结果窗口中删除 "Hints"

Azure 单元测试在 MSTest 中失败,但在 Resharper 中通过

c# - .NET BindingSource.Filter 与正则表达式

c# - 如何添加或减去相同类/类型的两个实例

visual-studio-2010 - 如何使用 TFS 映射现有文件夹(已移动到新机器)而无需从 TFS 下载整个数据?

c# - 升级到VS 2010 framework 4.0的项目中的程序集资源FileNotFoundException

c# - ReSharper 生成此文件 : Annotations. cs。为什么?