Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
いまさら聞けない Rake 入門 2011/3/12 cuzic
自己紹介 cuzic  といいます きゅーじっく と読みます Ruby  暦は かれこれもう10年くらい 近況 通勤時間は  iPod  で英語字幕付きで  Tech Talk  を見ています Google Tech Talk  の多くは英語字幕データ付で公開 英語リスニングの訓練と最新技術のキャッチアップの両立 英語字幕付きで動画を見るために、専用のツールを開発 今回はそのツールについて、紹介 今後の勉強会予定 3 月 25 日(土) なんかするかも 5 月 12 日(土) メタプログラミング Ruby 読書会 #3 JR尼崎駅徒歩 2 分の場所で開催予定
ビルドツールの主な使い方 ビルド 定義されたルールに従った処理(コンパイルなど)   ex )  *.c  を  *.o  にコンパイル 依存関係の処理があるときに便利   ex)  hello.c  と  hello.h  のどちらかが更新されていた場合    コンパイルを実行し、  hello.o  を再作成  一部を書き換えたときに、必要な作業のみを実施可能 ex) hello.c  だけが変更がある場合は、 hello.o  を再作成 タスク 事前に登録した任意の作業を実施 Rails  での例 データベース処理(マイグレートなど) テスト キャッシュやログなどのクリア ドキュメント生成など
ビルドツールいろいろ 歴史的に数多くのビルドツールが存在 Make  :  伝統的なビルドツール    単語のリストや展開などの概念がカオス Ant  :  Java  で多く使われる    あの  XML  を Ant エディターなしで作る気にはならない Maven  : ビルドを含めたプロジェクト管理ツール     Java 向け。 Ant よりはいいけど、 XML が、ね。。。   Rake  :  Ruby DSL  として書かれたビルドツール    なんでもでき、読みやすく、書きやすい。 Buildr :  Ruby  で書かれた  Java プロジェクト向けビルドツール     Maven 互換レイアウト、 Ant のタスクを網羅 Jake  :  Rake  の  JavaScript  移植版    すべてを  JavaScript  でしたい人向け Ninja  :  Google Chrome  のビルドシステム    高速にビルドできるのが特徴。大規模向け。
Q. Rake  クイズ 次の 2つの実行結果の違いを説明せよ > cat build.rb system <<SCRIPT ./hello ./world SCRIPT > ruby build.rb > cat Rakefile task :default do sh “./hello” sh “./world” end > rake (ヒント) ・  Kernel#system  は 任意のコマンドを実行するための組み込みメソッド。 ・ 複数行書かれれば、 1 行ずつ順に実行される ・  Rakefile  では、引数なしで実行すると、    ① カレントディレクトリの  Rakefile  を探し、    ② その中の  :default  タスクを実行する ・  Rakefile  では  task  タスク名  do  処理内容  end  でタスクを定義できる ・  sh  は任意のコマンドを実行する  Rake  が提供するメソッド
A. Rake クイズ 解答 (1) 表示内容の違い (2)失敗時に  abort  するかの違い > ruby build.rb hello world > rake (in /home/ ~  ) ./hello  hello ./world world  ./hello  :  1 行目のコマンド hello : 1 行目の実行結果 ./world  : 2行目のコマンド world  :  2 行目の実行結果 > ruby build.rb hello world > cat ./hello puts “hello”; exit 1 > rake (in /home/ ~  ) ./hello  hello rake aborted! Command failed with  ~~ 実行ディレクトリを表示 1 行目の exit code  が ゼロ以外でも 2行目が実行される 1 行目の exit code  が ゼロ以外の場合は、 abort  し、以降は実行されない
A. Rake クイズ 解説 (1) 表示内容の違い Rake  を利用すると、豊富なデバッグメッセージを利用できます。 実行したコマンド内容が逐次確認できて便利です。なお、 とすると、実行コマンドの表示を抑止できます。 (2)実行可否の違い Rake  の  sh  は、失敗時に自動的にエラーメッセージを表示して スクリプトの処理が異常終了し、それ以降の処理を実行しません。 この動作は、多くのバッチ処理で期待される動作です。 シェルスクリプトや  system  コマンドなどでは本来しなければ ならなかった異常終了させることを忘れ、困った結果になったりします。 しかしながら、 Rake  の  sh  を使えば異常終了を忘れることはありません。 > rake –q > rake –s または
今回作成する  Rake  プロジェクト Youtube  動画から字幕付動画の生成処理を作成 (0) プレイリストに字幕付き動画を登録(手動) (1) プレイリスト一覧を表示 > rake show (2) プレイリストから選択し動画 URL を保存 > rake download no=4 これで、 data/F6k8lTrAE2g/F6k8lTrAE2g.url  が生成される (3) 動画 URL  から字幕をダウンロード > rake data/F6k8lTrAE2g/F6k8lTrAE2g.timedtext (4) 字幕を  Youtube 形式から、 mencoder 用の形式に変換   > rake data/F6k8lTrAE2g/F6k8lTrAE2g.srt (5) 動画 URL  から動画をダウンロード > rake data/F6k8lTrAE2g/F6k8lTrAE2g.url (6) 動画と字幕を mencoder で合成し、新たな動画を生成   > rake data/F6k8lTrAE2g/F6k8lTrAE2g.eng.mp4
字幕付動画作成プロジェクトの依存関係 字幕付き動画 F6k8lTrAE2g.url F6k8lTrAE2g.mp4 F6k8lTrAE2g.timedtext F6k8lTrAE2g.srt F6k8lTrAE2g.eng.mp4 プレイリスト 1: ~ 2: ~ 3: ~ ・・・ bin/playlist --no 4 bin/youtube-dl $(cat F6k8lTrAE2g.url) bin/timedtext-dl  F6k8lTrAE2g.url bin/timedtext2srt  F6k8lTrAE2g.timedtext bin/embed_cc  F6k8lTrAE2g.eng.mp4 rake show bin/playlist --show
(1) プレイリスト一覧を表示 Rakefile  では、通常の  Ruby  の文法でなんでも処理を記述可能 冒頭で  bin  と  data  のディレクトリの変数への格納処理を実施 directory : 引数のディレクトリを作成 desc  :  rake –T  のタスク一覧を表示したときに説明文を掲載可能     タスクの簡単な説明を記述する task  タスク名  do  処理内容  end  :   ここでは実際の処理  playlist --show  を実行 > cat Rakefile bin = File.join(File.dirname(__FILE__), “bin”) data = File.join(File.dirname(__FILE__), “data”) directory data desc “show all video’s title and other info” task :show do   sh “#{bin}/playlist --show” end > rake –T rake show  # show all video’s title and other info
(2) プレイリストから選択し動画 URL を保存 Rake  のタスクで引数が必要な場合 タスク名のあとに 引数名 = 値 を書く 環境変数「引数名」に値が文字列として格納される 環境変数は定数  ENV  からハッシュとしてアクセス可能 明示的に失敗させる場合は、 fail  メソッドを使う 標準エラーに文字列を表示。 exit code (1)  で異常終了 desc &quot;download youtube video&quot; task :download do |t| no = ENV[&quot;no&quot;]   unless no    fail “please specify number. ex) rake download no=4“   end sh “#{bin}/playlist --no #{no}” end > rake download no=4
(3) 字幕ダウンロード (4)字幕の形式を変換 rule &quot;.timedtext&quot; => [&quot;.url&quot;] do |t| sh &quot;#{bin}/timedtext-dl #{t.source}&quot; end rule &quot;.srt&quot; => [&quot;.timedtext&quot;] do |t| sh &quot;#{bin}/timedtext2srt #{t.source}&quot; end > rake data/ F6k8lTrAE2g.srt   rule  を使うと、拡張子から必要なタスクを考えることができる 書き方は  rule  target  =>  source  do |t|  処理  end target  を生成するときに依存するファイルを  source  に記述する source  は1個の文字列。複数あれば配列で指定する。 t.source  で、最初の依存するファイル を取得する timedtext-dl  ~ .url timedtext2srt  ~ .timedtext
(5) 動画をダウンロード youtube-dl  はカレントディレクトリに保存 see  http://rg3.github.com/youtube-dl/ 22: mp4 1280x720, 18 :  mp4 480x360, 17: 3gp(176x144) Rake  タスク内では任意のコードを実行できるため、 open( filename ).read  でファイルの内容を取得可能 異常終了すると困る場合は、 system  を利用する or  で文をつなげると正常終了するまで続けられる Dir.chdir ( dir )  do  statements  end   で statements   の処理を実行するディレクトリを変更可能 > rake data/ F6k8lTrAE2g.mp4 rule &quot;.mp4&quot; => [&quot;.url&quot;] do |t| url = open(t.source).read.chomp Dir.chdir(File.dirname(t.name)) do  system(&quot;#{bin}/youtube-dl&quot;, &quot;-f&quot;, “18&quot;, &quot;-c&quot;, url) or system(&quot;#{bin}/youtube-dl&quot;, &quot;-f&quot;, &quot;17&quot;, &quot;-c&quot;, url) or sh(&quot;#{bin}/youtube-dl&quot;, &quot;-f&quot;, “22&quot;, &quot;-c&quot;, url) end end
(6) 字幕付動画を作成 rule  target  =>  sources  の  sources  配列の要素が Proc   オブジェクトの場合、依存ファイルの推定ロジックを 独自に実装可能 下記の例であれば、 target  が  data/F6k8lTrAE2g.eng.mp4   であれば、 data/F6k8lTrAE2g.mp4  と  data/F6k8lTrAE2g.srt  が  sources   になる ブロックの引数  t  は  target   のファイル名 rule  target  =>  sources  do |t|  statements  end の  t   は  Rake::Task  オブジェクト t.name :  target  のファイル名 > rake data/ F6k8lTrAE2g.eng.mp4 rule “.eng.mp4” => [proc{|t| t.gsub(&quot;.eng.mp4&quot;, &quot;.mp4&quot;)}, proc{|t| t.gsub(&quot;.eng.mp4&quot;, &quot;.srt&quot;)}] do |t| Dir.chdir(File.dirname(t.name)) do  sh &quot;#{bin}/embed_cc #{File.basename t.name}&quot; end end
複数の Rake  タスクの組み合わせ実行(1) 一連のタスクを一度の Rake  で実行したい URL の取得⇒動画 DL ⇒ 字幕 DL⇒ 字幕変換⇒字幕・動画合成 rake  は依存関係は自己解決するので下記の実行でOK 内部的に  rake  を呼び出す場合 > rake download no=23 > rake data/BZhxyXTHA3I/BZhxyXTHA3I.eng.mp4 task :captioned_video do   no = ENV[“no”] unless no fail “please specify no.” end sh “rake –f #{__FILE__} download no=#{no}” video_id = %x(#{bin}/playlist --no #{no} --video_id).chomp sh “rake –f #{__FILE__} #{data}/#{video_id}/#{video_id}.eng.mp4” end > rake captioned_video no=23 no  に対応する video_id  を取得
複数の Rake タスクを自動実行(2) 他の  Rake  タスクを実行するより良い方法 Rake::Task[‘ task_name ’].invoke sh  による方法よりも、 Rakefile  の呼び出しや  Ruby VM  の起動 回数を軽減できる 環境変数なども引き継いで利用することができる 環境変数などを引き継ぎたくない場合は内部で  rake  を呼び出す task :captioned_video2 do   no = ENV[“no”] unless no fail “please specify no.” end Rake::Task[“download”].invoke video_id = %x(#{bin}/playlist --no #{no} --video_id).chomp target = “#{data}/#{video_id}/#{video_id}.eng.mp4” Rake::Task[target].invoke end > rake captioned_video2 no=23 no  に対応する video_id  を取得 タスク(ファイルタスク) 名を動的に生成
クリーニング 作成したファイルを一度削除したいことはままある 依存関係が複雑で、更新日時だけではうまく解決できないとき 不要な一時ファイルを削除したいとき 疲れてきて、コーヒー休憩する口実が欲しいとき require ‘rake/clean’  で  clean  (一時ファイル用)と  clobber  (すべてのファイル用)の2つのタスクを利用可能 require ‘rake/clean’ CLEAN.include(“**/*.{mp4,log,srt,timedtext}”) CLEAN.exclude(“**/*.eng.mp4”) CLOBBER.include(“**/*.mp4”) > rake -T rake clean # Remove any temporary products. rake clobber # Remove any generated file. > rake clean CLEAN : 最終生成物(~ .eng.mp4 )以外はすべて削除 CLOBBER : 最終生成物を 含めてすべて削除
ディレクトリタスクなど 生成した動画は、すべて別のディレクトリに配置される ⇒利便性のため、同一のディレクトリに再配置したい ディレクトリタスクを使うと、ディレクトリの作成を明示不要 ディレクトリを必要とするタスクについては、依存タスクに記載しておく ない場合は作成するし、すでにある場合は何もしない root = File.dirname(__FILE__) DATA = File.join(ROOT, “data”) MP4_GLOB = “#{DATA}/*/*.eng.mp4” mp4_dir = File.join(ROOT, &quot;eng-mp4&quot;) directory mp4_dir desc “collect eng.mp4 files into eng-mp4 directory” task :collect => mp4_dir do ln FileList[MP4_GLOB], mp4_dir end > rake collect
Rake  落穂拾い( 1 ):  file rule  のように拡張子から推測される場合でないときは file  を使う 個別のファイルごとに依存関係を指定したい場合に用いる > cat Rakefile file &quot; F6k8lTrAE2g .timedtext&quot; => &quot; F6k8lTrAE2g .url&quot; do |t| sh &quot;#{bin}/timedtext-dl #{t.source}&quot; end
Rake  落穂拾い(2):  namespace Rake  のタスクを分類したいときは namespace  を使う タスクに “ -”  などを含めたいときは、 %s()  リテラルを使う > cat Rakefile data = File.join(File.dirname(__FILE__), “data”) namespace :zip do  task :srt do     Dir.chdir data do sh “zip srt.zip **/*.srt” end end task %s(eng-mp4) do Dir.chdir data do sh “zip eng-mp4.zip **/*.eng.mp4” end end end > rake zip:srt zip srt.zip **/*.srt
Rake 落穂拾い(3): 追加で用意されるタスク rake/clean  以外にも多数のタスクが用意されている rake/gempackagetask Gem  のパッケージを作成するためのタスク rake/packagetask tar.gz, zip  などのパッケージを作成するためのタスク rake/rdoctask rdoc  のドキュメンテーションを作成するタスク rake/testtask テストを実行するタスクを作成する 他にもあります gems/rake-0.x.x/lib/rake/contrib/  以下を参照
Rake  落穂拾い(4): 注意点 ブロックには  do  ~  end  を使う Ruby  の文法上の制限で  { }  が期待どおり動作しない > cat Rakefile task :default {|t| puts “Hello, World!” } > rake (in  ~ ) rake aborted! ~ : syntax error, unexpected '{', expecting $end (See full trace by running task with --trace) 下記の回避方法はあるが、 DSL  的でないため、通常は do  ~  end  を使うことが好まれる > cat Rakefile task(:default) {|t| puts “Hello, World!” }
まとめ Rake  を使うと、エラー処理を記述不要で楽 sh  を使えば、エラー時の処理停止が自動的に行われる 定義されたルールから依存関係を自動解決可能 コンパイル、テキスト処理、他多数のコマンドに応用可能 複雑なタスクも記述可能 依存ファイルの推定ロジックのカスタマイズ タスク処理中での別のタスクの呼び出し 任意の  Ruby  スクリプトも記述可能 ファイル名を動的に取得可能 標準的な Rake  タスクも  require  により用意可能 クリーニング、テスト、パッケージ、ドキュメント作成
ご清聴ありがとう ございました

More Related Content

いまさら聞けないRake入門

  • 2. 自己紹介 cuzic といいます きゅーじっく と読みます Ruby 暦は かれこれもう10年くらい 近況 通勤時間は iPod で英語字幕付きで Tech Talk を見ています Google Tech Talk の多くは英語字幕データ付で公開 英語リスニングの訓練と最新技術のキャッチアップの両立 英語字幕付きで動画を見るために、専用のツールを開発 今回はそのツールについて、紹介 今後の勉強会予定 3 月 25 日(土) なんかするかも 5 月 12 日(土) メタプログラミング Ruby 読書会 #3 JR尼崎駅徒歩 2 分の場所で開催予定
  • 3. ビルドツールの主な使い方 ビルド 定義されたルールに従った処理(コンパイルなど)   ex ) *.c を *.o にコンパイル 依存関係の処理があるときに便利   ex) hello.c と hello.h のどちらかが更新されていた場合    コンパイルを実行し、 hello.o を再作成 一部を書き換えたときに、必要な作業のみを実施可能 ex) hello.c だけが変更がある場合は、 hello.o を再作成 タスク 事前に登録した任意の作業を実施 Rails での例 データベース処理(マイグレートなど) テスト キャッシュやログなどのクリア ドキュメント生成など
  • 4. ビルドツールいろいろ 歴史的に数多くのビルドツールが存在 Make : 伝統的なビルドツール    単語のリストや展開などの概念がカオス Ant  : Java で多く使われる    あの XML を Ant エディターなしで作る気にはならない Maven : ビルドを含めたプロジェクト管理ツール     Java 向け。 Ant よりはいいけど、 XML が、ね。。。 Rake : Ruby DSL として書かれたビルドツール    なんでもでき、読みやすく、書きやすい。 Buildr : Ruby で書かれた Java プロジェクト向けビルドツール     Maven 互換レイアウト、 Ant のタスクを網羅 Jake : Rake の JavaScript 移植版    すべてを JavaScript でしたい人向け Ninja : Google Chrome のビルドシステム    高速にビルドできるのが特徴。大規模向け。
  • 5. Q. Rake クイズ 次の 2つの実行結果の違いを説明せよ > cat build.rb system <<SCRIPT ./hello ./world SCRIPT > ruby build.rb > cat Rakefile task :default do sh “./hello” sh “./world” end > rake (ヒント) ・ Kernel#system は 任意のコマンドを実行するための組み込みメソッド。 ・ 複数行書かれれば、 1 行ずつ順に実行される ・ Rakefile では、引数なしで実行すると、    ① カレントディレクトリの Rakefile を探し、    ② その中の :default タスクを実行する ・ Rakefile では task タスク名 do 処理内容 end でタスクを定義できる ・ sh は任意のコマンドを実行する Rake が提供するメソッド
  • 6. A. Rake クイズ 解答 (1) 表示内容の違い (2)失敗時に abort するかの違い > ruby build.rb hello world > rake (in /home/ ~ ) ./hello hello ./world world ./hello : 1 行目のコマンド hello : 1 行目の実行結果 ./world : 2行目のコマンド world : 2 行目の実行結果 > ruby build.rb hello world > cat ./hello puts “hello”; exit 1 > rake (in /home/ ~ ) ./hello hello rake aborted! Command failed with ~~ 実行ディレクトリを表示 1 行目の exit code が ゼロ以外でも 2行目が実行される 1 行目の exit code が ゼロ以外の場合は、 abort し、以降は実行されない
  • 7. A. Rake クイズ 解説 (1) 表示内容の違い Rake を利用すると、豊富なデバッグメッセージを利用できます。 実行したコマンド内容が逐次確認できて便利です。なお、 とすると、実行コマンドの表示を抑止できます。 (2)実行可否の違い Rake の sh は、失敗時に自動的にエラーメッセージを表示して スクリプトの処理が異常終了し、それ以降の処理を実行しません。 この動作は、多くのバッチ処理で期待される動作です。 シェルスクリプトや system コマンドなどでは本来しなければ ならなかった異常終了させることを忘れ、困った結果になったりします。 しかしながら、 Rake の sh を使えば異常終了を忘れることはありません。 > rake –q > rake –s または
  • 8. 今回作成する Rake プロジェクト Youtube 動画から字幕付動画の生成処理を作成 (0) プレイリストに字幕付き動画を登録(手動) (1) プレイリスト一覧を表示 > rake show (2) プレイリストから選択し動画 URL を保存 > rake download no=4 これで、 data/F6k8lTrAE2g/F6k8lTrAE2g.url が生成される (3) 動画 URL から字幕をダウンロード > rake data/F6k8lTrAE2g/F6k8lTrAE2g.timedtext (4) 字幕を Youtube 形式から、 mencoder 用の形式に変換   > rake data/F6k8lTrAE2g/F6k8lTrAE2g.srt (5) 動画 URL から動画をダウンロード > rake data/F6k8lTrAE2g/F6k8lTrAE2g.url (6) 動画と字幕を mencoder で合成し、新たな動画を生成   > rake data/F6k8lTrAE2g/F6k8lTrAE2g.eng.mp4
  • 9. 字幕付動画作成プロジェクトの依存関係 字幕付き動画 F6k8lTrAE2g.url F6k8lTrAE2g.mp4 F6k8lTrAE2g.timedtext F6k8lTrAE2g.srt F6k8lTrAE2g.eng.mp4 プレイリスト 1: ~ 2: ~ 3: ~ ・・・ bin/playlist --no 4 bin/youtube-dl $(cat F6k8lTrAE2g.url) bin/timedtext-dl F6k8lTrAE2g.url bin/timedtext2srt F6k8lTrAE2g.timedtext bin/embed_cc F6k8lTrAE2g.eng.mp4 rake show bin/playlist --show
  • 10. (1) プレイリスト一覧を表示 Rakefile では、通常の Ruby の文法でなんでも処理を記述可能 冒頭で bin と data のディレクトリの変数への格納処理を実施 directory : 引数のディレクトリを作成 desc : rake –T のタスク一覧を表示したときに説明文を掲載可能     タスクの簡単な説明を記述する task タスク名 do 処理内容 end :   ここでは実際の処理  playlist --show  を実行 > cat Rakefile bin = File.join(File.dirname(__FILE__), “bin”) data = File.join(File.dirname(__FILE__), “data”) directory data desc “show all video’s title and other info” task :show do sh “#{bin}/playlist --show” end > rake –T rake show # show all video’s title and other info
  • 11. (2) プレイリストから選択し動画 URL を保存 Rake のタスクで引数が必要な場合 タスク名のあとに 引数名 = 値 を書く 環境変数「引数名」に値が文字列として格納される 環境変数は定数 ENV からハッシュとしてアクセス可能 明示的に失敗させる場合は、 fail メソッドを使う 標準エラーに文字列を表示。 exit code (1) で異常終了 desc &quot;download youtube video&quot; task :download do |t| no = ENV[&quot;no&quot;] unless no   fail “please specify number. ex) rake download no=4“ end sh “#{bin}/playlist --no #{no}” end > rake download no=4
  • 12. (3) 字幕ダウンロード (4)字幕の形式を変換 rule &quot;.timedtext&quot; => [&quot;.url&quot;] do |t| sh &quot;#{bin}/timedtext-dl #{t.source}&quot; end rule &quot;.srt&quot; => [&quot;.timedtext&quot;] do |t| sh &quot;#{bin}/timedtext2srt #{t.source}&quot; end > rake data/ F6k8lTrAE2g.srt rule を使うと、拡張子から必要なタスクを考えることができる 書き方は  rule target => source do |t| 処理 end target を生成するときに依存するファイルを source に記述する source は1個の文字列。複数あれば配列で指定する。 t.source で、最初の依存するファイル を取得する timedtext-dl ~ .url timedtext2srt ~ .timedtext
  • 13. (5) 動画をダウンロード youtube-dl はカレントディレクトリに保存 see http://rg3.github.com/youtube-dl/ 22: mp4 1280x720, 18 : mp4 480x360, 17: 3gp(176x144) Rake タスク内では任意のコードを実行できるため、 open( filename ).read でファイルの内容を取得可能 異常終了すると困る場合は、 system を利用する or で文をつなげると正常終了するまで続けられる Dir.chdir ( dir ) do statements end で statements の処理を実行するディレクトリを変更可能 > rake data/ F6k8lTrAE2g.mp4 rule &quot;.mp4&quot; => [&quot;.url&quot;] do |t| url = open(t.source).read.chomp Dir.chdir(File.dirname(t.name)) do system(&quot;#{bin}/youtube-dl&quot;, &quot;-f&quot;, “18&quot;, &quot;-c&quot;, url) or system(&quot;#{bin}/youtube-dl&quot;, &quot;-f&quot;, &quot;17&quot;, &quot;-c&quot;, url) or sh(&quot;#{bin}/youtube-dl&quot;, &quot;-f&quot;, “22&quot;, &quot;-c&quot;, url) end end
  • 14. (6) 字幕付動画を作成 rule target => sources の sources 配列の要素が Proc オブジェクトの場合、依存ファイルの推定ロジックを 独自に実装可能 下記の例であれば、 target が data/F6k8lTrAE2g.eng.mp4 であれば、 data/F6k8lTrAE2g.mp4 と data/F6k8lTrAE2g.srt が sources になる ブロックの引数 t は target のファイル名 rule target => sources do |t| statements end の t は Rake::Task オブジェクト t.name : target のファイル名 > rake data/ F6k8lTrAE2g.eng.mp4 rule “.eng.mp4” => [proc{|t| t.gsub(&quot;.eng.mp4&quot;, &quot;.mp4&quot;)}, proc{|t| t.gsub(&quot;.eng.mp4&quot;, &quot;.srt&quot;)}] do |t| Dir.chdir(File.dirname(t.name)) do sh &quot;#{bin}/embed_cc #{File.basename t.name}&quot; end end
  • 15. 複数の Rake タスクの組み合わせ実行(1) 一連のタスクを一度の Rake で実行したい URL の取得⇒動画 DL ⇒ 字幕 DL⇒ 字幕変換⇒字幕・動画合成 rake は依存関係は自己解決するので下記の実行でOK 内部的に rake を呼び出す場合 > rake download no=23 > rake data/BZhxyXTHA3I/BZhxyXTHA3I.eng.mp4 task :captioned_video do no = ENV[“no”] unless no fail “please specify no.” end sh “rake –f #{__FILE__} download no=#{no}” video_id = %x(#{bin}/playlist --no #{no} --video_id).chomp sh “rake –f #{__FILE__} #{data}/#{video_id}/#{video_id}.eng.mp4” end > rake captioned_video no=23 no に対応する video_id を取得
  • 16. 複数の Rake タスクを自動実行(2) 他の Rake タスクを実行するより良い方法 Rake::Task[‘ task_name ’].invoke sh による方法よりも、 Rakefile の呼び出しや Ruby VM の起動 回数を軽減できる 環境変数なども引き継いで利用することができる 環境変数などを引き継ぎたくない場合は内部で rake を呼び出す task :captioned_video2 do no = ENV[“no”] unless no fail “please specify no.” end Rake::Task[“download”].invoke video_id = %x(#{bin}/playlist --no #{no} --video_id).chomp target = “#{data}/#{video_id}/#{video_id}.eng.mp4” Rake::Task[target].invoke end > rake captioned_video2 no=23 no に対応する video_id を取得 タスク(ファイルタスク) 名を動的に生成
  • 17. クリーニング 作成したファイルを一度削除したいことはままある 依存関係が複雑で、更新日時だけではうまく解決できないとき 不要な一時ファイルを削除したいとき 疲れてきて、コーヒー休憩する口実が欲しいとき require ‘rake/clean’ で clean (一時ファイル用)と clobber (すべてのファイル用)の2つのタスクを利用可能 require ‘rake/clean’ CLEAN.include(“**/*.{mp4,log,srt,timedtext}”) CLEAN.exclude(“**/*.eng.mp4”) CLOBBER.include(“**/*.mp4”) > rake -T rake clean # Remove any temporary products. rake clobber # Remove any generated file. > rake clean CLEAN : 最終生成物(~ .eng.mp4 )以外はすべて削除 CLOBBER : 最終生成物を 含めてすべて削除
  • 18. ディレクトリタスクなど 生成した動画は、すべて別のディレクトリに配置される ⇒利便性のため、同一のディレクトリに再配置したい ディレクトリタスクを使うと、ディレクトリの作成を明示不要 ディレクトリを必要とするタスクについては、依存タスクに記載しておく ない場合は作成するし、すでにある場合は何もしない root = File.dirname(__FILE__) DATA = File.join(ROOT, “data”) MP4_GLOB = “#{DATA}/*/*.eng.mp4” mp4_dir = File.join(ROOT, &quot;eng-mp4&quot;) directory mp4_dir desc “collect eng.mp4 files into eng-mp4 directory” task :collect => mp4_dir do ln FileList[MP4_GLOB], mp4_dir end > rake collect
  • 19. Rake 落穂拾い( 1 ): file rule のように拡張子から推測される場合でないときは file を使う 個別のファイルごとに依存関係を指定したい場合に用いる > cat Rakefile file &quot; F6k8lTrAE2g .timedtext&quot; => &quot; F6k8lTrAE2g .url&quot; do |t| sh &quot;#{bin}/timedtext-dl #{t.source}&quot; end
  • 20. Rake 落穂拾い(2): namespace Rake のタスクを分類したいときは namespace を使う タスクに “ -” などを含めたいときは、 %s() リテラルを使う > cat Rakefile data = File.join(File.dirname(__FILE__), “data”) namespace :zip do task :srt do     Dir.chdir data do sh “zip srt.zip **/*.srt” end end task %s(eng-mp4) do Dir.chdir data do sh “zip eng-mp4.zip **/*.eng.mp4” end end end > rake zip:srt zip srt.zip **/*.srt
  • 21. Rake 落穂拾い(3): 追加で用意されるタスク rake/clean 以外にも多数のタスクが用意されている rake/gempackagetask Gem のパッケージを作成するためのタスク rake/packagetask tar.gz, zip などのパッケージを作成するためのタスク rake/rdoctask rdoc のドキュメンテーションを作成するタスク rake/testtask テストを実行するタスクを作成する 他にもあります gems/rake-0.x.x/lib/rake/contrib/ 以下を参照
  • 22. Rake 落穂拾い(4): 注意点 ブロックには do ~ end を使う Ruby の文法上の制限で { } が期待どおり動作しない > cat Rakefile task :default {|t| puts “Hello, World!” } > rake (in ~ ) rake aborted! ~ : syntax error, unexpected '{', expecting $end (See full trace by running task with --trace) 下記の回避方法はあるが、 DSL 的でないため、通常は do ~ end を使うことが好まれる > cat Rakefile task(:default) {|t| puts “Hello, World!” }
  • 23. まとめ Rake を使うと、エラー処理を記述不要で楽 sh を使えば、エラー時の処理停止が自動的に行われる 定義されたルールから依存関係を自動解決可能 コンパイル、テキスト処理、他多数のコマンドに応用可能 複雑なタスクも記述可能 依存ファイルの推定ロジックのカスタマイズ タスク処理中での別のタスクの呼び出し 任意の Ruby スクリプトも記述可能 ファイル名を動的に取得可能 標準的な Rake タスクも require により用意可能 クリーニング、テスト、パッケージ、ドキュメント作成