ruby rake の使い方

# rakeとは
makeコマンドのRubyでの代替

Rakefileにtaskを記述していく。

# 基本

## その1 基本中の基本
rake コマンドは指定しなければカレントディレクトリのRakefileを対象とする。
指定する場合は`rake -f Rakefile01`などとする。Jetbrains系ではRakefileのみFiletypeを解釈してくれるので、Rakefile01などとした場合はproject treeからファイルを右クリックして「Associate with File Type」でRubyを指定すればよい。

https://github.com/abcb2/how2rake/blob/master/Rakefile01

```ruby
# task :default => :hello
task default: :hello

desc "hello"
task :hello do
  puts "Hello Rake!!"
end
```

特に指定しなければdefaultタスクを実行する。defaultタスクはhelloタスクと指定している。hashのkey => valueで指定している。`default: :hello`は単なるhashの省略記法だ。`rake -T`でタスク一覧を表示

## その2 タスクの階層化
https://github.com/abcb2/how2rake/blob/master/Rakefile02

namespaceを使って構造化することができる。

```ruby
task default: 'basic:hello'

namespace :basic do
  desc "hello"
  task :hello do
    puts "Hello Rake!!"
  end
end

namespace :foo do
  namespace :bar do
    desc "foo bar hoge!!"
    task :hoge do
      puts "foo:bar:hoge!!"
    end
  end
end
```

```
$ rake -f Rakefile02 -T
rake basic:hello   # hello
rake foo:bar:hoge  # foo bar hoge
```
## その3 タスクのチェーン
https://github.com/abcb2/how2rake/blob/master/Rakefile03

taskをチェーンする。「helloタスクはfooタスクとbarタスクの実行」だ。

```ruby
desc "invoke foo bar"
task :hello => %w[foo bar]

task :foo do
  puts "hello foo"
end

task :bar do
  puts "hello bar"
end
```

```
$ rake -f Rakefile03 -T
rake hello  # invoke foo bar
$ rake -f Rakefile03 hello
hello foo
hello bar
```

## その4 タスクに引数を渡す
https://github.com/abcb2/how2rake/blob/master/Rakefile04

タスク実行時に引数を渡したい。柔軟なコマンドライン引数インタフェースにしたい場合はargparseなりでコマンドを作りこんでおいた方が良いかもしれない。

```ruby
desc "hello task"
task :hello, [:name, :job] => [:hi, :bye]


task :hi, [:name, :job] do |task, args|
  puts "DEBUG: #{task}, #{args}"
  puts "Hi #{args[:name]}, #{args[:job]}"
end

task :bye, [:name, :job] do |task, args|
  puts "DEBUG: #{task}, #{args}"
  puts "bye #{args[:name]}, #{args[:job]}"
end
```

```
$rake -f Rakefile04 -T
rake hello[name,job]  # hello task
$ rake -f Rakefile04 "hello[taro, jedi]"
DEBUG: hi, #<Rake::TaskArguments name: taro, job: jedi>
Hi taro, jedi
DEBUG: bye, #<Rake::TaskArguments name: taro, job: jedi>
bye taro, jedi
```
# ちょっとAdvance
## その1 rule, pathmapを使う

https://github.com/abcb2/how2rake/blob/master/Rakefile05

srcディレクトリ以下にあるmarkdownをoutディレクトリ以下にhtmlにコンバートするというタスクを作る。手続き型脳だと理解に苦しむところもあるかもしれないが、慣れかと思います。
pathmapはrakeに定義されている便利な関数。使い方の詳細は[ソースのコメント](https://github.com/ruby/rake/blob/master/lib/rake/ext/string.rb)を確認のこと。
ruleという新しいDSLも使っている。DSLの一覧もまぁ[ソース](https://github.com/ruby/rake/blob/master/lib/rake/dsl_definition.rb)をのぞくと理解が早い。FileUtilsExtがincludeされているのでファイル操作はlinuxのコマンドライン感覚でできる。

```ruby
src_files = Rake::FileList.new("src/*.md")
pathmapped_files = src_files.pathmap("%{src,out}X.html")
p src_files
p pathmapped_files

task default: :create_html
task :create_html => pathmapped_files

rule %r{out/.+\.html} => '%{^out,src}X.md' do |t|
  mkdir_p t.name.pathmap("%d")
  puts "convert #{t.source} to #{t.name}"
end

desc "rm -rf out/"
task :clean do
  rm_rf "out"
end
```

`--rules`オプションでルールの適用過程を確認できる。

```
$ rake -f Rakefile05 -T
["src/hoge.md", "src/moge.md"]
["out/hoge.html", "out/moge.html"]
rake clean  # rm -rf out/

$ rake -f Rakefile05 --rules
["src/hoge.md", "src/moge.md"]
["out/hoge.html", "out/moge.html"]
Attempting Rule out/hoge.html => src/hoge.md
(out/hoge.html => src/hoge.md ... EXIST)
Attempting Rule out/moge.html => src/moge.md
(out/moge.html => src/moge.md ... EXIST)
mkdir -p out
convert src/hoge.md to out/hoge.html
mkdir -p out
convert src/moge.md to out/moge.html

```