いまさら聞けないRake入門

  • 11,792 views
Uploaded on

Ruby/Rails勉強会第49回発表資料

Ruby/Rails勉強会第49回発表資料

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
11,792
On Slideshare
0
From Embeds
0
Number of Embeds
1

Actions

Shares
Downloads
45
Comments
0
Likes
14

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. いまさら聞けない Rake 入門 2011/3/12 cuzic
  • 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 により用意可能
      • クリーニング、テスト、パッケージ、ドキュメント作成
  • 24. ご清聴ありがとう ございました