20

ここで限界に挑戦しているのかもしれませんが、NuGetを活用して、自分がいるDLL地獄を緩和したいと思っています。

相互に関連するMercurialリポジトリにすべて存在する4つの主要な製品があります。それらはすべて3つのコアアセンブリを「共有」し、それ以外はほとんど製品固有です。ある製品が.NET4.0にアップグレードされ、.NET 4.0を必要とする外部依存関係を使用している一方で、別の製品が.NET 3.5にとどまっているため、管理が非常に困難になっています。

そのため、製品間の違いをマージする能力が失われました。

これを修正するには、3つのメインアセンブリを取り出して、独自のリリースサイクルで独自のプロジェクトに変換し、.NET 3.5と4.0の両方に対してコンパイルできるように注意してから、それらをに変換します。複数のフレームワークバージョンを含むNuGetパッケージ。

しかし、私は開発者がこれらのプロジェクトのソースを閲覧できるようにもしたいと思っています。

そこで、プライベートNuGetサーバープライベートSymbolSourceサーバーをセットアップしました。次に、すべてのリポジトリからのすべての変更を慎重にマージし、コアアセンブリを除くすべてを破棄しました。次に、.csprojファイルを入念に手動編集して、AnyCPUプラットフォームの代わりに、各プロジェクトに3.5および4.0のプラットフォームターゲットがあり、条件定数を指定して(System.Dynamicなどのプラットフォーム固有の機能を制御するため)、フレームワークのバージョンを設定します。

次に、「3.5デバッグ」、「3.5リリース」、「4.0デバッグ」、および「4.0リリース」のソリューション構成をセットアップしました。それぞれが適切な構成(デバッグまたはリリース)とプラットフォーム(3.5または4.0)を対象としています。

Visual Studio内で、どのプラットフォームでもすべてをうまく構築できます。NuGetに関しては、パッケージを作成する方法が2つあり、何かが足りない場合を除いて、どちらにも弱点があるため、問題が発生します。

プロジェクトファイルによるパッケージ

nuget pack MyProject.csproj -Build -Symbols -Version <insert-from-build-server> -Properties "Configuration=Release;Platform=3.5;"

これに関する問題は次のとおりです。

  • 3.5バージョンがビルドおよびパッケージ化されている間、出力には「ターゲットフレームワークのビルドプロジェクト'.NETFramework、Version=v4.0'」と表示されます。
  • 結果のパッケージを解凍すると、アセンブリがlib\net40間違っています。
  • この方法で2つのフレームワークターゲットをパッケージ化する方法はないと思います。フォルダと規則を使用して、別の方法でパッケージ化する必要があります。
  • フレームワークを一緒にパッケージ化して、MyProject(4.0として実行する)とMyProject.V35という2つのパッケージを作成することはできませんが、同じプロジェクトとnuspecを使用する方法がわかりません。そして、異なるIDで2つの異なる結果になります。

Nuspecファイルによるパッケージ

この方法では、すべてのmsbuildingを自分で実行してから、一連のファイルコピーを実行して、次のようなフォルダー構造を設定する必要があります。

* MyProject.nuspec
* net40
    * MyProject.dll
    * MyProject.pdb
* net35
    * MyProject.dll
    * MyProject.pdb

次に実行できますnuget pack MyProject.nuspecが、シンボルを使用するソースがありません。.csprojファイルがないと、NuGetはすべてのソースファイルを取得する場所を特定できず、その方法に関するドキュメントが表示されないためです。これは、ディレクトリ規則のいずれかを使用します。

だから私の質問は:

  1. コンベンションベースのパッケージにソースファイルを追加する方法はありますか?
  2. プロジェクトベースのパッケージを異なるIDで2回パッケージ化する方法はありますか?
  3. おそらく私が考えていなかった別の道はありますか?

どんな考えでも大歓迎です。

4

3 に答える 3

15

ザビエルの答えは私を正しい方向に導き、また私のグーグル検索に知らせました。私はファイル宣言を完全には認識していませんでした。それらの行に沿って検索すると、JoshuaFlanaganの投稿「NuGetパッケージを構築するためのヒント」が見つかりました。これは優れています。ザビエルとジョシュアは一緒に私にいくつかのことを教えてくれました:

  1. パッケージをビルドするために、規則に準拠したファイルツリーをアセンブルする必要はありません。file要素を使用してファイルを選択し、それらをアセンブルされたNuGetパッケージ内の宛先ディレクトリにターゲティングすることをお勧めします。
  2. NuGetの-Symbolsフラグは、.csprojファイルのパッケージ化に対してのみ機能するわけではありません。それをファイルで使用する場合.csproj、確かに、それがすべてのソースファイルをパッケージ化する方法を理解する方法です。ただし、ファイル要素を介してソースを含むファイルで使用-Symbolsすることもできます。.nuspec通常のNuGetパッケージにはsrcディレクトリは含まれませんが、Symbolsパッケージには含まれます。

それでは、CIサーバーで発生するビルドプロセスについて説明します。

  1. 「3.5リリース」ソリューション構成を使用してソリューションを構築します。
  2. 「4.0リリース」ソリューション構成を使用してソリューションを構築します。
  3. ILMerge.exeを使用して、一部のアセンブリを内部化します。これらの出力は(たとえば)bin\Release-3.5\mergedにあるので、マージで使用する前に、ターゲットアセンブリの名前をtemp.dllに変更する必要はありません。
  4. Powershellでパッケージをビルドします.nuspec

パッケージコマンドは次のとおりです。

nuget pack src\MyProject\MyProject.nuspec -OutputDirectory .\output -Build -Symbols -Version $Version

$ Versionはビルドサーバーから渡されるため、バージョンの最後の部分としてビルド番号を使用できることに注意してください。

.nu​​specファイルは次のとおりです。

<?xml version="1.0"?>
<package>
    <metadata>
        <id>MyProject</id>
        <version>0.0.0</version>
        <title>MyProject</title>
        <authors>David Boike</authors>
        <owners>David Boike</owners>
        <requireLicenseAcceptance>false</requireLicenseAcceptance>
        <description>MyProject</description>
        <releaseNotes></releaseNotes>
        <copyright>Copyright 2012</copyright>
        <tags>my tags</tags>
    </metadata>
    <files>
        <file src="bin\Release-4.0\merged\MyProject.dll" target="lib\net40" />
        <file src="bin\Release-4.0\merged\MyProject.pdb" target="lib\net40" />
        <file src="bin\Release-4.0\MyProject.xml" target="lib\net40" />
        <file src="bin\Release-3.5\merged\MyProject.dll" target="lib\net35" />
        <file src="bin\Release-3.5\merged\MyProject.pdb" target="lib\net35" />
        <file src="bin\Release-3.5\MyProject.xml" target="lib\net35" />
        <file src="**\*.cs" target="src" />
    </files>
</package>

このような内部プロジェクトでは問題にならないため、nuspecからより有益な要素をたくさん削除したことに注意してください。

その結果、.NET 3.5と4.0の両方のアセンブリのDLL、PDB、およびXMLドキュメントを含むプライベートNuGetサーバーのパッケージと、上記のすべてとソースを含むプライベートSymbolServerの個別のシンボルパッケージが作成されます。これは、ダウンロードすることを強くお勧めするNuGetパッケージエクスプローラーで非常に簡単に表示できます。

最後に、すべてをテストし、symbolsource.orgで提案されているVisual Studioのセットアップ(自分のプライベートシンボルサーバーを除く)を使用して、コードをデバッグし、ソースに簡単にステップインすることができました。

私を正しい道に導いてくれたザビエルにもう一度感謝します!

于 2012-10-17T14:44:33.173 に答える
8

第三の選択肢があることを知っていますか?csproj ファイルをターゲットにすると、プロジェクト ファイルと同じ名前の nuspec ファイルも検索されます (myProject.csproj --> myProject.nuspec)。これは、結果のパッケージを nuspec ファイルに定義することで、追加のメタデータを追加できることを意味しますが、csproj ファイルをターゲットにします。要するに、csproj ファイルと nuspec ファイルからマージされたメタデータを含むパッケージになります。

特定のシナリオで、同じプロジェクトの複数のプラットフォーム ビルドをパッケージ化する場合は、nuspec を使用してパッケージ化する前に、まずそれらのプロジェクトをビルドする必要があります。

2 つのプロジェクトを作成することをお勧めします。1 つは NET35 を対象とし、もう 1 つは NET40 を対象とし、ファイルをリンクとしてプロジェクトの 1 つに追加します。そのため、両方のプロジェクトをビルドし、nuspec ファイルを使用してすべての出力を 1 つの NuGet パッケージにパッケージ化できます

シンボルに関しては、2 つ目の nuspec ファイル (たとえば myProject.symbols.nuspec) を作成し、以下に示すように、ワイルドカード文字を使用してプロジェクトのすべてのコンテンツ (ソースなど) を追加できると思います。

<file src="myProject35\**\*.cs" target="src" />
<file src="myProject40\bin\Release\*.dll" target="lib\net40" />
<file src="myProject40\bin\Release\*.pdb" target="lib\net40" />
<file src="myProject35\bin\Release\*.dll" target="lib\net35" />
<file src="myProject35\bin\Release\*.pdb" target="lib\net35" />

これが助けになるか、少なくとも抜け道を見つけるための情報を提供してくれることを願っています:)

乾杯、ザビエル

于 2012-10-12T22:02:58.327 に答える