Реализация StyleCop MSBUILD из пакета NuGet

Быстрый предвестник, чтобы сказать, что я проделал обычный поиск по форумам и в сети в целом, и я пробовал множество предложений, найденных на этом форуме и в других местах, но безрезультатно.

Проблема, с которой я столкнулся, заключается в том, что моя компания стремится реализовать внутренние автоматизированные экспертные оценки (в определенной степени, конечно) с использованием таких инструментов, как StyleCop, ReSharper и JSLint (и т. Д. И т. Д.).

Мы используем настраиваемый пакет NuGet для нашего внутреннего репозитория пакетов 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, похоже, работает некорректно. Он используется, поскольку Visual Studio 2010 выдает ошибки при удалении файла и создает файл StyleCop.Cache. Файл StyleCop.Targets был изменен так, чтобы указывать на локальную DLL в папке пакета NuGet, и я попробовал несколько разных файлов .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 не показывает никаких сообщений в окне вывода.

Всем привет!


person Jimmy    schedule 14.02.2012    source источник
comment
К вашему сведению, я только что опубликовал NuGet-пакет StyleCop.MSBuild для использования со сценариями сборки, а не в качестве ссылки на библиотеку. См. nuget.org/packages/StyleCop.MSBuild.   -  person Adam Ralph    schedule 17.03.2012


Ответы (4)


Я публикую решение, с которым столкнулся для всех, кто находится в аналогичной должности.

Сначала я последовал этому отличному руководству по отладке операций MSBuild, которое помогло мне сгладить некоторые логические элементы и переменные:

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

После этого я проверил StyleCopViolations.xml, который находился в моей папке / obj / Debug /. Однако это всегда возвращало 0 результатов только со следующим XML:

<StyleCopViolations/>

Я провел небольшое исследование по этому поводу и обнаружил, что мне нужно включить StyleCop.CSharpRules.dll в мою папку NuGet / lib / net40 / с файлами StyleCop.dll, StyleCop.CSharp.dll и StyleCop.Settings.

В моем проекте не требовались ссылки ни на одну из вышеупомянутых сборок, но я понял, что мой пакет NuGet зависит от пакета NuGet StyleCop, который не включает StyleCop.CSharpRules.dll.

После добавления этой сборки я все еще видел 0 результатов, поэтому я вручную переопределил все 3 сборки и файл .Settings из новой установки StyleCop C: \ Program Files \ StyleCop \ installer (из CodePlex). После перезаписи сборок пакета NuGet это начало работать!

Итак, чтобы завершить, отладьте свой MSBuild (по ссылке вверху этого сообщения) и пока не используйте пакет NuGet!

Ваше здоровье

person Jimmy    schedule 15.02.2012
comment
Ох ... спасибо за решение! Я пытался использовать StyleCop из NuGet пакета StyleCop для создания собственного сценария, но ничего не дало. Проблема заключалась в отсутствии StyleCop.CSharpRules.dll. Затем я перешел на пакет StyleCop.MSBuild NuGet, который содержит StyleCop.CSharpRules.dll, и теперь все работает нормально! - person Dmitrii Lobanov; 21.06.2012

Используйте StyleCop.MSBuild вместо StyleCop, как предложил Дмитрий Лобанов.

т.е. используйте команду install-package stylecop.msbuild в консоли диспетчера пакетов.

person Sherin Mathew    schedule 15.05.2014

Вы можете использовать комбинацию пакетов nuget StyleCop.MSBuild и StyleCop.Error.MSBuild, чтобы включить предупреждения stylecop как ошибки .

person Manish Kumar    schedule 18.01.2015

Перейдите в раздел «Включение и отключение функций Windows» и убедитесь, что установлен флажок .Net Framework. введите описание изображения здесь

Затем перестройте свой проект.

person yarchiT    schedule 22.01.2021