NuGet 4.8 以降では、クロス プラットフォーム プラグインのサポートが追加されました。 これは、厳密な一連の操作規則に準拠する必要がある新しいプラグイン拡張モデルを構築することで実現されました。 プラグインは、NuGet クライアントが別のプロセスで起動する自己完結型の実行可能ファイル (.NET Core の世界では実行可能ファイル) です。 これは「一度書けばどこでも動く」プラグインです。 すべての NuGet クライアント ツールで動作します。 プラグインは任意のプログラミング言語で記述できますが、最も簡単なプラグインの開発とインストールのエクスペリエンスは .NET になります。 NuGet クライアントとプラグインの間のバージョン管理された通信プロトコルが定義されています。 スタートアップ ハンドシェイク中、2 つのプロセスはプロトコル バージョンをネゴシエートします。
機能の概要について
ワークフローの概要は次のとおりです。
- NuGet は、使用可能なプラグインを検出します。
- 該当する場合、NuGet は優先順位でプラグインを反復処理し、それらを 1 つずつ開始します。
- NuGet は、要求にサービスを提供できる最初のプラグインを使用します。
- プラグインは、不要になったときにシャットダウンされます。
プラグインの一般的な要件
現在のプロトコル バージョンは 2.0.0 です。 このバージョンでは、要件は次のとおりです。
- NuGet クライアント ツールの現在のセキュリティ コンテキストでステートレス起動をサポートします。 たとえば、NuGet クライアント ツールは、後で説明するプラグイン プロトコルの外部で昇格や追加の初期化を実行しません。
- 明示的に指定されていない限り、非対話型にする。
- ネゴシエートされたプラグイン プロトコルのバージョンに従います。
- 妥当な期間内のすべての要求に応答します。
- 進行中の操作の取り消し要求を尊重します。
PATH 環境変数から検出されたプラグイン (たとえば、 dotnet tool
経由でインストール) は、ファイル名パターン nuget-plugin-*
に一致する必要があります。
nuget-plugin-
部分は、完全に小文字で記述する必要があります。
NuGet 6.12 (MSBuild 17.12 および .NET SDK 9.0.100) 以前では、Windows で Authenticode に署名するプラグインも必要でした。
技術仕様の詳細については、次の仕様を参照してください。
クライアント - プラグインの対話
NuGet クライアント ツールとプラグインは、標準ストリーム (stdin、stdout、stderr) 経由で JSON と通信します。 すべてのデータは UTF-8 でエンコードする必要があります。 プラグインは引数 "-Plugin" で起動されます。 ユーザーがこの引数なしでプラグイン実行可能ファイルを直接起動した場合、プラグインはプロトコルハンドシェイクを待つ代わりに有益なメッセージを提供できます。 プロトコル ハンドシェイクのタイムアウトは 5 秒です。 プラグインは、できるだけ少しの量でセットアップを完了する必要があります。 NuGet クライアント ツールは、NuGet ソースのサービス インデックスを渡すことによって、プラグインでサポートされている操作に対してクエリを実行します。 プラグインでは、サービス インデックスを使用して、サポートされているサービスの種類の有無を確認できます。
NuGet クライアント ツールとプラグインの間の通信は双方向です。 各要求のタイムアウトは 5 秒です。 操作に時間がかかる場合は、それぞれのプロセスで進行状況メッセージを送信して、要求がタイムアウトしないようにする必要があります。非アクティブ状態が 1 分続くと、プラグインはアイドル状態と見なされ、シャットダウンされます。
プラグインのインストールと検出
NuGet は、規則ベースのディレクトリ構造からプラグインを検索し、PATH 環境変数をスキャンします。
規則ベースの検出
CI/CD シナリオとパワー ユーザーは、環境変数を使用して動作をオーバーライドできます。
環境変数を使用する場合は、絶対パスのみが許可されます。
NUGET_NETFX_PLUGIN_PATHS
とNUGET_NETCORE_PLUGIN_PATHS
は、5.3 以降のバージョンの NuGet ツール以降でのみ使用できます。
-
NUGET_NETFX_PLUGIN_PATHS
- .NET Framework ベースのツール (NuGet.exe/MSBuild.exe/Visual Studio) で使用されるプラグインを定義します。NUGET_PLUGIN_PATHS
よりも優先されます。 (NuGet バージョン 5.3 以降のみ) -
NUGET_NETCORE_PLUGIN_PATHS
- .NET Core ベースのツール (dotnet.exe) で使用されるプラグインを定義します。NUGET_PLUGIN_PATHS
よりも優先されます。 (NuGet バージョン 5.3 以降のみ) -
NUGET_PLUGIN_PATHS
- その NuGet プロセスに使用されるプラグインを定義します。優先度は保持されます。 この環境変数を設定すると、規則ベースの検出がオーバーライドされます。 フレームワーク固有の変数のいずれかが指定されている場合は無視されます。 - ユーザーの場所、
%UserProfile%/.nuget/plugins
の NuGet ホームの場所。 この場所はオーバーライドできません。 .NET Core プラグインと .NET Framework プラグインには、別のルート ディレクトリが使用されます。
フレームワーク | ルート検出の場所 | 使用者 |
---|---|---|
.NET コア | %UserProfile%/.nuget/plugins/netcore |
dotnet CLI(.NET コマンドラインインターフェース) |
.NET Framework | %UserProfile%/.nuget/plugins/netfx |
MSBuild、NuGet.exe、Visual Studio |
各プラグインは、独自のフォルダーにインストールする必要があります。 プラグインのエントリ ポイントは、インストールされているフォルダーの名前で、.NET Core の .dll 拡張機能と、.NET Framework の .exe 拡張子になります。
.nuget
plugins
netfx
myPlugin
myPlugin.exe
nuget.protocol.dll
...
netcore
myPlugin
myPlugin.dll
nuget.protocol.dll
...
PATH 検出
NuGet 6.13 以降、NuGet は PATH 環境変数に指定された各ディレクトリで、パターン nuget-plugin-*
に一致するファイルを検索します。
パターン マッチングでは大文字と小文字が区別され、 nuget-plugin-
は完全に小文字で記述する必要があります。
Windows では、ファイルに .exe
または .bat
拡張子が必要です。
Linux および Mac では、ファイルに実行可能ビットが設定されている必要があります。
これにより、 dotnet tool
コマンド、WinGet、Linux ディストリビューションのパッケージ マネージャー、またはユーザーの PATH に実行可能ファイルを配置できるその他のメソッドを使用して NuGet プラグインをインストールできます。
これにより、NuGet プラグインを任意のプログラミング言語で記述することもできます (以前は Linux および Mac 用のプラグインを .NET で記述する必要があります)。
NuGet.Protocol パッケージを使用して json RPC コードを記述する必要がないようにし、ユーザーが dotnet package search nuget-plugin
経由でプラグインを検出できるように、.NET でプラグインを開発することをお勧めします。
サポート対象の操作
新しいプラグイン プロトコルでは、2 つの操作がサポートされています。
操作名 | 最小プロトコル バージョン | NuGet クライアントの最小バージョン |
---|---|---|
パッケージのダウンロード | 1.0.0 | 4.3.0 |
認証 | 2.0.0 | 4.8.0 |
正しいランタイムでのプラグインの実行
dotnet.exe シナリオの NuGet の場合、プラグインは、dotnet.exeの特定のランタイムで実行できる必要があります。 互換性のある dotnet.exeとプラグインの組み合わせを使用していることを確認するのは、プラグインプロバイダーとコンシューマーの責任です。 たとえば、2.0 ランタイムの下の dotnet.exe が 2.1 ランタイム用に記述されたプラグインを使用しようとすると、ユーザーロケーション プラグインで潜在的な問題が発生する可能性があります。
機能のキャッシュ
プラグインのセキュリティ検証とインスタンス化にはコストがかかります。 ダウンロード操作は認証操作よりも頻繁に行われますが、平均的な NuGet ユーザーは認証プラグインしか持っていない可能性があります。 エクスペリエンスを向上させるために、NuGet は指定された要求の操作要求をキャッシュします。 このキャッシュはプラグイン ごとのものであり、プラグイン キーはプラグイン パスであり、この機能キャッシュの有効期限は 30 日間です。
キャッシュは %LocalAppData%/NuGet/plugins-cache
にあり、環境変数 NUGET_PLUGINS_CACHE_PATH
でオーバーライドされます。
この キャッシュをクリアするには、 plugins-cache
オプションを使用してローカル コマンドを実行します。
all
ローカル オプションもプラグイン キャッシュを削除します。
プロトコル メッセージのインデックス
プロトコル バージョン 1.0.0 メッセージ :
閉める
- 要求の方向: NuGet -> プラグイン
- 要求にはペイロードが含まれません
- 応答は想定されません。 適切な応答は、プラグインプロセスがすぐに終了することです。
パッケージ内のファイルをコピーする
- 要求の方向: NuGet -> プラグイン
- 要求には次のものが含まれます。
- パッケージ ID とバージョン
- パッケージ ソース リポジトリの場所
- 宛先ディレクトリのパス
- コピー先のディレクトリ パスにコピーするパッケージ内のファイルの列挙可能な値
- 応答には次のものが含まれます。
- 操作の結果を示す応答コード
- 操作が成功した場合にコピー先ディレクトリにコピーされたファイルの完全パスの列挙可能
パッケージ ファイルのコピー (.nupkg)
- 要求の方向: NuGet -> プラグイン
- 要求には次のものが含まれます。
- パッケージ ID とバージョン
- パッケージ ソース リポジトリの場所
- 宛先ファイル パス
- 応答には次のものが含まれます。
- 操作の結果を示す応答コード
資格情報の取得
- 要求の方向: plugin -> NuGet
- 要求には次のものが含まれます。
- パッケージ ソース リポジトリの場所
- 現在の資格情報を使用してパッケージ ソース リポジトリから取得した HTTP 状態コード
- 応答には次のものが含まれます。
- 操作の結果を示す応答コード
- ユーザー名 (使用可能な場合)
- パスワード (使用可能な場合)
パッケージ内のファイルを取得する
- 要求の方向: NuGet -> プラグイン
- 要求には次のものが含まれます。
- パッケージ ID とバージョン
- パッケージ ソース リポジトリの場所
- 応答には次のものが含まれます。
- 操作の結果を示す応答コード
- 操作が成功した場合のパッケージ内のファイル パスの列挙可能な値
操作要求を取得する
- 要求の方向: NuGet -> プラグイン
- 要求には次のものが含まれます。
- パッケージ ソースのサービス index.json
- パッケージ ソース リポジトリの場所
- 応答には次のものが含まれます。
- 操作の結果を示す応答コード
- 操作が成功した場合にサポートされる操作 (例: パッケージのダウンロード) の列挙可能。 プラグインがパッケージ ソースをサポートしていない場合、プラグインはサポートされている操作の空のセットを返す必要があります。
注
このメッセージはバージョン 2.0.0 で更新されました。 これは、下位互換性を維持するためにクライアント上にあります。
パッケージ ハッシュを取得する
- 要求の方向: NuGet -> プラグイン
- 要求には次のものが含まれます。
- パッケージ ID とバージョン
- パッケージ ソース リポジトリの場所
- ハッシュ アルゴリズム
- 応答には次のものが含まれます。
- 操作の結果を示す応答コード
- 操作が成功した場合、要求されたハッシュ アルゴリズムを用いて算出されたパッケージ ファイル ハッシュ
パッケージのバージョンを取得する
- 要求の方向: NuGet -> プラグイン
- 要求には次のものが含まれます。
- パッケージ ID
- パッケージ ソース リポジトリの場所
- 応答には次のものが含まれます。
- 操作の結果を示す応答コード
- 操作が成功した場合、パッケージ バージョンの列挙が可能になります。
サービス インデックスを取得する
- 要求の方向: plugin -> NuGet
- 要求には次のものが含まれます。
- パッケージ ソース リポジトリの場所
- 応答には次のものが含まれます。
- 操作の結果を示す応答コード
- 操作が成功した場合のサービス インデックス
握手
- 要求の方向: NuGet <-> プラグイン
- 要求には次のものが含まれます。
- 現在のプラグイン プロトコル バージョン
- サポートされている最小プラグイン プロトコル バージョン
- 応答には次のものが含まれます。
- 操作の結果を示す応答コード
- 操作が成功した場合は、ネゴシエートされたプロトコル のバージョン。 エラーが発生すると、プラグインが終了します。
初期化する
- 要求の方向: NuGet -> プラグイン
- 要求には次のものが含まれます。
- NuGet クライアント ツールのバージョン
- NuGet クライアント ツールの有効な言語。 使用する場合は、ForceEnglishOutput の設定が考慮されます。
- 既定の要求タイムアウト。プロトコルの既定値よりも優先されます。
- 応答には次のものが含まれます。
- 操作の結果を示す応答コード。 エラーが発生すると、プラグインが終了します。
ログ
- 要求の方向: plugin -> NuGet
- 要求には次のものが含まれます。
- 要求のログ レベル
- ログに記録するメッセージ
- 応答には次のものが含まれます。
- 操作の結果を示す応答コード。
NuGet プロセスの終了を監視する
- 要求の方向: NuGet -> プラグイン
- 要求には次のものが含まれます。
- NuGet プロセス ID
- 応答には次のものが含まれます。
- 操作の結果を示す応答コード。
プリフェッチ パッケージ
- 要求の方向: NuGet -> プラグイン
- 要求には次のものが含まれます。
- パッケージ ID とバージョン
- パッケージ ソース リポジトリの場所
- 応答には次のものが含まれます。
- 操作の結果を示す応答コード
資格情報を設定する
- 要求の方向: NuGet -> プラグイン
- 要求には次のものが含まれます。
- パッケージ ソース リポジトリの場所
- 最新の既知のパッケージ ソース ユーザー名 (使用可能な場合)
- 最新の既知のパッケージ ソース パスワード (使用可能な場合)
- 最後の既知のプロキシ ユーザー名 (使用可能な場合)
- 最後の既知のプロキシ パスワード (使用可能な場合)
- 応答には次のものが含まれます。
- 操作の結果を示す応答コード
ログ レベルを設定する
- 要求の方向: NuGet -> プラグイン
- 要求には次のものが含まれます。
- 既定のログ レベル
- 応答には次のものが含まれます。
- 操作の結果を示す応答コード
プロトコル バージョン 2.0.0 メッセージ
- 操作に関するクレームの取得
要求の方向: NuGet -> プラグイン
- 要求には次のものが含まれます。
- パッケージ ソースのサービス index.json
- パッケージ ソース リポジトリの場所
- 応答には次のものが含まれます。
- 操作の結果を示す応答コード
- 操作が成功した場合にサポートされる操作の列挙可能。 プラグインがパッケージ ソースをサポートしていない場合、プラグインはサポートされている操作の空のセットを返す必要があります。
サービス インデックスとパッケージ ソースが null の場合、プラグインは認証で応答できます。
- 要求には次のものが含まれます。
- 認証資格情報を取得する
- 要求の方向: NuGet -> プラグイン
- 要求には次のものが含まれます。
- うり
- リトライするか
- 非対話型
- ダイアログを表示できます
- 応答には次のものが含まれます。
- ユーザー名
- パスワード
- メッセージ
- 認証の種類の一覧
- メッセージ応答コード