StyleCop から 結果の XML を出力する

StyleCop - Home をインストールすると、VS に統合してくれて、VS でビルドすると警告を出してくれて便利なんですが、他のツールに連携する xml ファイルはどうやって吐くのかなと調べてみました。
参考にしたサイト
How to use StyleCop with TeamCity - Stack Overflow


とりあえず、プロジェクトを作成し、NuGet から StyleCop.MSBuild をインストールします。
これだけで、VS からビルドすると、出力ウィンドウ にStyleCop の警告が表示されるようになります。
この段階で .csproj ファイルには色々追加されてます。

.csproj 一部抜粋

  <PropertyGroup>
    <StyleCopMSBuildTargetsFile>..\packages\StyleCop.MSBuild.4.7.41.0\tools\StyleCop.targets</StyleCopMSBuildTargetsFile>
  </PropertyGroup>
  <Import Condition="Exists('$(StyleCopMSBuildTargetsFile)')" Project="$(StyleCopMSBuildTargetsFile)" />
  <PropertyGroup>
    <StyleCopMSBuildMessageMissing>Failed to import StyleCop.MSBuild targets from '$(StyleCopMSBuildTargetsFile)'. The StyleCop.MSBuild package was either missing or incomplete when the project was loaded. Ensure that the package is present and then restart the build. If you are using an IDE (e.g. Visual Studio), reload the project before restarting the build.</StyleCopMSBuildMessageMissing>
    <StyleCopMSBuildMessagePresent>Failed to import StyleCop.MSBuild targets from '$(StyleCopMSBuildTargetsFile)'. The StyleCop.MSBuild package was either missing or incomplete when the project was loaded (but is now present). To fix this, restart the build. If you are using an IDE (e.g. Visual Studio), reload the project before restarting the build.</StyleCopMSBuildMessagePresent>
    <StyleCopMSBuildMessageRestore>Failed to import StyleCop.MSBuild targets from '$(StyleCopMSBuildTargetsFile)'. The StyleCop.MSBuild package was either missing or incomplete when the project was loaded. To fix this, restore the package and then restart the build. If you are using an IDE (e.g. Visual Studio), you may need to reload the project before restarting the build. Note that regular NuGet package restore (during build) does not work with this package because the package needs to be present before the project is loaded. If this is an automated build (e.g. CI server), you may want to ensure that the build process restores the StyleCop.MSBuild package before the project is built.</StyleCopMSBuildMessageRestore>
    <StyleCopMSBuildMessageRestored>Failed to import StyleCop.MSBuild targets from '$(StyleCopMSBuildTargetsFile)'. The StyleCop.MSBuild package was either missing or incomplete when the project was loaded (but is now present). To fix this, restart the build. If you are using an IDE (e.g. Visual Studio), reload the project before restarting the build. Note that when using regular NuGet package restore (during build) the package will not be available for the initial build because the package needs to be present before the project is loaded. If package restore executes successfully in the intitial build then the package will be available for subsequent builds. If this is an automated build (e.g. CI server), you may want to ensure that the build process restores the StyleCop.MSBuild package before the initial build.</StyleCopMSBuildMessageRestored>
  </PropertyGroup>
  <Target Name="StyleCopMSBuildTargetsNotFound">
    <Warning Condition="!Exists('$(StyleCopMSBuildTargetsFile)') And $(RestorePackages)!=true And $(StyleCopTreatErrorsAsWarnings)!=false" Text="$(StyleCopMSBuildMessageMissing)" />
    <Warning Condition="Exists('$(StyleCopMSBuildTargetsFile)')  And $(RestorePackages)!=true And $(StyleCopTreatErrorsAsWarnings)!=false" Text="$(StyleCopMSBuildMessagePresent)" />
    <Warning Condition="!Exists('$(StyleCopMSBuildTargetsFile)') And $(RestorePackages)==true And $(StyleCopTreatErrorsAsWarnings)!=false" Text="$(StyleCopMSBuildMessageRestore)" />
    <Warning Condition="Exists('$(StyleCopMSBuildTargetsFile)')  And $(RestorePackages)==true And $(StyleCopTreatErrorsAsWarnings)!=false" Text="$(StyleCopMSBuildMessageRestored)" />
    <Error Condition="!Exists('$(StyleCopMSBuildTargetsFile)') And $(RestorePackages)!=true And $(StyleCopTreatErrorsAsWarnings)==false" Text="$(StyleCopMSBuildMessageMissing)" />
    <Error Condition="Exists('$(StyleCopMSBuildTargetsFile)')  And $(RestorePackages)!=true And $(StyleCopTreatErrorsAsWarnings)==false" Text="$(StyleCopMSBuildMessagePresent)" />
    <Error Condition="!Exists('$(StyleCopMSBuildTargetsFile)') And $(RestorePackages)==true And $(StyleCopTreatErrorsAsWarnings)==false" Text="$(StyleCopMSBuildMessageRestore)" />
    <Error Condition="Exists('$(StyleCopMSBuildTargetsFile)')  And $(RestorePackages)==true And $(StyleCopTreatErrorsAsWarnings)==false" Text="$(StyleCopMSBuildMessageRestored)" />
  </Target>
  <PropertyGroup>
    <PrepareForBuildDependsOn Condition="!Exists('$(StyleCopMSBuildTargetsFile)')">StyleCopMSBuildTargetsNotFound;$(PrepareForBuildDependsOn)</PrepareForBuildDependsOn>
  </PropertyGroup>

ここからが本番。StyleCop.targets を Import しているので、StyleCop のタスクが使えます。StyleCop.targets ファイル開き、Output で検索していくと、OutputFile を指定する StyleCopTask というのが見つかります。こいつを使って、.xml を出力します。
.csproj に 新しい Target を追加し、StyleCopTask を使って .xml を出力します。

.csproj の最後に OutputStyleCop(名前は何でも良い) ターゲットを追加します。

  <Target Name="OutputStyleCop">
    <!-- Create a collection of files to scan -->
    <CreateItem Include=".\**\*.cs">
      <Output TaskParameter="Include" ItemName="StyleCopFiles" />
    </CreateItem>
    <StyleCopTask 
      ProjectFullPath="$(MSBuildProjectFile)"
      SourceFiles="@(StyleCopFiles)" 
      ForceFullAnalysis="true" 
      TreatErrorsAsWarnings="true" 
      OutputFile="StyleCopReport.xml" 
      />
  </Target>
</Project>

この .csproj を MSBuild から /t:OutputStyleCop で蹴ると、StyleCopReport.xml が出力されます。