从NuGet包中实现StyleCop MSBUILD

9

首先,我想说我已经在论坛和网络上进行了通常的搜索,并尝试了许多在此论坛和其他地方找到的建议,但都没有成功。

我的问题是,公司希望使用诸如StyleCop、ReSharper和JSLint等工具实现内部自动对等审查(当然只是部分实现)。

我们使用自定义NuGet包针对我们的内部NuGet包存储库(feed),以便我们的开发人员获取受管理的工具发布(即在审核和发布之前,不能下载最新的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似乎无法正常工作。 它被用作Visual Studio 2010抛出错误,如果文件被删除,则创建一个StyleCop.Cache文件。 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
我刚刚发布了StyleCop.MSBuild NuGet包,可以用于构建脚本而不是作为库引用。请见https://nuget.org/packages/StyleCop.MSBuild。 - Adam Ralph
4个回答

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\安装程序(来自CodePlex)的所有3个程序集和.Settings文件。在覆盖NuGet包程序集后,这开始工作了!
总之,调试你的MSBuild(使用本帖顶部的链接),暂时不要使用NuGet包!
干杯!

1
啊...感谢您提供的解决方案!我曾尝试使用NuGet包"StyleCop"中的StyleCop来构建自己的场景,但是它没有起作用。问题在于缺少StyleCop.CSharpRules.dll。然后我切换到"StyleCop.MSBuild" NuGet包,其中包含StyleCop.CSharpRules.dll,现在一切都正常工作了! - Dmitrii Lobanov

2

建议使用 Dmitry Lobanov 推荐的 StyleCop.MSBuild,而非 StyleCop

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


0
您可以使用NuGet包的组合StyleCop.MSBuildStyleCop.Error.MSBuild,将StyleCop警告作为错误启用。

0

前往“打开或关闭Windows功能”,确保已选中.Net Framework 输入图像描述

然后重新构建您的项目。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接