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:
Jean-Philippe Lang committed 2009-02-21 11:04:50 +00:00
1 parent 9a986ac0a5
commit fe28193e4e
237 files changed
+27994 -32194

No files matched your search

+7 -2
View File
@@ -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
-2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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