NuGet の Source Link で新しいバージョンのソースが見れない問題とその解決


問題

NuGetのライブラリに変更を加えて、バージョンを上げて、Packしたものを、LocalNuGetに上げて、~/.nuget配下のキャッシュを消したのち、そのライブラリをテストするための簡単なサンプルを動かしてみたら、期待通りに動かない。そこで、Go to Definition でソースコードを見ると、更新したはずの、ソースコードが古いままだった。もちろん、VSの再起動とか、クリーンも実施したが同じだった。

なんでやねん!ということで、csprojを再確認して、Packagesを参照するとちゃんと想定のバージョンになっている。

発生した現象

残念ながら、解決策ではないのだが、この問題は、どうやら Gitに関係していると思われる。上記の環境は、あるリポジトリのForkリポジトリで、自分のクライアントに Clone している。私は大きい Pull Request が嫌いなので、パッケージの変更のPullRequestと、それを使った新しいサンプルで別のBranchを切って作業していた。

つまり、ワークフローとしては

  1. ブランチAで、NuGetのリポジトリを変更、pack で NuGet パッケージを作成、それをLocalNuGet に格納する
  2. ブランチをAからBに切り替える
  3. .nugetのキャッシュを削除する
  4. 先ほど作ったNuGetパッケージを使うためのサンプルがあるので、そこで、新しく作ったバージョンのNuGetを取り込む。
  5. サンプルの中でNuGetの中身のクラスに対して、Go To Definitionを実施している。

ところか、こうすると折角ブランチAでいれた変更がなされてないように見える。これには相当はまった。

ワークアラウンド

解決したわけではないのだが、ワークアラウンドとしては、サンプルを同じリポジトリには、置かず、まったく別のローカルPCの場所に作り、リポジトリのブランチはAのままにしておくと、NuGetパッケージが全く同じなのに新しいソースを見ることができた。そこで、これは、ビルドやPackの問題ではなく、きっと、Source Linkの振る舞いの問題ではないか?と推察した。

NuGet Package エクスプローラーで中身を見てみる。

NuGet Package Explorer というツールがあるっぽく、packによってできたものの中味を閲覧できる。Repository: で指定されている箇所が、SourceLinkの見に行くリポジトリであると、下記のドキュメントには記述してあった。ここでは特にSourceLinkを明確に設定していない。

ちなみに、画面にある、Health: のところに、Source Link: があるが、Contains untracked sourcesがあり、オーバーレイすると、 明らかにNuGetパッケージは、どこでビルドされたのかの情報を持ってそうだ。明確なメタデータの値としてはなさそうだった。

考察

このNuGetの定義を見る限り、Repository: のところにコミットを持っているので、これをある特定の優先順位でいろいろなところを見に行くようになっているのでは?と推察している。例えば、最初にURLを見に行って同じコミットを探して、なければローカルのビルドされたソースの位置にあるコミットを探して、、、といった具合だ。それに従えば、最初の振る舞いは妥当に感じる。ただし、これは、自分が妄想しているだけなので、確実に挙動を理解するために、Source Link の Issue として質問しておいた。

まとめ

NuGet Package Explorer いい感じ!ちなみに、NuGet Package Explorer からキャッシュが消せそうな雰囲気である。Dependencyとかもざっと見れて、かなりいい感じ!今回みたいにはまったときにはいい感じかも。

リソース