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ではなく自分のマニフェストで管理されます。

マニフェストを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パッケージの放流直後はまだNuGet FeedにはListingされてないことがあります。

バージョンが見つからない場合以下のエラーが出るので、出たらパッケージがあるか確認するといいでしょう。

もう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