1
0
mirror of https://github.com/meineerde/redmine.git synced 2026-02-01 03:57:15 +00:00

Extract Redmine::PluginLoader from Redmine::Plugin (#32938).

Patch by Takashi Kato.

git-svn-id: http://svn.redmine.org/redmine/trunk@21283 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
Marius Balteanu 2021-11-17 20:36:53 +00:00
parent 2192d4c22d
commit 838e719edf
3 changed files with 150 additions and 89 deletions

View File

@ -5,6 +5,7 @@ I18n.backend = Redmine::I18n::Backend.new
I18n.config.available_locales = nil
require 'redmine'
require 'redmine/plugin_loader'
# Load the secret token from the Redmine configuration file
secret = Redmine::Configuration['secret_token']
@ -17,15 +18,9 @@ if Object.const_defined?(:OpenIdAuthentication)
OpenIdAuthentication.store = openid_authentication_store.presence || :memory
end
Redmine::Plugin.load
Redmine::PluginLoader.load
plugin_assets_reloader = Redmine::PluginLoader.create_assets_reloader
plugin_assets_dirs = {}
Redmine::Plugin.all.each do |plugin|
plugin_assets_dirs[plugin.assets_directory] = ["*"]
end
plugin_assets_reloader = ActiveSupport::FileUpdateChecker.new([], plugin_assets_dirs) do
Redmine::Plugin.mirror_assets
end
Rails.application.reloaders << plugin_assets_reloader
unless Redmine::Configuration['mirror_plugins_assets_on_startup'] == false
plugin_assets_reloader.execute

View File

@ -52,15 +52,17 @@ module Redmine
class Plugin
# Absolute path to the directory where plugins are located
cattr_accessor :directory
self.directory = File.join(Rails.root, 'plugins')
self.directory = PluginLoader.directory
# Absolute path to the plublic directory where plugins assets are copied
cattr_accessor :public_directory
self.public_directory = File.join(Rails.root, 'public', 'plugin_assets')
self.public_directory = PluginLoader.public_directory
@registered_plugins = {}
@used_partials = {}
attr_accessor :path
class << self
attr_reader :registered_plugins
private :new
@ -102,6 +104,8 @@ module Redmine
raise PluginNotFound, "Plugin not found. The directory for plugin #{p.id} should be #{p.directory}."
end
p.path = PluginLoader.directories{ |d| d.dir == p.directory }
# Adds plugin locales if any
# YAML translation files should be found under <plugin>/config/locales/
Rails.application.config.i18n.load_path += Dir.glob(File.join(p.directory, 'config', 'locales', '*.yml'))
@ -113,15 +117,6 @@ module Redmine
ActionMailer::Base.prepend_view_path(view_path)
end
# Add the plugin directories to rails autoload paths
engine_cfg = Rails::Engine::Configuration.new(p.directory)
engine_cfg.paths.add 'lib', eager_load: true
Rails.application.config.eager_load_paths += engine_cfg.eager_load_paths
Rails.application.config.autoload_once_paths += engine_cfg.autoload_once_paths
Rails.application.config.autoload_paths += engine_cfg.autoload_paths
ActiveSupport::Dependencies.autoload_paths +=
engine_cfg.eager_load_paths + engine_cfg.autoload_once_paths + engine_cfg.autoload_paths
# Defines plugin setting if present
if p.settings
Setting.define_plugin_setting p
@ -174,23 +169,6 @@ module Redmine
registered_plugins[id.to_sym].present?
end
def self.load
Dir.glob(File.join(self.directory, '*')).sort.each do |directory|
if File.directory?(directory)
lib = File.join(directory, "lib")
if File.directory?(lib)
$:.unshift lib
ActiveSupport::Dependencies.autoload_paths += [lib]
end
initializer = File.join(directory, "init.rb")
if File.file?(initializer)
require initializer
end
end
end
Redmine::Hook.call_hook :after_plugins_loaded
end
def initialize(id)
@id = id.to_sym
end
@ -205,7 +183,7 @@ module Redmine
# Returns the absolute path to the plugin assets directory
def assets_directory
File.join(directory, 'assets')
path.assedts_dir
end
def <=>(plugin)
@ -441,58 +419,6 @@ module Redmine
settings && settings.is_a?(Hash) && !settings[:partial].blank?
end
def mirror_assets
source = assets_directory
destination = public_directory
return unless File.directory?(source)
source_files = Dir[source + "/**/*"]
source_dirs = source_files.select {|d| File.directory?(d)}
source_files -= source_dirs
unless source_files.empty?
base_target_dir = File.join(destination, File.dirname(source_files.first).gsub(source, ''))
begin
FileUtils.mkdir_p(base_target_dir)
rescue => e
raise "Could not create directory #{base_target_dir}: " + e.message
end
end
source_dirs.each do |dir|
# strip down these paths so we have simple, relative paths we can
# add to the destination
target_dir = File.join(destination, dir.gsub(source, ''))
begin
FileUtils.mkdir_p(target_dir)
rescue => e
raise "Could not create directory #{target_dir}: " + e.message
end
end
source_files.each do |file|
begin
target = File.join(destination, file.gsub(source, ''))
unless File.exist?(target) && FileUtils.identical?(file, target)
FileUtils.cp(file, target)
end
rescue => e
raise "Could not copy #{file} to #{target}: " + e.message
end
end
end
# Mirrors assets from one or all plugins to public/plugin_assets
def self.mirror_assets(name=nil)
if name.present?
find(name).mirror_assets
else
all.each do |plugin|
plugin.mirror_assets
end
end
end
# The directory containing this plugin's migrations (<tt>plugin/db/migrate</tt>)
def migration_directory
File.join(directory, 'db', 'migrate')

View File

@ -0,0 +1,140 @@
# frozen_string_literal: true
# Redmine - project management software
# Copyright (C) 2006-2021 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
module Redmine
class PluginPath
attr_reader :assets_dir, :initializer
def initialize(dir)
@dir = dir
@assets_dir = File.join dir, 'assets'
@initializer = File.join dir, 'init.rb'
end
def run_initializer
load initializer if has_initializer?
end
def to_s
@dir
end
def mirror_assets
return unless has_assets_dir?
source_files = Dir["#{assets_dir}/**/*"]
source_dirs = source_files.select { |d| File.directory?(d)}
source_files -= source_dirs
unless source_files.empty?
base_target_dir = File.join(PluginLoader.public_directory, File.dirname(source_files.first).gsub(assets_dir, ''))
begin
FileUtils.mkdir_p(base_target_dir)
rescue => e
raise "Could not create directory #{base_target_dir}: " + e.message
end
end
source_dirs.each do |dir|
# strip down these paths so we have simple, relative paths we can
# add to the destination
target_dir = File.join(PluginLoader.public_directory, dir.gsub(assets_dir, ''))
begin
FileUtils.mkdir_p(target_dir)
rescue => e
raise "Could not create directory #{target_dir}: " + e.message
end
end
source_files.each do |file|
target = File.join(PluginLoader.public_directory, file.gsub(assets_dir, ''))
unless File.exist?(target) && FileUtils.identical?(file, target)
FileUtils.cp(file, target)
end
rescue => e
raise "Could not copy #{file} to #{target}: " + e.message
end
end
def has_assets_dir?
File.directory?(@assets_dir)
end
def has_initializer?
File.file?(@initializer)
end
end
class PluginLoader
# Absolute path to the directory where plugins are located
cattr_accessor :directory
self.directory = Rails.root.join('plugins')
# Absolute path to the plublic directory where plugins assets are copied
cattr_accessor :public_directory
self.public_directory = Rails.root.join('public/plugin_assets')
def self.create_assets_reloader
plugin_assets_dirs = {}
@plugin_directories.each do |dir|
plugin_assets_dirs[dir.assets_dir] = ['*']
end
ActiveSupport::FileUpdateChecker.new([], plugin_assets_dirs) do
mirror_assets
end
end
def self.load
setup
add_autoload_paths
Rails.application.config.to_prepare do
PluginLoader.directories.each(&:run_initializer)
Redmine::Hook.call_hook :after_plugins_loaded
end
end
def self.setup
@plugin_directories = []
Dir.glob(File.join(directory, '*')).sort.each do |directory|
next unless File.directory?(directory)
@plugin_directories << PluginPath.new(directory)
end
end
def self.add_autoload_paths
directories.each do |directory|
# Add the plugin directories to rails autoload paths
engine_cfg = Rails::Engine::Configuration.new(directory.to_s)
engine_cfg.paths.add 'lib', eager_load: true
Rails.application.config.eager_load_paths += engine_cfg.eager_load_paths
Rails.application.config.autoload_once_paths += engine_cfg.autoload_once_paths
Rails.application.config.autoload_paths += engine_cfg.autoload_paths
end
end
def self.directories
@plugin_directories
end
def self.mirror_assets
directories.each(&:mirror_assets)
end
end
end