首页 文章

从NuGet包实现StyleCop MSBUILD

提问于
浏览
9

一个快速的前兆,说我已经在论坛和网络上进行了一般性的搜索,我已经尝试了在这个论坛和其他地方发现的大量建议,但无济于事 .

我遇到的问题是我的公司正在寻求使用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不会在“输出”窗口中显示任何消息 .

干得好!

3 回答

  • 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包含在我的NuGet / lib / net40 /文件夹中,包含StyleCop.dll,StyleCop.CSharp.dll和StyleCop.Settings文件 .

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

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

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

    干杯

  • 2

    根据Dmitry Lobanov的建议,使用 StyleCop.MSBuild 而不是 StyleCop .

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

  • 0

    您可以使用nuget包 StyleCop.MSBuildStyleCop.Error.MSBuild 的组合来启用stylecop警告作为错误 .

相关问题