plugin.rb 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. require 'rails/engine'
  2. require 'active_support/core_ext/array/conversions'
  3. module Rails
  4. # Rails::Plugin is nothing more than a Rails::Engine, but since it's loaded too late
  5. # in the boot process, it does not have the same configuration powers as a bare
  6. # Rails::Engine.
  7. #
  8. # Opposite to Rails::Railtie and Rails::Engine, you are not supposed to inherit from
  9. # Rails::Plugin. Rails::Plugin is automatically configured to be an engine by simply
  10. # placing inside vendor/plugins. Since this is done automatically, you actually cannot
  11. # declare a Rails::Engine inside your Plugin, otherwise it would cause the same files
  12. # to be loaded twice. This means that if you want to ship an Engine as gem it cannot
  13. # be used as plugin and vice-versa.
  14. #
  15. # Besides this conceptual difference, the only difference between Rails::Engine and
  16. # Rails::Plugin is that plugins automatically load the file "init.rb" at the plugin
  17. # root during the boot process.
  18. #
  19. class Plugin < Engine
  20. def self.global_plugins
  21. @global_plugins ||= []
  22. end
  23. def self.inherited(base)
  24. raise "You cannot inherit from Rails::Plugin"
  25. end
  26. def self.all(list, paths)
  27. plugins = []
  28. paths.each do |path|
  29. Dir["#{path}/*"].each do |plugin_path|
  30. plugin = new(plugin_path)
  31. next unless list.include?(plugin.name) || list.include?(:all)
  32. if global_plugins.include?(plugin.name)
  33. warn "WARNING: plugin #{plugin.name} from #{path} was not loaded. Plugin with the same name has been already loaded."
  34. next
  35. end
  36. global_plugins << plugin.name
  37. plugins << plugin
  38. end
  39. end
  40. plugins.sort_by do |p|
  41. [list.index(p.name) || list.index(:all), p.name.to_s]
  42. end
  43. end
  44. attr_reader :name, :path
  45. def railtie_name
  46. name.to_s
  47. end
  48. def initialize(root)
  49. ActiveSupport::Deprecation.warn "You have Rails 2.3-style plugins in vendor/plugins! Support for these plugins will be removed in Rails 4.0. Move them out and bundle them in your Gemfile, or fold them in to your app as lib/myplugin/* and config/initializers/myplugin.rb. See the release notes for more on this: http://weblog.rubyonrails.org/2012/1/4/rails-3-2-0-rc2-has-been-released"
  50. @name = File.basename(root).to_sym
  51. config.root = root
  52. end
  53. def config
  54. @config ||= Engine::Configuration.new
  55. end
  56. initializer :handle_lib_autoload, :before => :set_load_path do |app|
  57. autoload = if app.config.reload_plugins
  58. config.autoload_paths
  59. else
  60. config.autoload_once_paths
  61. end
  62. autoload.concat paths["lib"].existent
  63. end
  64. initializer :load_init_rb, :before => :load_config_initializers do |app|
  65. init_rb = File.expand_path("init.rb", root)
  66. if File.file?(init_rb)
  67. # This double assignment is to prevent an "unused variable" warning on Ruby 1.9.3.
  68. config = config = app.config
  69. # TODO: think about evaling initrb in context of Engine (currently it's
  70. # always evaled in context of Rails::Application)
  71. eval(File.read(init_rb), binding, init_rb)
  72. end
  73. end
  74. initializer :sanity_check_railties_collision do
  75. if Engine.subclasses.map { |k| k.root.to_s }.include?(root.to_s)
  76. raise "\"#{name}\" is a Railtie/Engine and cannot be installed as a plugin"
  77. end
  78. end
  79. end
  80. end