从NuGet包实现StyleCop MSBUILD

时间:2012-02-14 14:13:09

标签: c# msbuild nuget stylecop

一个快速的先兆,说我已经在论坛和网络上进行了一般性的搜索,我尝试了在这个论坛和其他地方发现的大量建议,但没有用。

我遇到的问题是我的公司希望通过使用StyleCop,ReSharper和JSLint等工具来实现内部自动化同行评审(在某种程度上)。

我们正在使用针对我们内部NuGet包存储库(feed)的自定义NuGet包,以便我们的开发人员获得管理版本的工具(即,在它被审核和发布之前,它们无法下载最新的StyleCop)添加了我们的自定义规则(StyleCop设置文件)。因为我们想在构建时使用StyleCop MSBUILD任务来突出显示错误,所以StyleCop的程序集必须准确,因此我们排除了C:\ Program Files \版本的安装,转而使用NuGet版本。

我设法创建一个安装到项目(类库,网站等)的NuGet包,复制批准的StyleCop程序集(StyleCop.dll,StyleCop.CSharp.dll和StyleCop.CSharpRules.dll), Settings.StyleCop和StyleCop.Targets到包文件夹,并修改.csproj文件以包含以下节点(当然这只是一个片段):

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup Condition=" '$(Configuration)' != 'Debug' ">
        <StyleCopTreatErrorsAsWarnings>false</StyleCopTreatErrorsAsWarnings>
    </PropertyGroup>

    <Import Project="$(SolutionDir)\packages\NuGetPackageName.1.0.0\StyleCop.Targets" />
</Project>

如果我将StyleCop安装为C:\ Program Files \并且在C:\ Program Files \ MSBUILD中,则一切正常,但使用此方法时,StyleCop.Targets似乎无法正常工作。如果文件被删除并且它创建了一个StyleCop.Cache文件,它将被用作Visual Studio 2010引发错误。 StyleCop.Targets文件已更改为指向NuGet包文件夹中的本地DLL,我尝试了几个不同的.Targets文件,包括标准的StyleCop文件(相对文件路径更改)。即使我在本地覆盖MSBUILD属性,它也不起作用,例如OverrideSettingsFile。

StyleCop.Targets文件目前看起来像这样:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <!-- Specify where tasks are implemented. -->
    <UsingTask AssemblyFile="$(SolutionDir)\packages\NuGetPackageName.1.0.0\lib\net40\StyleCop.dll" TaskName="StyleCopTask"/>

    <PropertyGroup>
        <BuildDependsOn>$(BuildDependsOn);StyleCop</BuildDependsOn>
        <RebuildDependsOn>StyleCopForceFullAnalysis;$(RebuildDependsOn)</RebuildDependsOn>
    </PropertyGroup>

    <!-- Define StyleCopForceFullAnalysis property. -->
    <PropertyGroup Condition="('$(SourceAnalysisForceFullAnalysis)' != '') and ('$(StyleCopForceFullAnalysis)' == '')">
        <StyleCopForceFullAnalysis>$(SourceAnalysisForceFullAnalysis)</StyleCopForceFullAnalysis>
    </PropertyGroup>
    <PropertyGroup Condition="'$(StyleCopForceFullAnalysis)' == ''">
        <StyleCopForceFullAnalysis>false</StyleCopForceFullAnalysis>
    </PropertyGroup>

    <!-- Define StyleCopCacheResults property. -->
    <PropertyGroup Condition="('$(SourceAnalysisCacheResults)' != '') and ('$(StyleCopCacheResults)' == '')">
        <StyleCopCacheResults>$(SourceAnalysisCacheResults)</StyleCopCacheResults>
    </PropertyGroup>
    <PropertyGroup Condition="'$(StyleCopCacheResults)' == ''">
        <StyleCopCacheResults>true</StyleCopCacheResults>
    </PropertyGroup>

    <!-- Define StyleCopTreatErrorsAsWarnings property. -->
    <PropertyGroup Condition="('$(SourceAnalysisTreatErrorsAsWarnings)' != '') and ('$(StyleCopTreatErrorsAsWarnings)' == '')">
        <StyleCopTreatErrorsAsWarnings>$(SourceAnalysisTreatErrorsAsWarnings)</StyleCopTreatErrorsAsWarnings>
    </PropertyGroup>
    <PropertyGroup Condition="'$(StyleCopTreatErrorsAsWarnings)' == ''">
        <StyleCopTreatErrorsAsWarnings>true</StyleCopTreatErrorsAsWarnings>
    </PropertyGroup>

    <!-- Define StyleCopEnabled property. -->
    <PropertyGroup Condition="('$(SourceAnalysisEnabled)' != '') and ('$(StyleCopEnabled)' == '')">
        <StyleCopEnabled>$(SourceAnalysisEnabled)</StyleCopEnabled>
    </PropertyGroup>
    <PropertyGroup Condition="'$(StyleCopEnabled)' == ''">
        <StyleCopEnabled>true</StyleCopEnabled>
    </PropertyGroup>

    <!-- Define StyleCopOverrideSettingsFile property. -->
    <PropertyGroup Condition="('$(SourceAnalysisOverrideSettingsFile)' != '') and ('$(StyleCopOverrideSettingsFile)' == '')">
        <StyleCopOverrideSettingsFile>$(SourceAnalysisOverrideSettingsFile)</StyleCopOverrideSettingsFile>
    </PropertyGroup>
    <PropertyGroup Condition="'$(StyleCopOverrideSettingsFile)' == ''">
        <StyleCopOverrideSettingsFile> </StyleCopOverrideSettingsFile>
    </PropertyGroup>

    <!-- Define StyleCopOutputFile property. -->
    <PropertyGroup Condition="('$(SourceAnalysisOutputFile)' != '') and ('$(StyleCopOutputFile)' == '')">
        <StyleCopOutputFile>$(SourceAnalysisOutputFile)</StyleCopOutputFile>
    </PropertyGroup>
    <PropertyGroup Condition="'$(StyleCopOutputFile)' == ''">
        <StyleCopOutputFile>$(IntermediateOutputPath)StyleCopViolations.xml</StyleCopOutputFile>
    </PropertyGroup>

    <!-- Define all new properties which do not need to have both StyleCop and SourceAnalysis variations. -->
    <PropertyGroup>
        <!-- Specifying 0 will cause StyleCop to use the default violation count limit.
         Specifying any positive number will cause StyleCop to use that number as the violation count limit.
         Specifying any negative number will cause StyleCop to allow any number of violations without limit.
    -->
        <StyleCopMaxViolationCount Condition="'$(StyleCopMaxViolationCount)' == ''">0</StyleCopMaxViolationCount>
    </PropertyGroup>

    <!-- Define target: StyleCopForceFullAnalysis -->
    <Target Name="StyleCopForceFullAnalysis">
        <CreateProperty Value="true">
            <Output TaskParameter="Value" PropertyName="StyleCopForceFullAnalysis" />
        </CreateProperty>
    </Target>

    <!-- Define target: StyleCop -->
    <Target Name="StyleCop" Condition="'$(StyleCopEnabled)' != 'false'">
        <Message Text="Forcing full StyleCop reanalysis." Condition="'$(StyleCopForceFullAnalysis)' == 'true'" Importance="Low" />

        <!-- Determine what files should be checked. Take all Compile items, but exclude those that have set ExcludeFromStyleCop=true or ExcludeFromSourceAnalysis=true. -->
        <CreateItem Include="@(Compile)" Condition="('%(Compile.ExcludeFromStyleCop)' != 'true') and ('%(Compile.ExcludeFromSourceAnalysis)' != 'true')">
            <Output TaskParameter="Include" ItemName="StyleCopFiles"/>
        </CreateItem>

        <Message Text="Analyzing @(StyleCopFiles)" Importance="Low" />

        <!-- Show list of what files should be excluded. checked. Take all Compile items, but exclude those that have set ExcludeFromStyleCop=true or ExcludeFromSourceAnalysis=true. -->
        <CreateItem Include="@(Compile)" Condition="('%(Compile.ExcludeFromStyleCop)' == 'true') or ('%(Compile.ExcludeFromSourceAnalysis)' == 'true')">
            <Output TaskParameter="Include" ItemName="StyleCopExcludedFiles"/>
        </CreateItem>

        <ItemGroup>
            <StyleCopFiles Remove="@(ExcludeFromStyleCop)" />
        </ItemGroup>

        <Message Text="Excluding @(StyleCopExcludedFiles)" Importance="Normal" />

        <!-- Run the StyleCop MSBuild task. -->
        <StyleCopTask ProjectFullPath="$(MSBuildProjectDirectory)" SourceFiles="@(StyleCopFiles)"
                  AdditionalAddinPaths="@(StyleCopAdditionalAddinPaths)" ForceFullAnalysis="$(StyleCopForceFullAnalysis)"
                  DefineConstants="$(DefineConstants)" TreatErrorsAsWarnings="$(StyleCopTreatErrorsAsWarnings)"
                  CacheResults="$(StyleCopCacheResults)" OverrideSettingsFile="$(StyleCopOverrideSettingsFile)"
                  OutputFile="$(StyleCopOutputFile)" MaxViolationCount="$(StyleCopMaxViolationCount)" />

        <!-- Make output files cleanable -->
        <CreateItem Include="$(StyleCopOutputFile)">
            <Output TaskParameter="Include" ItemName="FileWrites"/>
        </CreateItem>

        <!-- Add the StyleCop.cache file to the list of files we've written - so they can be cleaned up on a Build Clean. -->
        <CreateItem Include="StyleCop.Cache" Condition="'$(StyleCopCacheResults)' == 'true'">
            <Output TaskParameter="Include" ItemName="FileWrites"/>
        </CreateItem>
    </Target>
</Project>

有谁知道我怎么能让这个工作? Visual Studio 2010在“输出”窗口中不显示任何消息。

干杯!

4 个答案:

答案 0 :(得分:7)

我发布了我遇到过类似职位的人的解决方案。

首先,我遵循了关于调试MSBuild操作的优秀指南,这有助于我解决一些逻辑和变量:

http://blogs.msdn.com/b/visualstudio/archive/2010/07/06/debugging-msbuild-script-with-visual-studio.aspx

在此之后,我检查了我的/ obj / Debug /文件夹中的StyleCopViolations.xml。但是,这总是返回0结果,只有以下XML:

<StyleCopViolations/>

我对此做了一些研究,发现我需要将StyleCop.CSharpRules.dll包含在带有StyleCop.dll,StyleCop.CSharp.dll和StyleCop.Settings文件的NuGet / lib / net40 /文件夹中。

我的项目不需要引用任何上述程序集,但我意识到我的NuGet包依赖于StyleCop NuGet包,它不包含StyleCop.CSharpRules.dll。

添加此程序集后,我仍然看到0结果,所以我从全新安装的StyleCop C:\ Program Files \ StyleCop \ installer(来自CodePlex)手动覆盖了所有3个程序集和.Settings文件。覆盖NuGet包装配件后,这开始工作了!

所以要结束,调试你的MSBuild(使用这篇文章顶部的链接),不要再使用NuGet包了!

干杯

答案 1 :(得分:2)

根据Dmitry Lobanov的建议,使用StyleCop.MSBuild代替StyleCop

即在程序包管理器控制台中使用命令install-package stylecop.msbuild

答案 2 :(得分:0)

您可以结合使用nuget包 StyleCop.MSBuild StyleCop.Error.MSBuild 来启用stylecop警告为错误。

答案 3 :(得分:0)

转到打开和关闭 Windows 功能,并确保选中 .Net Framework enter image description here

然后重建您的项目。