Patch #44016 » 0001-Enable-instantiation-of-PluginLoader.patch
| lib/redmine/plugin.rb | ||
|---|---|---|
| 49 | 49 |
# |
| 50 | 50 |
# See: http://www.redmine.org/projects/redmine/wiki/Plugin_Tutorial |
| 51 | 51 |
class Plugin |
| 52 |
cattr_accessor :loader |
|
| 53 | ||
| 52 | 54 |
# Absolute path to the directory where plugins are located |
| 53 |
cattr_accessor :directory |
|
| 54 |
self.directory = PluginLoader.directory |
|
| 55 |
def self.directory |
|
| 56 |
loader.directory |
|
| 57 |
end |
|
| 55 | 58 | |
| 56 | 59 |
# Absolute path to the public directory where plugins assets are copied |
| 57 |
cattr_accessor :public_directory |
|
| 58 |
self.public_directory = PluginLoader.public_directory |
|
| 60 |
def self.public_directory |
|
| 61 |
loader.public_directory |
|
| 62 |
end |
|
| 59 | 63 | |
| 60 | 64 |
@registered_plugins = {}
|
| 61 | 65 |
@used_partials = {}
|
| ... | ... | |
| 103 | 107 |
raise PluginNotFound, "Plugin not found. The directory for plugin #{p.id} should be #{p.directory}."
|
| 104 | 108 |
end |
| 105 | 109 | |
| 106 |
p.path = PluginLoader.directories.find {|d| d.to_s == p.directory}
|
|
| 110 |
p.path = loader.directories.find {|d| d.to_s == p.directory}
|
|
| 107 | 111 | |
| 108 | 112 |
# Adds plugin locales if any |
| 109 | 113 |
# YAML translation files should be found under <plugin>/config/locales/ |
| ... | ... | |
| 192 | 196 |
def asset_paths |
| 193 | 197 |
return unless path.has_assets_dir? |
| 194 | 198 | |
| 195 |
base_dir = Pathname.new(path.assets_dir) |
|
| 196 |
paths = base_dir.children.select(&:directory?) |
|
| 197 |
Redmine::AssetPath.new(base_dir, paths, asset_prefix) |
|
| 199 |
Redmine::AssetPath.new(path.base_dir, path.asset_paths, asset_prefix) |
|
| 198 | 200 |
end |
| 199 | 201 | |
| 200 | 202 |
def <=>(plugin) |
| lib/redmine/plugin_loader.rb | ||
|---|---|---|
| 19 | 19 | |
| 20 | 20 |
module Redmine |
| 21 | 21 |
class PluginPath |
| 22 |
attr_reader :assets_dir, :initializer |
|
| 22 |
attr_reader :assets_dir, :initializer, :prefix
|
|
| 23 | 23 | |
| 24 |
def initialize(dir) |
|
| 24 |
def initialize(dir, prefix)
|
|
| 25 | 25 |
@dir = dir |
| 26 |
@assets_dir = File.join dir, 'assets' |
|
| 27 |
@initializer = File.join dir, 'init.rb' |
|
| 26 |
@prefix = prefix |
|
| 27 |
@assets_dir = File.join @dir, 'assets' |
|
| 28 |
@initializer = File.join @dir, 'init.rb' |
|
| 28 | 29 |
end |
| 29 | 30 | |
| 30 | 31 |
def run_initializer |
| ... | ... | |
| 42 | 43 |
def has_initializer? |
| 43 | 44 |
File.file?(@initializer) |
| 44 | 45 |
end |
| 46 | ||
| 47 |
def base_dir |
|
| 48 |
@base_dir ||= Pathname.new(assets_dir) |
|
| 49 |
end |
|
| 50 | ||
| 51 |
def asset_paths |
|
| 52 |
paths = base_dir.children.select(&:directory?) |
|
| 53 |
paths |
|
| 54 |
end |
|
| 45 | 55 |
end |
| 46 | 56 | |
| 47 | 57 |
class PluginLoader |
| 48 | 58 |
# Absolute path to the directory where plugins are located |
| 49 |
cattr_accessor :directory |
|
| 50 |
self.directory = Rails.root.join Rails.application.config.redmine_plugins_directory |
|
| 59 |
attr_accessor :directory |
|
| 60 | ||
| 61 |
attr_accessor :prefix |
|
| 51 | 62 | |
| 52 | 63 |
# Absolute path to the public directory where plugins assets are copied |
| 53 |
cattr_accessor :public_directory |
|
| 54 |
self.public_directory = Rails.public_path.join('plugin_assets')
|
|
| 64 |
attr_accessor :public_directory |
|
| 55 | 65 | |
| 56 |
def self.load |
|
| 57 |
setup |
|
| 58 |
add_autoload_paths |
|
| 66 |
def initialize(directory:, prefix:) |
|
| 67 |
@directory = directory |
|
| 68 |
@prefix = prefix |
|
| 69 |
@plugin_directories = [] |
|
| 59 | 70 | |
| 60 |
Rails.application.config.to_prepare do
|
|
| 61 |
PluginLoader.directories.each(&:run_initializer)
|
|
| 71 |
Dir.glob(File.join(directory, '*')).each do |directory|
|
|
| 72 |
next unless File.directory?(directory)
|
|
| 62 | 73 | |
| 63 |
Redmine::Hook.call_hook :after_plugins_loaded
|
|
| 74 |
@plugin_directories << PluginPath.new(directory, prefix)
|
|
| 64 | 75 |
end |
| 65 | 76 |
end |
| 66 | 77 | |
| 67 |
def self.setup |
|
| 68 |
@plugin_directories = [] |
|
| 78 |
def self.load |
|
| 79 |
directory = Rails.root.join(Rails.application.config.redmine_plugins_directory) |
|
| 80 |
prefix = 'plugin_assets' |
|
| 81 |
loader = new(directory: directory, prefix: prefix) |
|
| 69 | 82 | |
| 70 |
Dir.glob(File.join(directory, '*')).each do |directory| |
|
| 71 |
next unless File.directory?(directory) |
|
| 83 |
loader.public_directory = Rails.public_path.join(prefix) |
|
| 84 |
loader.add_autoload_paths |
|
| 85 | ||
| 86 |
Rails.application.config.to_prepare do |
|
| 87 |
Redmine::Plugin.loader = loader |
|
| 88 |
loader.directories.each(&:run_initializer) |
|
| 72 | 89 | |
| 73 |
@plugin_directories << PluginPath.new(directory)
|
|
| 90 |
Redmine::Hook.call_hook :after_plugins_loaded
|
|
| 74 | 91 |
end |
| 75 | 92 |
end |
| 76 | 93 | |
| 77 |
def self.add_autoload_paths
|
|
| 94 |
def add_autoload_paths |
|
| 78 | 95 |
directories.each do |directory| |
| 79 | 96 |
# Add the plugin directories to rails autoload paths |
| 80 | 97 |
engine_cfg = Rails::Engine::Configuration.new(directory.to_s) |
| ... | ... | |
| 86 | 103 |
end |
| 87 | 104 |
end |
| 88 | 105 | |
| 89 |
def self.directories
|
|
| 106 |
def directories |
|
| 90 | 107 |
@plugin_directories |
| 91 | 108 |
end |
| 92 | 109 |
end |
| test/fixtures/plugins/foo_plugin/app/javascript/foo.js | ||
|---|---|---|
| 1 |
export sample() {
|
|
| 2 |
} |
|
| test/fixtures/plugins/foo_plugin/init.rb | ||
|---|---|---|
| 1 |
Redmine::Plugin.register :foo_plugin do |
|
| 2 |
name 'Test plugin redmine_test_plugin_foo' |
|
| 3 |
author 'Author name' |
|
| 4 |
description 'This is a plugin for Redmine test' |
|
| 5 |
version '0.0.1' |
|
| 6 |
end |
|
| 7 | ||
| 8 | ||
| test/generators/controller_generator_test.rb | ||
|---|---|---|
| 29 | 29 | |
| 30 | 30 |
setup do |
| 31 | 31 |
@plugin_directory = Redmine::Plugin.directory |
| 32 |
Redmine::Plugin.directory = TMP_DIR |
|
| 32 |
Redmine::Plugin.loader.directory = TMP_DIR
|
|
| 33 | 33 |
end |
| 34 | 34 | |
| 35 | 35 |
teardown do |
| 36 |
Redmine::Plugin.directory = @plugin_directory |
|
| 36 |
Redmine::Plugin.loader.directory = @plugin_directory
|
|
| 37 | 37 |
end |
| 38 | 38 | |
| 39 | 39 |
def test_generates_files_from_templates |
| test/generators/migration_generator_test.rb | ||
|---|---|---|
| 29 | 29 | |
| 30 | 30 |
setup do |
| 31 | 31 |
@plugin_directory = Redmine::Plugin.directory |
| 32 |
Redmine::Plugin.directory = TMP_DIR |
|
| 32 |
Redmine::Plugin.loader.directory = TMP_DIR
|
|
| 33 | 33 |
end |
| 34 | 34 | |
| 35 | 35 |
teardown do |
| 36 |
Redmine::Plugin.directory = @plugin_directory |
|
| 36 |
Redmine::Plugin.loader.directory = @plugin_directory
|
|
| 37 | 37 |
end |
| 38 | 38 | |
| 39 | 39 |
def test_migration_file_name_is_snake_case |
| test/generators/model_generator_test.rb | ||
|---|---|---|
| 29 | 29 | |
| 30 | 30 |
setup do |
| 31 | 31 |
@plugin_directory = Redmine::Plugin.directory |
| 32 |
Redmine::Plugin.directory = TMP_DIR |
|
| 32 |
Redmine::Plugin.loader.directory = TMP_DIR
|
|
| 33 | 33 |
end |
| 34 | 34 | |
| 35 | 35 |
teardown do |
| 36 |
Redmine::Plugin.directory = @plugin_directory |
|
| 36 |
Redmine::Plugin.loader.directory = @plugin_directory
|
|
| 37 | 37 |
end |
| 38 | 38 | |
| 39 | 39 |
def test_generates_files_from_templates |
| test/integration/routing/plugins_test.rb | ||
|---|---|---|
| 21 | 21 | |
| 22 | 22 |
class RoutingPluginsTest < Redmine::RoutingTest |
| 23 | 23 |
def setup |
| 24 |
@original_plugin_dir = Redmine::PluginLoader.directory
|
|
| 24 |
@original_loader = Redmine::Plugin.loader
|
|
| 25 | 25 | |
| 26 | 26 |
Redmine::Plugin.clear |
| 27 |
Redmine::PluginLoader.directory = Rails.root.join('test/fixtures/plugins')
|
|
| 28 |
Redmine::Plugin.directory = Rails.root.join('test/fixtures/plugins')
|
|
| 29 |
Redmine::PluginLoader.load |
|
| 30 |
Redmine::PluginLoader.directories.each(&:run_initializer) # to define relative controllers |
|
| 27 |
loader = Redmine::PluginLoader.new(directory: Rails.root.join('test/fixtures/plugins'), prefix: @original_loader.prefix)
|
|
| 28 |
loader.public_directory = Rails.public_path.join(@original_loader.prefix) |
|
| 29 |
loader.add_autoload_paths |
|
| 30 |
Redmine::Plugin.loader = loader |
|
| 31 | ||
| 32 |
loader.directories.each(&:run_initializer) # to define relative controllers |
|
| 31 | 33 |
RedmineApp::Application.instance.routes_reloader.reload! |
| 32 | 34 |
end |
| 33 | 35 | |
| 34 | 36 |
def teardown |
| 35 | 37 |
Redmine::Plugin.clear |
| 36 |
Redmine::PluginLoader.directory = @original_plugin_dir |
|
| 37 |
Redmine::Plugin.directory = @original_plugin_dir |
|
| 38 |
Redmine::Plugin.loader = @original_loader |
|
| 38 | 39 |
Redmine::PluginLoader.load |
| 39 | 40 |
RedmineApp::Application.instance.routes_reloader.reload! |
| 40 | 41 |
end |
| test/unit/lib/redmine/plugin_test.rb | ||
|---|---|---|
| 22 | 22 |
class Redmine::PluginTest < ActiveSupport::TestCase |
| 23 | 23 |
def setup |
| 24 | 24 |
@klass = Redmine::Plugin |
| 25 |
@original_loader = Redmine::Plugin.loader |
|
| 26 | ||
| 25 | 27 |
# Change plugin directory for testing to default |
| 26 | 28 |
# plugins/foo => test/fixtures/plugins/foo |
| 27 |
@klass.directory = Rails.root.join('test/fixtures/plugins')
|
|
| 29 |
loader = Redmine::PluginLoader.new(directory: Rails.root.join('test/fixtures/plugins'), prefix: @original_loader.prefix)
|
|
| 30 |
@klass.loader = loader |
|
| 28 | 31 |
# In case some real plugins are installed |
| 29 | 32 |
@klass.clear |
| 30 | ||
| 31 |
# Change plugin loader's directory for testing |
|
| 32 |
Redmine::PluginLoader.directory = @klass.directory |
|
| 33 |
Redmine::PluginLoader.setup |
|
| 34 | 33 |
end |
| 35 | 34 | |
| 36 | 35 |
def teardown |
| 37 | 36 |
@klass.clear |
| 37 |
Redmine::Plugin.loader = @original_loader |
|
| 38 | 38 |
end |
| 39 | 39 | |
| 40 | 40 |
def test_register |