今日は料理をします
スタイルコップ
目的:設計ルールに準拠するための完全な強制コードチェック(C#)を実装します。
条件:合計、強制。 つまり アセンブリに該当するすべてのコードは必ず検証する必要があります。 違反の場合-ビルドエラーと転送、リファクタリング。
ツール: StyleCop 、MSBuild(TFSまたはTeamCity-関係ありません)。
だから。 StyleCopを介してコードを実行する必要があります。 開発者の怠慢と無責任を認識しているため、クライアントの検証を信頼していません。 つまり VSIXは、上記のリンクから入手できるStyleCopディストリビューションからインストールされ、スタジオがプロジェクト/ソリューションを右クリックしてRun Stylecopを実行することを可能にしますが、私たちには適していません。
あらゆる種類のStyleCopチェックインポリシーも私たちのやり方ではありません。 さらに、それらはリポジトリのようにTFSに結び付けられているためです。 したがって、Git for TFSを起動すると、これらのポリシーはすでに失われます。 いいえ、考慮していません(ただし、純粋にイデオロギー的には、これが最も正しい方法です-「ダーティ」コードは単にリポジトリに入れないでください)。
したがって、コードを単純に1にすることはできません。 残っているのは、彼が集まるのを防ぐことだけです。 これを行うために、MSBuildパイプラインで実装メカニズムを十分に研究しています。 幸いなことに、ほとんどの作業はすでに私たちに渡されています-nugetパッケージStyleCop.MSBuildには、必要なすべてのファイルがあります。 これらは、StyleCop自体のファイル(MSBuildに必要なタスクを実装するStyleCopTaskクラスは既にStyleCop.dll自体にあります)、デフォルト設定( StyleCop.Settings )、そして最も重要なのはStyleCop.MSBuild.targetsです。 これが最後に必要なものです。
どのように紹介されますか?
MSBuildの場合、 ImportBefore / Afterを介した非常に便利な拡張メカニズムがあります。 要するに:
...インポートファイルにファイル名を明示的に追加する必要なく、他の誰かがファイルをインポートできるように拡張ポイントを提供する場合。 この目的のために、Microsoft.Common.Targetsにはファイルの先頭に次の行が含まれています。
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\$(MSBuildThisFile)\ImportBefore\*" Condition="'$(ImportByWildcardBeforeMicrosoftCommonTargets)' == 'true' and exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\$(MSBuildThisFile)\ImportBefore')"/>
同様に、 ImportAfterのファイルは自動的にインポートされます。 つまり 各アセンブリで、MSBuildは$(MSBuildExtensionsPath)\ $(MSBuildToolsVersion)\ Microsoft.Common.Targets \ ImportBefore \およびImportAfterにあるファイルをインポートします。 それらの違いは、収集されたファイル(sln / csproj / other proj)をロードする前またはロードした後です。これは...もう1回説明します。
モンキーワークのパスをたどることができます:stylecop Webサイトから.msiをダウンロードし、MSBuildが回転しているマシンにインストールし、手で.targetsファイルを配置します...
ただし、ビルドエージェント(以前はTFS、現在はTeamCityの下にある)を備えた複数のマシンがあり、何とかすべてを手でコピー/インストールしたくありません。 神は別の更新を禁止してから流出します...いいえ、ありがとう。
自動化します。
TFS / TeamCityがあるので、先に進むことができます。 次のファイル構造でリポジトリを作成します。
/ ├[lib] │├mssp7en.dll │├mssp7en.lex │├Settings.StyleCop │├StyleCop.CSharp.dll │├StyleCop.CSharp.Rules.dll │├StyleCop.dll ├[ターゲット] │├StyleCop.MSBuild.Targets └build.proj
build.proj
これはmsbuild形式のプロジェクトファイルに過ぎず、エージェント上で実行され、必要な場所にファイルを分解する操作を実行します。
コンテンツは、たとえば、
<?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" DefaultTargets="StyleCopUpdate" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> <StyleCopTargetsFolder Condition="'$(StyleCopTargetsFolder)' == ''">$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.targets\ImportAfter</StyleCopTargetsFolder> <StyleCopFolder Condition="'$(StyleCopFolder)' == ''">$(MSBuildExtensionsPath)\StyleCop</StyleCopFolder> </PropertyGroup> <Target Name="StyleCopUpdate" DependsOnTargets="StyleCopClear"> <ItemGroup> <StyleCopTargets Include="$(MSBuildThisFileDirectory)targets\ImportAfter\StyleCop*.targets" /> </ItemGroup> <ItemGroup> <StyleCopLibs Include="$(MSBuildThisFileDirectory)lib\*.*" /> </ItemGroup> <MakeDir Directories="$(StyleCopTargetsFolder)" Condition="!Exists('$(StyleCopTargetsFolder)')" /> <Copy DestinationFolder="$(StyleCopTargetsFolder)" SourceFiles="@(StyleCopTargets)" SkipUnchangedFiles="true" OverwriteReadOnlyFiles="true" /> <MakeDir Directories="$(StyleCopFolder)" Condition="!Exists('$(StyleCopFolder)')" /> <Copy DestinationFolder="$(StyleCopFolder)" SourceFiles="@(StyleCopLibs)" SkipUnchangedFiles="true" OverwriteReadOnlyFiles="true" /> </Target> <Target Name="StyleCopClear"> <ItemGroup> <StyleCopToDelete Include="$(StyleCopTargetsFolder)\StyleCop*.targets" /> <StyleCopToDelete Include="$(StyleCopFolder)\*.*" /> </ItemGroup> <Delete Files="@(StyleCopToDelete)" TreatErrorsAsWarnings="true" Condition="@(StyleCopToDelete) != ''" /> </Target> </Project>
msbuild.exe build.projを実行すると次のようになります:
0.古いファイルがある場合-削除
1.ターゲットからファイルを$(MSBuildExtensionsPath)\ $(MSBuildToolsVersion)\ Microsoft.Common.targets \ ImportAfter (起動するMSBuildのバージョンに応じて、 C:\ Program Files(x86)\ MSBuild \ 14.0 \ Microsoft.Common.Targets \ ImportAfter
2. libから$(MSBuildExtensionsPath)\ StyleCop(たとえば、 C:\ Program Files(x86)\ MSBuild \ StyleCop )にファイルをコピーします。
TFS / TeamCityで、継続的インテグレーションモードでこのリポジトリへのコミットに応答し、各エージェントで強制的に腐敗させるビルドを構成します。 したがって、変更を加えた後、すべてのエージェントは自動的に新しいスクリプト/ dll / configs StyleCopに更新されます。 ミロタ。
StyleCopをカスタマイズする
StyleCop.MSBuild.targetsでは、2つの問題を修正することが重要です。
1. StyleCopを有効にします。 falseからtrueへの変更を見つけます。
<PropertyGroup Condition="'$(StyleCopEnabled)' == ''"> <StyleCopEnabled>true</StyleCopEnabled> </PropertyGroup> <PropertyGroup Condition="'$(StyleCopTreatErrorsAsWarnings)' == ''"> <StyleCopTreatErrorsAsWarnings>false</StyleCopTreatErrorsAsWarnings> </PropertyGroup>
(2番目-テスト結果が警告ではなくエラーで落ちるようにするため)。
2. StyleCop.dllへのパスを修正します
<UsingTask AssemblyFile="$(MSBuildExtensionsPath)\StyleCop\StyleCop.dll" TaskName="StyleCopTask"/>
そして構成へ
<PropertyGroup Condition="'$(StyleCopOverrideSettingsFile)' == '' and Exists('$(MSBuildExtensionsPath)\StyleCop\Settings.StyleCop')"> <StyleCopOverrideSettingsFile>$(MSBuildExtensionsPath)\StyleCop\Settings.StyleCop</StyleCopOverrideSettingsFile> </PropertyGroup>
ここにはニュアンスがあります。
Settings.StyleCopファイル
StyleCopルールはデフォルトではかなり物議を醸しています。 疑わしいだけでなく、単に不快なものも数多くあります。 このファイルを手で編集するのは不便です。 これを行うには、サイトから同じ.msiを配置するのが簡単で、同時にStyleCopSettingsEditor.exeをインストールします。これは、ルールのリストを編集するための便利なGUIです。
秘Theは、デフォルトでは、StyleCopには設定の継承が含まれ、デフォルトはmsiからインストールしたものから取得されるということです(ただし、.stylecopファイルを検索してディレクトリツリー全体が上方にスキャンされ、自動的に継承されます)。
したがって、独自のフォルダでファイルを開き、ルールを修正して保存すると、実際にはデフォルトとの違いのみが保存されます 。 また、この変更された独自のファイルのみをリポジトリに配置すると、その中にあるもののみがチェックされます。 StyleCopは同じデフォルトファイルを持たないため、MSBuilの下にデフォルトで含まれるルールを受け取りません。
ソースファイルを編集せず、何かの場合にそれを置き換えることができるように、私の変更を保存しながら、私はこれをしました:
初期のSettings.StyleCopファイルはdefault.StyleCopに名前が変更され、その隣に配置されています。
結果は何ですか?
StyleCopによる強制的なコードチェックがあります。 違反は、ビルドログにエラーとしてすぐに表示されます。
ビルドマシンのstylecopを自動的に更新するメカニズムがあります。
PS:この「msbuild.exe build.proj」をローカルで実行できます。 その後、これらすべての同じエラーがスタジオですぐに表示されます。 つまり msbuildは、スタジオから実行される場合でも、これらのImportBefore / Afterをインポートします。 プラグインのインストールなどは必要ありませんが、すぐにエラーリストに表示されます。リストをクリックして、スタジオがカーソルを置く場所を編集してください。 ビルドサーバーからログを減算しません。
1 ここで説明されているように、私は正直にISubscriberを介してTFSの拡張機能を作成しようとしましたが、公開用のツールが完全に欠けて貧弱なドキュメントにdrれていました(「 サーバーのプラグインディレクトリにアセンブリをドロップします\アプリケーション層\ Webサービス\ビン\プラグイン。その後、アプリプールをリサイクルすると、プラグインがアクティブになります。 "-これはばかげています)、このMicrosoft.TeamFoundation.Git.Serverライブラリのクラス/依存関係の非常に明白で混乱した構造と不整合メソッドとそのアクション。 そして、TFS2015の下で後で再構築する必要があることをどのように想像したか-私はCloseソリューションを作成し、それを実装する他の方法を探しに行きました。