Froze rails gems
[depot.git] / vendor / rails / railties / lib / rails / plugin / locator.rb
1 module Rails
2 class Plugin
3
4 # The Plugin::Locator class should be subclasses to provide custom plugin-finding
5 # abilities to Rails (i.e. loading plugins from Gems, etc). Each subclass should implement
6 # the <tt>located_plugins</tt> method, which return an array of Plugin objects that have been found.
7 class Locator
8 include Enumerable
9
10 attr_reader :initializer
11
12 def initialize(initializer)
13 @initializer = initializer
14 end
15
16 # This method should return all the plugins which this Plugin::Locator can find
17 # These will then be used by the current Plugin::Loader, which is responsible for actually
18 # loading the plugins themselves
19 def plugins
20 raise "The `plugins' method must be defined by concrete subclasses of #{self.class}"
21 end
22
23 def each(&block)
24 plugins.each(&block)
25 end
26
27 def plugin_names
28 plugins.map(&:name)
29 end
30 end
31
32 # The Rails::Plugin::FileSystemLocator will try to locate plugins by examining the directories
33 # the the paths given in configuration.plugin_paths. Any plugins that can be found are returned
34 # in a list.
35 #
36 # The criteria for a valid plugin in this case is found in Rails::Plugin#valid?, although
37 # other subclasses of Rails::Plugin::Locator can of course use different conditions.
38 class FileSystemLocator < Locator
39
40 # Returns all the plugins which can be loaded in the filesystem, under the paths given
41 # by configuration.plugin_paths.
42 def plugins
43 initializer.configuration.plugin_paths.flatten.inject([]) do |plugins, path|
44 plugins.concat locate_plugins_under(path)
45 plugins
46 end.flatten
47 end
48
49 private
50
51 # Attempts to create a plugin from the given path. If the created plugin is valid?
52 # (see Rails::Plugin#valid?) then the plugin instance is returned; otherwise nil.
53 def create_plugin(path)
54 plugin = Rails::Plugin.new(path)
55 plugin.valid? ? plugin : nil
56 end
57
58 # This starts at the base path looking for valid plugins (see Rails::Plugin#valid?).
59 # Since plugins can be nested arbitrarily deep within an unspecified number of intermediary
60 # directories, this method runs recursively until it finds a plugin directory, e.g.
61 #
62 # locate_plugins_under('vendor/plugins/acts/acts_as_chunky_bacon')
63 # => <Rails::Plugin name: 'acts_as_chunky_bacon' ... >
64 #
65 def locate_plugins_under(base_path)
66 Dir.glob(File.join(base_path, '*')).sort.inject([]) do |plugins, path|
67 if plugin = create_plugin(path)
68 plugins << plugin
69 elsif File.directory?(path)
70 plugins.concat locate_plugins_under(path)
71 end
72 plugins
73 end
74 end
75 end
76
77 # The GemLocator scans all the loaded RubyGems, looking for gems with
78 # a <tt>rails/init.rb</tt> file.
79 class GemLocator < Locator
80 def plugins
81 gem_index = initializer.configuration.gems.inject({}) { |memo, gem| memo.update gem.specification => gem }
82 specs = gem_index.keys
83 specs += Gem.loaded_specs.values.select do |spec|
84 spec.loaded_from && # prune stubs
85 File.exist?(File.join(spec.full_gem_path, "rails", "init.rb"))
86 end
87 specs.compact!
88
89 require "rubygems/dependency_list"
90
91 deps = Gem::DependencyList.new
92 deps.add(*specs) unless specs.empty?
93
94 deps.dependency_order.collect do |spec|
95 Rails::GemPlugin.new(spec, gem_index[spec])
96 end
97 end
98 end
99 end
100 end