##// END OF EJS Templates
Fixed: rubytree gem breaks db:migrate:plugins (#4394)....
Jean-Philippe Lang -
r3072:1ba5779f9431
parent child
Show More
@@ -1,280 +1,281
1 # This code lets us redefine existing Rake tasks, which is extremely
1 # This code lets us redefine existing Rake tasks, which is extremely
2 # handy for modifying existing Rails rake tasks.
2 # handy for modifying existing Rails rake tasks.
3 # Credit for the original snippet of code goes to Jeremy Kemper
3 # Credit for the original snippet of code goes to Jeremy Kemper
4 # http://pastie.caboo.se/9620
4 # http://pastie.caboo.se/9620
5 unless Rake::TaskManager.methods.include?('redefine_task')
5 unless Rake::TaskManager.methods.include?('redefine_task')
6 module Rake
6 module Rake
7 module TaskManager
7 module TaskManager
8 def redefine_task(task_class, args, &block)
8 def redefine_task(task_class, args, &block)
9 task_name, arg_names, deps = resolve_args([args])
9 task_name, arg_names, deps = resolve_args([args])
10 task_name = task_class.scope_name(@scope, task_name)
10 task_name = task_class.scope_name(@scope, task_name)
11 deps = [deps] unless deps.respond_to?(:to_ary)
11 deps = [deps] unless deps.respond_to?(:to_ary)
12 deps = deps.collect {|d| d.to_s }
12 deps = deps.collect {|d| d.to_s }
13 task = @tasks[task_name.to_s] = task_class.new(task_name, self)
13 task = @tasks[task_name.to_s] = task_class.new(task_name, self)
14 task.application = self
14 task.application = self
15 task.add_description(@last_description)
15 task.add_description(@last_description)
16 @last_description = nil
16 @last_description = nil
17 task.enhance(deps, &block)
17 task.enhance(deps, &block)
18 task
18 task
19 end
19 end
20
20
21 end
21 end
22 class Task
22 class Task
23 class << self
23 class << self
24 def redefine_task(args, &block)
24 def redefine_task(args, &block)
25 Rake.application.redefine_task(self, [args], &block)
25 Rake.application.redefine_task(self, [args], &block)
26 end
26 end
27 end
27 end
28 end
28 end
29 end
29 end
30 end
30 end
31
31
32 namespace :db do
32 namespace :db do
33 namespace :migrate do
33 namespace :migrate do
34 desc 'Migrate database and plugins to current status.'
34 desc 'Migrate database and plugins to current status.'
35 task :all => [ 'db:migrate', 'db:migrate:plugins' ]
35 task :all => [ 'db:migrate', 'db:migrate:plugins' ]
36
36
37 desc 'Migrate plugins to current status.'
37 desc 'Migrate plugins to current status.'
38 task :plugins => :environment do
38 task :plugins => :environment do
39 Engines.plugins.each do |plugin|
39 Engines.plugins.each do |plugin|
40 next unless plugin.respond_to?(:migration_directory)
40 next unless File.exists? plugin.migration_directory
41 next unless File.exists? plugin.migration_directory
41 puts "Migrating plugin #{plugin.name} ..."
42 puts "Migrating plugin #{plugin.name} ..."
42 plugin.migrate
43 plugin.migrate
43 end
44 end
44 end
45 end
45
46
46 desc 'For engines coming from Rails version < 2.0 or for those previously updated to work with Sven Fuch\'s fork of engines, you need to upgrade the schema info table'
47 desc 'For engines coming from Rails version < 2.0 or for those previously updated to work with Sven Fuch\'s fork of engines, you need to upgrade the schema info table'
47 task :upgrade_plugin_migrations => :environment do
48 task :upgrade_plugin_migrations => :environment do
48 svens_fork_table_name = 'plugin_schema_migrations'
49 svens_fork_table_name = 'plugin_schema_migrations'
49
50
50 # Check if app was previously using Sven's fork
51 # Check if app was previously using Sven's fork
51 if ActiveRecord::Base.connection.table_exists?(svens_fork_table_name)
52 if ActiveRecord::Base.connection.table_exists?(svens_fork_table_name)
52 old_sm_table = svens_fork_table_name
53 old_sm_table = svens_fork_table_name
53 else
54 else
54 old_sm_table = ActiveRecord::Migrator.proper_table_name(Engines.schema_info_table)
55 old_sm_table = ActiveRecord::Migrator.proper_table_name(Engines.schema_info_table)
55 end
56 end
56
57
57 unless ActiveRecord::Base.connection.table_exists?(old_sm_table)
58 unless ActiveRecord::Base.connection.table_exists?(old_sm_table)
58 abort "Cannot find old migration table - assuming nothing needs to be done"
59 abort "Cannot find old migration table - assuming nothing needs to be done"
59 end
60 end
60
61
61 # There are two forms of the engines schema info - pre-fix_plugin_migrations and post
62 # There are two forms of the engines schema info - pre-fix_plugin_migrations and post
62 # We need to figure this out before we continue.
63 # We need to figure this out before we continue.
63
64
64 results = ActiveRecord::Base.connection.select_rows(
65 results = ActiveRecord::Base.connection.select_rows(
65 "SELECT version, plugin_name FROM #{old_sm_table}"
66 "SELECT version, plugin_name FROM #{old_sm_table}"
66 ).uniq
67 ).uniq
67
68
68 def insert_new_version(plugin_name, version)
69 def insert_new_version(plugin_name, version)
69 version_string = "#{version}-#{plugin_name}"
70 version_string = "#{version}-#{plugin_name}"
70 new_sm_table = ActiveRecord::Migrator.schema_migrations_table_name
71 new_sm_table = ActiveRecord::Migrator.schema_migrations_table_name
71
72
72 # Check if the row already exists for some reason - maybe run this task more than once.
73 # Check if the row already exists for some reason - maybe run this task more than once.
73 return if ActiveRecord::Base.connection.select_rows("SELECT * FROM #{new_sm_table} WHERE version = #{version_string.dump.gsub("\"", "'")}").size > 0
74 return if ActiveRecord::Base.connection.select_rows("SELECT * FROM #{new_sm_table} WHERE version = #{version_string.dump.gsub("\"", "'")}").size > 0
74
75
75 puts "Inserting new version #{version} for plugin #{plugin_name}.."
76 puts "Inserting new version #{version} for plugin #{plugin_name}.."
76 ActiveRecord::Base.connection.insert("INSERT INTO #{new_sm_table} (version) VALUES (#{version_string.dump.gsub("\"", "'")})")
77 ActiveRecord::Base.connection.insert("INSERT INTO #{new_sm_table} (version) VALUES (#{version_string.dump.gsub("\"", "'")})")
77 end
78 end
78
79
79 # We need to figure out if they already used "fix_plugin_migrations"
80 # We need to figure out if they already used "fix_plugin_migrations"
80 versions = {}
81 versions = {}
81 results.each do |r|
82 results.each do |r|
82 versions[r[1]] ||= []
83 versions[r[1]] ||= []
83 versions[r[1]] << r[0].to_i
84 versions[r[1]] << r[0].to_i
84 end
85 end
85
86
86 if versions.values.find{ |v| v.size > 1 } == nil
87 if versions.values.find{ |v| v.size > 1 } == nil
87 puts "Fixing migration info"
88 puts "Fixing migration info"
88 # We only have one listed migration per plugin - this is pre-fix_plugin_migrations,
89 # We only have one listed migration per plugin - this is pre-fix_plugin_migrations,
89 # so we build all versions required. In this case, all migrations should
90 # so we build all versions required. In this case, all migrations should
90 versions.each do |plugin_name, version|
91 versions.each do |plugin_name, version|
91 version = version[0] # There is only one version
92 version = version[0] # There is only one version
92
93
93 # We have to make an assumption that numeric migrations won't get this long..
94 # We have to make an assumption that numeric migrations won't get this long..
94 # I'm not sure if there is a better assumption, it should work in all
95 # I'm not sure if there is a better assumption, it should work in all
95 # current cases.. (touch wood..)
96 # current cases.. (touch wood..)
96 if version.to_s.size < "YYYYMMDDHHMMSS".size
97 if version.to_s.size < "YYYYMMDDHHMMSS".size
97 # Insert version records for each migration
98 # Insert version records for each migration
98 (1..version).each do |v|
99 (1..version).each do |v|
99 insert_new_version(plugin_name, v)
100 insert_new_version(plugin_name, v)
100 end
101 end
101 else
102 else
102 # If the plugin is new-format "YYYYMMDDHHMMSS", we just copy it across...
103 # If the plugin is new-format "YYYYMMDDHHMMSS", we just copy it across...
103 # The case in which this occurs is very rare..
104 # The case in which this occurs is very rare..
104 insert_new_version(plugin_name, version)
105 insert_new_version(plugin_name, version)
105 end
106 end
106 end
107 end
107 else
108 else
108 puts "Moving migration info"
109 puts "Moving migration info"
109 # We have multiple migrations listed per plugin - thus we can assume they have
110 # We have multiple migrations listed per plugin - thus we can assume they have
110 # already applied fix_plugin_migrations - we just copy it across verbatim
111 # already applied fix_plugin_migrations - we just copy it across verbatim
111 versions.each do |plugin_name, version|
112 versions.each do |plugin_name, version|
112 version.each { |v| insert_new_version(plugin_name, v) }
113 version.each { |v| insert_new_version(plugin_name, v) }
113 end
114 end
114 end
115 end
115
116
116 puts "Migration info successfully migrated - removing old schema info table"
117 puts "Migration info successfully migrated - removing old schema info table"
117 ActiveRecord::Base.connection.drop_table(old_sm_table)
118 ActiveRecord::Base.connection.drop_table(old_sm_table)
118 end
119 end
119
120
120 desc 'Migrate a specified plugin.'
121 desc 'Migrate a specified plugin.'
121 task(:plugin => :environment) do
122 task(:plugin => :environment) do
122 name = ENV['NAME']
123 name = ENV['NAME']
123 if plugin = Engines.plugins[name]
124 if plugin = Engines.plugins[name]
124 version = ENV['VERSION']
125 version = ENV['VERSION']
125 puts "Migrating #{plugin.name} to " + (version ? "version #{version}" : 'latest version') + " ..."
126 puts "Migrating #{plugin.name} to " + (version ? "version #{version}" : 'latest version') + " ..."
126 plugin.migrate(version ? version.to_i : nil)
127 plugin.migrate(version ? version.to_i : nil)
127 else
128 else
128 puts "Plugin #{name} does not exist."
129 puts "Plugin #{name} does not exist."
129 end
130 end
130 end
131 end
131 end
132 end
132 end
133 end
133
134
134
135
135 namespace :db do
136 namespace :db do
136 namespace :fixtures do
137 namespace :fixtures do
137 namespace :plugins do
138 namespace :plugins do
138
139
139 desc "Load plugin fixtures into the current environment's database."
140 desc "Load plugin fixtures into the current environment's database."
140 task :load => :environment do
141 task :load => :environment do
141 require 'active_record/fixtures'
142 require 'active_record/fixtures'
142 ActiveRecord::Base.establish_connection(RAILS_ENV.to_sym)
143 ActiveRecord::Base.establish_connection(RAILS_ENV.to_sym)
143 Dir.glob(File.join(RAILS_ROOT, 'vendor', 'plugins', ENV['PLUGIN'] || '**',
144 Dir.glob(File.join(RAILS_ROOT, 'vendor', 'plugins', ENV['PLUGIN'] || '**',
144 'test', 'fixtures', '*.yml')).each do |fixture_file|
145 'test', 'fixtures', '*.yml')).each do |fixture_file|
145 Fixtures.create_fixtures(File.dirname(fixture_file), File.basename(fixture_file, '.*'))
146 Fixtures.create_fixtures(File.dirname(fixture_file), File.basename(fixture_file, '.*'))
146 end
147 end
147 end
148 end
148
149
149 end
150 end
150 end
151 end
151 end
152 end
152
153
153 # this is just a modification of the original task in railties/lib/tasks/documentation.rake,
154 # this is just a modification of the original task in railties/lib/tasks/documentation.rake,
154 # because the default task doesn't support subdirectories like <plugin>/app or
155 # because the default task doesn't support subdirectories like <plugin>/app or
155 # <plugin>/component. These tasks now include every file under a plugin's load paths (see
156 # <plugin>/component. These tasks now include every file under a plugin's load paths (see
156 # Plugin#load_paths).
157 # Plugin#load_paths).
157 namespace :doc do
158 namespace :doc do
158
159
159 plugins = FileList['vendor/plugins/**'].collect { |plugin| File.basename(plugin) }
160 plugins = FileList['vendor/plugins/**'].collect { |plugin| File.basename(plugin) }
160
161
161 namespace :plugins do
162 namespace :plugins do
162
163
163 # Define doc tasks for each plugin
164 # Define doc tasks for each plugin
164 plugins.each do |plugin|
165 plugins.each do |plugin|
165 desc "Create plugin documentation for '#{plugin}'"
166 desc "Create plugin documentation for '#{plugin}'"
166 Rake::Task.redefine_task(plugin => :environment) do
167 Rake::Task.redefine_task(plugin => :environment) do
167 plugin_base = RAILS_ROOT + "/vendor/plugins/#{plugin}"
168 plugin_base = RAILS_ROOT + "/vendor/plugins/#{plugin}"
168 options = []
169 options = []
169 files = Rake::FileList.new
170 files = Rake::FileList.new
170 options << "-o doc/plugins/#{plugin}"
171 options << "-o doc/plugins/#{plugin}"
171 options << "--title '#{plugin.titlecase} Plugin Documentation'"
172 options << "--title '#{plugin.titlecase} Plugin Documentation'"
172 options << '--line-numbers' << '--inline-source'
173 options << '--line-numbers' << '--inline-source'
173 options << '-T html'
174 options << '-T html'
174
175
175 # Include every file in the plugin's load_paths (see Plugin#load_paths)
176 # Include every file in the plugin's load_paths (see Plugin#load_paths)
176 if Engines.plugins[plugin]
177 if Engines.plugins[plugin]
177 files.include("#{plugin_base}/{#{Engines.plugins[plugin].load_paths.join(",")}}/**/*.rb")
178 files.include("#{plugin_base}/{#{Engines.plugins[plugin].load_paths.join(",")}}/**/*.rb")
178 end
179 end
179 if File.exists?("#{plugin_base}/README")
180 if File.exists?("#{plugin_base}/README")
180 files.include("#{plugin_base}/README")
181 files.include("#{plugin_base}/README")
181 options << "--main '#{plugin_base}/README'"
182 options << "--main '#{plugin_base}/README'"
182 end
183 end
183 files.include("#{plugin_base}/CHANGELOG") if File.exists?("#{plugin_base}/CHANGELOG")
184 files.include("#{plugin_base}/CHANGELOG") if File.exists?("#{plugin_base}/CHANGELOG")
184
185
185 if files.empty?
186 if files.empty?
186 puts "No source files found in #{plugin_base}. No documentation will be generated."
187 puts "No source files found in #{plugin_base}. No documentation will be generated."
187 else
188 else
188 options << files.to_s
189 options << files.to_s
189 sh %(rdoc #{options * ' '})
190 sh %(rdoc #{options * ' '})
190 end
191 end
191 end
192 end
192 end
193 end
193 end
194 end
194 end
195 end
195
196
196
197
197
198
198 namespace :test do
199 namespace :test do
199 task :warn_about_multiple_plugin_testing_with_engines do
200 task :warn_about_multiple_plugin_testing_with_engines do
200 puts %{-~============== A Moste Polite Warninge ===========================~-
201 puts %{-~============== A Moste Polite Warninge ===========================~-
201
202
202 You may experience issues testing multiple plugins at once when using
203 You may experience issues testing multiple plugins at once when using
203 the code-mixing features that the engines plugin provides. If you do
204 the code-mixing features that the engines plugin provides. If you do
204 experience any problems, please test plugins individually, i.e.
205 experience any problems, please test plugins individually, i.e.
205
206
206 $ rake test:plugins PLUGIN=my_plugin
207 $ rake test:plugins PLUGIN=my_plugin
207
208
208 or use the per-type plugin test tasks:
209 or use the per-type plugin test tasks:
209
210
210 $ rake test:plugins:units
211 $ rake test:plugins:units
211 $ rake test:plugins:functionals
212 $ rake test:plugins:functionals
212 $ rake test:plugins:integration
213 $ rake test:plugins:integration
213 $ rake test:plugins:all
214 $ rake test:plugins:all
214
215
215 Report any issues on http://dev.rails-engines.org. Thanks!
216 Report any issues on http://dev.rails-engines.org. Thanks!
216
217
217 -~===============( ... as you were ... )============================~-}
218 -~===============( ... as you were ... )============================~-}
218 end
219 end
219
220
220 namespace :engines do
221 namespace :engines do
221
222
222 def engine_plugins
223 def engine_plugins
223 Dir["vendor/plugins/*"].select { |f| File.directory?(File.join(f, "app")) }.map { |f| File.basename(f) }.join(",")
224 Dir["vendor/plugins/*"].select { |f| File.directory?(File.join(f, "app")) }.map { |f| File.basename(f) }.join(",")
224 end
225 end
225
226
226 desc "Run tests from within engines plugins (plugins with an 'app' directory)"
227 desc "Run tests from within engines plugins (plugins with an 'app' directory)"
227 task :all => [:units, :functionals, :integration]
228 task :all => [:units, :functionals, :integration]
228
229
229 desc "Run unit tests from within engines plugins (plugins with an 'app' directory)"
230 desc "Run unit tests from within engines plugins (plugins with an 'app' directory)"
230 Rake::TestTask.new(:units => "test:plugins:setup_plugin_fixtures") do |t|
231 Rake::TestTask.new(:units => "test:plugins:setup_plugin_fixtures") do |t|
231 t.pattern = "vendor/plugins/{#{ENV['PLUGIN'] || engine_plugins}}/test/unit/**/*_test.rb"
232 t.pattern = "vendor/plugins/{#{ENV['PLUGIN'] || engine_plugins}}/test/unit/**/*_test.rb"
232 t.verbose = true
233 t.verbose = true
233 end
234 end
234
235
235 desc "Run functional tests from within engines plugins (plugins with an 'app' directory)"
236 desc "Run functional tests from within engines plugins (plugins with an 'app' directory)"
236 Rake::TestTask.new(:functionals => "test:plugins:setup_plugin_fixtures") do |t|
237 Rake::TestTask.new(:functionals => "test:plugins:setup_plugin_fixtures") do |t|
237 t.pattern = "vendor/plugins/{#{ENV['PLUGIN'] || engine_plugins}}/test/functional/**/*_test.rb"
238 t.pattern = "vendor/plugins/{#{ENV['PLUGIN'] || engine_plugins}}/test/functional/**/*_test.rb"
238 t.verbose = true
239 t.verbose = true
239 end
240 end
240
241
241 desc "Run integration tests from within engines plugins (plugins with an 'app' directory)"
242 desc "Run integration tests from within engines plugins (plugins with an 'app' directory)"
242 Rake::TestTask.new(:integration => "test:plugins:setup_plugin_fixtures") do |t|
243 Rake::TestTask.new(:integration => "test:plugins:setup_plugin_fixtures") do |t|
243 t.pattern = "vendor/plugins/{#{ENV['PLUGIN'] || engine_plugins}}/test/integration/**/*_test.rb"
244 t.pattern = "vendor/plugins/{#{ENV['PLUGIN'] || engine_plugins}}/test/integration/**/*_test.rb"
244 t.verbose = true
245 t.verbose = true
245 end
246 end
246 end
247 end
247
248
248 namespace :plugins do
249 namespace :plugins do
249
250
250 desc "Run the plugin tests in vendor/plugins/**/test (or specify with PLUGIN=name)"
251 desc "Run the plugin tests in vendor/plugins/**/test (or specify with PLUGIN=name)"
251 task :all => [:warn_about_multiple_plugin_testing_with_engines,
252 task :all => [:warn_about_multiple_plugin_testing_with_engines,
252 :units, :functionals, :integration]
253 :units, :functionals, :integration]
253
254
254 desc "Run all plugin unit tests"
255 desc "Run all plugin unit tests"
255 Rake::TestTask.new(:units => :setup_plugin_fixtures) do |t|
256 Rake::TestTask.new(:units => :setup_plugin_fixtures) do |t|
256 t.pattern = "vendor/plugins/#{ENV['PLUGIN'] || "**"}/test/unit/**/*_test.rb"
257 t.pattern = "vendor/plugins/#{ENV['PLUGIN'] || "**"}/test/unit/**/*_test.rb"
257 t.verbose = true
258 t.verbose = true
258 end
259 end
259
260
260 desc "Run all plugin functional tests"
261 desc "Run all plugin functional tests"
261 Rake::TestTask.new(:functionals => :setup_plugin_fixtures) do |t|
262 Rake::TestTask.new(:functionals => :setup_plugin_fixtures) do |t|
262 t.pattern = "vendor/plugins/#{ENV['PLUGIN'] || "**"}/test/functional/**/*_test.rb"
263 t.pattern = "vendor/plugins/#{ENV['PLUGIN'] || "**"}/test/functional/**/*_test.rb"
263 t.verbose = true
264 t.verbose = true
264 end
265 end
265
266
266 desc "Integration test engines"
267 desc "Integration test engines"
267 Rake::TestTask.new(:integration => :setup_plugin_fixtures) do |t|
268 Rake::TestTask.new(:integration => :setup_plugin_fixtures) do |t|
268 t.pattern = "vendor/plugins/#{ENV['PLUGIN'] || "**"}/test/integration/**/*_test.rb"
269 t.pattern = "vendor/plugins/#{ENV['PLUGIN'] || "**"}/test/integration/**/*_test.rb"
269 t.verbose = true
270 t.verbose = true
270 end
271 end
271
272
272 desc "Mirrors plugin fixtures into a single location to help plugin tests"
273 desc "Mirrors plugin fixtures into a single location to help plugin tests"
273 task :setup_plugin_fixtures => :environment do
274 task :setup_plugin_fixtures => :environment do
274 Engines::Testing.setup_plugin_fixtures
275 Engines::Testing.setup_plugin_fixtures
275 end
276 end
276
277
277 # Patch the default plugin testing task to have setup_plugin_fixtures as a prerequisite
278 # Patch the default plugin testing task to have setup_plugin_fixtures as a prerequisite
278 Rake::Task["test:plugins"].prerequisites << "test:plugins:setup_plugin_fixtures"
279 Rake::Task["test:plugins"].prerequisites << "test:plugins:setup_plugin_fixtures"
279 end
280 end
280 end
281 end
General Comments 0
You need to be logged in to leave comments. Login now