我被要求将StyleCop集成到我们的CI构建过程中,其方式如下:
第一个要求(我还没有完全理解这个要求)是因为我们不想直接在整个解决方案上运行StyleCop。显然,当从VS内部运行StyleCop时,它会忽略指定要忽略的文件的某些属性。因此,如果我们让它在开发机上运行,我们将不断受到成千上万的违规行为的打击,我们还没有准备好应对。所以最重要的是我们希望能够仅在构建服务器上运行它。
我们的构建环境目前包括:
巡航控制>执行msbuild的非任务(通过exec)
下面的任务如下:
<target name="buildSolution">
<echo message="Building solution..." />
<exec program="C:\WINDOWS\Microsoft.NET\Framework\v3.5\msbuild.exe"
commandline="${Project.SolutionFile} /t:Rebuild /p:Configuration=${Project.SolutionBuildConfiguration} /v:q" workingdir="." />
</target>
当我第一次看到这个时,我认为以与msbuild执行方式类似的方式执行StyleCop是一个简单的例子。
然而,StyleCop是一组dll ......
所以这意味着我不能做我想要的......我想......
我今天用Google搜索的所有文章都说“使用StyleCopCmd”,由于第三方工具的限制,我也做不到。
我看过这个工具,它似乎实现了一个自定义的nant任务,它启动了StyleCopConsole,挂钩了几个事件并输出了格式良好的报告。但是为了能够证明在内部创建任何工具的合理性,我需要能够完全解释为什么我不能在nant配置文件中实现我想要的。或者以任何其他方式不涉及创建或使用工具。理想情况下,如果我不必编写或使用工具,它会更快。
所以我的问题是,这可能吗?
答案 0 :(得分:5)
我们设法做到了这一点。只需按照以下步骤操作:
在项目中创建一个目录并复制其中的所有StyleCop文件(Microsoft.StyleCop.CSharp.dll,Microsoft.StyleCop.Targets等)
将Microsoft.StyleCop.Targets编辑为如下所示:
-
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask AssemblyFile="Microsoft.StyleCop.dll" TaskName="StyleCopTask" />
<PropertyGroup>
<BuildDependsOn>StyleCop</BuildDependsOn>
<RebuildDependsOn>StyleCopForceFullAnalysis;StyleCop</RebuildDependsOn>
</PropertyGroup>
<PropertyGroup Condition="('$(SourceAnalysisForceFullAnalysis)' != '') and ('$(StyleCopForceFullAnalysis)' == '')">
<StyleCopForceFullAnalysis>$(SourceAnalysisForceFullAnalysis)</StyleCopForceFullAnalysis>
</PropertyGroup>
<PropertyGroup Condition="'$(StyleCopForceFullAnalysis)' == ''">
<StyleCopForceFullAnalysis>false</StyleCopForceFullAnalysis>
</PropertyGroup>
<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>
<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="('$(StyleCopOutputPath)' == '')">
<StyleCopOutputPath>$(IntermediateOutputPath)</StyleCopOutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(StyleCopOutputFile)' == ''">
<StyleCopOutputFile Condition="!HasTrailingSlash('$(StyleCopOutputPath)')">$(StyleCopOutputPath)\$(AssemblyName).StyleCopViolations.xml</StyleCopOutputFile>
<StyleCopOutputFile Condition="HasTrailingSlash('$(StyleCopOutputPath)')">$(StyleCopOutputPath)$(AssemblyName).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)' == ''">100</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'">
<!-- 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="Forcing full StyleCop reanalysis." Condition="'$(StyleCopForceFullAnalysis)' == 'true'" Importance="Low" />
<Message Text="Analyzing @(StyleCopFiles)" Importance="Low" />
<!-- Run the StyleCop MSBuild task. -->
<StyleCopTask
ProjectFullPath="$(MSBuildProjectFile)"
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>
将以下任务添加到要运行StyleCop的NAnt脚本中。只需将NAnt属性替换为对构建脚本有意义的属性或值。
<msbuild project="${solutionfile}" target="ReBuild" verbosity="Quiet">
<property name="CustomAfterMicrosoftCommonTargets" value="${path::combine(project:get-base-directory(), relative-path-to-Microsoft.StyleCop.Targets)}"/>
<property name="Configuration" value="Release"/>
<property name="StyleCopEnabled" value="true" />
<property name="StyleCopOutputPath" value="${directory-to-dump-output-report-to}" />
<arg value="/noconsolelogger" />
</msbuild>