2007-11-08 00:29:44 -05:00
|
|
|
module Rails
|
|
|
|
# The Plugin class should be an object which provides the following methods:
|
|
|
|
#
|
2008-05-09 05:38:02 -04:00
|
|
|
# * +name+ - Used during initialisation to order the plugin (based on name and
|
|
|
|
# the contents of <tt>config.plugins</tt>).
|
|
|
|
# * +valid?+ - Returns true if this plugin can be loaded.
|
|
|
|
# * +load_paths+ - Each path within the returned array will be added to the <tt>$LOAD_PATH</tt>.
|
|
|
|
# * +load+ - Finally 'load' the plugin.
|
2007-11-08 00:29:44 -05:00
|
|
|
#
|
|
|
|
# These methods are expected by the Rails::Plugin::Locator and Rails::Plugin::Loader classes.
|
2008-05-09 05:38:02 -04:00
|
|
|
# The default implementation returns the <tt>lib</tt> directory as its <tt>load_paths</tt>,
|
2007-11-08 00:29:44 -05:00
|
|
|
# and evaluates <tt>init.rb</tt> when <tt>load</tt> is called.
|
2008-03-27 13:47:51 -04:00
|
|
|
#
|
|
|
|
# You can also inspect the about.yml data programmatically:
|
|
|
|
#
|
|
|
|
# plugin = Rails::Plugin.new(path_to_my_plugin)
|
|
|
|
# plugin.about["author"] # => "James Adam"
|
|
|
|
# plugin.about["url"] # => "http://interblah.net"
|
2007-11-08 00:29:44 -05:00
|
|
|
class Plugin
|
|
|
|
include Comparable
|
|
|
|
|
|
|
|
attr_reader :directory, :name
|
|
|
|
|
|
|
|
def initialize(directory)
|
|
|
|
@directory = directory
|
2008-03-27 13:47:51 -04:00
|
|
|
@name = File.basename(@directory) rescue nil
|
|
|
|
@loaded = false
|
2007-11-08 00:29:44 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def valid?
|
2008-11-26 08:41:20 -05:00
|
|
|
File.directory?(directory) && (has_app_directory? || has_lib_directory? || has_init_file?)
|
2007-11-08 00:29:44 -05:00
|
|
|
end
|
|
|
|
|
2008-05-09 05:38:02 -04:00
|
|
|
# Returns a list of paths this plugin wishes to make available in <tt>$LOAD_PATH</tt>.
|
2007-11-08 00:29:44 -05:00
|
|
|
def load_paths
|
|
|
|
report_nonexistant_or_empty_plugin! unless valid?
|
2008-11-26 08:41:20 -05:00
|
|
|
|
2009-04-22 19:10:49 -04:00
|
|
|
load_paths = []
|
|
|
|
load_paths << lib_path if has_lib_directory?
|
|
|
|
load_paths << app_paths if has_app_directory?
|
|
|
|
load_paths.flatten
|
2007-11-08 00:29:44 -05:00
|
|
|
end
|
2008-11-26 14:03:25 -05:00
|
|
|
|
2008-05-09 05:38:02 -04:00
|
|
|
# Evaluates a plugin's init.rb file.
|
2007-11-08 00:29:44 -05:00
|
|
|
def load(initializer)
|
2007-11-08 10:41:46 -05:00
|
|
|
return if loaded?
|
2007-11-08 00:29:44 -05:00
|
|
|
report_nonexistant_or_empty_plugin! unless valid?
|
|
|
|
evaluate_init_rb(initializer)
|
|
|
|
@loaded = true
|
|
|
|
end
|
|
|
|
|
|
|
|
def loaded?
|
|
|
|
@loaded
|
|
|
|
end
|
|
|
|
|
|
|
|
def <=>(other_plugin)
|
|
|
|
name <=> other_plugin.name
|
|
|
|
end
|
2008-03-27 13:47:51 -04:00
|
|
|
|
|
|
|
def about
|
|
|
|
@about ||= load_about_information
|
|
|
|
end
|
2008-11-26 14:03:25 -05:00
|
|
|
|
|
|
|
# Engines are plugins with an app/ directory.
|
|
|
|
def engine?
|
|
|
|
has_app_directory?
|
|
|
|
end
|
2007-11-08 00:29:44 -05:00
|
|
|
|
2008-11-26 14:03:25 -05:00
|
|
|
# Returns true if the engine ships with a routing file
|
|
|
|
def routed?
|
|
|
|
File.exist?(routing_file)
|
|
|
|
end
|
|
|
|
|
2009-03-24 09:49:47 -04:00
|
|
|
# Returns true if there is any localization file in locale_path
|
|
|
|
def localized?
|
|
|
|
locale_files.any?
|
|
|
|
end
|
2008-11-27 12:59:24 -05:00
|
|
|
|
|
|
|
def view_path
|
|
|
|
File.join(directory, 'app', 'views')
|
|
|
|
end
|
|
|
|
|
2008-11-26 14:03:25 -05:00
|
|
|
def controller_path
|
|
|
|
File.join(directory, 'app', 'controllers')
|
|
|
|
end
|
|
|
|
|
2009-02-22 14:23:04 -05:00
|
|
|
def metal_path
|
|
|
|
File.join(directory, 'app', 'metal')
|
|
|
|
end
|
|
|
|
|
2008-11-26 14:03:25 -05:00
|
|
|
def routing_file
|
|
|
|
File.join(directory, 'config', 'routes.rb')
|
|
|
|
end
|
2009-03-24 09:49:47 -04:00
|
|
|
|
|
|
|
def locale_path
|
|
|
|
File.join(directory, 'config', 'locales')
|
|
|
|
end
|
|
|
|
|
|
|
|
def locale_files
|
|
|
|
Dir[ File.join(locale_path, '*.{rb,yml}') ]
|
|
|
|
end
|
2008-11-26 14:03:25 -05:00
|
|
|
|
|
|
|
|
2007-11-08 00:29:44 -05:00
|
|
|
private
|
2008-03-27 13:47:51 -04:00
|
|
|
def load_about_information
|
|
|
|
about_yml_path = File.join(@directory, "about.yml")
|
|
|
|
parsed_yml = File.exist?(about_yml_path) ? YAML.load(File.read(about_yml_path)) : {}
|
|
|
|
parsed_yml || {}
|
|
|
|
rescue Exception
|
|
|
|
{}
|
|
|
|
end
|
2007-11-08 00:29:44 -05:00
|
|
|
|
|
|
|
def report_nonexistant_or_empty_plugin!
|
|
|
|
raise LoadError, "Can not find the plugin named: #{name}"
|
2008-11-26 08:41:20 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
def app_paths
|
2009-02-22 14:23:04 -05:00
|
|
|
[ File.join(directory, 'app', 'models'), File.join(directory, 'app', 'helpers'), controller_path, metal_path ]
|
2008-11-26 08:41:20 -05:00
|
|
|
end
|
2008-11-26 14:03:25 -05:00
|
|
|
|
2007-11-08 00:29:44 -05:00
|
|
|
def lib_path
|
|
|
|
File.join(directory, 'lib')
|
|
|
|
end
|
|
|
|
|
2008-05-28 15:30:44 -04:00
|
|
|
def classic_init_path
|
2007-11-08 00:29:44 -05:00
|
|
|
File.join(directory, 'init.rb')
|
|
|
|
end
|
|
|
|
|
2008-05-28 15:30:44 -04:00
|
|
|
def gem_init_path
|
|
|
|
File.join(directory, 'rails', 'init.rb')
|
|
|
|
end
|
|
|
|
|
|
|
|
def init_path
|
|
|
|
File.file?(gem_init_path) ? gem_init_path : classic_init_path
|
|
|
|
end
|
|
|
|
|
2008-11-26 08:41:20 -05:00
|
|
|
|
|
|
|
def has_app_directory?
|
|
|
|
File.directory?(File.join(directory, 'app'))
|
|
|
|
end
|
|
|
|
|
2007-11-08 00:29:44 -05:00
|
|
|
def has_lib_directory?
|
|
|
|
File.directory?(lib_path)
|
|
|
|
end
|
|
|
|
|
|
|
|
def has_init_file?
|
|
|
|
File.file?(init_path)
|
|
|
|
end
|
|
|
|
|
2008-11-26 08:41:20 -05:00
|
|
|
|
2007-11-08 00:29:44 -05:00
|
|
|
def evaluate_init_rb(initializer)
|
2008-06-08 14:04:04 -04:00
|
|
|
if has_init_file?
|
2009-05-19 15:19:58 -04:00
|
|
|
require 'active_support/core_ext/kernel/reporting'
|
2008-06-08 14:04:04 -04:00
|
|
|
silence_warnings do
|
|
|
|
# Allow plugins to reference the current configuration object
|
|
|
|
config = initializer.configuration
|
|
|
|
|
|
|
|
eval(IO.read(init_path), binding, init_path)
|
|
|
|
end
|
|
|
|
end
|
2007-11-08 00:29:44 -05:00
|
|
|
end
|
|
|
|
end
|
2008-03-27 14:37:53 -04:00
|
|
|
|
2008-05-07 09:43:12 -04:00
|
|
|
# This Plugin subclass represents a Gem plugin. Although RubyGems has already
|
2008-05-31 19:46:47 -04:00
|
|
|
# taken care of $LOAD_PATHs, it exposes its load_paths to add them
|
2008-05-07 09:43:12 -04:00
|
|
|
# to Dependencies.load_paths.
|
2008-03-27 14:37:53 -04:00
|
|
|
class GemPlugin < Plugin
|
|
|
|
# Initialize this plugin from a Gem::Specification.
|
2008-06-08 14:04:04 -04:00
|
|
|
def initialize(spec, gem)
|
Fix a number of errors in the config.gem mechanism.
* Rails::GemDependency was missing definitions for hash and eql?, causing Array#uniq to not work.
* If several versions of a gem are unpacked in vendor, now chooses the highest if no version is specified.
* streamlined add_load_path. Now sets up Rubygems correctly to allow 'gem' to find frozen gems, with
gems frozen to vendor/gems and specifications in vendor/gems/<gem-name>/.specification
* Rails::GemDependency#specification would return a spec for the highest installed version, even for
frozen gems and/or previously loaded lower versions. See in part ticket #1123.
* removed vendor from default_load_paths - it was causing autoloading to append Gems::Gems::<gem-dir> to
constant names
* added additional tests for loading frozen gems.
* incorporates the fix from #1107 for vendor rails
* defers to freeze:gems for handling the Rails framework. gems:unpack WILL NOT place a copy of Rails
in vendor/gems. Should close #1123 completely.
* incorporates, via using the gem loader for frozen gems, fixes corresponding to #227, #324, #362, #527, and #742.
* gem plugins now work the same whether frozen or not. Correctness of the behavior is a matter for another ticket...
Signed-off-by: rick <technoweenie@gmail.com>
2008-10-04 13:51:23 -04:00
|
|
|
directory = spec.full_gem_path
|
2008-06-08 14:04:04 -04:00
|
|
|
super(directory)
|
2008-03-27 14:37:53 -04:00
|
|
|
@name = spec.name
|
|
|
|
end
|
|
|
|
|
2008-05-07 09:43:12 -04:00
|
|
|
def init_path
|
|
|
|
File.join(directory, 'rails', 'init.rb')
|
2008-03-27 14:37:53 -04:00
|
|
|
end
|
|
|
|
end
|
2009-02-22 14:23:04 -05:00
|
|
|
end
|