tech.guitarrapc.cóm

Technical updates

DotNetCliToolReference から .NET Core Local Tools へ移行する

前回、.NET Core Tools と DotNetCliToolReference についてみてみました。

tech.guitarrapc.com

DotNetCliToolReference がオワコンということで、.NET Core Local Tools に移行しないと、ということもあるわけでどのようにやったかを残しておきます。

目次

TL;DR

  • .NET Core 3.1 からはDotNetCliToolReference を .NET Core Local Tools へ移行が必要
  • .NET Global Tools に公開してあるパッケージなら支障なく移行できる
  • 実行タイミングなどのTarget は今まで通りでok

Step by Step

都合により、.NET Framework 4.6 で組んでいたプロジェクトを .NET Core 3.1 プロジェクトに変更する流れで見ていきます。

net46 参照でも、SDK Style な csproj であれば DotNetCliToolReference は利用できます。

Before & After

もともと DotNetCliToolReference を使っていたプロジェクトを、.NET Core Local Tools に移行してみます。

Before

DotCliToolReference で参照していた dotnet-kustomizationconfigmapgenerator-project-tool をやめます。

NuGet Gallery | dotnet-kustomizationconfigmapgenerator-project-tool 0.2.1

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net46</TargetFramework>
    <DisableFastUpToDateCheck>True</DisableFastUpToDateCheck>
  </PropertyGroup>

  <ItemGroup>
    <DotNetCliToolReference Include="dotnet-kustomizationconfigmapgenerator-project-tool" Version="0.2.1" />
  </ItemGroup>

  <Target Name="PreBuild" BeforeTargets="PreBuildEvent">
    <Exec Command="dotnet kustomizationconfigmapgenerator" />
  </Target>

</Project>

After

.NET Tool として公開している .NET Core Tools のKustomizeConfigMapGenerator に切り替えます。

NuGet Gallery | KustomizeConfigMapGenerator 0.2.1

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <DisableFastUpToDateCheck>True</DisableFastUpToDateCheck>
  </PropertyGroup>

  <Target Name="PreBuild" BeforeTargets="PreBuildEvent">
    <Exec Command="dotnet tool restore" />
    <Exec Command="dotnet tool run dotnet-kustomizeconfigmapgenerator" />
  </Target>

</Project>

Step1. DotNetCliToolReference を外す

DotNetCliToolReference は Visual Studio などのUIからは操作できません。 .csproj を直接触ってDotNetCliToolReference の参照を消しましょう。

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net46</TargetFramework>
    <DisableFastUpToDateCheck>True</DisableFastUpToDateCheck>
  </PropertyGroup>

  <Target Name="PreBuild" BeforeTargets="PreBuildEvent">
    <Exec Command="dotnet kustomizationconfigmapgenerator" />
  </Target>

</Project>

Step2. .NET Core 3.1に変更する

TargetFramework を net46 から netcoreapp3.1 に変更します。

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <DisableFastUpToDateCheck>True</DisableFastUpToDateCheck>
  </PropertyGroup>

  <Target Name="PreBuild" BeforeTargets="PreBuildEvent">
    <Exec Command="dotnet kustomizationconfigmapgenerator" />
  </Target>

</Project>

Step3. .NET Core Local Tool のマニフェストを生成する

.NET Core Local Tools は、.csproj ではなく自分のマニフェストで管理されます。

マニフェストを、.NET Core 3.1 SDK で実行できる dotnet new tool-manifest で生成します。

dotnet new tool-manifest

Step4. ツールの参照を追加

.NET Core Local Tools は、.NET Global Tools で配布しているパッケージを追加できます。

dotnet-kustomizationconfigmapgenerator-project-tool は DotNetCliToolReference 専用の nuget パッケージでしたが、.NET Tool として公開している KustomizeConfigMapGenerator に変更します。

dotnet tool install KustomizeConfigMapGenerator

これで .config/dotnet-tools.jsonKustomizeConfigMapGenerator が追記されました。

{
  "version": 1,
  "isRoot": true,
  "tools": {
    "kustomizeconfigmapgenerator": {
      "version": "0.2.1",
      "commands": [
        "dotnet-kustomizeconfigmapgenerator"
      ]
    }
  }
}

Step5. ビルド前処理に差し込みます

.NET Local Tools を任意のビルドターゲットで実行します。

TIPS: 実行前に必ず dotnet tool restore を行います。

例えばビルド前 BeforeBuild に行いたいならこうでしょう。(PreBuild ターゲットもありです)

<Target Name="Your_Task" BeforeTargets="BeforeBuild">
    <Exec Command="dotnet tool restore" />
    <Exec Command="dotnet tool run dotnet-kustomizeconfigmapgenerator" />
</Target>

うまく実行できればあとはいい感じで引数を渡せばいいでしょう。

TIPS

複数の実行処理をTaskに定義したい

.NET Core Local Tools のTIPS ではないのですが、ターゲットの中で複数行にわたる処理を書きたい場合は、複数 Exec にすると見やすいです。 上からシーケンシャルに実行されることが保証されているのでシンプルでいいでしょう。

↑の例はそうですね。

Exec 内で処理が完結するなら見やすくなります。

指定したバージョンのNuGetパッケージが見つからないケース

dotnet tool install 後に、バージョンを更新した、ということで手で dotnet-tools.json を書き換えた場合、そのバージョンのNuGet パッケージがあるか保証されません。

もし放流直後だと、まだ NuGet Feed にはListingされてないことがあります。

そうすると以下のエラーが出るので、出たらパッケージがあるか確認するといいでしょう。

f:id:guitarrapc_tech:20191220235554p:plain

もう push したと思っても、NuGet にはまだ index されていないと出ています。

This package has not been indexed yet. It will appear in search results and will be available for install/restore after indexing is complete.

DisableFastUpToDateCheck は何

Visual Studio は、ファイル更新がない場合ビルドをスキップします。 このプロパティを有効にすると、ファイル更新の有無にかかわらず ビルド処理まで進んで dotnet cli / msbuild に再ビルドするかを任せます。

つまり、.NET Core Tools などで常にビルド前に処理を挟みたいときはこのプロパティを使うといい感じです。

.NET Core の決定的ビルドと組み合わさることでこれがいい感じになるのですが、詳細はまた別の機会に。

REF

.NET Core ツールの使用に関する問題のトラブルシューティング - .NET Core CLI | Microsoft Docs

New in .NET Core 3.0: local tools: Exploring ASP.NET Core 3.0 - Part 7

.NET Core 3 Local Tools