こんにちはHabr! 主な焦点は.Net開発、つまり、Microsoft Visual Studio、ReSharper、Nugetなどを使用することです。
多くのサブプロジェクトで素晴らしいソリューション( msdn-solution )を開発したと思います。 この場合、Nugetパッケージ、ビルド設定などの同期の問題がしばしば問題になりました。 さらに、ReSharperは、使用される多くのライブラリで混乱し始めない限り、ここではあまり役に立ちません。
ソースコードを確認するために、 オープンソースソリューション-SolutionCopが作成されました。これは無料で使用できます。
まず、ソリューションを確認しても問題がない場合の例をいくつか示します。
例1:Nugetライブラリの異なるバージョン。
たとえば、exe、dll1、dll2の3つのプロジェクトがあります。 exeは両方のライブラリを指し、それぞれは、たとえばRXを指します。 ただし、dll1はRX 2.2.0を使用し、dll2はRX 2.2.5を使用します。 実際、関数シグネチャがほぼ一致するため、エラーを取得することはすぐには不可能です。さらに、MsBuildはほとんどの場合、同じ順序でプロジェクトを収集します。 ただし、このような構成では、展開後に、すべてのユニットテストに合格したとき(ライブラリを参照するだけなので)、結果のファイルセットが準備されるときに問題が発生する可能性があります。
例2:プロジェクトはNugetを介さずにライブラリを直接参照します。
繰り返しますが、3つのプロジェクト、exe、dll1、およびdll2を使用します。 Jetbrains.Annotationsを使用して、属性でNotNull / CanBeNullコードをマークアップし、 適切な静的分析を取得するとします。 しかし、ここには不運があります。dll1については、パッケージバージョン9.2.0を正直にダウンロードし、dll2では、ReSharperにリンクを追加するように要求しました。 その結果、packages.configファイルdll2には属性を持つパッケージがありません。つまり、プロジェクトがdll2-> dll1-> exeの順序でアセンブルされた場合、Nugetパッケージはdll1の収集時にのみダウンロードされるため、エラーが発生します。
プロジェクトのさまざまな設定がおかしな問題を引き起こす可能性があるいくつかの例があります。 たとえば、.Net 4.0と.Net 4.5のプロジェクトは同じパッケージを参照できますが、その中の異なるライブラリを参照できます( Nugetのヘルプを参照 )。これは、プロジェクトをビルドするときに再び特殊効果を受け取ることを意味します。 ただし、SolutionCopに移行することをお勧めします。
設置
SolutionCopはNugetで利用でき、ソリューション全体のレベルでインストールされます。 パッケージをインストールした後、ルールを使用してxmlファイルを作成し、それらを構成し、テスターをCIのビルド手順に統合する必要があります。
ステップバイステップ:
- ルールを使用してxmlファイルを作成します(SolutionCop自体を確認します)。
SolutionCop.exe -s "C:\git\SolutionCop\src\SolutionCop.sln"
このコマンドの後、slnファイルの近くにSolutionCop.xmlファイルが表示されます。 すべてのルールがリストされますが、すべてオフになっています。 後で検討します。 - SolutionCopが各ビルドで開始されるようにCIサーバーを構成します(100プロジェクトのソリューションが3〜4秒間チェックされます)。 TeamCityの場合、ステータスをより便利な形式で公開することもできます。 それ以外の場合は、エラー出力を読む必要があります。 すべてのルールが正常に実行されると、アプリケーションは0を返します。 したがって、TeamCityのコマンドライン:
SolutionCop.exe -s "C:\git\SolutionCop\src\SolutionCop.sln" -b TeamCity --suppress-success-status-message.
最後の引数は、TeamCityがユニットテストのステータスを書き込まない場合に必要です(後で実行されたという事実にもかかわらず)。 すべてのルールに従っている場合、SolutionCopの出力を無効にします。
ルール
したがって、SolutionCopは構成され、ソリューションを調べますが、何もチェックしません。 したがって、役に立つルールをリストします。 それらの使用の詳細な説明はGitHubにあります 、私は単に興味深いものをリストします。 もちろん、ルールごとに例外などを設定できます。
- 警告レベル 。 すべてのプロジェクトの警告レベルが指定されたレベル以上であることを確認します。
- TreatWarningsAsErrors 。 前のものに隣接。 コンパイル設定も同期します 。
- TargetFrameworkVersion 。 すべてのプロジェクトの.Netバージョンを同期します
- SuppressWarnings 。 コンパイラーが目をつぶる警告のリストを同期します。
- FilesIncludedIntoProject 。 プロジェクトフォルダー内のすべてのファイルがこのプロジェクトに含まれていることを確認します(拡張子は追加で示されます)。 信じられないほど便利なルール。 たとえば、一度間違ったgit mergeを行うと、約3分の1のファイルが単体テストのあるプロジェクトから落ちました。 もちろん、これはすぐには気づかなかったが、それまでにいくつかのバグを見逃していた。 また、リポジトリをクリアして、誰も使用していない大量のファイルがハングアップするのを防ぎます。
- ReferenceNuGetPackagesOnly NuGetパッケージとして追加されていないライブラリへの動的リンクを禁止します。 実際、これは上記の例2の修正です。
- NuGetPackagesUsage 。 使用できるnugetパッケージを定義します。 この設定は、製品に複数のコマンドがあり、それぞれに独自のリポジトリがあり、それらが相互に、またいくつかの一般的なコンポーネントを参照する場合に必要です。 また、コードを結合する際の問題を回避するために、全員に一般的なルール(使用できるパッケージのバージョン)を定義できます。 この場合、すべてのルールはコードとは別に、別個のリポジトリに保存されます。
- SameNuGetPackageVersions 。 ソリューションでのさまざまなNugetパッケージの使用を禁止します。 例1のエラーの修正。
- NuGetAutomaticPackagesRestore 。 ビルドプロセス中にすべてのプロジェクトがNugetパッケージを復元することを確認します。 そうしないと、一部のプロジェクトが他のプロジェクトがその依存関係をロードするという事実を使用するため、CIサーバーでの異なるコンパイル順序により、時間どおりにロードされないnugetパッケージが生じる可能性があります。
実際、SolutionCopにはコードのクリーンアップに役立つ他の多くのルールがあります。 .Netで開発するほとんどすべての人が必要とする可能性のあるものをリストしようとしました。