FAKE4からFAKE5への移行手順

6月6日にFAKE5がリリースされました。

この記事は、手元のプロジェクトをFAKE4からFAKE5に移行した時の記録です。 FAKE4ユーザー視点の内容が多いです。

FAKE5のドキュメント

英語しか無いですが、公式ドキュメントのチュートリアルを読めば大体のことは書いてあります。

https://fake.build/

FAKE4を使っている人は、マイグレーションガイドも読みましょう。

FAKE5の変更点

まずはリリースノートを読んでみます。 FAKE4を使っている人にとって特に重要なのがこれらの更新です。

  • Deep integration into the .NET SDK and .Net Core
  • The old runner (FAKE nuget package) is obsolete
  • FakeLib and FAKE.Deploy are obsolete
  • Clean and modularized API - A lot of stuff is obsolete now as it moved to a different location and will be removed with version 6

要約すると、「APIを刷新しました。FAKE6までに移行してください」ということです。

新しいAPIのデザイン

Legacy FAKEではAutoOpenを多用しているために不要なモジュールまでopenされており、個人的に不満に思ってました。 New FAKEではAutoOpenを使わなくなったので、必要なモジュールだけ使えるようになりました。 とても良い変更だと思いますが、パッケージまで細かく分かれるとは思ってませんでした。やりすぎなんだよなあ。

関数の命名規則も変わりました。 Legacy FAKEには「タスクとなるような関数は大文字で始まる。オプションを表現する関数は小文字で始まる」みたいなルールがありましたが、「小文字で始まる」に統一されたみたいです。

実行方法の変更

実行方法がdotnet cli-toolに変わりました。 特に気をつけることは、引数の指定方法が変わったことです。

CLI Migrationによると、 Legacy FAKEではfake.exe build.fsx target=Releaseや、fake.exe build.fsx Releaseという風にターゲットを指定していましたが、 New FAKEではfake.exe build --target Releaseと指定します。 --targetを省略してfake.exe build Releaseとすると、Releaseがターゲット名と認識されず、正しく実行できません。

組み込みPaket

PaketがFAKEに組み込まれています。そのため、FAKE単体で動作するようになります。 組み込みのPaketを使うには、ビルドスクリプトに次のように記述します。

#r "paket:
nuget Fake.Core.Target"
#load "./.fake/build.fsx/intellisense.fsx"

#r "paket: ..."で、ビルドスクリプトで使用するパッケージ依存を記述できます。 #load "./.fake/build.fsx/intellisense.fsx"IDEでビルドスクリプトを編集するために必要です。 intellisense.fsxの中身は、Paketで参照しているアセンブリをロードする記述があるだけです。

もちろん外部のPaketも利用できて、paket.dependenciesが既にある場合は次のように記述します。

#r "paket: groupref Build"
#load "./.fake/build.fsx/intellisense.fsx"

ただ、この#r "paket: ..."はfsxファイルのFAKE拡張なので、Visual Studioで開くと警告が出ます。 警告を防ぐには、次のように記述します。

#if FAKE
#r "paket: ..."
#endif
#load "./.fake/build.fsx/intellisense.fsx"

またVisual Studioの問題で、netstandardの参照を追加する必要がある場合があります。

最終的に、現状では次のようにするのが良さそうです。

#if FAKE
#r "paket: ..."
#else
#r "netstandard"
#endif
#load "./.fake/build.fsx/intellisense.fsx"

Legacy FAKEとNew FAKEパッケージの見分け方

Legacy FAKEとNew FAKEのNuGetパッケージは完全に別れており、互換性はありません。すべて大文字のFAKEが含まれるパッケージがLegacy FAKEで、先頭だけ大文字のFakeが含まれるパッケージがNew FAKEです。

移行手順

実際にFAKE4からFAKE5に移行した時の手順を書いていこうと思います。 基本的にはマイグレーションガイドの通りですが、一部うまくいかないところもありました。

想定するプロジェクトは次のとおりです。

  • FAKE4を使っている
  • Paketを使っている
  • FAKEがインストールされていない環境(例えばCI)でも、自動でFAKEをインストールしてビルドできるようにしたい

FAKE.Lib を更新してAPIの変更点を洗い出す

FAKE5にもLegacyなAPIは"FAKE.Lib"パッケージとして残されています。"FAKE.Lib"のバージョンを5.0.0以降に更新します。 更新すると、LegacyなAPI全てにObsoleteAttributeが付与されているので、警告がでます。 警告メッセージに移行先のモジュールが書かれているので、覚えておきます。どの関数に移行したかまでは書かれていません。

FAKE5のdotnet cli-toolとテンプレートをインストールする

Getting Startedに書かれている方法で、FAKE5とテンプレートをインストールします。 次のコマンドでインストールします。

dotnet tool install fake-cli-g
dotnet new -i "fake-template::*"

FAKEのbootstrapをプロジェクトにインストールする

この作業はCIでビルドしないのなら必要ないです。

  1. build.fsxとpaket.depencenciesを削除する

    bootstrapをインストールするときにこの2つがあると実行できません。 あとでgitを使って復元します。

  2. dotnet new fake --bootstrap projectを実行する

    build.fsxbuild.projfake.cmdfake.shpaket.dependenciesが新しく作られます。

  3. build.fsxとpaket.depencenciesを復元する

    git checout -- build.fsx paket.dependencies

これで、リポジトリのclone後にfake.cmdを実行すると、FAKEがインストールされるようになります。 bootstrapの原理はfake.cmdbuild.projの中身を見てください。

ビルドスクリプトをFAKE5に移行する

paket.dependenciesのBuildグループを書き換える

とりあえず最小の構成にします。必要なパッケージは後で追加します。

group Build
  framework: netstandard2.0
  source https://nuget.org/api/v2

  nuget Fake.Core.Target

ProjectScaffoldを使っている場合は、github fsharp/FAKE modules/Octokit/Octokit.fsxも削除します。

build.fsxにPaket関係を追記する

#if FAKE
#r "paket: groupref Build"
#else
#r "netstandard"
#endif
#load "./.fake/build.fsx/intellisense.fsx"

この時点では、まだ./.fake/build.fsx/intellisense.fsxは存在しません。

intellisense.fsxを生成する

ビルドスクリプトfake.exeに読み込ませると、intellisence.fsxが更新されます。

スクリプトのターゲットを実行せずに、ただ読み込ませるだけなら、次のコマンドを実行します。

fake.exe build --help

build.fsxの旧APIを新APIに移行する

先程洗い出した変更点の警告に従って、

  1. paket.dependencies にパッケージを追加
  2. intellisense.fsx を再生成
  3. build.fsx を編集

を繰り返していきます。

APIの移行先のモジュール名とパッケージ名は一致しています。 "Use Fake.DotNet.MSBuild instead"という警告が出た場合は、"Fake.DotNet.MSBuild"パッケージを追加して、"Fake.DotNet"名前空間をopenすると新APIを利用できます。

動作確認

動作確認して無事動いたら終了です。

自分の場合は、FAKE.PersimmonがFAKE5に対応していないので、同等のモジュールを自作することになりました。 他は特に問題なく動作しました。

ProjectScaffoldの状況

現在ProjectScaffoldはFAKE5に移行中です。急いでFAKE5に移行する必要もないので、ProjectScaffoldを使っている人は待ってみるのも良い選択だと思います。