Updated Rails to 2.1.0
[gitorious:georgyos-clone.git] / vendor / plugins / rspec / pre_commit / lib / pre_commit / rspec_on_rails.rb
1 class PreCommit::RspecOnRails < PreCommit
2   def pre_commit
3     install_plugins
4     check_dependencies
5     used_railses = []
6     VENDOR_DEPS.each do |dependency|
7       rails_dir = File.expand_path(dependency[:checkout_path])
8       rails_version = rails_version_from_dir(rails_dir)
9       begin
10         rspec_pre_commit(rails_version, false)
11         used_railses << rails_version
12       rescue Exception => e
13         unless rails_version == 'edge'
14           raise e
15         end
16       end
17     end
18     uninstall_plugins
19     puts "All specs passed against the following released versions of Rails: #{used_railses.join(", ")}"
20     unless used_railses.include?('edge')
21       puts "There were errors running pre_commit against edge"
22     end
23   end
24
25   def rails_version_from_dir(rails_dir)
26     File.basename(rails_dir)
27   end
28
29   def rspec_pre_commit(rails_version=ENV['RSPEC_RAILS_VERSION'],uninstall=true)
30     puts "#####################################################"
31     puts "running pre_commit against rails #{rails_version}"
32     puts "#####################################################"
33     ENV['RSPEC_RAILS_VERSION'] = rails_version
34     cleanup(uninstall)
35     ensure_db_config
36     clobber_sqlite_data
37     install_plugins
38     generate_rspec
39
40     generate_login_controller
41     create_purchase
42
43     rake_sh "spec"
44     rake_sh "spec:plugins:rspec_on_rails"
45     
46     # TODO - why is this necessary? Shouldn't the specs leave
47     # a clean DB?
48     rake_sh "db:test:prepare"
49     sh "ruby vendor/plugins/rspec_on_rails/stories/all.rb"
50     cleanup(uninstall)
51   end
52
53   def cleanup(uninstall=true)
54     revert_routes
55     rm_generated_login_controller_files
56     destroy_purchase
57     uninstall_plugins if uninstall
58   end
59
60   def revert_routes
61     output = silent_sh("cp config/routes.rb.bak config/routes.rb")
62     raise "Error reverting routes.rb" if shell_error?(output)
63   end
64
65   def create_purchase
66     generate_purchase
67     migrate_up
68   end
69
70   def install_plugins
71     install_plugin :rspec_on_rails
72     install_plugin :rspec
73   end
74   
75   def install_plugin(plugin)
76     rm_rf "vendor/plugins/#{plugin}" if File.exist?("vendor/plugins/#{plugin}")
77     FileUtils.mkdir_p("vendor/plugins") unless File.directory?("vendor/plugins")
78     copy "../#{plugin}", "vendor/plugins"
79   end
80
81   def uninstall_plugins
82     rm_rf 'vendor/plugins/rspec_on_rails'
83     rm_rf 'vendor/plugins/rspec'
84     rm_rf 'script/spec'
85     rm_rf 'script/spec_server'
86     rm_rf 'spec/spec_helper.rb'
87     rm_rf 'spec/spec.opts'
88     rm_rf 'spec/rcov.opts'
89   end
90   
91   def copy(source, target)
92     output = silent_sh("cp -R #{File.expand_path(source)} #{File.expand_path(target)}")
93     raise "Error installing rspec" if shell_error?(output)
94   end
95   
96   def generate_rspec
97     result = silent_sh("ruby script/generate rspec --force")
98     if error_code? || result =~ /^Missing/
99       raise "Failed to generate rspec environment:\n#{result}"
100     end
101   end
102
103   def ensure_db_config
104     config_path = 'config/database.yml'
105     unless File.exists?(config_path)
106       message = <<-EOF
107       #####################################################
108       Could not find #{config_path}
109
110       You can get rake to generate this file for you using either of:
111         rake rspec:generate_mysql_config
112         rake rspec:generate_sqlite3_config
113         rake rspec:generate_postgres_config
114
115       If you use mysql, you'll need to create dev and test
116       databases and users for each. To do this, standing
117       in rspec_on_rails, log into mysql as root and then...
118         mysql> source db/mysql_setup.sql;
119
120       There is also a teardown script that will remove
121       the databases and users:
122         mysql> source db/mysql_teardown.sql;
123       #####################################################
124       EOF
125       raise message.gsub(/^      /, '')
126     end
127   end
128
129   def generate_mysql_config
130     copy 'config/database.mysql.yml', 'config/database.yml'
131   end
132
133   def generate_sqlite3_config
134     copy 'config/database.sqlite3.yml', 'config/database.yml'
135   end
136
137   def generate_postgres_config
138     copy 'config/database.pgsql.yml', 'config/database.yml'
139   end
140
141   def clobber_db_config
142     rm 'config/database.yml'
143   end
144
145   def clobber_sqlite_data
146     rm_rf 'db/*.db'
147   end
148
149   def generate_purchase
150     generator = "ruby script/generate rspec_scaffold purchase order_id:integer created_at:datetime amount:decimal keyword:string description:text --force"
151     notice = <<-EOF
152     #####################################################
153     #{generator}
154     #####################################################
155     EOF
156     puts notice.gsub(/^    /, '')
157     result = silent_sh(generator)
158     if error_code? || result =~ /not/
159       raise "rspec_scaffold failed. #{result}"
160     end
161   end
162   
163   def purchase_migration_version
164     "005"
165   end
166
167   def migrate_up
168     rake_sh "db:migrate"
169   end
170
171   def destroy_purchase
172     migrate_down
173     rm_generated_purchase_files
174   end
175
176   def migrate_down
177     notice = <<-EOF
178     #####################################################
179     Migrating down and reverting config/routes.rb
180     #####################################################
181     EOF
182     puts notice.gsub(/^    /, '')
183     rake_sh "db:migrate", 'VERSION' => (purchase_migration_version.to_i - 1)
184     output = silent_sh("cp config/routes.rb.bak config/routes.rb")
185     raise "revert failed: #{output}" if error_code?
186   end
187
188   def rm_generated_purchase_files
189     puts "#####################################################"
190     puts "Removing generated files:"
191     generated_files = %W{
192       app/helpers/purchases_helper.rb
193       app/models/purchase.rb
194       app/controllers/purchases_controller.rb
195       app/views/purchases
196       db/migrate/#{purchase_migration_version}_create_purchases.rb
197       spec/models/purchase_spec.rb
198       spec/helpers/purchases_helper_spec.rb
199       spec/controllers/purchases_controller_spec.rb
200       spec/controllers/purchases_routing_spec.rb
201       spec/fixtures/purchases.yml
202       spec/views/purchases
203     }
204     generated_files.each do |file|
205       rm_rf file
206     end
207     puts "#####################################################"
208   end
209   
210   def generate_login_controller
211     generator = "ruby script/generate rspec_controller login signup login logout --force"
212     notice = <<-EOF
213     #####################################################
214     #{generator}
215     #####################################################
216     EOF
217     puts notice.gsub(/^    /, '')
218     result = silent_sh(generator)
219     if error_code? || result =~ /not/
220       raise "rspec_scaffold failed. #{result}"
221     end
222   end
223
224   def rm_generated_login_controller_files
225     puts "#####################################################"
226     puts "Removing generated files:"
227     generated_files = %W{
228       app/helpers/login_helper.rb
229       app/controllers/login_controller.rb
230       app/views/login
231       spec/helpers/login_helper_spec.rb
232       spec/controllers/login_controller_spec.rb
233       spec/views/login
234     }
235     generated_files.each do |file|
236       rm_rf file
237     end
238     puts "#####################################################"
239   end
240
241   def install_dependencies
242     VENDOR_DEPS.each do |dep|
243       puts "\nChecking for #{dep[:name]} ..."
244       dest = dep[:checkout_path]
245       if File.exists?(dest)
246         puts "#{dep[:name]} already installed"
247       else
248         cmd = "svn co #{dep[:url]} #{dest}"
249         puts "Installing #{dep[:name]}"
250         puts "This may take a while."
251         puts cmd
252         system(cmd)
253         puts "Done!"
254       end
255     end
256     puts
257   end
258
259   def check_dependencies
260     VENDOR_DEPS.each do |dep|
261       unless File.exist?(dep[:checkout_path])
262         raise "There is no checkout of #{dep[:checkout_path]}. Please run rake install_dependencies"
263       end
264       # Verify that the current working copy is right
265       if `svn info #{dep[:checkout_path]}` =~ /^URL: (.*)/
266         actual_url = $1
267         if actual_url != dep[:url]
268           raise "Your working copy in #{dep[:checkout_path]} points to \n#{actual_url}\nIt has moved to\n#{dep[:url]}\nPlease delete the working copy and run rake install_dependencies"
269         end
270       end
271     end
272   end
273   
274   def update_dependencies
275     check_dependencies
276     VENDOR_DEPS.each do |dep|
277       next if dep[:tagged?] #
278       puts "\nUpdating #{dep[:name]} ..."
279       dest = dep[:checkout_path]
280       system("svn cleanup #{dest}")
281       cmd = "svn up #{dest}"
282       puts cmd
283       system(cmd)
284       puts "Done!"
285     end
286   end
287
288   VENDOR_DEPS = [
289     {
290       :checkout_path => "vendor/rails/2.0.2",
291       :name =>  "rails 2.0.2",
292       :url => "http://dev.rubyonrails.org/svn/rails/tags/rel_2-0-2",
293       :tagged? => true
294     },
295     {
296       :checkout_path => "vendor/rails/1.2.6",
297       :name =>  "rails 1.2.6",
298       :url => "http://dev.rubyonrails.org/svn/rails/tags/rel_1-2-6",
299       :tagged? => true
300     },
301     {
302       :checkout_path => "vendor/rails/1.2.3",
303       :name =>  "rails 1.2.3",
304       :url => "http://dev.rubyonrails.org/svn/rails/tags/rel_1-2-3",
305       :tagged? => true
306     },
307     {
308       :checkout_path => "vendor/rails/edge",
309       :name =>  "edge rails",
310       :url => "http://svn.rubyonrails.org/rails/trunk",
311       :tagged? => false
312     }
313   ]
314 end