著作一覧 |
Rails 3.2.1でちょっとアプリケーションを作ってみようかと試したら、いきなりrake assets:precompileでエラーになる。
C:\tmp\webtest>rake assets:precompile c:/Users/arton/NougakuDo/bin/ruby.exe c:/Users/arton/NougakuDo/bin/rake.bat asse ts:precompile:all RAILS_ENV=production RAILS_GROUPS=assets c:/Users/arton/NougakuDo/bin/rake.bat:1: syntax error, unexpected tIDENTIFIER, e xpecting $end rake aborted! Command failed with status (1): [c:/Users/arton/NougakuDo/bin/ruby.exe c:/U...] Tasks: TOP => assets:precompile (See full trace by running task with --trace)
なんだこれ? と追っかけて行ったら、actionpackにたどりついた。
namespace :assets do def ruby_rake_task(task, fork = true) env = ENV['RAILS_ENV'] || 'production' groups = ENV['RAILS_GROUPS'] || 'assets' args = [$0, task,"RAILS_ENV=#{env}","RAILS_GROUPS=#{groups}"] args << "--trace" if Rake.application.options.trace fork ? ruby(*args) : Kernel.exec(FileUtils::RUBY, *args) end
fork = true1なら、ruby(*args)を実行し、そうでなければKernel.exec(FileUtils::Ruby, *args)を実行する。これが諸悪の根源だ。
Rails 3.1.0のときは次のようになっていた。
Kernel.exec $0, *ARGV
元のコマンド($0)に引数を与える。
こういうことだ。
3.1.0のときに、rake assets:precompile とコマンドラインで打つと、それはrake.batの実行となるので、$0にはrake.batが入る。つまり、rake.batに引数を与えて実行することになる。
でも、3.2.1では違う。明示的にFileUtils::RUBY(これはrake/file_utilsによる、本物のfileutilsに対する拡張定数)を指定した呼び出しとなるか、またはrubyメソッド(これもrake/file_utilsのメソッド)呼び出しとなる。
ここでは、第2引数を指定していないのでrubyメソッドの呼び出しとなる。
これは中で結局は、rubyを指定して以降を引数として実行する。
つまり、ruby rake.bat ... となる。
Rubyはバッチコマンドの羅列を当たり前だがRubyのスクリプトとはみなさない。
当然、エラーとなる。
actionpackのChangeLogを読むと、Rails 3.1.1 (unreleased)に次の記述を見つけられる。
* Re-launch assets:precompile task using (Rake.)ruby instead of Kernel.exec so it works on Windows [cablegram]
ほー、Windowsで動くようにするためとな……
3.1.0で動いていたのが動かなくなったのだが、いったい、どういうマジックなんだろうか?
Ruby 1.8.7との組み合わせとかか? これをチェックしないと単なるシーソーになりそうだなぁ。
ジェズイットを見習え |
事情は全く知りませんが、とりあえず https://github.com/rails/rails/pull/3121 これみたいですね
そこにつけたらPRしろと応答があったのですが、PRって何かご存じですか?
ちなむと、そこに書いてあることはcygwinあたりだとインチキシェルがshebangを見るので、rake ... 形式で呼び出せるけど、Rubyのsystem関数でまっとうに起動しようとすると、まともなWin32のプロセス起動関数が利用されるので起動できないから、という特殊事情のためみたいですね。
PRってPull Requestか。(Railsをgithubでforkするのってすげぇ面倒な気がするが、考えたらテストを提供しとかないと危ないからしょうがないかな)