Merged Rails 2.2 branch. Redmine now requires Rails 2.2.2.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2493 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
1 parent
9a986ac0a5
commit
fe28193e4e
237 files changed
+27994
-32194
No files matched your search
Vendored
+7
@@ -1,5 +1,12 @@
|
||||
= EDGE
|
||||
|
||||
* Samuel Williams (http://www.oriontransfer.co.nz/):
|
||||
Thanks to Tekin for his patches.
|
||||
Updated migrations system to tie in more closely with the current rails mechanism.
|
||||
Rake task for updating database schema info
|
||||
rake db:migrate:upgrade_plugin_migrations
|
||||
Please see http://engines.lighthouseapp.com/projects/10178-engines-plugin/tickets/17 for more information.
|
||||
|
||||
* Refactored the view loading to work with changes in Edge Rails
|
||||
|
||||
* Fixed integration of plugin migrations with the new, default timestamped migrations in Edge Rails
|
||||
|
||||
Vendored
+4
-2
@@ -92,7 +92,7 @@ namespace :test do
|
||||
run ["cd #{vendor_dir}",
|
||||
"mkdir rails",
|
||||
"cd rails",
|
||||
"curl -s -L http://github.com/rails/rails/tarball/v2.1.0 | tar xzv --strip-components 1"]
|
||||
"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}",
|
||||
@@ -124,6 +124,8 @@ namespace :test do
|
||||
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
|
||||
|
||||
@@ -207,5 +209,5 @@ 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")
|
||||
exec("cd #{test_app_dir} && rake db:migrate && rake")
|
||||
end
|
||||
Vendored
+2
-3
@@ -1,8 +1,7 @@
|
||||
begin
|
||||
require 'rails/version'
|
||||
unless Rails::VERSION::MAJOR >= 2 ||
|
||||
(Rails::VERSION::MAJOR >= 1 && Rails::VERSION::MINOR >= 99)
|
||||
raise "This version of the engines plugin requires Rails 2.0 or later!"
|
||||
unless Rails::VERSION::MAJOR >= 2 && Rails::VERSION::MINOR >= 2 && Rails::VERSION::TINY >= 0
|
||||
raise "This version of the engines plugin requires Rails 2.2.0 or later!"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
+29
-10
@@ -2,11 +2,15 @@
|
||||
# within the database.
|
||||
class PluginMigrationGenerator < Rails::Generator::Base
|
||||
|
||||
# 255 characters max for Windows NTFS (http://en.wikipedia.org/wiki/Filename)
|
||||
# minus 14 for timestamp, minus some extra chars for dot, underscore, file
|
||||
# extension. So let's have 230.
|
||||
MAX_FILENAME_LENGTH = 230
|
||||
|
||||
def initialize(runtime_args, runtime_options={})
|
||||
super
|
||||
@options = {:assigns => {}}
|
||||
|
||||
ensure_plugin_schema_table_exists
|
||||
ensure_schema_table_exists
|
||||
get_plugins_to_migrate(runtime_args)
|
||||
|
||||
if @plugins_to_migrate.empty?
|
||||
@@ -25,10 +29,9 @@ class PluginMigrationGenerator < Rails::Generator::Base
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# Create the plugin schema table if it doesn't already exist. See
|
||||
# Engines::RailsExtensions::Migrations#initialize_schema_migrations_table_with_engine_additions
|
||||
def ensure_plugin_schema_table_exists
|
||||
|
||||
# Create the schema table if it doesn't already exist.
|
||||
def ensure_schema_table_exists
|
||||
ActiveRecord::Base.connection.initialize_schema_migrations_table
|
||||
end
|
||||
|
||||
@@ -69,11 +72,27 @@ class PluginMigrationGenerator < Rails::Generator::Base
|
||||
@options[:assigns][:current_versions] = @current_versions
|
||||
end
|
||||
|
||||
# Construct a unique migration name based on the plugins involved and the
|
||||
# versions they should reach after this migration is run.
|
||||
# Returns a migration name. If the descriptive migration name based on the
|
||||
# plugin names involved is shorter than 230 characters that one will be
|
||||
# used. Otherwise a shorter name will be returned.
|
||||
def build_migration_name
|
||||
returning descriptive_migration_name do |name|
|
||||
name.replace short_migration_name if name.length > MAX_FILENAME_LENGTH
|
||||
end
|
||||
end
|
||||
|
||||
# Construct a unique migration name based on the plugins involved and the
|
||||
# versions they should reach after this migration is run. The name constructed
|
||||
# needs to be lowercase
|
||||
def descriptive_migration_name
|
||||
@plugins_to_migrate.map do |plugin|
|
||||
"#{plugin.name}_to_version_#{@new_versions[plugin.name]}"
|
||||
end.join("_and_")
|
||||
end
|
||||
end.join("_and_").downcase
|
||||
end
|
||||
|
||||
# Short migration name that will be used if the descriptive_migration_name
|
||||
# exceeds 230 characters
|
||||
def short_migration_name
|
||||
'plugin_migrations'
|
||||
end
|
||||
end
|
||||
+7
-2
@@ -43,7 +43,7 @@ module Engines
|
||||
|
||||
# List of extensions to load, can be changed in init.rb before calling Engines.init
|
||||
mattr_accessor :rails_extensions
|
||||
self.rails_extensions = %w(action_mailer asset_helpers routing migrations dependencies)
|
||||
self.rails_extensions = %w(action_mailer asset_helpers form_tag_helpers routing migrations dependencies)
|
||||
|
||||
# The name of the public directory to mirror public engine assets into.
|
||||
# Defaults to <tt>RAILS_ROOT/public/plugin_assets</tt>.
|
||||
@@ -143,6 +143,11 @@ module Engines
|
||||
source_dirs = source_files.select { |d| File.directory?(d) }
|
||||
source_files -= source_dirs
|
||||
|
||||
unless source_files.empty?
|
||||
base_target_dir = File.join(destination, File.dirname(source_files.first).gsub(source, ''))
|
||||
FileUtils.mkdir_p(base_target_dir)
|
||||
end
|
||||
|
||||
source_dirs.each do |dir|
|
||||
# strip down these paths so we have simple, relative paths we can
|
||||
# add to the destination
|
||||
@@ -166,4 +171,4 @@ module Engines
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -13,7 +13,6 @@ should edit the files within the <plugin_name>/assets/ directory itself.}
|
||||
def initialize_base_public_directory
|
||||
dir = Engines.public_directory
|
||||
unless File.exist?(dir)
|
||||
Engines.logger.debug "Creating public engine files directory '#{dir}'"
|
||||
FileUtils.mkdir_p(dir)
|
||||
end
|
||||
readme = File.join(dir, "README")
|
||||
@@ -26,7 +25,6 @@ should edit the files within the <plugin_name>/assets/ directory itself.}
|
||||
def mirror_files_for(plugin)
|
||||
return if plugin.public_directory.nil?
|
||||
begin
|
||||
Engines.logger.debug "Attempting to copy plugin assets from '#{plugin.public_directory}' to '#{Engines.public_directory}'"
|
||||
Engines.mirror_files_from(plugin.public_directory, File.join(Engines.public_directory, plugin.name))
|
||||
rescue Exception => e
|
||||
Engines.logger.warn "WARNING: Couldn't create the public file structure for plugin '#{plugin.name}'; Error follows:"
|
||||
|
||||
+24
-6
@@ -76,6 +76,7 @@ module Engines
|
||||
return if loaded?
|
||||
super initializer
|
||||
add_plugin_view_paths
|
||||
add_plugin_locale_paths
|
||||
Assets.mirror_files_for(self)
|
||||
end
|
||||
|
||||
@@ -88,11 +89,24 @@ module Engines
|
||||
def add_plugin_view_paths
|
||||
view_path = File.join(directory, 'app', 'views')
|
||||
if File.exist?(view_path)
|
||||
ActionController::Base.prepend_view_path(view_path) # push it just underneath the app
|
||||
ActionView::TemplateFinder.process_view_paths(view_path)
|
||||
ActionController::Base.view_paths.insert(1, view_path) # push it just underneath the app
|
||||
end
|
||||
end
|
||||
|
||||
def add_plugin_locale_paths
|
||||
locale_path = File.join(directory, 'locales')
|
||||
return unless File.exists?(locale_path)
|
||||
|
||||
locale_files = Dir[File.join(locale_path, '*.{rb,yml}')]
|
||||
return if locale_files.blank?
|
||||
|
||||
first_app_element =
|
||||
I18n.load_path.select{ |e| e =~ /^#{ RAILS_ROOT }/ }.reject{ |e| e =~ /^#{ RAILS_ROOT }\/vendor\/plugins/ }.first
|
||||
app_index = I18n.load_path.index(first_app_element) || - 1
|
||||
|
||||
I18n.load_path.insert(app_index, *locale_files)
|
||||
end
|
||||
|
||||
# The path to this plugin's public files
|
||||
def public_asset_directory
|
||||
"#{File.basename(Engines.public_directory)}/#{name}"
|
||||
@@ -111,11 +125,15 @@ module Engines
|
||||
# Returns the version number of the latest migration for this plugin. Returns
|
||||
# nil if this plugin has no migrations.
|
||||
def latest_migration
|
||||
migrations = Dir[migration_directory+"/*.rb"]
|
||||
return nil if migrations.empty?
|
||||
migrations.map { |p| File.basename(p) }.sort.last.match(/0*(\d+)\_/)[1].to_i
|
||||
migrations.last
|
||||
end
|
||||
|
||||
|
||||
# Returns the version numbers of all migrations for this plugin.
|
||||
def migrations
|
||||
migrations = Dir[migration_directory+"/*.rb"]
|
||||
migrations.map { |p| File.basename(p).match(/0*(\d+)\_/)[1].to_i }.sort
|
||||
end
|
||||
|
||||
# Migrate this plugin to the given version. See Engines::Plugin::Migrator for more
|
||||
# information.
|
||||
def migrate(version = nil)
|
||||
|
||||
+20
-53
@@ -12,63 +12,30 @@ class Engines::Plugin::Migrator < ActiveRecord::Migrator
|
||||
# We need to be able to set the 'current' engine being migrated.
|
||||
cattr_accessor :current_plugin
|
||||
|
||||
# Runs the migrations from a plugin, up (or down) to the version given
|
||||
def self.migrate_plugin(plugin, version)
|
||||
self.current_plugin = plugin
|
||||
# There seems to be a bug in Rails' own migrations, where migrating
|
||||
# to the existing version causes all migrations to be run where that
|
||||
# migration number doesn't exist (i.e. zero). We could fix this by
|
||||
# removing the line if the version hits zero...?
|
||||
return if current_version(plugin) == version
|
||||
migrate(plugin.migration_directory, version)
|
||||
end
|
||||
|
||||
# Returns the name of the table used to store schema information about
|
||||
# installed plugins.
|
||||
#
|
||||
# See Engines.schema_info_table for more details.
|
||||
def self.schema_info_table_name
|
||||
proper_table_name Engines.schema_info_table
|
||||
end
|
||||
|
||||
# Returns the current version of the given plugin
|
||||
def self.current_version(plugin=current_plugin)
|
||||
result = ActiveRecord::Base.connection.select_one(<<-ESQL
|
||||
SELECT version FROM #{schema_info_table_name}
|
||||
WHERE plugin_name = '#{plugin.name}'
|
||||
ESQL
|
||||
)
|
||||
if result
|
||||
result["version"].to_i
|
||||
else
|
||||
# There probably isn't an entry for this engine in the migration info table.
|
||||
# We need to create that entry, and set the version to 0
|
||||
ActiveRecord::Base.connection.execute(<<-ESQL
|
||||
INSERT INTO #{schema_info_table_name} (version, plugin_name)
|
||||
VALUES (0,'#{plugin.name}')
|
||||
ESQL
|
||||
)
|
||||
0
|
||||
class << self
|
||||
# Runs the migrations from a plugin, up (or down) to the version given
|
||||
def migrate_plugin(plugin, version)
|
||||
self.current_plugin = plugin
|
||||
return if current_version(plugin) == version
|
||||
migrate(plugin.migration_directory, version)
|
||||
end
|
||||
|
||||
def current_version(plugin=current_plugin)
|
||||
# Delete migrations that don't match .. to_i will work because the number comes first
|
||||
::ActiveRecord::Base.connection.select_values(
|
||||
"SELECT version FROM #{schema_migrations_table_name}"
|
||||
).delete_if{ |v| v.match(/-#{plugin.name}/) == nil }.map(&:to_i).max || 0
|
||||
end
|
||||
end
|
||||
|
||||
def migrated(plugin=current_plugin)
|
||||
current = ActiveRecord::Base.connection.select_value(<<-ESQL
|
||||
SELECT version FROM #{self.class.schema_info_table_name}
|
||||
WHERE plugin_name = '#{plugin.name}'
|
||||
ESQL
|
||||
).to_i
|
||||
current ? (1..current).to_a : []
|
||||
|
||||
def migrated
|
||||
sm_table = self.class.schema_migrations_table_name
|
||||
::ActiveRecord::Base.connection.select_values(
|
||||
"SELECT version FROM #{sm_table}"
|
||||
).delete_if{ |v| v.match(/-#{current_plugin.name}/) == nil }.map(&:to_i).sort
|
||||
end
|
||||
|
||||
# Sets the version of the plugin in Engines::Plugin::Migrator.current_plugin to
|
||||
# the given version.
|
||||
def record_version_state_after_migrating(version)
|
||||
ActiveRecord::Base.connection.update(<<-ESQL
|
||||
UPDATE #{self.class.schema_info_table_name}
|
||||
SET version = #{down? ? version.to_i - 1 : version.to_i}
|
||||
WHERE plugin_name = '#{self.current_plugin.name}'
|
||||
ESQL
|
||||
)
|
||||
super(version.to_s + "-" + current_plugin.name)
|
||||
end
|
||||
end
|
||||
@@ -16,9 +16,6 @@
|
||||
module Engines::RailsExtensions::ActionMailer
|
||||
def self.included(base) #:nodoc:
|
||||
base.class_eval do
|
||||
# TODO commented this out because it seems to break ActionMailer
|
||||
# how can this be fixed?
|
||||
|
||||
alias_method_chain :template_path, :engine_additions
|
||||
alias_method_chain :initialize_template_class, :engine_additions
|
||||
end
|
||||
@@ -70,7 +67,7 @@ module Engines::RailsExtensions::ActionMailer
|
||||
#
|
||||
# ActionView::Base.new(ActionController::Base.view_paths.dup, assigns, self)
|
||||
renderer = initialize_template_class_without_engine_additions(assigns)
|
||||
renderer.finder.view_paths = ActionController::Base.view_paths.dup
|
||||
renderer.view_paths.unshift(*ActionController::Base.view_paths.dup)
|
||||
renderer
|
||||
end
|
||||
end
|
||||
|
||||
@@ -102,16 +102,14 @@ module Engines::RailsExtensions::Dependencies
|
||||
# if we recognise this type
|
||||
# (this regexp splits out the module/filename from any instances of app/#{type}, so that
|
||||
# modules are still respected.)
|
||||
if file_name =~ /^(.*app\/#{file_type}s\/)?(.*_#{file_type})(\.rb)?$/
|
||||
if file_name =~ /^(.*app\/#{file_type}s\/)+(.*_#{file_type})(\.rb)?$/
|
||||
base_name = $2
|
||||
# ... go through the plugins from first started to last, so that
|
||||
# code with a high precedence (started later) will override lower precedence
|
||||
# implementations
|
||||
Engines.plugins.each do |plugin|
|
||||
plugin_file_name = File.expand_path(File.join(plugin.directory, 'app', "#{file_type}s", base_name))
|
||||
Engines.logger.debug("checking plugin '#{plugin.name}' for '#{base_name}'")
|
||||
if File.file?("#{plugin_file_name}.rb")
|
||||
Engines.logger.debug("==> loading from plugin '#{plugin.name}'")
|
||||
file_loaded = true if require_or_load_without_engine_additions(plugin_file_name, const_path)
|
||||
end
|
||||
end
|
||||
@@ -119,16 +117,11 @@ module Engines::RailsExtensions::Dependencies
|
||||
# finally, load any application-specific controller classes using the 'proper'
|
||||
# rails load mechanism, EXCEPT when we're testing engines and could load this file
|
||||
# from an engine
|
||||
if Engines.disable_application_code_loading
|
||||
Engines.logger.debug("loading from application disabled.")
|
||||
else
|
||||
unless Engines.disable_application_code_loading
|
||||
# Ensure we are only loading from the /app directory at this point
|
||||
app_file_name = File.join(RAILS_ROOT, 'app', "#{file_type}s", "#{base_name}")
|
||||
if File.file?("#{app_file_name}.rb")
|
||||
Engines.logger.debug("loading from application: #{base_name}")
|
||||
file_loaded = true if require_or_load_without_engine_additions(app_file_name, const_path)
|
||||
else
|
||||
Engines.logger.debug("(file not found in application)")
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -140,4 +133,6 @@ module Engines::RailsExtensions::Dependencies
|
||||
end
|
||||
end
|
||||
|
||||
ActiveSupport::Dependencies.send :include, Engines::RailsExtensions::Dependencies
|
||||
module ActiveSupport::Dependencies #:nodoc:
|
||||
include Engines::RailsExtensions::Dependencies
|
||||
end
|
||||
@@ -0,0 +1,37 @@
|
||||
# == Using plugin assets for form tag helpers
|
||||
#
|
||||
# It's as easy to use plugin images for image_submit_tag using Engines as it is for image_tag:
|
||||
#
|
||||
# <%= image_submit_tag "my_face", :plugin => "my_plugin" %>
|
||||
#
|
||||
# ---
|
||||
#
|
||||
# This module enhances one of the methods from ActionView::Helpers::FormTagHelper:
|
||||
#
|
||||
# * image_submit_tag
|
||||
#
|
||||
# This method now accepts the key/value pair <tt>:plugin => "plugin_name"</tt>,
|
||||
# which can be used to specify the originating plugin for any assets.
|
||||
#
|
||||
module Engines::RailsExtensions::FormTagHelpers
|
||||
def self.included(base)
|
||||
base.class_eval do
|
||||
alias_method_chain :image_submit_tag, :engine_additions
|
||||
end
|
||||
end
|
||||
|
||||
# Adds plugin functionality to Rails' default image_submit_tag method.
|
||||
def image_submit_tag_with_engine_additions(source, options={})
|
||||
options.stringify_keys!
|
||||
if options["plugin"]
|
||||
source = Engines::RailsExtensions::AssetHelpers.plugin_asset_path(options["plugin"], "images", source)
|
||||
options.delete("plugin")
|
||||
end
|
||||
image_submit_tag_without_engine_additions(source, options)
|
||||
end
|
||||
end
|
||||
|
||||
module ::ActionView::Helpers::FormTagHelper #:nodoc:
|
||||
include Engines::RailsExtensions::FormTagHelpers
|
||||
end
|
||||
|
||||
@@ -32,8 +32,8 @@ require "engines/plugin/migrator"
|
||||
# |- lib/
|
||||
# |- db/
|
||||
# |-migrate/
|
||||
# |- 001_do_something.rb
|
||||
# |- 002_and_something_else.rb
|
||||
# |- 20081105123419_add_some_new_feature.rb
|
||||
# |- 20081107144959_and_something_else.rb
|
||||
# |- ...
|
||||
#
|
||||
# When you install a plugin which contains migrations, you are undertaking a
|
||||
@@ -44,8 +44,8 @@ require "engines/plugin/migrator"
|
||||
#
|
||||
# == An example
|
||||
#
|
||||
# For example, our current application is at version 14 (according to the
|
||||
# +schema_info+ table), when we decide that we want to add a tagging plugin. The
|
||||
# For example, our current application is at version 20081106164503 (according to the
|
||||
# +schema_migrations+ table), when we decide that we want to add a tagging plugin. The
|
||||
# tagging plugin chosen includes migrations to create the tables it requires
|
||||
# (say, _tags_ and _taggings_, for instance), along with the models and helpers
|
||||
# one might expect.
|
||||
@@ -57,14 +57,14 @@ require "engines/plugin/migrator"
|
||||
#
|
||||
# $ script/generate plugin_migration
|
||||
# exists db/migrate
|
||||
# create db/migrate/015_migrate_tagging_plugin_to_version_3.rb
|
||||
# create db/migrate/20081108120415_my_plugin_to_version_20081107144959.rb
|
||||
#
|
||||
# This migration will take our application to version 15, and contains the following,
|
||||
# typical migration code:
|
||||
# This migration will take our application to version 20081108120415, and contains the
|
||||
# following, typical migration code:
|
||||
#
|
||||
# class MigrateTaggingPluginToVersion3 < ActiveRecord::Migration
|
||||
# class TaggingToVersion20081107144959 < ActiveRecord::Migration
|
||||
# def self.up
|
||||
# Engines.plugins[:tagging].migrate(3)
|
||||
# Engines.plugins[:tagging].migrate(20081107144959)
|
||||
# end
|
||||
# def self.down
|
||||
# Engines.plugins[:tagging].migrate(0)
|
||||
@@ -72,8 +72,8 @@ require "engines/plugin/migrator"
|
||||
# end
|
||||
#
|
||||
# When we migrate our application up, using <tt>rake db:migrate</tt> as normal,
|
||||
# the plugin will be migrated up to its latest version (3 in this example). If we
|
||||
# ever decide to migrate the application back to the state it was in at version 14,
|
||||
# the plugin will be migrated up to its latest version (20081108120415 in this example). If we
|
||||
# ever decide to migrate the application back to the state it was in at version 20081106164503,
|
||||
# the plugin migrations will be taken back down to version 0 (which, typically,
|
||||
# would remove all tables the plugin migrations define).
|
||||
#
|
||||
@@ -88,21 +88,21 @@ require "engines/plugin/migrator"
|
||||
#
|
||||
# $ script/generate plugin_migration
|
||||
# exists db/migrate
|
||||
# create db/migrate/023_migrate_tagging_plugin_to_version_5.rb
|
||||
# create db/migrate/20081210131437_tagging_to_version_20081201172034.rb
|
||||
#
|
||||
# The contents of this migration are:
|
||||
#
|
||||
# class MigrateTaggingPluginToVersion3 < ActiveRecord::Migration
|
||||
# class TaggingToVersion20081108120415 < ActiveRecord::Migration
|
||||
# def self.up
|
||||
# Engines.plugins[:tagging].migrate(5)
|
||||
# Engines.plugins[:tagging].migrate(20081201172034)
|
||||
# end
|
||||
# def self.down
|
||||
# Engines.plugins[:tagging].migrate(3)
|
||||
# Engines.plugins[:tagging].migrate(20081107144959)
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# Notice that if we were to migrate down to revision 22 or lower, the tagging plugin
|
||||
# will be migrated back down to version 3 - the version we were previously at.
|
||||
# Notice that if we were to migrate down to revision 20081108120415 or lower, the tagging plugin
|
||||
# will be migrated back down to version 20081107144959 - the version we were previously at.
|
||||
#
|
||||
#
|
||||
# = Creating migrations in plugins
|
||||
@@ -118,44 +118,16 @@ require "engines/plugin/migrator"
|
||||
#
|
||||
# Engines.plugins[:whatever].migrate(version)
|
||||
#
|
||||
# ---
|
||||
#
|
||||
# The Engines::RailsExtensions::Migrations module defines extensions for Rails'
|
||||
# migration systems. Specifically:
|
||||
# = Upgrading from previous versions of the engines plugin
|
||||
#
|
||||
# * Adding a hook to initialize_schema_migrations_table to create the plugin schema
|
||||
# info table.
|
||||
# Thanks to the tireless work of the plugin developer community, we can now relying on the migration
|
||||
# mechanism in Rails 2.1+ to do much of the plugin migration work for us. This also means that we
|
||||
# don't need a seperate schema_info table for plugins.
|
||||
#
|
||||
module Engines::RailsExtensions::Migrations
|
||||
def self.included(base) # :nodoc:
|
||||
base.class_eval { alias_method_chain :initialize_schema_migrations_table, :engine_additions }
|
||||
end
|
||||
|
||||
# Create the schema tables, and ensure that the plugin schema table
|
||||
# is also initialized. The plugin schema info table is defined by
|
||||
# Engines::Plugin::Migrator.schema_info_table_name.
|
||||
def initialize_schema_migrations_table_with_engine_additions
|
||||
initialize_schema_migrations_table_without_engine_additions
|
||||
|
||||
# create the plugin schema stuff.
|
||||
begin
|
||||
execute <<-ESQL
|
||||
CREATE TABLE #{Engines::Plugin::Migrator.schema_info_table_name}
|
||||
(plugin_name #{type_to_sql(:string)}, version #{type_to_sql(:integer)})
|
||||
ESQL
|
||||
rescue ActiveRecord::StatementInvalid
|
||||
# Schema has been initialized
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module ::ActiveRecord #:nodoc:
|
||||
module ConnectionAdapters #:nodoc:
|
||||
module SchemaStatements #:nodoc:
|
||||
include Engines::RailsExtensions::Migrations
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Set ActiveRecord to ignore the plugin schema table by default
|
||||
::ActiveRecord::SchemaDumper.ignore_tables << Engines.schema_info_table
|
||||
# To update your application, run
|
||||
#
|
||||
# rake db:migrate:upgrade_plugin_migrations
|
||||
#
|
||||
# This will ensure that migration information is carried over into the main schema_migrations table.
|
||||
#
|
||||
@@ -8,13 +8,13 @@
|
||||
# == Including routes in your plugin
|
||||
#
|
||||
# The engines plugin makes it possible to include a set of routes within your plugin
|
||||
# very simply, as it turns out. In your plugin, you simply include a <tt>routes.rb</tt>
|
||||
# file like the one below at the root of your plugin:
|
||||
# very simply, as it turns out. Include a <tt>routes.rb</tt> file like the one below
|
||||
# at the root of your plugin (along-side <tt>init.rb</tt> and <tt>lib/</tt>):
|
||||
#
|
||||
# connect "/login", :controller => "my_plugin/account", :action => "login"
|
||||
# connect "/login", :controller => "account", :action => "login"
|
||||
#
|
||||
# # add a named route
|
||||
# logout "/logout", :controller => "my_plugin/account", :action => "logout"
|
||||
# logout "/logout", :controller => "account", :action => "logout"
|
||||
#
|
||||
# # some restful stuff
|
||||
# resources :things do |t|
|
||||
@@ -67,7 +67,6 @@ module Engines::RailsExtensions::Routing
|
||||
def from_plugin(name)
|
||||
map = self # to make 'map' available within the plugin route file
|
||||
routes_path = Engines.plugins[name].routes_path
|
||||
Engines.logger.debug "loading routes from #{routes_path}"
|
||||
eval(IO.read(routes_path), binding, routes_path) if File.file?(routes_path)
|
||||
end
|
||||
end
|
||||
|
||||
+1
-1
@@ -81,7 +81,7 @@ module Engines::Testing
|
||||
# Sets the fixture path used by Test::Unit::TestCase to the temporary
|
||||
# directory which contains all plugin fixtures.
|
||||
def self.set_fixture_path
|
||||
Test::Unit::TestCase.fixture_path = self.temporary_fixtures_directory
|
||||
ActiveSupport::TestCase.fixture_path = self.temporary_fixtures_directory
|
||||
$LOAD_PATH.unshift self.temporary_fixtures_directory
|
||||
end
|
||||
end
|
||||
+77
-3
@@ -43,6 +43,80 @@ namespace :db do
|
||||
end
|
||||
end
|
||||
|
||||
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'
|
||||
task :upgrade_plugin_migrations => :environment do
|
||||
svens_fork_table_name = 'plugin_schema_migrations'
|
||||
|
||||
# Check if app was previously using Sven's fork
|
||||
if ActiveRecord::Base.connection.table_exists?(svens_fork_table_name)
|
||||
old_sm_table = svens_fork_table_name
|
||||
else
|
||||
old_sm_table = ActiveRecord::Migrator.proper_table_name(Engines.schema_info_table)
|
||||
end
|
||||
|
||||
unless ActiveRecord::Base.connection.table_exists?(old_sm_table)
|
||||
abort "Cannot find old migration table - assuming nothing needs to be done"
|
||||
end
|
||||
|
||||
# There are two forms of the engines schema info - pre-fix_plugin_migrations and post
|
||||
# We need to figure this out before we continue.
|
||||
|
||||
results = ActiveRecord::Base.connection.select_rows(
|
||||
"SELECT version, plugin_name FROM #{old_sm_table}"
|
||||
).uniq
|
||||
|
||||
def insert_new_version(plugin_name, version)
|
||||
version_string = "#{version}-#{plugin_name}"
|
||||
new_sm_table = ActiveRecord::Migrator.schema_migrations_table_name
|
||||
|
||||
# Check if the row already exists for some reason - maybe run this task more than once.
|
||||
return if ActiveRecord::Base.connection.select_rows("SELECT * FROM #{new_sm_table} WHERE version = #{version_string.dump.gsub("\"", "'")}").size > 0
|
||||
|
||||
puts "Inserting new version #{version} for plugin #{plugin_name}.."
|
||||
ActiveRecord::Base.connection.insert("INSERT INTO #{new_sm_table} (version) VALUES (#{version_string.dump.gsub("\"", "'")})")
|
||||
end
|
||||
|
||||
# We need to figure out if they already used "fix_plugin_migrations"
|
||||
versions = {}
|
||||
results.each do |r|
|
||||
versions[r[1]] ||= []
|
||||
versions[r[1]] << r[0].to_i
|
||||
end
|
||||
|
||||
if versions.values.find{ |v| v.size > 1 } == nil
|
||||
puts "Fixing migration info"
|
||||
# We only have one listed migration per plugin - this is pre-fix_plugin_migrations,
|
||||
# so we build all versions required. In this case, all migrations should
|
||||
versions.each do |plugin_name, version|
|
||||
version = version[0] # There is only one version
|
||||
|
||||
# We have to make an assumption that numeric migrations won't get this long..
|
||||
# I'm not sure if there is a better assumption, it should work in all
|
||||
# current cases.. (touch wood..)
|
||||
if version.to_s.size < "YYYYMMDDHHMMSS".size
|
||||
# Insert version records for each migration
|
||||
(1..version).each do |v|
|
||||
insert_new_version(plugin_name, v)
|
||||
end
|
||||
else
|
||||
# If the plugin is new-format "YYYYMMDDHHMMSS", we just copy it across...
|
||||
# The case in which this occurs is very rare..
|
||||
insert_new_version(plugin_name, version)
|
||||
end
|
||||
end
|
||||
else
|
||||
puts "Moving migration info"
|
||||
# We have multiple migrations listed per plugin - thus we can assume they have
|
||||
# already applied fix_plugin_migrations - we just copy it across verbatim
|
||||
versions.each do |plugin_name, version|
|
||||
version.each { |v| insert_new_version(plugin_name, v) }
|
||||
end
|
||||
end
|
||||
|
||||
puts "Migration info successfully migrated - removing old schema info table"
|
||||
ActiveRecord::Base.connection.drop_table(old_sm_table)
|
||||
end
|
||||
|
||||
desc 'Migrate a specified plugin.'
|
||||
task({:plugin => :environment}, :name, :version) do |task, args|
|
||||
name = args[:name] || ENV['NAME']
|
||||
@@ -53,7 +127,7 @@ namespace :db do
|
||||
else
|
||||
puts "Plugin #{name} does not exist."
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -174,5 +248,5 @@ Report any issues on http://dev.rails-engines.org. Thanks!
|
||||
|
||||
# Patch the default plugin testing task to have setup_plugin_fixtures as a prerequisite
|
||||
Rake::Task["test:plugins"].prerequisites << "test:plugins:setup_plugin_fixtures"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in new issue
Block a user