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