redmine_plugins_helper 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 474a2a3d3fd82a0eeedd525edad8db6adaf84f1fda9785e910ffbe06046d8f47
4
+ data.tar.gz: 309ff8226411dadced5b3639b0bff781c8d41ed307f2451ee865317ddc2d2e08
5
+ SHA512:
6
+ metadata.gz: c1714ab95b6af124afe772dbb1e196323a655ef907cd83865ceb6088915a91176f0e739ad9e172909d4141b412ef4fb129e37219cb8278f2e0c2860303488ede
7
+ data.tar.gz: 582161dbc0800d84c89a5ea5faa6a0f2620843123239337083878e44e92db8ad1fd406f2502cd08d51f96a37955ea62fbb98c22081b81f32f0ba599238aa19c4
@@ -0,0 +1,5 @@
1
+ <% Redmine::Plugin.registered_plugins.values.each do |plugin| %>
2
+ <% if plugin.main_javascript_asset_path %>
3
+ <% require_asset plugin.main_javascript_asset_path %>
4
+ <% end %>
5
+ <% end %>
@@ -0,0 +1,5 @@
1
+ <% Redmine::Plugin.registered_plugins.values.each do |plugin| %>
2
+ <% if plugin.main_stylesheet_asset_path %>
3
+ @import "<%= plugin.main_stylesheet_asset_path %>";
4
+ <% end %>
5
+ <% end %>
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'redmine_plugins_helper/hooks/add_assets'
4
+ Rails.application.config.assets.precompile += %w[plugins_autoload.css plugins_autoload.js]
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_record/connection_adapters/postgresql/schema_statements'
4
+
5
+ #
6
+ # Monkey-patch the refused Rails 4.2 patch at https://github.com/rails/rails/pull/31330
7
+ #
8
+ # Updates sequence logic to support PostgreSQL 10.
9
+ #
10
+
11
+ module ActiveRecord
12
+ module ConnectionAdapters
13
+ module PostgreSQL
14
+ module SchemaStatements
15
+ # Resets the sequence of a table's primary key to the maximum value.
16
+ def reset_pk_sequence!(table, pkey = nil, sequence = nil) #:nodoc:
17
+ unless pkey && sequence
18
+ default_pk, default_sequence = pk_and_sequence_for(table)
19
+ pkey ||= default_pk
20
+ sequence ||= default_sequence
21
+ end
22
+ reset_pk_sequence_log(sequence, table, pkey)
23
+ return unless pkey && sequence
24
+
25
+ reset_pk_sequence_select_value(sequence, table, pkey)
26
+ end
27
+
28
+ private
29
+
30
+ def reset_pk_sequence_max_pk(table, pkey)
31
+ select_value("SELECT MAX(#{quote_column_name pkey}) FROM #{quote_table_name(table)}")
32
+ end
33
+
34
+ def reset_pk_sequence_minvalue(max_pk, quoted_sequence)
35
+ return nil unless max_pk.nil?
36
+
37
+ if postgresql_version >= 100_000
38
+ select_value('SELECT seqmin FROM pg_sequence WHERE seqrelid = ' \
39
+ "#{quote(quoted_sequence)}::regclass")
40
+ else
41
+ select_value("SELECT min_value FROM #{quoted_sequence}")
42
+ end
43
+ end
44
+
45
+ def reset_pk_sequence_log(sequence, table, pkey)
46
+ return unless @logger && pkey && !sequence
47
+
48
+ @logger.warn "#{table} has primary key #{pkey} with no default sequence"
49
+ end
50
+
51
+ def reset_pk_sequence_select_value(sequence, table, pkey)
52
+ quoted_sequence = quote_table_name(sequence)
53
+ max_pk = reset_pk_sequence_max_pk(table, pkey)
54
+ minvalue = reset_pk_sequence_minvalue(max_pk, quoted_sequence)
55
+ select_value <<-END_SQL, 'SCHEMA'
56
+ SELECT setval(#{quote(quoted_sequence)}, #{max_pk || minvalue}, #{max_pk ? true : false})
57
+ END_SQL
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
data/init.rb ADDED
@@ -0,0 +1,18 @@
1
+ # coding: utf-8
2
+
3
+ require 'redmine'
4
+ require 'redmine_plugins_helper/version'
5
+ require 'redmine_plugins_helper/patches/test_case_patch'
6
+
7
+ Redmine::Plugin.register :redmine_plugins_helper do
8
+ name 'Redmine Plugins\' Helper'
9
+ author ::RedminePluginsHelper::AUTHOR
10
+ description ::RedminePluginsHelper::SUMMARY
11
+ version ::RedminePluginsHelper::VERSION
12
+ end
13
+
14
+ Rails.configuration.to_prepare do
15
+ require_dependency 'redmine_plugins_helper/patches/redmine/plugin_patch'
16
+ ::Redmine::Plugin.registered_plugins.values.each(&:add_assets_paths)
17
+ ::Redmine::Plugin.registered_plugins.values.each(&:load_initializers)
18
+ end
@@ -0,0 +1,100 @@
1
+ module RedminePluginsHelper
2
+ class FixMigrations
3
+ def initialize
4
+ run
5
+ end
6
+
7
+ private
8
+
9
+ def run
10
+ database_plugins_versions.each do |dbv|
11
+ check_database_version(dbv)
12
+ end
13
+ Rails.logger.info("Database versions checked: #{database_plugins_versions.count}")
14
+ Rails.logger.info("Local versions found: #{local_versions.count}")
15
+ end
16
+
17
+ def check_database_version(dbv)
18
+ lv = local_version(dbv[:timestamp])
19
+ return unless lv && lv.count == 1 && dbv[:plugin] != lv.first[:plugin]
20
+ fix_plugin_version(dbv, lv.first[:plugin])
21
+ end
22
+
23
+ def fix_plugin_version(dbv, target_plugin)
24
+ target_version = plugin_version(target_plugin, dbv[:timestamp])
25
+ if database_version?(target_version)
26
+ remove_plugin_version(dbv[:version])
27
+ else
28
+ move_plugin_version(dbv[:version], target_version)
29
+ end
30
+ end
31
+
32
+ def database_version?(version)
33
+ r = ::ActiveRecord::Base.connection.execute(<<EOS.strip_heredoc)
34
+ select exists(
35
+ select 1
36
+ from #{ActiveRecord::Migrator.schema_migrations_table_name}
37
+ where version=#{ActiveRecord::Base.sanitize(version)}
38
+ )
39
+ EOS
40
+ r.getvalue(0, 0) == 't'
41
+ end
42
+
43
+ def remove_plugin_version(source_version)
44
+ Rails.logger.info("Removing #{source_version}")
45
+ ::ActiveRecord::Base.connection.execute(<<EOS.strip_heredoc)
46
+ delete from #{ActiveRecord::Migrator.schema_migrations_table_name}
47
+ where version=#{ActiveRecord::Base.sanitize(source_version)}
48
+ EOS
49
+ end
50
+
51
+ def move_plugin_version(source_version, target_version)
52
+ Rails.logger.info("Moving #{source_version} to plugin \"#{target_version}\"")
53
+ ::ActiveRecord::Base.connection.execute(<<EOS.strip_heredoc)
54
+ update #{ActiveRecord::Migrator.schema_migrations_table_name}
55
+ set version=#{ActiveRecord::Base.sanitize(target_version)}
56
+ where version=#{ActiveRecord::Base.sanitize(source_version)}
57
+ EOS
58
+ end
59
+
60
+ def local_version(timestamp)
61
+ return [] unless local_versions.key?(timestamp)
62
+ local_versions[timestamp]
63
+ end
64
+
65
+ def local_versions
66
+ @local_versions = begin
67
+ r = {}
68
+ Redmine::Plugin.registered_plugins.values.each do |p|
69
+ p.migrations.each do |m|
70
+ r[m] ||= []
71
+ r[m] << { plugin: p.id, timestamp: m, version: plugin_version(p.id, m) }
72
+ end
73
+ end
74
+ r
75
+ end
76
+ end
77
+
78
+ def database_plugins_versions
79
+ @database_plugins_versions = begin
80
+ r = []
81
+ ::RedminePluginsHelper::Migrations.db_all_versions.each do |v|
82
+ pv = parse_plugin_version(v)
83
+ next unless pv
84
+ r << pv
85
+ end
86
+ r
87
+ end
88
+ end
89
+
90
+ def parse_plugin_version(v)
91
+ h = ::RedminePluginsHelper::Migrations.parse_plugin_version(v)
92
+ h[:version] = v if h.is_a?(Hash)
93
+ h
94
+ end
95
+
96
+ def plugin_version(plugin_id, timestamp)
97
+ "#{timestamp}-#{plugin_id}"
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RedminePluginsHelper
4
+ module Hooks
5
+ class AddAssets < Redmine::Hook::ViewListener
6
+ def view_layouts_base_html_head(_context = {})
7
+ safe_join([plugins_autoload_stylesheet_tag, plugins_autoload_script_tag])
8
+ end
9
+
10
+ private
11
+
12
+ def plugins_autoload_stylesheet_tag
13
+ tag('link', media: 'all', rel: 'stylesheet',
14
+ href: asset_path('assets/plugins_autoload.css'))
15
+ end
16
+
17
+ def plugins_autoload_script_tag
18
+ content_tag('script', "\n", src: asset_path('assets/plugins_autoload.js'))
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,41 @@
1
+ module RedminePluginsHelper
2
+ class Migrate
3
+ def initialize
4
+ run
5
+ end
6
+
7
+ private
8
+
9
+ def run
10
+ versions_sorted.each do |v|
11
+ migrate_plugin_version(v)
12
+ end
13
+ end
14
+
15
+ def migrate_plugin_version(v)
16
+ return if migrated?(v)
17
+ ::Redmine::Plugin.registered_plugins[v[:plugin]].migrate(v[:timestamp])
18
+ end
19
+
20
+ def versions_sorted
21
+ versions.sort_by { |e| [e[:timestamp]] }
22
+ end
23
+
24
+ def versions
25
+ r = []
26
+ ::RedminePluginsHelper::Migrations.local_versions.each do |plugin, ts|
27
+ ts.each { |t| r << { plugin: plugin, timestamp: t } }
28
+ end
29
+ r
30
+ end
31
+
32
+ def migrated?(v)
33
+ return false unless db_versions.key?(v[:plugin])
34
+ db_versions[v[:plugin]].include?(v[:timestamp])
35
+ end
36
+
37
+ def db_versions
38
+ @db_versions ||= ::RedminePluginsHelper::Migrations.db_versions
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,38 @@
1
+ module RedminePluginsHelper
2
+ class Migrations
3
+ class << self
4
+ def local_versions
5
+ r = {}
6
+ Redmine::Plugin.registered_plugins.values.each do |p|
7
+ p.migrations.each do |ts|
8
+ r[p.id] ||= []
9
+ r[p.id] << ts
10
+ end
11
+ end
12
+ r
13
+ end
14
+
15
+ def db_versions
16
+ r = {}
17
+ db_all_versions.each do |v|
18
+ pv = parse_plugin_version(v)
19
+ next unless pv
20
+ r[pv[:plugin]] ||= []
21
+ r[pv[:plugin]] << pv[:timestamp]
22
+ end
23
+ r
24
+ end
25
+
26
+ def db_all_versions
27
+ ::ActiveRecord::SchemaMigration.create_table
28
+ ::ActiveRecord::SchemaMigration.all.pluck(:version)
29
+ end
30
+
31
+ def parse_plugin_version(v)
32
+ m = v.match(/^(\d+)\-(\S+)$/)
33
+ return nil unless m
34
+ { plugin: m[2].to_sym, timestamp: m[1].to_i }
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,76 @@
1
+ module RedminePluginsHelper
2
+ module Patches
3
+ module Redmine
4
+ module PluginPatch
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ extend ClassMethods
9
+ include InstanceMethods
10
+ end
11
+
12
+ ASSETS_SUBDIRS = %w[stylesheets javascripts images].freeze
13
+
14
+ module ClassMethods
15
+ def post_register(plugin_name, &block)
16
+ plugin = registered_plugins[plugin_name]
17
+ raise "Plugin not registered: #{plugin_name}" unless plugin
18
+
19
+ plugin.instance_eval(&block)
20
+ end
21
+ end
22
+
23
+ module InstanceMethods
24
+ def load_initializers
25
+ Dir["#{initializers_directory}/*.rb"].each { |f| require f }
26
+ end
27
+
28
+ ASSETS_SUBDIRS.each do |assert_subdir|
29
+ class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
30
+ def #{assert_subdir}_directory
31
+ ::File.join(directory, 'app', 'assets', '#{assert_subdir}')
32
+ end
33
+ RUBY_EVAL
34
+ end
35
+
36
+ def add_assets_paths
37
+ ASSETS_SUBDIRS.each do |assert_subdir|
38
+ assets_directory = send("#{assert_subdir}_directory")
39
+ next unless ::File.directory?(assets_directory)
40
+
41
+ Rails.application.config.assets.paths << assets_directory
42
+ end
43
+ end
44
+
45
+ def main_javascript_asset_path
46
+ find_asset(javascripts_directory, %w[js coffee js.coffee])
47
+ end
48
+
49
+ def main_stylesheet_asset_path
50
+ find_asset(stylesheets_directory, %w[css scss])
51
+ end
52
+
53
+ private
54
+
55
+ def initializers_directory
56
+ File.join(directory, 'config', 'initializers')
57
+ end
58
+
59
+ def find_asset(assets_directory, extensions)
60
+ extensions.each do |extension|
61
+ ['', '.erb'].each do |erb_extension|
62
+ path = ::File.join(assets_directory, "#{id}.#{extension}#{erb_extension}")
63
+ return id if ::File.exist?(path)
64
+ end
65
+ end
66
+ nil
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ patch = ::RedminePluginsHelper::Patches::Redmine::PluginPatch
75
+ target = ::Redmine::Plugin
76
+ target.send(:include, patch) unless target.include?(patch)
@@ -0,0 +1,30 @@
1
+ require 'active_support'
2
+
3
+ module RedminePluginsHelper
4
+ module Patches
5
+ module TestCasePatch
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ extend ClassMethods
10
+ end
11
+
12
+ module ClassMethods
13
+ def plugin_fixtures(plugin_name, *files)
14
+ fixtures_dir = File.expand_path(
15
+ 'test/fixtures',
16
+ ::Redmine::Plugin.registered_plugins[plugin_name].directory
17
+ )
18
+ ActiveRecord::FixtureSet.create_fixtures(fixtures_dir, files)
19
+ fixtures(*files)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ unless ActiveSupport::TestCase.included_modules.include?(
27
+ RedminePluginsHelper::Patches::TestCasePatch
28
+ )
29
+ ActiveSupport::TestCase.send(:include, RedminePluginsHelper::Patches::TestCasePatch)
30
+ end
@@ -0,0 +1,25 @@
1
+ require_dependency 'redmine_plugins_helper'
2
+
3
+ module RedminePluginsHelper
4
+ class Settings
5
+ class << self
6
+ def default(plugin, default)
7
+ return unless ::RedminePluginsHelper.settings_table_exist?
8
+ p = plugin_current_setting_value(plugin)
9
+ default.each do |k, v|
10
+ p[k.to_s] = v unless p.key?(k)
11
+ end
12
+ ::Setting.send("plugin_#{plugin}=", p)
13
+ end
14
+
15
+ private
16
+
17
+ def plugin_current_setting_value(plugin)
18
+ p = ::Setting.send("plugin_#{plugin}")
19
+ p = {} unless p.is_a?(::Hash)
20
+ p = p.with_indifferent_access
21
+ p
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,31 @@
1
+ module RedminePluginsHelper
2
+ class StatusMigrations
3
+ def initialize
4
+ run
5
+ end
6
+
7
+ private
8
+
9
+ def run
10
+ local_versions.each do |plugin, timestamps|
11
+ timestamps.each do |timestamp|
12
+ m = migrated_version?(plugin, timestamp) ? 'up' : 'down'
13
+ puts "#{m}\t#{plugin}\t#{timestamp}"
14
+ end
15
+ end
16
+ end
17
+
18
+ def migrated_version?(plugin, timestamp)
19
+ db_versions.key?(plugin) &&
20
+ db_versions[plugin].include?(timestamp)
21
+ end
22
+
23
+ def local_versions
24
+ @local_versions ||= ::RedminePluginsHelper::Migrations.local_versions
25
+ end
26
+
27
+ def db_versions
28
+ @db_versions ||= ::RedminePluginsHelper::Migrations.db_versions
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RedminePluginsHelper
4
+ AUTHOR = 'Eduardo Henrique Bogoni'
5
+ SUMMARY = 'Helper for Redmine plugins'
6
+ VERSION = '0.5.2'
7
+ end
@@ -0,0 +1,9 @@
1
+ require 'sass-rails'
2
+
3
+ module RedminePluginsHelper
4
+ class << self
5
+ def settings_table_exist?
6
+ ActiveRecord::Base.connection.table_exists? ::Setting.table_name
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,27 @@
1
+ Rake::Task['redmine:plugins:migrate'].clear
2
+
3
+ namespace :redmine do
4
+ desc 'Run migrations of core Redmine and installed plugins.'
5
+ task migrate: ['db:migrate', 'redmine:plugins:migrate:fix', 'redmine:plugins:migrate'] do
6
+ end
7
+
8
+ namespace :plugins do
9
+ desc 'Migrates installed plugins.'
10
+ task migrate: :environment do
11
+ RedminePluginsHelper::Migrate.new
12
+ Rake::Task['db:schema:dump'].invoke
13
+ end
14
+
15
+ namespace :migrate do
16
+ desc 'Fix migrations moved from a plugin to another'
17
+ task fix: :environment do
18
+ RedminePluginsHelper::FixMigrations.new
19
+ end
20
+
21
+ desc 'Show migrations status of all plugins'
22
+ task status: :environment do
23
+ RedminePluginsHelper::StatusMigrations.new
24
+ end
25
+ end
26
+ end
27
+ end
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: redmine_plugins_helper
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.2
5
+ platform: ruby
6
+ authors:
7
+ - 0.5.2
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-08-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: sass-rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '5.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '5.0'
27
+ description:
28
+ email:
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - app/assets/javascripts/plugins_autoload.js.erb
34
+ - app/assets/stylesheets/plugins_autoload.scss.erb
35
+ - config/initializers/assets.rb
36
+ - config/initializers/backport_pg_10_support_to_rails_4.rb
37
+ - init.rb
38
+ - lib/redmine_plugins_helper.rb
39
+ - lib/redmine_plugins_helper/fix_migrations.rb
40
+ - lib/redmine_plugins_helper/hooks/add_assets.rb
41
+ - lib/redmine_plugins_helper/migrate.rb
42
+ - lib/redmine_plugins_helper/migrations.rb
43
+ - lib/redmine_plugins_helper/patches/redmine/plugin_patch.rb
44
+ - lib/redmine_plugins_helper/patches/test_case_patch.rb
45
+ - lib/redmine_plugins_helper/settings.rb
46
+ - lib/redmine_plugins_helper/status_migrations.rb
47
+ - lib/redmine_plugins_helper/version.rb
48
+ - lib/tasks/redmine_plugins_helper.rake
49
+ homepage:
50
+ licenses: []
51
+ metadata: {}
52
+ post_install_message:
53
+ rdoc_options: []
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ requirements: []
67
+ rubyforge_project:
68
+ rubygems_version: 2.7.7
69
+ signing_key:
70
+ specification_version: 4
71
+ summary: Helper for Redmine plugins
72
+ test_files: []