ソフトウェアエンジニアの雑記

日々思ったことをまとめます

タスクランナーTaskでモノレポでも快適な開発環境を構築する

Taskを使うとプロジェクトで使うタスクランナーをMakefileから脱却できます。モジュラーモノリス構成のモノレポでも各サブプロジェクトごとにTaskfile.ymlを設置でき便利です。簡単な使い方をご紹介します。

インストール

brew install go-task
scoop bucket add extras
scoop install task

基本的な使い方

go-taskのタスクはTaskfile.ymlに定義します。以下は簡単な例:

version: '3'

tasks:
  hello:
    cmds:
      - echo 'Hello, World!'
    silent: true

このファイルをプロジェクトのルートに置き、task helloを実行するとHello, World!が出力されます。silent: trueはコマンドの実行ログを非表示にし、結果のみを表示します

環境変数の利用

環境変数が使用できます。環境変数は、 {{ .環境変数名 }} で使用できます。 下記は、使用例になります。

version: '3'

env:
  ENV: task env

tasks:
  stdout:
    cmds:
      - echo "Hello,  {{ .ENV }}"
      - echo "Hello, {{ .SHELL_ENV }}"

実行してみます。

export SHELL_ENV="shell env"
task  stdout

Hello, task env
Hello, shell env

Taskfile.ymlからTaskfile.ymlを読み込む

Taskでは、Taskfile.ymlのネストが可能です。 include という機能になります。今回は、commonという共通用のサブプロジェクトがいるという想定にします。

project/
├── Taskfile.yml
├── common/
│   └── Taskfile.yml

common/Taskfile.ymlの内容

version: '3'

tasks:
  common-echo:
    cmds:
      - echo "Hello, Common Taskfile!"

上記をルートのTaskfile.ymlでcommonサブプロジェクトのTaskfile.ymlを読み込む

Taskfile.ymlの内容

version: '3'

includes:
  common:
    basedir: ./common
    desc: Common echo task
    taskfile: ./common/Taskfile.yml

tasks:
  echo:
    desc: Run the dev task
    deps:
      - common:common-echo
    cmds:
      - echo "Hello, Root Taskfile"

タスク一覧をみてみると、下記のようにincludeが成功しています。

task -l

* echo:                     Run the dev task
* common:common-echo:       Common echo task

これでタスクランナーに階層を持たせることができました。

サブプロジェクトからほかのサブプロジェクトのTaskfile.ymlを読み込む

下記のようなディレクトリ構成になっているとします。serviceAサブプロジェクトからcommonサブプロジェクトのタスクを使用したい場合の方法になります。

├── Taskfile.yml
├── common/
│   └── Taskfile.yml
├── serviceA/
│   └── Taskfile.yml

serviceA/Taskfile.ymlは下記のようになります。

version: '3'
includes:
  common:
    description: Common tasks
    basedir: ../common
    taskfile: ../common/Taskfile.yml

tasks:
  serviceA-echo:
    desc: Service A echo task
    deps:
      - common:common-echo
    cmds:
      - echo "Hello, ServiceA Taskfile!"

includesで、common/Taskfile.ymlを読み込めばOKです。こうすることで、プロジェクトで共通のタスクランナーの管理が簡単になります。

ホットリロード

Taskにはホットリロード機能も備わっています。これはかなり便利で、npmなどより軽いので、移行できるならしてもいいかなと思います。

Taskfile.ymlは下記のように書きます。

version: '3'

tasks:
  test:
    cmd: |
       ./gradlew test  // 実行するコマンドを指定
    ignore_error: true   // エラーが発生しても無視 
    sources:   // 対象のファイル群を指定
      - src/main/java/**/*.java
      - src/main/resources/**/*.*
    method: timestamp   // 更新要素を指定する(他にchecksumも使える)

このようにすると、sourcesのファイル群が変更された際にテストが別タスクで実行される

コマンドは、watch用のコマンドがあるので、それを実行する。

task test -w

これで、ファイル変更ごとに./gradlew testが実行される。

まとめ

MakefileだとShellで自前で実装しないといけないものが、Taskだと大体備わっています。GithubActionsでもすぐ使えるので、大変便利かなと。開発環境をよりよくするお供にぜひ使ってみてください。