Froze rails gems
[depot.git] / vendor / rails / railties / lib / rails / plugin.rb
1 module Rails
2 # The Plugin class should be an object which provides the following methods:
3 #
4 # * +name+ - Used during initialisation to order the plugin (based on name and
5 # the contents of <tt>config.plugins</tt>).
6 # * +valid?+ - Returns true if this plugin can be loaded.
7 # * +load_paths+ - Each path within the returned array will be added to the <tt>$LOAD_PATH</tt>.
8 # * +load+ - Finally 'load' the plugin.
9 #
10 # These methods are expected by the Rails::Plugin::Locator and Rails::Plugin::Loader classes.
11 # The default implementation returns the <tt>lib</tt> directory as its <tt>load_paths</tt>,
12 # and evaluates <tt>init.rb</tt> when <tt>load</tt> is called.
13 #
14 # You can also inspect the about.yml data programmatically:
15 #
16 # plugin = Rails::Plugin.new(path_to_my_plugin)
17 # plugin.about["author"] # => "James Adam"
18 # plugin.about["url"] # => "http://interblah.net"
19 class Plugin
20 include Comparable
21
22 attr_reader :directory, :name
23
24 def initialize(directory)
25 @directory = directory
26 @name = File.basename(@directory) rescue nil
27 @loaded = false
28 end
29
30 def valid?
31 File.directory?(directory) && (has_lib_directory? || has_init_file?)
32 end
33
34 # Returns a list of paths this plugin wishes to make available in <tt>$LOAD_PATH</tt>.
35 def load_paths
36 report_nonexistant_or_empty_plugin! unless valid?
37 has_lib_directory? ? [lib_path] : []
38 end
39
40 # Evaluates a plugin's init.rb file.
41 def load(initializer)
42 return if loaded?
43 report_nonexistant_or_empty_plugin! unless valid?
44 evaluate_init_rb(initializer)
45 @loaded = true
46 end
47
48 def loaded?
49 @loaded
50 end
51
52 def <=>(other_plugin)
53 name <=> other_plugin.name
54 end
55
56 def about
57 @about ||= load_about_information
58 end
59
60 private
61 def load_about_information
62 about_yml_path = File.join(@directory, "about.yml")
63 parsed_yml = File.exist?(about_yml_path) ? YAML.load(File.read(about_yml_path)) : {}
64 parsed_yml || {}
65 rescue Exception
66 {}
67 end
68
69 def report_nonexistant_or_empty_plugin!
70 raise LoadError, "Can not find the plugin named: #{name}"
71 end
72
73 def lib_path
74 File.join(directory, 'lib')
75 end
76
77 def classic_init_path
78 File.join(directory, 'init.rb')
79 end
80
81 def gem_init_path
82 File.join(directory, 'rails', 'init.rb')
83 end
84
85 def init_path
86 File.file?(gem_init_path) ? gem_init_path : classic_init_path
87 end
88
89 def has_lib_directory?
90 File.directory?(lib_path)
91 end
92
93 def has_init_file?
94 File.file?(init_path)
95 end
96
97 def evaluate_init_rb(initializer)
98 if has_init_file?
99 silence_warnings do
100 # Allow plugins to reference the current configuration object
101 config = initializer.configuration
102
103 eval(IO.read(init_path), binding, init_path)
104 end
105 end
106 end
107 end
108
109 # This Plugin subclass represents a Gem plugin. Although RubyGems has already
110 # taken care of $LOAD_PATHs, it exposes its load_paths to add them
111 # to Dependencies.load_paths.
112 class GemPlugin < Plugin
113 # Initialize this plugin from a Gem::Specification.
114 def initialize(spec, gem)
115 directory = spec.full_gem_path
116 super(directory)
117 @name = spec.name
118 end
119
120 def init_path
121 File.join(directory, 'rails', 'init.rb')
122 end
123 end
124 end