.NET Core 3 で導入された Local tools

.NET Core は Windows でも Linux でも複数バージョン入れられるし、global.json でプロジェクト毎のスイッチもできるので便利なのだけど、自分は terminal での作業が多いので Global tools の切り替えにちょっと悩んでいた。というよりも、ベストな方法がなにか良く分かっていなかった。個別に path 指定するのもなぁと。

What's new in .NET Core 3.0 | Microsoft Docs

上記のリリースノートに Local tools という項目があるのに気づいたのだけど、これが求めていたもののよう。

Local tools とはなにか

簡単には特定のディレクトリ内でだけ有効になる dotnet tools のこと。

install 先に関しては Global だと %USERPROFILE%\.dotnet になるが、%USERPROFILE%\.nuget\packages になるため、有効にしたいディレクトリ内に install されるという訳ではない。

Ruby でいえば、gem install されるのは global だが、それが複数の Rails プロジェクトで使われるというのと似ている。

もちろん gem install --path と同様に dotnet tool install --tool-path も用意されているので、これを利用してもいい。

以下の dotnet tool install のドキュメントもあるが、少し古い。現在だと以下のようなオプションになっている。

> dotnet tool install --help                                                                                                                                                        Usage: dotnet tool install [options] <PACKAGE_ID>                                                                                                                                                                        
  <PACKAGE_ID>   The NuGet Package Id of the tool to install.

  -g, --global              Install the tool for the current user.
  --local                   Install the tool and add to the local tool manifest (default).
  --tool-path <PATH>        The directory where the tool will be installed. The directory will be created if it does not exist.
  --version <VERSION>       The version of the tool package to install.
  --configfile <FILE>       The NuGet configuration file to use.
  --tool-manifest <PATH>    Path to the manifest file.
  --add-source <SOURCE>     Add an additional NuGet package source to use during installation.
  --framework <FRAMEWORK>   The target framework to install the tool for.
  --disable-parallel        Prevent restoring multiple projects in parallel.
  --ignore-failed-sources   Treat package source failures as warnings.
  --no-cache                Do not cache packages and http requests.
  --interactive             Allows the command to stop and wait for user input or action (for example to complete authentication).
  -h, --help                Show command line help.
  -v, --verbosity <LEVEL>   Set the MSBuild verbosity level. Allowed values are q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic].


> mkdir test
> cd test
> dotnet tool install dotnet-script -g                                                                                                                                              You can invoke the tool using the following command: dotnet-script                                                                                                                                                                    > dotnet script --version                                                                                                                                                           0.50.1                       

まずは上記のように特定のディレクトリで Global tool を導入してみる。バージョンは最新が入る。

次に Local tool をバージョンを変えて導入しようとしてみる。 --localは default なので不要だけど今回だけ。

> dotnet tool install dotnet-script --local --version 0.50.0                                                                                                                        Cannot find a manifest file.                                                                                                                                                                                             For a list of locations searched, specify the "-d" option before the tool name.                                                                                                                                          If you intended to install a global tool, add `--global` to the command.                                                                                                                                                 If you would like to create a manifest, use `dotnet new tool-manifest`, usually in the repo root directory.                          

上記の通り manifest が無いと言われる。suggest されている通り以下のコマンドを実行する。

> dotnet new tool-manifest
> ls 
Mode                 LastWriteTime         Length Name                                                                                                                                                                   ----                 -------------         ------ ----                                                                                                                                                                   d-----        10/18/2019   7:46 AM                .config  
> ls .\.config\                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   Mode                 LastWriteTime         Length Name                                                                                                                                                                   ----                 -------------         ------ ----                                                                                                                                                                   -a----        10/18/2019   7:46 AM            173 dotnet-tools.json   

上記のように .config/dotnet-tools.json が生成されていることが分かる。内容は以下のようになっている。

{version”: 1,
  “isRoot”: true,
  “tools”: {}


> dotnet tool install dotnet-script --version 0.50.0                                                                                                                                You can invoke the tool from this directory using the following commands: 'dotnet tool run dotnet-script' or 'dotnet dotnet-script'.                                                                                     Tool 'dotnet-script' (version '0.50.0') was successfully installed. Entry is added to the manifest file C:\Users\dany1\work\LocalToolsTest\.config\dotnet-tools.json.                                                    
> dotnet script --version

指定されたバージョンが利用できるようになっている。 manifest は以下のように変化している。

  "version": 1,
  "isRoot": true,
  "tools": {
    "dotnet-script": {
      "version": "0.50.0",
      "commands": [

当然ながら、このディレクトリの外になると Global tool が使われる。

> cd ../                                                                                                                                                                            
> dotnet script --version


manifest を repository に commit しておけば、以下のように dotnet tool restore で復元できる。

> dotnet script                                                                                                                                                                     Run "dotnet tool restore" to make the "dotnet-script" command available.                                                                                                                                                 > dotnet tool restore                                                                                                                                                               Tool 'dotnet-script' (version '0.50.0') was restored. Available commands: dotnet-script                                                                                                                                                                                                                                                                                                                                                           Restore was successful.                                                                                                                                                                                                  
> dotnet script --version                                                                                                                                                           


プロジェクトで利用される tool の種類やバージョンを repository に含められて、かつすぐに利用できるようにできるのはいいですね!