summaryrefslogtreecommitdiffstats
path: root/vendor/plugins/engines/Rakefile
blob: b9640226c80217db4d81e5ff429cd76cc1f4ca18 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
require 'rake'
require 'rake/rdoctask'
require 'tmpdir'

task :default => :doc

desc 'Generate documentation for the engines plugin.'
Rake::RDocTask.new(:doc) do |doc|
  doc.rdoc_dir = 'doc'
  doc.title    = 'Engines'
  doc.main     = "README"
  doc.rdoc_files.include("README", "CHANGELOG", "MIT-LICENSE")
  doc.rdoc_files.include('lib/**/*.rb')
  doc.options << '--line-numbers' << '--inline-source'
end

desc 'Run the engine plugin tests within their test harness'
task :cruise do
  # checkout the project into a temporary directory
  version = "rails_2.0"
  test_dir = "#{Dir.tmpdir}/engines_plugin_#{version}_test"
  puts "Checking out test harness for #{version} into #{test_dir}"
  `svn co http://svn.rails-engines.org/test/engines/#{version} #{test_dir}`

  # run all the tests in this project
  Dir.chdir(test_dir)
  load 'Rakefile'
  puts "Running all tests in test harness"
  ['db:migrate', 'test', 'test:plugins'].each do |t|
    Rake::Task[t].invoke
  end  
end

task :clean => [:clobber_doc, "test:clean"]

namespace :test do
  
  # Yields a block with STDOUT and STDERR silenced. If you *really* want
  # to output something, the block is yielded with the original output
  # streams, i.e.
  #
  #   silence do |o, e|
  #     puts 'hello!' # no output produced
  #     o.puts 'hello!' # output on STDOUT
  #   end
  #
  # (based on silence_stream in ActiveSupport.)
  def silence
    yield(STDOUT, STDERR) if ENV['VERBOSE']
    streams = [STDOUT, STDERR]
    actual_stdout = STDOUT.dup
    actual_stderr = STDERR.dup
    streams.each do |s| 
      s.reopen(RUBY_PLATFORM =~ /mswin/ ? 'NUL:' : '/dev/null') 
      s.sync = true
    end
    yield actual_stdout, actual_stderr
  ensure
    STDOUT.reopen(actual_stdout)
    STDERR.reopen(actual_stderr)
  end
  
  def test_app_dir
    File.join(File.dirname(__FILE__), 'test_app')
  end
  
  def run(cmd)
    cmd = cmd.join(" && ") if cmd.is_a?(Array)
    system(cmd) || raise("failed running '#{cmd}'")
  end
  
  desc 'Remove the test application'
  task :clean do
    FileUtils.rm_r(test_app_dir) if File.exist?(test_app_dir)
  end
  
  desc 'Build the test rails application (use RAILS=[edge,<directory>] to test against specific version)'
  task :generate_app do
    silence do |out, err|
      out.puts "> Creating test application at #{test_app_dir}"
        
      if ENV['RAILS']
        vendor_dir = File.join(test_app_dir, 'vendor')
        FileUtils.mkdir_p vendor_dir
        
        if ENV['RAILS'] == 'edge'
          out.puts "    Cloning Edge Rails from GitHub"
          run "cd #{vendor_dir} && git clone --depth 1 git://github.com/rails/rails.git"
        elsif ENV['RAILS'] =~ /\d\.\d\.\d/
          if ENV['CURL']
            out.puts "    Cloning Rails Tag #{ENV['RAILS']} from GitHub using curl and tar"
            run ["cd #{vendor_dir}",
                 "mkdir rails",
                 "cd rails",
                 "curl -s -L http://github.com/rails/rails/tarball/#{ENV['RAILS']} | tar xzv --strip-components 1"]
          else
            out.puts "    Cloning Rails Tag #{ENV['RAILS']} from GitHub (can be slow - set CURL=true to use curl)"
            run ["cd #{vendor_dir}",
                 "git clone git://github.com/rails/rails.git",
                 "cd rails",
                 "git pull",
                 "git checkout v#{ENV['RAILS']}"]
          end
        elsif File.exist?(ENV['RAILS'])
          out.puts "    Linking rails from #{ENV['RAILS']}"
          run "cd #{vendor_dir} && ln -s #{ENV['RAILS']} rails"
        else
          raise "Couldn't build test application from '#{ENV['RAILS']}'"
        end
      
        out.puts "    generating rails default directory structure"
        run "ruby #{File.join(vendor_dir, 'rails', 'railties', 'bin', 'rails')} #{test_app_dir}"
      else
        version = `rails --version`.chomp.split.last
        out.puts "    building rails using the 'rails' command (rails version: #{version})"
        run "rails #{test_app_dir}"
      end
    
      # get the database config and schema in place
      out.puts "    writing database.yml"
      require 'yaml'
      File.open(File.join(test_app_dir, 'config', 'database.yml'), 'w') do |f|
        f.write(%w(development test).inject({}) do |h, env| 
          h[env] = {"adapter" => "sqlite3", "database" => "engines_#{env}.sqlite3"} ; h
        end.to_yaml)
      end
      out.puts "    installing exception_notification plugin"
      run "cd #{test_app_dir} && ./script/plugin install git://github.com/rails/exception_notification.git"
    end
  end
  
  # We can't link the plugin, as it needs to be present for script/generate to find
  # the plugin generator.
  # TODO: find and +1/create issue for loading generators from symlinked plugins
  desc 'Mirror the engines plugin into the test application'
  task :copy_engines_plugin do
    puts "> Copying engines plugin into test application"
    engines_plugin = File.join(test_app_dir, "vendor", "plugins", "engines")
    FileUtils.rm_r(engines_plugin) if File.exist?(engines_plugin)
    FileUtils.mkdir_p(engines_plugin)
    FileList["*"].exclude("test_app").each do |file|
      FileUtils.cp_r(file, engines_plugin)
    end
  end
  
  def insert_line(line, options)
    line = line + "\n"
    target_file = File.join(test_app_dir, options[:into])
    lines = File.readlines(target_file)
    return if lines.include?(line)
    
    if options[:after]
      if options[:after].is_a?(String)
        after_line = options[:after] + "\n"
      else
        after_line = lines.find { |l| l =~ options[:after] }
        raise "couldn't find a line matching #{options[:after].inspect} in #{target_file}" unless after_line
      end
      index = lines.index(after_line)
      raise "couldn't find line '#{after_line}' in #{target_file}" unless index
      lines.insert(index + 1, line)
    else
      lines << line
    end
    File.open(target_file, 'w') { |f| f.write lines.join }
  end
  
  def mirror_test_files(src, dest=nil)
    destination_dir = File.join(*([test_app_dir, dest].compact))
    FileUtils.cp_r(File.join(File.dirname(__FILE__), 'test', src), destination_dir)
  end
  
  desc 'Update the plugin and tests files in the test application from the plugin'
  task :mirror_engine_files => [:test_app, :copy_engines_plugin] do
    puts "> Modifying default config files to load engines plugin"
    insert_line("require File.join(File.dirname(__FILE__), '../vendor/plugins/engines/boot')",
                :into => 'config/environment.rb',
                :after => "require File.join(File.dirname(__FILE__), 'boot')")
                
    insert_line('map.from_plugin :test_routing', :into => 'config/routes.rb', 
                :after => /\AActionController::Routing::Routes/)
                
    insert_line("require 'engines_test_helper'", :into => 'test/test_helper.rb')
    
    puts "> Mirroring test application files into #{test_app_dir}"
    mirror_test_files('app')
    mirror_test_files('lib')
    mirror_test_files('plugins', 'vendor')
    mirror_test_files('unit', 'test')
    mirror_test_files('functional', 'test')
  end
  
  desc 'Prepare the engines test environment'
  task :test_app do
    version_tag = File.join(test_app_dir, 'RAILS_VERSION')
    existing_version = File.read(version_tag).chomp rescue 'unknown'
    if existing_version == ENV['RAILS']
      puts "> Reusing existing test application (#{ENV['RAILS']})"
    else
      puts "> Recreating test application"
      Rake::Task["test:clean"].invoke
      Rake::Task["test:generate_app"].invoke
      
      File.open(version_tag, "w") { |f| f.write ENV['RAILS'] }
    end
  end
end

task :test => "test:mirror_engine_files" do
  puts "> Loading the test application environment and running tests"
  # We use exec here to replace the current running rake process
  exec("cd #{test_app_dir} && rake db:migrate && rake")
end