2022年4月20日水曜日

rake 超入門

rake 超入門

概要

rake は Ruby 製のタスク管理ツールです
make の Ruby 版で rake という名前になっています
今回は導入としてサンプルを元に基本的な使い方を紹介します

環境

  • macOS 11.6.5
  • ruby 3.1.1p18

ruby スクリプトをコールするタスク

まずは基本の形です
task メソッドにリテラルでタスク名を渡します
そしてブロックでタスクの内容を記述します

rake にはいくつかのリソースが定義されており ruby リソースを使うと指定したパスにある ruby ファイルを実行することができます

desc は rake -T でタスクの一覧を表示する対象となるために必要です
公開するタスクには基本的に desc を使って説明文を挿入しましょう

desc "Execute ruby script."
task :run_script do
  ruby "app.rb"
end

実行する場合は以下で実行できます

  • rake run_script

タスクの依存関係を定義する

例えばあるタスクの前に別のタスクを実行したいことがあると思います
その場合はタスクの定義をハッシュで渡します

desc "Execute ruby script."
task :run_script do
  ruby "app.rb"
end

desc "Show hello message."
task echo: [:run_script] do |t|
  sh "echo Hello #{t.name} task."
end

echo: [:run_script] の部分がハッシュになっているのがわかります
以下の書き方でも動作します

echo_task = {
  echo: [:run_script]
}
desc "Show hello message."
task echo_task  do |t|
  sh "echo Hello #{t.name} task."
end

ちなみに sh リソースは指定されたコマンドを実行することができるリソースです

  • rake echo

タスクに引数を渡す

タスクに引数を渡すこともできます
タスク名の次の引数で配列で引数名を渡します
ブロック内で参照する場合は

args.name
のように参照できます

with_defaults を使うとデフォルト値を設定できます

desc "Show args."
task :puts, [:name, :age]  do |t, args|
  args.with_defaults(:name => "hawk", :age => 10)
  puts "name => #{args.name}, age => #{args.age}"
end

シングルクオートでタスク名を囲っているのは zsh: no matches found 対策です

ファイルタスク

いままでは task を使ってきましたが file というタスクも定義できます
ファイルやディレクトリの操作に特化したタスクで依存しているファイルタスクで指定したファイル名がすでに存在する場合は依存タスクを実行しないという特性があります

file "date.txt" do
  touch "date.txt"
end

desc "Print current time to file if does not exist."
file "print_now" => ["date.txt"] do |t|
  sh "date > date.txt"
end

これで

  • rake print_now

をすると一回目は touch が実行されますが二回目は touch が実行されないのが確認できると思います

namespace でタスクをまとめる

タスク同士をまとめて管理したい場合は namespace を使うと管理しやすくなります

namespace :test do
  desc "Print hello."
  task :echo do
    puts "hello."
  end
end

タスクをクラスとして定義する

Rake::Task を継承してやることもできそうですがいろいろ面倒なのでタスクの内容を単純にクラスにしてあげることでも実現できます

class User
  def initialize(name, age)
    @name = name
    @age = age
  end

  def show
    puts "name => #{@name}, age => #{@age}"
  end
end

desc "Show user profile."
task :show_profile do
  user = User.new("hawk", 20)
  user.show
end

この User クラスの部分だけ他のファイルに分割して管理してあげるとタスクの内容がクラスに分割できるので良いかなと思います

最後に

単純に Ruby を書くことができるので例えばクラスを定義して何かしたり net/http などを使って外部にアクセスするようなタスクを定義することもできます

rake 自体にいろいろなデフォルトメソッドが用意されているのでこれでも十分かなと思います

rake のデフォルトメソッド一覧 -> https://ruby.github.io/rake/table_of_contents.html#methods

あとはクラスとして定義したいというケースもあるかなと思います
書けなくはないっぽいですがかなり面倒な感じなのでクラスとしてタスクを書きたい場合はタスクの内容をクラスとして定義するか rake にしないで単純に ruby ファイルとしてタスクの内容を定義しましょう

rake タスクとしてわざわざタスク化するメリットとしては以下があるかなと思います

  • rake -T でタスク化したものをまとめて確認することができる
  • rake のデフォルトメソッドが使える
  • make は書けないが ruby は書ける人がタスク定義したい場合

参考サイト

0 件のコメント:

コメントを投稿