rake rails:freeze:edge が上手く動かない

現在の環境

試しにfreeze

この状態で、1.2.6のrails アプリに対してfreeze を実行しようとする。

  • 1. config/environment.rb の内容を書き換える(今回の例では1.2.6)
# Specifies gem version of Rails to use when vendor/rails is not present
# RAILS_GEM_VERSION = '1.2.6' unless defined? RAILS_GEM_VERSION
RAILS_GEM_VERSION = '2.2.2' unless defined? RAILS_GEM_VERSION
  • 2. freeze
$ rake rails:freeze:edge RELEASE=1.2.6
(in /Users/luke/apps/rails/depot)
/Users/luke/apps/rails/depot/config/boot.rb:26:Warning: Gem::SourceIndex#search support for String patterns is deprecated
cd vendor
Downloading Rails from http://dev.rubyonrails.org/archives/rails_1.2.6.zip
Unpacking Rails
rm -rf rails
rm -f rails.zip
rm -f rails/Rakefile
rm -f rails/cleanlogs.sh
rm -f rails/pushgems.rb
rm -f rails/release.rb
touch rails/REVISION_606176a55b90c27687ae17f40fd1af0a86b62246
cd -
Updating current scripts, javascripts, and configuration settings
install -c -m 0755 /opt/local/lib/ruby/gems/1.8/gems/rails-2.2.2/lib/tasks/../../bin/dbconsole script/dbconsole
install -c -m 0755 /opt/local/lib/ruby/gems/1.8/gems/rails-2.2.2/lib/tasks/../../bin/performance/request script/performance/request

vendor 以下にrails コンポーネントが入る、

  • 3. config/environment.rb の内容を元に戻す
# Specifies gem version of Rails to use when vendor/rails is not present
RAILS_GEM_VERSION = '1.2.6' unless defined? RAILS_GEM_VERSION
  • 4. 正しく入ったか試す
$ ruby script/about
./script/../config/../vendor/rails/railties/lib/initializer.rb:47:in `send': undefined method `install_gem_spec_stubs' for #<Rails::Initializer:0x69c08> (NoMethodError)
        from ./script/../config/../vendor/rails/railties/lib/initializer.rb:47:in `run'
        from ./script/../config/boot.rb:46:in `load_initializer'
        from ./script/../config/boot.rb:38:in `run'
        from ./script/../config/boot.rb:11:in `boot!'
        from ./script/../config/boot.rb:109
        from script/about:2:in `require'
        from script/about:2

上手くいかない。

原因

端的に言うと、freeze する際にboot.rb とかまで書き換えられてしまうから。実際に、freeze 前と現時点での差分は以下のようになっている。

$ svn st
?      script/dbconsole
?      script/performance/request
M      config/boot.rb
?      vendor/rails
M      public/javascripts/prototype.js
M      public/javascripts/effects.js
M      public/javascripts/dragdrop.js
M      public/javascripts/controls.js

対策

boot.rb が問題なので、boot.rb を元に戻す。

$ svn revert config/boot.rb


js のファイルも最新版にUpdate されているので戻す。

$ svn revert -R public/javascripts
Reverted 'public/javascripts/prototype.js'
Reverted 'public/javascripts/effects.js'
Reverted 'public/javascripts/dragdrop.js'
Reverted 'public/javascripts/controls.js'


これで、正常に動くようになりました。

$ ruby script/about
About your application's environment
Ruby version                 1.8.7 (i686-darwin9)
RubyGems version             1.3.1
Rails version                1.2.6
Active Record version        1.15.6
Action Pack version          1.13.6
Action Web Service version   1.2.6
Action Mailer version        1.3.6
Active Support version       1.4.4
Edge Rails revision          unknown
Application root             /Users/luke/apps/rails/depot
Environment                  development
Database adapter             mysql

残る問題点

今回の場合のように、元々rails 1.2.6 で開発していたプロジェクトのファイル一覧があれば、上記の方法は上手く行きます。
しかし、手元にrails 2.2.2 しかなくて、でも1.x 系のrails プロジェクトを作成したい場合、この方法では上手く行きません。最初にrails コマンドで生成されるファイル構成が、1.x 系のファイル構成とはかなり異なるためです。
このような場合は、以下のように一回1.x 系のrails をインストールしてあげなきゃいけないっぽいですね・・・。rails をインストールしなくてもfreeze できないものか。

$ sudo gem install rails -v 1.2.6
$ rake --require=rubygems/gem_runner rails:freeze:gems VERSION=1.2.6