loaded_plugins 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +62 -0
- data/MIT-LICENSE +20 -0
- data/README +66 -0
- data/Rakefile +79 -0
- data/init.rb +3 -0
- data/lib/loaded_plugins.rb +4 -0
- data/lib/loaded_plugins/extensions/initializer.rb +81 -0
- data/lib/loaded_plugins/extensions/rails.rb +6 -0
- data/lib/loaded_plugins/plugin.rb +77 -0
- data/lib/loaded_plugins/plugin_list.rb +53 -0
- data/test/app_root/config/boot.rb +28 -0
- data/test/app_root/vendor/plugins/a_plugin_with_dependencies/init.rb +1 -0
- data/test/app_root/vendor/plugins/dependent_plugin/init.rb +0 -0
- data/test/app_root/vendor/plugins/first_plugin/init.rb +7 -0
- data/test/app_root/vendor/plugins/first_plugin/lib/first_plugin.rb +0 -0
- data/test/app_root/vendor/plugins/invalid_plugin/empty +0 -0
- data/test/app_root/vendor/plugins/plugin_with_lib_and_init/init.rb +0 -0
- data/test/app_root/vendor/plugins/plugin_with_lib_and_init/lib/empty +0 -0
- data/test/app_root/vendor/plugins/plugin_with_only_init/init.rb +0 -0
- data/test/app_root/vendor/plugins/plugin_with_only_lib/lib/empty +0 -0
- data/test/app_root/vendor/plugins/second_plugin_with_dependencies/init.rb +1 -0
- data/test/app_root/vendor/plugins/second_plugins_dependency/init.rb +0 -0
- data/test/app_root/vendor/plugins/subfolder/plugin_with_lib_and_init/init.rb +0 -0
- data/test/app_root/vendor/plugins/subfolder/plugin_with_lib_and_init/lib/empty +0 -0
- data/test/test_helper.rb +22 -0
- data/test/unit/initializer_test.rb +138 -0
- data/test/unit/plugin_list_test.rb +61 -0
- data/test/unit/plugin_test.rb +115 -0
- data/test/unit/rails_test.rb +8 -0
- metadata +73 -0
data/CHANGELOG
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
*SVN*
|
2
|
+
|
3
|
+
*0.1.2* (August 25th, 2007)
|
4
|
+
|
5
|
+
* Refactor unit tests
|
6
|
+
|
7
|
+
* Convert dos newlines to unix newlines
|
8
|
+
|
9
|
+
*0.1.1* (August 7th, 2007)
|
10
|
+
|
11
|
+
* Update documentation
|
12
|
+
|
13
|
+
* Simplify tracking of plugins that are missed before loaded_plugins is loaded
|
14
|
+
|
15
|
+
* Move '*' support in config.plugins to a separate plugin (see partial_plugin_list plugin).
|
16
|
+
|
17
|
+
* Move loaded_plugins/loaded_plugins.rb code to where it belongs in loaded_plugins/extensions/initializer.rb
|
18
|
+
|
19
|
+
* Add support for '*' in configuration.plugins like so (based on James Adam's Engines 1.2):
|
20
|
+
|
21
|
+
Rails::Initializer.run do |config|
|
22
|
+
config.plugins = [
|
23
|
+
'plugins_plus',
|
24
|
+
'*'
|
25
|
+
]
|
26
|
+
end
|
27
|
+
|
28
|
+
* If a plugin path cannot be found, continue loading it as normal rather than failing. This:
|
29
|
+
(1) Produces a descriptive error if the plugin doesn't really exist
|
30
|
+
(2) Allows you to call load_plugin from within your plugin's init.rb (e.g. if you have other plugins via svn:externals within your plugin)
|
31
|
+
|
32
|
+
*0.1.0* (March 31st, 2007)
|
33
|
+
|
34
|
+
* Add a more diverse set of Plugin callbacks (before_load, after_load, and after_initialize)
|
35
|
+
|
36
|
+
* Add support for getting the proper name of plugin gem formats (i.e. plugin_xyz-1.2.0)
|
37
|
+
|
38
|
+
* Respect manual specification of plugins in configuration.plugins instead of assuming that all plugins will be loaded
|
39
|
+
|
40
|
+
* Refactor laded_plugins.rb into files for each individual class being extended. #12 [Brian Takita]
|
41
|
+
|
42
|
+
* Adopt James Adam's Engines 1.2 style of tracking plugins
|
43
|
+
|
44
|
+
* Added empty files so that test directories get added to the gem
|
45
|
+
|
46
|
+
*0.0.4 (February 15th, 2007)
|
47
|
+
|
48
|
+
* Don't add plugins that weren't specified in the configuration
|
49
|
+
|
50
|
+
*0.0.3* (February 3rd, 2007)
|
51
|
+
|
52
|
+
* Fix inserting already-loaded plugins in the wrong order when loaded_plugins has been loaded as a gem midway through initialization
|
53
|
+
|
54
|
+
* Moved tasks into lib files so that they could be more easily tested
|
55
|
+
|
56
|
+
*0.0.2* (February 1st, 2007)
|
57
|
+
|
58
|
+
* When using dependencies, dependent plugins now appear +before+ the plugin that required them
|
59
|
+
|
60
|
+
*0.0.1* (November 2nd, 2006)
|
61
|
+
|
62
|
+
* Initial release
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2006-2007 James Adam, 2006-2007 Aaron Pfeifer, Neil Abraham
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
= loaded_plugins
|
2
|
+
|
3
|
+
loaded_plugins adds +Rails.plugins+, a list all of the plugins that Rails has
|
4
|
+
loaded.
|
5
|
+
|
6
|
+
== Resources
|
7
|
+
|
8
|
+
API
|
9
|
+
|
10
|
+
* http://api.pluginaweek.org/loaded_plugins
|
11
|
+
|
12
|
+
Wiki
|
13
|
+
|
14
|
+
* http://wiki.pluginaweek.org/Loaded_plugins
|
15
|
+
|
16
|
+
Announcement
|
17
|
+
|
18
|
+
* http://www.pluginaweek.org/2006/11/02/2-loaded_plugins-a-monkey-plugin
|
19
|
+
|
20
|
+
Source
|
21
|
+
|
22
|
+
* http://svn.pluginaweek.org/trunk/plugins/rails/loaded_plugins
|
23
|
+
|
24
|
+
Development
|
25
|
+
|
26
|
+
* http://dev.pluginaweek.org/browser/trunk/plugins/rails/loaded_plugins
|
27
|
+
|
28
|
+
== Description
|
29
|
+
|
30
|
+
During initialization, +Rails.plugins+ will keep track of a list of all of the
|
31
|
+
plugins that have been loaded so far. Once initialization is complete,
|
32
|
+
+Rails.plugins+ will contain all of the plugins loaded in the application.
|
33
|
+
|
34
|
+
The order of the plugins will be based on the order in which the plugins were
|
35
|
+
loaded during initialization.
|
36
|
+
|
37
|
+
== Usage
|
38
|
+
|
39
|
+
If you need access to Rails.plugins during initialization of your application,
|
40
|
+
you must use one of two things:
|
41
|
+
|
42
|
+
1. Use config.plugins to specify the order in which plugins are
|
43
|
+
loaded, for example:
|
44
|
+
|
45
|
+
Rails::Initializer.run do |config|
|
46
|
+
...
|
47
|
+
config.plugins = [
|
48
|
+
'loaded_plugins',
|
49
|
+
...
|
50
|
+
]
|
51
|
+
end
|
52
|
+
|
53
|
+
2. Require the plugin with the plugin_dependencies plugin installed.
|
54
|
+
|
55
|
+
If using +require+ without plugin_dependencies installed, loaded_plugins will
|
56
|
+
not track all of the plugins that were loaded prior to it being loaded until *after*
|
57
|
+
initialization is complete.
|
58
|
+
|
59
|
+
Also, note that the plugins are listed in the order that they are *completely*
|
60
|
+
loaded. That is, only after the entire initialization of a plugin is complete
|
61
|
+
will it get added to Rails.plugins.
|
62
|
+
|
63
|
+
== References
|
64
|
+
|
65
|
+
This plugin has been heavily influenced by the work James Adam has done in
|
66
|
+
Engines 1.2 (http://www.rails-engines.org/).
|
data/Rakefile
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'rake/testtask'
|
2
|
+
require 'rake/rdoctask'
|
3
|
+
require 'rake/gempackagetask'
|
4
|
+
require 'rake/contrib/sshpublisher'
|
5
|
+
|
6
|
+
PKG_NAME = 'loaded_plugins'
|
7
|
+
PKG_VERSION = '0.1.2'
|
8
|
+
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
|
9
|
+
RUBY_FORGE_PROJECT = 'pluginaweek'
|
10
|
+
|
11
|
+
desc 'Default: run unit tests.'
|
12
|
+
task :default => :test
|
13
|
+
|
14
|
+
desc 'Test the loaded_plugins plugin.'
|
15
|
+
Rake::TestTask.new(:test) do |t|
|
16
|
+
t.libs << 'lib'
|
17
|
+
t.pattern = 'test/**/*_test.rb'
|
18
|
+
t.verbose = true
|
19
|
+
end
|
20
|
+
|
21
|
+
desc 'Generate documentation for the loaded_plugins plugin.'
|
22
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
23
|
+
rdoc.rdoc_dir = 'rdoc'
|
24
|
+
rdoc.title = 'LoadedPlugins'
|
25
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
26
|
+
rdoc.rdoc_files.include('README')
|
27
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
28
|
+
end
|
29
|
+
|
30
|
+
spec = Gem::Specification.new do |s|
|
31
|
+
s.name = PKG_NAME
|
32
|
+
s.version = PKG_VERSION
|
33
|
+
s.platform = Gem::Platform::RUBY
|
34
|
+
s.summary = 'Adds Rails.plugins, a list all of the plugins that Rails has loaded'
|
35
|
+
|
36
|
+
s.files = FileList['{lib,test}/**/*'].to_a + %w(CHANGELOG init.rb MIT-LICENSE Rakefile README)
|
37
|
+
s.require_path = 'lib'
|
38
|
+
s.autorequire = 'loaded_plugins'
|
39
|
+
s.has_rdoc = true
|
40
|
+
s.test_files = Dir['test/**/*_test.rb']
|
41
|
+
|
42
|
+
s.author = 'Aaron Pfeifer, Neil Abraham'
|
43
|
+
s.email = 'info@pluginaweek.org'
|
44
|
+
s.homepage = 'http://www.pluginaweek.org'
|
45
|
+
end
|
46
|
+
|
47
|
+
Rake::GemPackageTask.new(spec) do |p|
|
48
|
+
p.gem_spec = spec
|
49
|
+
p.need_tar = true
|
50
|
+
p.need_zip = true
|
51
|
+
end
|
52
|
+
|
53
|
+
desc 'Publish the beta gem'
|
54
|
+
task :pgem => [:package] do
|
55
|
+
Rake::SshFilePublisher.new('pluginaweek@pluginaweek.org', '/home/pluginaweek/gems.pluginaweek.org/gems', 'pkg', "#{PKG_FILE_NAME}.gem").upload
|
56
|
+
end
|
57
|
+
|
58
|
+
desc 'Publish the API documentation'
|
59
|
+
task :pdoc => [:rdoc] do
|
60
|
+
Rake::SshDirPublisher.new('pluginaweek@pluginaweek.org', "/home/pluginaweek/api.pluginaweek.org/#{PKG_NAME}", 'rdoc').upload
|
61
|
+
end
|
62
|
+
|
63
|
+
desc 'Publish the API docs and gem'
|
64
|
+
task :publish => [:pdoc, :release]
|
65
|
+
|
66
|
+
desc 'Publish the release files to RubyForge.'
|
67
|
+
task :release => [:gem, :package] do
|
68
|
+
require 'rubyforge'
|
69
|
+
|
70
|
+
ruby_forge = RubyForge.new
|
71
|
+
ruby_forge.login
|
72
|
+
|
73
|
+
%w( gem tgz zip ).each do |ext|
|
74
|
+
file = "pkg/#{PKG_FILE_NAME}.#{ext}"
|
75
|
+
puts "Releasing #{File.basename(file)}..."
|
76
|
+
|
77
|
+
ruby_forge.add_release(RUBY_FORGE_PROJECT, PKG_NAME, PKG_VERSION, file)
|
78
|
+
end
|
79
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
module PluginAWeek #:nodoc:
|
2
|
+
module LoadedPlugins
|
3
|
+
module Extensions #:nodoc:
|
4
|
+
# Keeps track of all the plugins that Rails loaded during initialization
|
5
|
+
module Initializer
|
6
|
+
def self.included(base) #:nodoc:
|
7
|
+
base.class_eval do
|
8
|
+
alias_method_chain :load_plugin, :loaded_plugins
|
9
|
+
alias_method_chain :after_initialize, :loaded_plugins
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.extended(initializer) #:nodoc:
|
14
|
+
# Get all of the paths we missed before this plugin was loaded. This
|
15
|
+
# is only necessary for plugins that need +Rails.plugins+ during
|
16
|
+
# initialization.
|
17
|
+
initializer.add_loaded_plugins
|
18
|
+
end
|
19
|
+
|
20
|
+
# Loads the plugin from the specified directory, tracking all successfully
|
21
|
+
# loaded plugins in +Rails.plugins+
|
22
|
+
def load_plugin_with_loaded_plugins(directory)
|
23
|
+
plugin = Plugin.new(directory)
|
24
|
+
return false if loaded_plugins.include?(plugin.name)
|
25
|
+
|
26
|
+
# Be careful to place the plugin in the correct order in case a plugin
|
27
|
+
# has required another plugin
|
28
|
+
if @loaded_plugin_index
|
29
|
+
Rails.plugins.insert(@loaded_plugin_index, plugin)
|
30
|
+
else
|
31
|
+
Rails.plugins << plugin
|
32
|
+
@loaded_plugin_index = Rails.plugins.size - 1
|
33
|
+
end
|
34
|
+
|
35
|
+
# Plugin is about to be loaded
|
36
|
+
plugin.before_load
|
37
|
+
|
38
|
+
load_plugin_without_loaded_plugins(directory)
|
39
|
+
|
40
|
+
# Plugin has been loaded
|
41
|
+
plugin.after_load
|
42
|
+
|
43
|
+
# We no longer need to track the current index in LOADED_PLUGINS if
|
44
|
+
# we're the last one
|
45
|
+
@loaded_plugin_index = nil if Rails.plugins.last == plugin
|
46
|
+
|
47
|
+
true
|
48
|
+
end
|
49
|
+
|
50
|
+
# Freezes the list of loaded plugins and invokes the +after_initialize+
|
51
|
+
# callback for each plugin
|
52
|
+
def after_initialize_with_loaded_plugins #:nodoc:
|
53
|
+
add_loaded_plugins
|
54
|
+
Rails.plugins.freeze
|
55
|
+
Rails.plugins.each {|plugin| plugin.after_initialize}
|
56
|
+
|
57
|
+
after_initialize_without_loaded_plugins
|
58
|
+
end
|
59
|
+
|
60
|
+
# Adds all of the loaded plugins that were missed to +Rails.plugins+
|
61
|
+
def add_loaded_plugins
|
62
|
+
loaded_plugins.reverse.each do |name|
|
63
|
+
if !Rails.plugins[name] && path = find_plugin_path(name)
|
64
|
+
Rails.plugins.insert(0, Plugin.new(path))
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
# Finds the path of the specified plugin
|
71
|
+
def find_plugin_path(name)
|
72
|
+
find_plugins(configuration.plugin_paths).find {|path| Plugin.name_for(path) == name}
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
Rails::Initializer.class_eval do
|
80
|
+
include PluginAWeek::LoadedPlugins::Extensions::Initializer
|
81
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# An instance of Plugin is created for each plugin loaded by Rails, and
|
2
|
+
# stored in the +Rails.plugins+ list
|
3
|
+
class Plugin
|
4
|
+
# The name of this plugin
|
5
|
+
attr_accessor :name
|
6
|
+
|
7
|
+
# The directory in which this plugin is located
|
8
|
+
attr_accessor :root
|
9
|
+
|
10
|
+
class << self
|
11
|
+
# Gets the name of the plugin, given the path to it. The following would
|
12
|
+
# return "plugin_xyz":
|
13
|
+
# * plugin_xyz
|
14
|
+
# * plugin_xyz-1.2
|
15
|
+
# * plugin_xyz-1.2.0
|
16
|
+
# * plugin_xyz-1.2.0-win32
|
17
|
+
def name_for(path)
|
18
|
+
name = File.basename(path)
|
19
|
+
/^(.+)-#{Gem::Version::NUM_RE}(-.+)?$/.match(name) && $1 || name
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize(root) #:nodoc:
|
24
|
+
root.chop! if root.ends_with?('/')
|
25
|
+
|
26
|
+
@root = root
|
27
|
+
@name = self.class.name_for(root)
|
28
|
+
end
|
29
|
+
|
30
|
+
# The path to the plugin's lib folder
|
31
|
+
def lib_path
|
32
|
+
"#{root}/lib"
|
33
|
+
end
|
34
|
+
|
35
|
+
# Does the plugin's lib path exist?
|
36
|
+
def lib_path?
|
37
|
+
File.exists?(lib_path)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Gets all of the plugins that were loaded before this one
|
41
|
+
def plugins_before
|
42
|
+
if Rails.plugins.first == self
|
43
|
+
[]
|
44
|
+
else
|
45
|
+
Rails.plugins[0..Rails.plugins.index(self)-1]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Gets all of the plugins that were loaded after this one
|
50
|
+
def plugins_after
|
51
|
+
if Rails.plugins.last == self
|
52
|
+
[]
|
53
|
+
else
|
54
|
+
Rails.plugins[Rails.plugins.index(self)+1..Rails.plugins.length-1]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Invoked immediately before +Rails::Initializer+ loads the plugin
|
59
|
+
def before_load
|
60
|
+
end
|
61
|
+
|
62
|
+
# Invoked immediately after +Rails::Initializer+ loads the plugin
|
63
|
+
def after_load
|
64
|
+
end
|
65
|
+
|
66
|
+
# Invoked during the +Rails::Initializer#after_initialize+ callback
|
67
|
+
def after_initialize
|
68
|
+
end
|
69
|
+
|
70
|
+
def ==(other_obj) #:nodoc:
|
71
|
+
if other_obj.is_a?(Plugin)
|
72
|
+
other_obj.name == name
|
73
|
+
else
|
74
|
+
other_obj.to_s == name
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# The PluginList class is an array, enhanced to allow access to loaded plugins
|
2
|
+
# by name, and iteration over loaded plugins in order of priority.
|
3
|
+
#
|
4
|
+
# Each loaded plugin has a corresponding Plugin instance within this array, and
|
5
|
+
# the order the plugins were loaded is reflected in the entries in this array.
|
6
|
+
class PluginList < Array
|
7
|
+
# Finds plugins with the given name or index. For example,
|
8
|
+
#
|
9
|
+
# Rails.plugins[0] # => The first plugin loaded
|
10
|
+
# Rails.plugins[:foo] # => The "foo" plugin
|
11
|
+
# Rails.plugins['foo'] # => The "foo" plugin
|
12
|
+
#
|
13
|
+
# This will return an instance of the +Plugin+ class.
|
14
|
+
def [](name)
|
15
|
+
if name.is_a?(String) || name.is_a?(Symbol)
|
16
|
+
self.find {|plugin| plugin.name.to_s == name.to_s}
|
17
|
+
else
|
18
|
+
super
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Gets the plugins in the specified comma-delimited list. If the list is
|
23
|
+
# not specified (i.e. nil), then all plugins are returned.
|
24
|
+
#
|
25
|
+
# If a specific plugin cannot be found, an exception will be raised indicating
|
26
|
+
# so.
|
27
|
+
def find_by_names(names = nil)
|
28
|
+
if names
|
29
|
+
plugins = names.split(',')
|
30
|
+
missing_plugins = plugins - map(&:name)
|
31
|
+
|
32
|
+
raise ArgumentError, "Couldn't find plugin(s): #{missing_plugins.to_sentence}" if missing_plugins.any?
|
33
|
+
plugins.collect! {|name| self[name]}
|
34
|
+
else
|
35
|
+
plugins = self
|
36
|
+
end
|
37
|
+
|
38
|
+
plugins
|
39
|
+
end
|
40
|
+
|
41
|
+
# Iterates through each plugin by priority. The last loaded plugin will
|
42
|
+
# always have the highest priority.
|
43
|
+
#
|
44
|
+
# Effectively, this is like +Rails.plugins.reverse+. When given a block, it
|
45
|
+
# behaves like +Rails.plugins.reverse.each+.
|
46
|
+
def by_precedence(&block)
|
47
|
+
if block_given?
|
48
|
+
reverse.each { |x| yield x }
|
49
|
+
else
|
50
|
+
reverse
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# Don't change this file. Configuration is done in config/environment.rb and config/environments/*.rb
|
2
|
+
|
3
|
+
RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT)
|
4
|
+
|
5
|
+
unless defined?(Rails::Initializer)
|
6
|
+
require 'rubygems'
|
7
|
+
|
8
|
+
if defined?(RAILS_GEM_VERSION) && version = RAILS_GEM_VERSION
|
9
|
+
# Asking for 1.1.6 will give you 1.1.6.5206, if available -- makes it easier to use beta gems
|
10
|
+
rails_gem = Gem.cache.search('rails', "~>#{version}.0").sort_by { |g| g.version.version }.last
|
11
|
+
|
12
|
+
if rails_gem
|
13
|
+
gem "rails", "=#{rails_gem.version.version}"
|
14
|
+
require rails_gem.full_gem_path + '/lib/initializer'
|
15
|
+
else
|
16
|
+
STDERR.puts %(Cannot find gem for Rails ~>#{version}.0:
|
17
|
+
Install the missing gem with 'gem install -v=#{version} rails', or
|
18
|
+
change environment.rb to define RAILS_GEM_VERSION with your desired version.
|
19
|
+
)
|
20
|
+
exit 1
|
21
|
+
end
|
22
|
+
else
|
23
|
+
require_gem "rails"
|
24
|
+
require 'initializer'
|
25
|
+
end
|
26
|
+
|
27
|
+
Rails::Initializer.run(:set_load_path)
|
28
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
load_plugin(find_plugins(configuration.plugin_paths).find {|path| path =~ /\/dependent_plugin$/})
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
load_plugin(find_plugins(configuration.plugin_paths).find {|path| path =~ /\/second_plugins_dependency$/})
|
File without changes
|
File without changes
|
File without changes
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# Load the environment
|
2
|
+
ENV['RAILS_ENV'] ||= 'test'
|
3
|
+
require File.dirname(__FILE__) + '/app_root/config/boot'
|
4
|
+
|
5
|
+
# Load the plugin
|
6
|
+
$:.unshift("#{File.dirname(__FILE__)}/../lib")
|
7
|
+
require 'loaded_plugins'
|
8
|
+
|
9
|
+
# Load the testing framework
|
10
|
+
require 'test/unit'
|
11
|
+
|
12
|
+
# Helper methods
|
13
|
+
class Test::Unit::TestCase
|
14
|
+
protected
|
15
|
+
def plugins_path
|
16
|
+
"#{RAILS_ROOT}/vendor/plugins"
|
17
|
+
end
|
18
|
+
|
19
|
+
def plugin_path(name)
|
20
|
+
"#{plugins_path}/#{name}"
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/../test_helper"
|
2
|
+
|
3
|
+
class Rails::Initializer
|
4
|
+
public :find_plugin_path
|
5
|
+
end
|
6
|
+
|
7
|
+
class Plugin
|
8
|
+
attr_accessor :callbacks
|
9
|
+
|
10
|
+
def initialize_with_callbacks(*args)
|
11
|
+
@callbacks = []
|
12
|
+
initialize_without_callbacks(*args)
|
13
|
+
end
|
14
|
+
alias_method_chain :initialize, :callbacks
|
15
|
+
|
16
|
+
def before_load
|
17
|
+
callbacks << :before_load
|
18
|
+
end
|
19
|
+
|
20
|
+
def after_load
|
21
|
+
callbacks << :after_load
|
22
|
+
end
|
23
|
+
|
24
|
+
def after_initialize
|
25
|
+
callbacks << :after_initialize
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class LoadedPluginsTest < Test::Unit::TestCase
|
30
|
+
def setup
|
31
|
+
Rails.plugins = PluginList.new
|
32
|
+
@original_load_path = $LOAD_PATH.clone
|
33
|
+
@config = Rails::Configuration.new
|
34
|
+
@config.plugin_paths = [plugins_path]
|
35
|
+
@initializer = Rails::Initializer.new(@config)
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_should_find_plugin_path_if_plugin_exists
|
39
|
+
assert_equal plugin_path('first_plugin'), @initializer.find_plugin_path('first_plugin')
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_should_not_find_plugin_path_if_plugin_doesnt_exist
|
43
|
+
assert_nil @initializer.find_plugin_path('nonexistent_plugin')
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_should_track_plugin_when_loaded
|
47
|
+
@initializer.load_plugin(plugin_path('first_plugin'))
|
48
|
+
assert_not_nil Rails.plugins[:first_plugin]
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_should_track_multiple_plugins_when_loaded
|
52
|
+
@initializer.load_plugin(plugin_path('first_plugin'))
|
53
|
+
@initializer.load_plugin(plugin_path('plugin_with_only_init'))
|
54
|
+
assert_not_nil Rails.plugins[:first_plugin]
|
55
|
+
assert_not_nil Rails.plugins[:plugin_with_only_init]
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_should_not_track_plugin_if_already_loaded
|
59
|
+
@initializer.load_plugin(plugin_path('first_plugin'))
|
60
|
+
@initializer.load_plugin(plugin_path('first_plugin'))
|
61
|
+
assert_equal 1, Rails.plugins.size
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_should_maintain_order_if_plugin_loaded_from_another_plugin
|
65
|
+
@initializer.load_plugin(plugin_path('a_plugin_with_dependencies'))
|
66
|
+
assert_equal %w(dependent_plugin a_plugin_with_dependencies), Rails.plugins.map(&:name)
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_should_invoke_plugin_callbacks_during_load
|
70
|
+
@initializer.load_plugin(plugin_path('first_plugin'))
|
71
|
+
expected = [
|
72
|
+
:before_load,
|
73
|
+
:after_load
|
74
|
+
]
|
75
|
+
|
76
|
+
assert_equal expected, Rails.plugins[:first_plugin].callbacks
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_should_load_missed_plugins_after_initialize
|
80
|
+
expected = %w(
|
81
|
+
dependent_plugin
|
82
|
+
a_plugin_with_dependencies
|
83
|
+
first_plugin
|
84
|
+
plugin_with_lib_and_init
|
85
|
+
plugin_with_only_init
|
86
|
+
plugin_with_only_lib
|
87
|
+
second_plugins_dependency
|
88
|
+
second_plugin_with_dependencies
|
89
|
+
)
|
90
|
+
|
91
|
+
@initializer.instance_variable_set('@loaded_plugins', expected)
|
92
|
+
@initializer.after_initialize
|
93
|
+
assert_equal expected, Rails.plugins.map(&:name)
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_should_freeze_plugin_list_after_initialize
|
97
|
+
@initializer.load_plugins
|
98
|
+
@initializer.after_initialize
|
99
|
+
|
100
|
+
assert Rails.plugins.frozen?
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_should_invoke_callbacks_after_initialize
|
104
|
+
@initializer.load_plugins
|
105
|
+
@initializer.after_initialize
|
106
|
+
|
107
|
+
expected = [
|
108
|
+
:before_load,
|
109
|
+
:after_load,
|
110
|
+
:after_initialize
|
111
|
+
]
|
112
|
+
assert_equal expected, Rails.plugins[:first_plugin].callbacks
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_should_user_plugin_names_and_paths_when_tracking
|
116
|
+
@initializer.load_plugins
|
117
|
+
|
118
|
+
expected = [
|
119
|
+
['dependent_plugin', plugin_path('dependent_plugin')],
|
120
|
+
['a_plugin_with_dependencies', plugin_path('a_plugin_with_dependencies')],
|
121
|
+
['first_plugin', plugin_path('first_plugin')],
|
122
|
+
['plugin_with_lib_and_init', plugin_path('plugin_with_lib_and_init')],
|
123
|
+
['plugin_with_only_init', plugin_path('plugin_with_only_init')],
|
124
|
+
['plugin_with_only_lib', plugin_path('plugin_with_only_lib')],
|
125
|
+
['second_plugins_dependency', plugin_path('second_plugins_dependency')],
|
126
|
+
['second_plugin_with_dependencies', plugin_path('second_plugin_with_dependencies')]
|
127
|
+
]
|
128
|
+
|
129
|
+
Rails.plugins.each_with_index do |plugin, index|
|
130
|
+
assert_equal expected[index][0], plugin.name
|
131
|
+
assert_equal expected[index][1], plugin.root
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def teardown
|
136
|
+
$LOAD_PATH.replace(@original_load_path)
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/../test_helper"
|
2
|
+
|
3
|
+
class PluginListTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@plugin_list = PluginList.new
|
6
|
+
@plugin_list << (@first_plugin = Plugin.new('/path/to/first_plugin'))
|
7
|
+
@plugin_list << (@second_plugin = Plugin.new('/path/to/second_plugin'))
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_should_index_by_position
|
11
|
+
assert_equal @first_plugin, @plugin_list[0]
|
12
|
+
assert_equal @second_plugin, @plugin_list[1]
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_should_index_by_symbol_name
|
16
|
+
assert_equal @first_plugin, @plugin_list[:first_plugin]
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_should_index_by_string_name
|
20
|
+
assert_equal @first_plugin, @plugin_list['first_plugin']
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_should_return_nil_if_indexed_plugin_name_not_found
|
24
|
+
assert_nil @plugin_list[:invalid_plugin]
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_should_find_all_plugins_if_no_names_specified
|
28
|
+
assert_equal @plugin_list, @plugin_list.find_by_names
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_should_find_plugin_if_single_plugin_specified
|
32
|
+
assert_equal [@first_plugin], @plugin_list.find_by_names('first_plugin')
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_should_find_multiple_plugins_if_multiple_plugins_specified
|
36
|
+
assert_equal [@first_plugin, @second_plugin], @plugin_list.find_by_names('first_plugin,second_plugin')
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_should_not_find_any_plugins_if_empty
|
40
|
+
assert_equal [], PluginList.new.find_by_names
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_should_raise_exception_if_invalid_plugin_searched_for
|
44
|
+
assert_raise(ArgumentError) {@plugin_list.find_by_names('invalid_plugin')}
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_should_raise_exception_if_valid_and_invalid_plugins_searched_for
|
48
|
+
assert_raise(ArgumentError) {@plugin_list.find_by_names('first_plugin,invalid_plugin,second_plugin')}
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_by_precedence_should_reverse_order
|
52
|
+
assert_equal @plugin_list.reverse, @plugin_list.by_precedence
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_by_precedence_should_iterate_if_block_given
|
56
|
+
counter = 0
|
57
|
+
@plugin_list.by_precedence {|plugin| counter += 1 }
|
58
|
+
|
59
|
+
assert_equal @plugin_list.size, counter
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/../test_helper"
|
2
|
+
|
3
|
+
class PluginTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
Rails.plugins = PluginList.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_should_parse_name_without_version
|
9
|
+
assert_equal 'plugin', Plugin.name_for('plugin')
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_should_parse_name_with_major_version
|
13
|
+
assert_equal 'plugin', Plugin.name_for('plugin-1.2')
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_should_parse_name_with_minor_version
|
17
|
+
assert_equal 'plugin', Plugin.name_for('plugin-1.2.0')
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_should_parse_name_with_version_and_os
|
21
|
+
assert_equal 'plugin', Plugin.name_for('plugin-1.2.0-win32')
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_should_use_plugin_path_for_root
|
25
|
+
assert_equal '/path/to/plugin', Plugin.new('/path/to/plugin').root
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_should_truncate_root_with_trailing_slash
|
29
|
+
assert_equal '/path/to/plugin', Plugin.new('/path/to/plugin/').root
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_should_use_base_name_for_name
|
33
|
+
assert_equal 'plugin', Plugin.new('/path/to/plugin').name
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_should_use_parsed_base_name_without_version_for_name
|
37
|
+
assert_equal 'plugin', Plugin.new('/path/to/plugin-1.2.0').name
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_should_use_parsed_base_name_without_version_and_os_for_name
|
41
|
+
assert_equal 'plugin', Plugin.new('/path/to/plugin-1.2.0-win32').name
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_lib_path_should_be_relative_to_root
|
45
|
+
assert_equal '/path/to/plugin/lib', Plugin.new('/path/to/plugin').lib_path
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_lib_path_should_be_false_if_nonexistent
|
49
|
+
assert !Plugin.new('/path/to/plugin').lib_path?
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_lib_path_should_be_true_if_it_exists
|
53
|
+
assert Plugin.new(plugin_path('first_plugin')).lib_path?
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_should_have_no_plugins_before_if_first_plugin
|
57
|
+
Rails.plugins << (plugin = Plugin.new('/path/to/plugin'))
|
58
|
+
assert_equal [], plugin.plugins_before
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_should_have_plugins_before_if_not_first_plugin
|
62
|
+
Rails.plugins << (first_plugin = Plugin.new('/path/to/first_plugin'))
|
63
|
+
Rails.plugins << (second_plugin = Plugin.new('/path/to/second_plugin'))
|
64
|
+
expected = [first_plugin]
|
65
|
+
|
66
|
+
assert_equal expected, second_plugin.plugins_before
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_should_have_plugins_before_if_last_plugin
|
70
|
+
Rails.plugins << (first_plugin = Plugin.new('/path/to/first_plugin'))
|
71
|
+
Rails.plugins << (second_plugin = Plugin.new('/path/to/second_plugin'))
|
72
|
+
Rails.plugins << (third_plugin = Plugin.new('/path/to/third_plugin'))
|
73
|
+
expected = [first_plugin, second_plugin]
|
74
|
+
|
75
|
+
assert_equal expected, third_plugin.plugins_before
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_should_have_plugins_after_if_first_plugin
|
79
|
+
Rails.plugins << (first_plugin = Plugin.new('/path/to/first_plugin'))
|
80
|
+
Rails.plugins << (second_plugin = Plugin.new('/path/to/second_plugin'))
|
81
|
+
Rails.plugins << (third_plugin = Plugin.new('/path/to/third_plugin'))
|
82
|
+
expected = [second_plugin, third_plugin]
|
83
|
+
|
84
|
+
assert_equal expected, first_plugin.plugins_after
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_should_have_plugins_after_if_not_last_plugin
|
88
|
+
Rails.plugins << (first_plugin = Plugin.new('/path/to/first_plugin'))
|
89
|
+
Rails.plugins << (second_plugin = Plugin.new('/path/to/second_plugin'))
|
90
|
+
expected = [second_plugin]
|
91
|
+
|
92
|
+
assert_equal expected, first_plugin.plugins_after
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_should_have_no_plugins_after_if_last_plugin
|
96
|
+
Rails.plugins << (plugin = Plugin.new('/path/to/plugin'))
|
97
|
+
assert_equal [], plugin.plugins_after
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_should_be_equal_if_same_base_name
|
101
|
+
assert Plugin.new('/path/to/plugin') == Plugin.new('/different/path/to/plugin')
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_should_not_be_equal_if_different_base_name
|
105
|
+
assert Plugin.new('/path/to/plugin') != Plugin.new('/different/path/to/different_plugin')
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_should_be_equal_if_compared_with_stringified_version_of_plugin_name
|
109
|
+
assert Plugin.new('/path/to/plugin') == 'plugin'
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_should_not_be_equal_if_compared_with_stringified_version_of_different_plugin_name
|
113
|
+
assert Plugin.new('/path/to/plugin') != 'different_plugin'
|
114
|
+
end
|
115
|
+
end
|
metadata
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: loaded_plugins
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.2
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Aaron Pfeifer, Neil Abraham
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-11-09 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description:
|
15
|
+
email: info@pluginaweek.org
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- lib/loaded_plugins.rb
|
21
|
+
- lib/loaded_plugins/plugin.rb
|
22
|
+
- lib/loaded_plugins/plugin_list.rb
|
23
|
+
- lib/loaded_plugins/extensions/initializer.rb
|
24
|
+
- lib/loaded_plugins/extensions/rails.rb
|
25
|
+
- test/test_helper.rb
|
26
|
+
- test/app_root/vendor/plugins/a_plugin_with_dependencies/init.rb
|
27
|
+
- test/app_root/vendor/plugins/plugin_with_only_lib/lib/empty
|
28
|
+
- test/app_root/vendor/plugins/first_plugin/init.rb
|
29
|
+
- test/app_root/vendor/plugins/first_plugin/lib/first_plugin.rb
|
30
|
+
- test/app_root/vendor/plugins/second_plugins_dependency/init.rb
|
31
|
+
- test/app_root/vendor/plugins/dependent_plugin/init.rb
|
32
|
+
- test/app_root/vendor/plugins/plugin_with_lib_and_init/init.rb
|
33
|
+
- test/app_root/vendor/plugins/plugin_with_lib_and_init/lib/empty
|
34
|
+
- test/app_root/vendor/plugins/subfolder/plugin_with_lib_and_init/init.rb
|
35
|
+
- test/app_root/vendor/plugins/subfolder/plugin_with_lib_and_init/lib/empty
|
36
|
+
- test/app_root/vendor/plugins/second_plugin_with_dependencies/init.rb
|
37
|
+
- test/app_root/vendor/plugins/plugin_with_only_init/init.rb
|
38
|
+
- test/app_root/vendor/plugins/invalid_plugin/empty
|
39
|
+
- test/app_root/config/boot.rb
|
40
|
+
- test/unit/plugin_list_test.rb
|
41
|
+
- test/unit/plugin_test.rb
|
42
|
+
- test/unit/rails_test.rb
|
43
|
+
- test/unit/initializer_test.rb
|
44
|
+
- CHANGELOG
|
45
|
+
- init.rb
|
46
|
+
- MIT-LICENSE
|
47
|
+
- Rakefile
|
48
|
+
- README
|
49
|
+
homepage:
|
50
|
+
licenses: []
|
51
|
+
post_install_message:
|
52
|
+
rdoc_options: []
|
53
|
+
require_paths:
|
54
|
+
- lib
|
55
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ! '>='
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
63
|
+
requirements:
|
64
|
+
- - ! '>='
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
requirements: []
|
68
|
+
rubyforge_project:
|
69
|
+
rubygems_version: 1.7.2
|
70
|
+
signing_key:
|
71
|
+
specification_version: 3
|
72
|
+
summary: Adds Rails.plugins, a list all of the plugins that Rails has loaded
|
73
|
+
test_files: []
|