redmine_events_manager 0.4.15 → 0.5.0
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 +4 -4
- data/.rubocop.yml +3 -40
- data/app/controllers/event_exceptions_controller.rb +3 -3
- data/app/models/listener_option.rb +2 -2
- data/config/initializers/001_requires.rb +8 -8
- data/db/migrate/20160509152749_create_delayed_jobs.rb +5 -5
- data/db/migrate/20160717222418_create_event_exceptions.rb +1 -1
- data/db/migrate/20180711170315_rename_plugin_events_manager_to_redmine_events_manager.rb +2 -2
- data/init.rb +5 -5
- data/lib/{events_manager → redmine_events_manager}/event.rb +1 -1
- data/lib/{events_manager → redmine_events_manager}/hooks/add_assets.rb +2 -2
- data/lib/{events_manager → redmine_events_manager}/patches/issue_patch.rb +5 -5
- data/lib/{events_manager → redmine_events_manager}/patches/issue_relation_patch.rb +5 -5
- data/lib/{events_manager → redmine_events_manager}/patches/journal_patch.rb +4 -4
- data/lib/redmine_events_manager/patches/repository/git_patch.rb +19 -0
- data/lib/redmine_events_manager/patches/test_case_patch.rb +16 -0
- data/lib/{events_manager → redmine_events_manager}/patches/time_entry_patch.rb +8 -8
- data/lib/{events_manager → redmine_events_manager}/removed_record.rb +1 -1
- data/lib/{events_manager → redmine_events_manager}/settings.rb +2 -2
- data/lib/redmine_events_manager/test_config.rb +3 -3
- data/lib/{events_manager → redmine_events_manager}/updated_record.rb +1 -1
- data/lib/redmine_events_manager/version.rb +1 -1
- data/lib/redmine_events_manager.rb +96 -0
- data/lib/tasks/redmine_events_manager.rake +45 -0
- data/redmine_events_manager.gemspec +7 -6
- data/spec/controllers/event_exceptions_controller_spec.rb +4 -4
- data/spec/lib/{events_manager_spec.rb → redmine_events_manager_spec.rb} +4 -4
- data/spec/models/event_exception_spec.rb +6 -6
- metadata +19 -28
- data/config/initializers/assets.rb +0 -0
- data/lib/events_manager/patches/repository/git_patch.rb +0 -18
- data/lib/events_manager/patches/test_case_patch.rb +0 -17
- data/lib/events_manager.rb +0 -99
- data/lib/tasks/events.rake +0 -46
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cb809ed55e74dcbc51efe7c054125cdf0f645ad57381f1937adde5fc0c9c7d00
|
4
|
+
data.tar.gz: e57c1ead5a2ff3c49ddd835e660c8022233eced7c1f8847ed0267f532a5afae5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '096a4a71edb8b66915b731a027a1b5b5fde6890d0de719d97ec2b719896d775fa0b50b7cc6129746599f457fe356f095be53a99ba6cf17e02361ed75f15bd30a'
|
7
|
+
data.tar.gz: 255b9298aa2e98d1f52922e8fd6d958b611c9eedcb0ac7af0a26de43b048dcd4e666a8f217914a89fe81f63cf37e220884b3be493250ad5df708e8fe45367f8a
|
data/.rubocop.yml
CHANGED
@@ -1,40 +1,3 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
AllCops:
|
6
|
-
TargetRubyVersion: 2.4
|
7
|
-
TargetRailsVersion: 4.2
|
8
|
-
|
9
|
-
Layout/LineLength:
|
10
|
-
Max: 100
|
11
|
-
Exclude:
|
12
|
-
- 'db/migrate/**/*'
|
13
|
-
|
14
|
-
Metrics/AbcSize:
|
15
|
-
Exclude:
|
16
|
-
- 'db/migrate/**/*'
|
17
|
-
- 'test/**/*'
|
18
|
-
|
19
|
-
Metrics/BlockLength:
|
20
|
-
Exclude:
|
21
|
-
- 'db/migrate/**/*'
|
22
|
-
- 'lib/tasks/**/*'
|
23
|
-
- 'spec/**/*.rb'
|
24
|
-
|
25
|
-
Metrics/MethodLength:
|
26
|
-
Exclude:
|
27
|
-
- 'db/migrate/**/*'
|
28
|
-
- 'test/**/*'
|
29
|
-
|
30
|
-
Style/Documentation:
|
31
|
-
Enabled: false
|
32
|
-
|
33
|
-
Style/HashEachMethods:
|
34
|
-
Enabled: true
|
35
|
-
|
36
|
-
Style/HashTransformKeys:
|
37
|
-
Enabled: true
|
38
|
-
|
39
|
-
Style/HashTransformValues:
|
40
|
-
Enabled: true
|
1
|
+
---
|
2
|
+
inherit_gem:
|
3
|
+
eac_rails_gem_support: ".rubocop.yml"
|
@@ -22,11 +22,11 @@ class EventExceptionsController < ApplicationController
|
|
22
22
|
def download_filename(error)
|
23
23
|
[Setting.host_name, 'exception', error.id.to_s, error.created_at.to_s].map do |s|
|
24
24
|
s.parameterize.strip
|
25
|
-
end.select(&:present?).join('_')
|
25
|
+
end.select(&:present?).join('_') # rubocop:disable Rails/CompactBlank
|
26
26
|
end
|
27
27
|
|
28
28
|
def clear_event_exception_unchecked
|
29
|
-
|
30
|
-
|
29
|
+
RedmineEventsManager::Settings.event_exception_unchecked = false if
|
30
|
+
RedmineEventsManager::Settings.event_exception_unchecked
|
31
31
|
end
|
32
32
|
end
|
@@ -6,7 +6,7 @@ class ListenerOption < ActiveRecord::Base
|
|
6
6
|
|
7
7
|
class << self
|
8
8
|
def listener_class_list
|
9
|
-
@listener_class_list ||= ::
|
9
|
+
@listener_class_list ||= ::RedmineEventsManager.all_listeners
|
10
10
|
end
|
11
11
|
|
12
12
|
def listener_class_options
|
@@ -30,7 +30,7 @@ class ListenerOption < ActiveRecord::Base
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
validates :listener_class, presence: true, uniqueness: true,
|
33
|
+
validates :listener_class, presence: true, uniqueness: true, # rubocop:disable Rails/UniqueValidationWithoutIndex
|
34
34
|
inclusion: { in: listener_class_list }
|
35
35
|
validates :delay, allow_blank: true,
|
36
36
|
numericality: { integer_only: true }
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require '
|
4
|
-
require '
|
5
|
-
require '
|
6
|
-
require '
|
7
|
-
require '
|
8
|
-
require '
|
9
|
-
require '
|
10
|
-
|
3
|
+
require 'redmine_events_manager/patches/issue_patch'
|
4
|
+
require 'redmine_events_manager/patches/issue_relation_patch'
|
5
|
+
require 'redmine_events_manager/patches/journal_patch'
|
6
|
+
require 'redmine_events_manager/patches/test_case_patch'
|
7
|
+
require 'redmine_events_manager/patches/time_entry_patch'
|
8
|
+
require 'redmine_events_manager/patches/repository/git_patch'
|
9
|
+
require 'redmine_events_manager'
|
10
|
+
require 'redmine_events_manager/hooks/add_assets'
|
@@ -3,16 +3,16 @@
|
|
3
3
|
class CreateDelayedJobs < (
|
4
4
|
Rails.version < '5.2' ? ActiveRecord::Migration : ActiveRecord::Migration[4.2]
|
5
5
|
)
|
6
|
-
def self.up
|
6
|
+
def self.up # rubocop:disable Metrics/MethodLength
|
7
7
|
create_table :delayed_jobs, force: true do |table|
|
8
8
|
table.integer :priority, default: 0, null: false # Allows some jobs to jump to the front of
|
9
9
|
# the queue
|
10
|
-
table.integer :attempts, default: 0, null: false # Provides for retries, but still fail eventually.
|
11
|
-
table.text :handler, null: false # YAML-encoded string of the object that will do work
|
10
|
+
table.integer :attempts, default: 0, null: false # Provides for retries, but still fail eventually. # rubocop:disable Layout/LineLength
|
11
|
+
table.text :handler, null: false # YAML-encoded string of the object that will do work # rubocop:disable Layout/LineLength
|
12
12
|
table.text :last_error # reason for last failure (See Note below)
|
13
|
-
table.datetime :run_at # When to run. Could be Time.zone.now for immediately, or sometime in the future.
|
13
|
+
table.datetime :run_at # When to run. Could be Time.zone.now for immediately, or sometime in the future. # rubocop:disable Layout/LineLength
|
14
14
|
table.datetime :locked_at # Set when a client is working on this object
|
15
|
-
table.datetime :failed_at # Set when all retries have failed (actually, by default, the record is deleted instead)
|
15
|
+
table.datetime :failed_at # Set when all retries have failed (actually, by default, the record is deleted instead) # rubocop:disable Layout/LineLength
|
16
16
|
table.string :locked_by # Who is working on this object (if locked)
|
17
17
|
table.string :queue # The name of the queue this job is in
|
18
18
|
table.timestamps null: true
|
@@ -3,7 +3,7 @@
|
|
3
3
|
class CreateEventExceptions < (
|
4
4
|
Rails.version < '5.2' ? ActiveRecord::Migration : ActiveRecord::Migration[4.2]
|
5
5
|
)
|
6
|
-
def change
|
6
|
+
def change # rubocop:disable Metrics/MethodLength
|
7
7
|
create_table :event_exceptions do |t|
|
8
8
|
t.string :event_entity
|
9
9
|
t.string :event_action
|
@@ -7,11 +7,11 @@ class RenamePluginEventsManagerToRedmineEventsManager < (
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def up
|
10
|
-
rename_plugin('
|
10
|
+
rename_plugin('redmine_events_manager', 'redmine_events_manager')
|
11
11
|
end
|
12
12
|
|
13
13
|
def down
|
14
|
-
rename_plugin('redmine_events_manager', '
|
14
|
+
rename_plugin('redmine_events_manager', 'redmine_events_manager')
|
15
15
|
end
|
16
16
|
|
17
17
|
private
|
data/init.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'redmine'
|
4
|
-
|
4
|
+
require 'redmine_events_manager/version'
|
5
5
|
|
6
6
|
Redmine::Plugin.register :redmine_events_manager do
|
7
7
|
name 'Events Manager'
|
8
|
-
author ::RedmineEventsManager::AUTHOR
|
9
|
-
description ::RedmineEventsManager::SUMMARY
|
10
|
-
version ::RedmineEventsManager::VERSION
|
8
|
+
author ::RedmineEventsManager::AUTHOR # rubocop:disable Style/RedundantConstantBase
|
9
|
+
description ::RedmineEventsManager::SUMMARY # rubocop:disable Style/RedundantConstantBase
|
10
|
+
version ::RedmineEventsManager::VERSION # rubocop:disable Style/RedundantConstantBase
|
11
11
|
|
12
12
|
settings default: { event_exception_unchecked: false }
|
13
13
|
|
@@ -22,7 +22,7 @@ Redmine::Plugin.register :redmine_events_manager do
|
|
22
22
|
menu.push :event_exception_unchecked,
|
23
23
|
{ controller: 'event_exceptions', action: 'index', id: nil },
|
24
24
|
caption: '', last: true, if: proc {
|
25
|
-
User.current.admin? &&
|
25
|
+
User.current.admin? && RedmineEventsManager::Settings.event_exception_unchecked
|
26
26
|
}
|
27
27
|
end
|
28
28
|
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module RedmineEventsManager
|
4
4
|
module Hooks
|
5
5
|
class AddAssets < Redmine::Hook::ViewListener
|
6
6
|
def view_layouts_base_html_head(_context = {})
|
7
|
-
stylesheet_link_tag(:application, plugin: 'redmine_events_manager')
|
7
|
+
"#{stylesheet_link_tag(:application, plugin: 'redmine_events_manager')}\n"
|
8
8
|
end
|
9
9
|
end
|
10
10
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module RedmineEventsManager
|
4
4
|
module Patches
|
5
5
|
module IssuePatch
|
6
6
|
def self.included(base)
|
@@ -16,17 +16,17 @@ module EventsManager
|
|
16
16
|
|
17
17
|
module InstanceMethods
|
18
18
|
def issue_create_event
|
19
|
-
|
19
|
+
RedmineEventsManager.trigger(Issue, :create, self)
|
20
20
|
end
|
21
21
|
|
22
22
|
def issue_destroy_event
|
23
|
-
|
23
|
+
RedmineEventsManager.trigger(Issue, :delete, self)
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
unless Issue.included_modules.include?
|
31
|
-
Issue.include
|
30
|
+
unless Issue.included_modules.include? RedmineEventsManager::Patches::IssuePatch
|
31
|
+
Issue.include RedmineEventsManager::Patches::IssuePatch
|
32
32
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module RedmineEventsManager
|
4
4
|
module Patches
|
5
5
|
module IssueRelationPatch
|
6
6
|
def self.included(base)
|
@@ -16,17 +16,17 @@ module EventsManager
|
|
16
16
|
|
17
17
|
module InstanceMethods
|
18
18
|
def issue_relation_create_event
|
19
|
-
|
19
|
+
RedmineEventsManager.trigger(IssueRelation, :create, self)
|
20
20
|
end
|
21
21
|
|
22
22
|
def issue_relation_destroy_event
|
23
|
-
|
23
|
+
RedmineEventsManager.trigger(IssueRelation, :delete, self)
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
unless IssueRelation.included_modules.include?
|
31
|
-
IssueRelation.include
|
30
|
+
unless IssueRelation.included_modules.include? RedmineEventsManager::Patches::IssueRelationPatch
|
31
|
+
IssueRelation.include RedmineEventsManager::Patches::IssueRelationPatch
|
32
32
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module RedmineEventsManager
|
4
4
|
module Patches
|
5
5
|
module JournalPatch
|
6
6
|
def self.included(base)
|
@@ -17,13 +17,13 @@ module EventsManager
|
|
17
17
|
def journal_create_event
|
18
18
|
return unless journalized_type == 'Issue'
|
19
19
|
|
20
|
-
|
20
|
+
RedmineEventsManager.trigger(Issue, :update, self)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
unless Journal.included_modules.include?
|
28
|
-
Journal.include
|
27
|
+
unless Journal.included_modules.include? RedmineEventsManager::Patches::JournalPatch
|
28
|
+
Journal.include RedmineEventsManager::Patches::JournalPatch
|
29
29
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RedmineEventsManager
|
4
|
+
module Patches
|
5
|
+
module Repository
|
6
|
+
module GitPatch
|
7
|
+
def fetch_changesets
|
8
|
+
super
|
9
|
+
RedmineEventsManager.trigger(::Repository, :receive, self)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
unless Repository::Git.included_modules
|
17
|
+
.include?(RedmineEventsManager::Patches::Repository::GitPatch)
|
18
|
+
::Repository::Git.prepend(RedmineEventsManager::Patches::Repository::GitPatch) # rubocop:disable Style/RedundantConstantBase
|
19
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RedmineEventsManager
|
4
|
+
module Patches
|
5
|
+
module TestCasePatch
|
6
|
+
def self.included(base)
|
7
|
+
base.setup { ::RedmineEventsManager::TestConfig.new.before_each }
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
if Rails.env.test? && ::ActiveSupport::TestCase # rubocop:disable Style/RedundantConstantBase
|
14
|
+
.included_modules.exclude?(RedmineEventsManager::Patches::TestCasePatch)
|
15
|
+
ActiveSupport::TestCase.include RedmineEventsManager::Patches::TestCasePatch # rubocop:disable Rails/ActiveSupportOnLoad
|
16
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module RedmineEventsManager
|
4
4
|
module Patches
|
5
5
|
module TimeEntryPatch
|
6
6
|
def self.included(base)
|
@@ -17,23 +17,23 @@ module EventsManager
|
|
17
17
|
|
18
18
|
module InstanceMethods
|
19
19
|
def time_entry_create_event
|
20
|
-
|
20
|
+
RedmineEventsManager.trigger(TimeEntry, :create, self)
|
21
21
|
end
|
22
22
|
|
23
23
|
def time_entry_destroy_event
|
24
|
-
|
25
|
-
|
24
|
+
RedmineEventsManager.trigger(TimeEntry, :delete,
|
25
|
+
RedmineEventsManager::RemovedRecord.new(self))
|
26
26
|
end
|
27
27
|
|
28
28
|
def time_entry_update_event
|
29
|
-
|
30
|
-
|
29
|
+
RedmineEventsManager.trigger(TimeEntry, :update,
|
30
|
+
RedmineEventsManager::UpdatedRecord.new(self))
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
-
unless TimeEntry.included_modules.include?
|
38
|
-
TimeEntry.include
|
37
|
+
unless TimeEntry.included_modules.include? RedmineEventsManager::Patches::TimeEntryPatch
|
38
|
+
TimeEntry.include RedmineEventsManager::Patches::TimeEntryPatch
|
39
39
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module RedmineEventsManager
|
4
4
|
class Settings
|
5
5
|
class << self
|
6
6
|
def event_exception_unchecked=(value)
|
@@ -9,7 +9,7 @@ module EventsManager
|
|
9
9
|
Setting.plugin_redmine_events_manager = s
|
10
10
|
end
|
11
11
|
|
12
|
-
def event_exception_unchecked
|
12
|
+
def event_exception_unchecked # rubocop:disable Naming/PredicateMethod
|
13
13
|
Setting.plugin_redmine_events_manager[:event_exception_unchecked] ? true : false
|
14
14
|
end
|
15
15
|
end
|
@@ -3,9 +3,9 @@
|
|
3
3
|
module RedmineEventsManager
|
4
4
|
class TestConfig
|
5
5
|
def before_each
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
RedmineEventsManager.delay_disabled = true
|
7
|
+
RedmineEventsManager.log_exceptions_disabled = true
|
8
|
+
RedmineEventsManager::Settings.event_exception_unchecked = false
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
@@ -2,4 +2,100 @@
|
|
2
2
|
|
3
3
|
module RedmineEventsManager
|
4
4
|
require 'delayed_job_active_record'
|
5
|
+
|
6
|
+
class << self
|
7
|
+
attr_accessor :delay_disabled, :log_exceptions_disabled
|
8
|
+
|
9
|
+
EVENT_EXCEPTION_ATTRIBUTES = {
|
10
|
+
event_entity: proc { |e, _l, _ex| e.entity.name },
|
11
|
+
event_action: proc { |e, _l, _ex| e.action.to_s },
|
12
|
+
event_data: proc { |e, _l, _ex| e.data.to_yaml },
|
13
|
+
listener_class: proc { |_e, l, _ex| l.class.name },
|
14
|
+
listener_instance: proc { |_e, l, _ex| l.to_s },
|
15
|
+
exception_class: proc { |_e, _l, ex| ex.class.name },
|
16
|
+
exception_message: proc { |_e, _l, ex| ex.message },
|
17
|
+
exception_stack: proc { |_e, _l, ex| ex.backtrace.join("\n") }
|
18
|
+
}.freeze
|
19
|
+
|
20
|
+
def add_listener(entity, action, listener)
|
21
|
+
return if listeners(entity, action).include?(listener)
|
22
|
+
|
23
|
+
listeners(entity, action) << listener.to_s
|
24
|
+
end
|
25
|
+
|
26
|
+
def trigger(entity, action, data)
|
27
|
+
event = RedmineEventsManager::Event.new(entity, action, data)
|
28
|
+
Rails.logger.debug("Event triggered: #{event}") # rubocop:disable Rails/EagerEvaluationLogMessage
|
29
|
+
listeners(entity, action).each do |l|
|
30
|
+
Rails.logger.debug("Listener found: #{l}") # rubocop:disable Rails/EagerEvaluationLogMessage
|
31
|
+
run_delayed_listener(event, l.constantize.new(event))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def all_listeners
|
36
|
+
r = []
|
37
|
+
@listeners.each_value do |e|
|
38
|
+
e.each_value do |a|
|
39
|
+
r += a
|
40
|
+
end
|
41
|
+
end
|
42
|
+
r.uniq
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def run_delayed_listener(event, listener)
|
48
|
+
return unless ::ListenerOption.listener_enabled?(listener.class)
|
49
|
+
|
50
|
+
if delay_disabled
|
51
|
+
run_listener(event, listener)
|
52
|
+
else
|
53
|
+
delay(run_at: ::ListenerOption.listener_delay(listener.class).seconds.from_now)
|
54
|
+
.run_listener(event, listener)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def run_listener(event, listener)
|
59
|
+
previous_locale = I18n.locale
|
60
|
+
begin
|
61
|
+
Rails.logger.info("Running listener: #{listener}")
|
62
|
+
I18n.locale = Setting.default_language
|
63
|
+
listener.run
|
64
|
+
rescue StandardError => e
|
65
|
+
on_listener_exception(event, listener, e)
|
66
|
+
ensure
|
67
|
+
I18n.locale = previous_locale
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def on_listener_exception(event, listener, exception)
|
72
|
+
raise exception if log_exceptions_disabled
|
73
|
+
|
74
|
+
Rails.logger.warn(exception)
|
75
|
+
begin
|
76
|
+
RedmineEventsManager::Settings.event_exception_unchecked = true
|
77
|
+
EventException.create!(event_exception_data(event, listener, exception))
|
78
|
+
rescue StandardError => e
|
79
|
+
Rails.logger.warn(e)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def event_exception_data(event, listener, exception)
|
84
|
+
data = {}
|
85
|
+
EVENT_EXCEPTION_ATTRIBUTES.each do |a, p|
|
86
|
+
data[a] = begin
|
87
|
+
p.call(event, listener, exception)
|
88
|
+
rescue StandardError => e
|
89
|
+
e.to_s
|
90
|
+
end
|
91
|
+
end
|
92
|
+
data
|
93
|
+
end
|
94
|
+
|
95
|
+
def listeners(entity, action)
|
96
|
+
@listeners ||= {}
|
97
|
+
@listeners[entity] ||= {}
|
98
|
+
@listeners[entity][action] ||= []
|
99
|
+
end
|
100
|
+
end
|
5
101
|
end
|
@@ -2,3 +2,48 @@
|
|
2
2
|
|
3
3
|
require 'redmine_plugins_helper/test_tasks/auto'
|
4
4
|
RedminePluginsHelper::TestTasks::Auto.register(:redmine_events_manager)
|
5
|
+
|
6
|
+
namespace :redmine_events_manager do # rubocop:disable Metrics/BlockLength
|
7
|
+
namespace :events do # rubocop:disable Metrics/BlockLength
|
8
|
+
namespace :issue_relation do
|
9
|
+
desc 'Envia notificações da criação de um IssueRelation'
|
10
|
+
task :create, [:issue_relation_id] => :environment do |_t, args|
|
11
|
+
RedmineEventsManager.trigger(
|
12
|
+
IssueRelation,
|
13
|
+
:create,
|
14
|
+
IssueRelation.find(args.issue_relation_id)
|
15
|
+
)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
namespace :issue do
|
19
|
+
desc 'Envia notificações da criação de um Issue'
|
20
|
+
task :create, [:issue_id] => :environment do |_t, args|
|
21
|
+
RedmineEventsManager.trigger(
|
22
|
+
Issue,
|
23
|
+
:create,
|
24
|
+
Issue.find(args.issue_id)
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
desc 'Envia notificações da alteração de um Issue'
|
29
|
+
task :update, [:journal_id] => :environment do |_t, args|
|
30
|
+
RedmineEventsManager.trigger(
|
31
|
+
Issue,
|
32
|
+
:update,
|
33
|
+
Journal.find(args.journal_id)
|
34
|
+
)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
namespace :repository do
|
38
|
+
desc 'Ativa evento de recebimento de conteúdo por repositório'
|
39
|
+
task :receive, [:repository_id] => :environment do |_t, args|
|
40
|
+
RedmineEventsManager.delay_disabled = true
|
41
|
+
RedmineEventsManager.trigger(
|
42
|
+
Repository,
|
43
|
+
:receive,
|
44
|
+
Repository.find(args.repository_id)
|
45
|
+
)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -8,17 +8,18 @@ require 'redmine_events_manager/version'
|
|
8
8
|
# Describe your gem and declare its dependencies:
|
9
9
|
Gem::Specification.new do |s|
|
10
10
|
s.name = 'redmine_events_manager'
|
11
|
-
s.version = ::RedmineEventsManager::VERSION
|
12
|
-
s.authors = [::RedmineEventsManager::AUTHOR]
|
13
|
-
s.summary = ::RedmineEventsManager::SUMMARY
|
14
|
-
s.homepage = ::RedmineEventsManager::HOMEPAGE
|
11
|
+
s.version = ::RedmineEventsManager::VERSION # rubocop:disable Style/RedundantConstantBase
|
12
|
+
s.authors = [::RedmineEventsManager::AUTHOR] # rubocop:disable Style/RedundantConstantBase
|
13
|
+
s.summary = ::RedmineEventsManager::SUMMARY # rubocop:disable Style/RedundantConstantBase
|
14
|
+
s.homepage = ::RedmineEventsManager::HOMEPAGE # rubocop:disable Style/RedundantConstantBase
|
15
15
|
|
16
16
|
s.require_paths = ['lib']
|
17
17
|
s.files = `git ls-files`.split("\n")
|
18
|
-
s.test_files = `git ls-files spec test`.split("\n")
|
18
|
+
s.test_files = `git ls-files spec test`.split("\n") # rubocop:disable Gemspec/DeprecatedAttributeAssignment
|
19
|
+
s.required_ruby_version = '>= 2.7'
|
19
20
|
|
20
21
|
s.add_dependency 'delayed_job_active_record', '~> 4.1', '>= 4.1.11'
|
21
22
|
|
22
23
|
# Test/development gems
|
23
|
-
s.add_development_dependency '
|
24
|
+
s.add_development_dependency 'eac_rails_gem_support', '~> 0.11'
|
24
25
|
end
|
@@ -3,16 +3,16 @@
|
|
3
3
|
RSpec.describe EventExceptionsController, type: :feature do
|
4
4
|
include_context 'with logged user', 'admin' do
|
5
5
|
before do
|
6
|
-
|
6
|
+
RedmineEventsManager::Settings.event_exception_unchecked = true
|
7
7
|
end
|
8
8
|
|
9
|
-
it { expect(
|
10
|
-
it { expect(::User.current.login).to eq('admin') }
|
9
|
+
it { expect(RedmineEventsManager::Settings.event_exception_unchecked).to be_truthy }
|
10
|
+
it { expect(::User.current.login).to eq('admin') } # rubocop:disable Style/RedundantConstantBase
|
11
11
|
|
12
12
|
context 'when index is accessed' do
|
13
13
|
before { visit '/event_exceptions' }
|
14
14
|
|
15
|
-
it { expect(
|
15
|
+
it { expect(RedmineEventsManager::Settings.event_exception_unchecked).to be_falsy }
|
16
16
|
end
|
17
17
|
end
|
18
18
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
RSpec.describe(::
|
4
|
-
let(:stub_entity_class) { ::Class.new }
|
5
|
-
let(:stub_listener_class) { ::Class.new }
|
3
|
+
RSpec.describe(::RedmineEventsManager) do # rubocop:disable Style/RedundantConstantBase
|
4
|
+
let(:stub_entity_class) { ::Class.new } # rubocop:disable Style/RedundantConstantBase
|
5
|
+
let(:stub_listener_class) { ::Class.new } # rubocop:disable Style/RedundantConstantBase
|
6
6
|
|
7
7
|
before do
|
8
8
|
described_class.add_listener(stub_entity_class, 'create', stub_listener_class)
|
@@ -11,6 +11,6 @@ RSpec.describe(::EventsManager) do
|
|
11
11
|
|
12
12
|
it { expect(described_class.all_listeners).to be_a(Array) }
|
13
13
|
it { expect(described_class.all_listeners.count).to be_positive }
|
14
|
-
it { expect(described_class.all_listeners).to(be_all { |l| l.is_a?(::String) }) }
|
14
|
+
it { expect(described_class.all_listeners).to(be_all { |l| l.is_a?(::String) }) } # rubocop:disable Style/RedundantConstantBase
|
15
15
|
it { expect(described_class.all_listeners.count).to eq(described_class.all_listeners.uniq.count) }
|
16
16
|
end
|
@@ -34,28 +34,28 @@ RSpec.describe EventException do
|
|
34
34
|
let(:event_exception_count_start) { described_class.count }
|
35
35
|
|
36
36
|
before do
|
37
|
-
|
37
|
+
RedmineEventsManager.log_exceptions_disabled = false
|
38
38
|
event_exception_count_start
|
39
|
-
|
39
|
+
RedmineEventsManager.add_listener(DummyEntity, :create, 'DummyListener')
|
40
40
|
end
|
41
41
|
|
42
42
|
context 'when event triggered is successful' do
|
43
43
|
before do
|
44
|
-
|
44
|
+
RedmineEventsManager.trigger(DummyEntity, :create, DummyEntity.new(false))
|
45
45
|
end
|
46
46
|
|
47
47
|
it 'successful event should not generate event exception' do
|
48
48
|
expect(described_class.count).to eq(event_exception_count_start)
|
49
49
|
end
|
50
50
|
|
51
|
-
it { expect(
|
51
|
+
it { expect(RedmineEventsManager::Settings.event_exception_unchecked).to be_falsy }
|
52
52
|
end
|
53
53
|
|
54
54
|
context 'when event triggered is fail' do
|
55
55
|
let(:ee) { described_class.last }
|
56
56
|
|
57
57
|
before do
|
58
|
-
|
58
|
+
RedmineEventsManager.trigger(DummyEntity, :create, DummyEntity.new(true))
|
59
59
|
end
|
60
60
|
|
61
61
|
it 'failed event should generate event exception' do
|
@@ -74,6 +74,6 @@ RSpec.describe EventException do
|
|
74
74
|
it { expect(ee.exception_class).to eq('RuntimeError') }
|
75
75
|
it { expect(ee.exception_message).to eq('Dummy failed!') }
|
76
76
|
it { expect(ee.exception_stack).to be_present }
|
77
|
-
it { expect(
|
77
|
+
it { expect(RedmineEventsManager::Settings.event_exception_unchecked).to be_truthy }
|
78
78
|
end
|
79
79
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redmine_events_manager
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eduardo Henrique Bogoni
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-09-
|
11
|
+
date: 2025-09-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: delayed_job_active_record
|
@@ -31,25 +31,19 @@ dependencies:
|
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: 4.1.11
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
|
-
name:
|
34
|
+
name: eac_rails_gem_support
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
36
36
|
requirements:
|
37
37
|
- - "~>"
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version: '0.
|
40
|
-
- - ">="
|
41
|
-
- !ruby/object:Gem::Version
|
42
|
-
version: 0.5.1
|
39
|
+
version: '0.11'
|
43
40
|
type: :development
|
44
41
|
prerelease: false
|
45
42
|
version_requirements: !ruby/object:Gem::Requirement
|
46
43
|
requirements:
|
47
44
|
- - "~>"
|
48
45
|
- !ruby/object:Gem::Version
|
49
|
-
version: '0.
|
50
|
-
- - ">="
|
51
|
-
- !ruby/object:Gem::Version
|
52
|
-
version: 0.5.1
|
46
|
+
version: '0.11'
|
53
47
|
description:
|
54
48
|
email:
|
55
49
|
executables: []
|
@@ -67,7 +61,6 @@ files:
|
|
67
61
|
- assets/stylesheets/application.css
|
68
62
|
- bin/bundle
|
69
63
|
- config/initializers/001_requires.rb
|
70
|
-
- config/initializers/assets.rb
|
71
64
|
- config/locales/pt-BR.yml
|
72
65
|
- config/routes.rb
|
73
66
|
- db/migrate/20160509152749_create_delayed_jobs.rb
|
@@ -77,26 +70,24 @@ files:
|
|
77
70
|
- db/migrate/20180711170315_rename_plugin_events_manager_to_redmine_events_manager.rb
|
78
71
|
- dependencies.yaml
|
79
72
|
- init.rb
|
80
|
-
- lib/events_manager.rb
|
81
|
-
- lib/events_manager/event.rb
|
82
|
-
- lib/events_manager/hooks/add_assets.rb
|
83
|
-
- lib/events_manager/patches/issue_patch.rb
|
84
|
-
- lib/events_manager/patches/issue_relation_patch.rb
|
85
|
-
- lib/events_manager/patches/journal_patch.rb
|
86
|
-
- lib/events_manager/patches/repository/git_patch.rb
|
87
|
-
- lib/events_manager/patches/test_case_patch.rb
|
88
|
-
- lib/events_manager/patches/time_entry_patch.rb
|
89
|
-
- lib/events_manager/removed_record.rb
|
90
|
-
- lib/events_manager/settings.rb
|
91
|
-
- lib/events_manager/updated_record.rb
|
92
73
|
- lib/redmine_events_manager.rb
|
74
|
+
- lib/redmine_events_manager/event.rb
|
75
|
+
- lib/redmine_events_manager/hooks/add_assets.rb
|
76
|
+
- lib/redmine_events_manager/patches/issue_patch.rb
|
77
|
+
- lib/redmine_events_manager/patches/issue_relation_patch.rb
|
78
|
+
- lib/redmine_events_manager/patches/journal_patch.rb
|
79
|
+
- lib/redmine_events_manager/patches/repository/git_patch.rb
|
80
|
+
- lib/redmine_events_manager/patches/test_case_patch.rb
|
81
|
+
- lib/redmine_events_manager/patches/time_entry_patch.rb
|
82
|
+
- lib/redmine_events_manager/removed_record.rb
|
83
|
+
- lib/redmine_events_manager/settings.rb
|
93
84
|
- lib/redmine_events_manager/test_config.rb
|
85
|
+
- lib/redmine_events_manager/updated_record.rb
|
94
86
|
- lib/redmine_events_manager/version.rb
|
95
|
-
- lib/tasks/events.rake
|
96
87
|
- lib/tasks/redmine_events_manager.rake
|
97
88
|
- redmine_events_manager.gemspec
|
98
89
|
- spec/controllers/event_exceptions_controller_spec.rb
|
99
|
-
- spec/lib/
|
90
|
+
- spec/lib/redmine_events_manager_spec.rb
|
100
91
|
- spec/models/event_exception_spec.rb
|
101
92
|
homepage: https://github.com/esquilo-azul/redmine_events_manager
|
102
93
|
licenses: []
|
@@ -109,7 +100,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
109
100
|
requirements:
|
110
101
|
- - ">="
|
111
102
|
- !ruby/object:Gem::Version
|
112
|
-
version: '
|
103
|
+
version: '2.7'
|
113
104
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
114
105
|
requirements:
|
115
106
|
- - ">="
|
@@ -122,5 +113,5 @@ specification_version: 4
|
|
122
113
|
summary: Management for events
|
123
114
|
test_files:
|
124
115
|
- spec/controllers/event_exceptions_controller_spec.rb
|
125
|
-
- spec/lib/
|
116
|
+
- spec/lib/redmine_events_manager_spec.rb
|
126
117
|
- spec/models/event_exception_spec.rb
|
File without changes
|
@@ -1,18 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module EventsManager
|
4
|
-
module Patches
|
5
|
-
module Repository
|
6
|
-
module GitPatch
|
7
|
-
def fetch_changesets
|
8
|
-
super
|
9
|
-
EventsManager.trigger(::Repository, :receive, self)
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
unless ::Repository::Git.included_modules.include?(EventsManager::Patches::Repository::GitPatch)
|
17
|
-
::Repository::Git.prepend(EventsManager::Patches::Repository::GitPatch)
|
18
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module EventsManager
|
4
|
-
module Patches
|
5
|
-
module TestCasePatch
|
6
|
-
def self.included(base)
|
7
|
-
base.setup { ::RedmineEventsManager::TestConfig.new.before_each }
|
8
|
-
end
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
if Rails.env.test?
|
14
|
-
unless ::ActiveSupport::TestCase.included_modules.include? EventsManager::Patches::TestCasePatch
|
15
|
-
::ActiveSupport::TestCase.include EventsManager::Patches::TestCasePatch
|
16
|
-
end
|
17
|
-
end
|
data/lib/events_manager.rb
DELETED
@@ -1,99 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module EventsManager
|
4
|
-
class << self
|
5
|
-
attr_accessor :delay_disabled, :log_exceptions_disabled
|
6
|
-
|
7
|
-
EVENT_EXCEPTION_ATTRIBUTES = {
|
8
|
-
event_entity: proc { |e, _l, _ex| e.entity.name },
|
9
|
-
event_action: proc { |e, _l, _ex| e.action.to_s },
|
10
|
-
event_data: proc { |e, _l, _ex| e.data.to_yaml },
|
11
|
-
listener_class: proc { |_e, l, _ex| l.class.name },
|
12
|
-
listener_instance: proc { |_e, l, _ex| l.to_s },
|
13
|
-
exception_class: proc { |_e, _l, ex| ex.class.name },
|
14
|
-
exception_message: proc { |_e, _l, ex| ex.message },
|
15
|
-
exception_stack: proc { |_e, _l, ex| ex.backtrace.join("\n") }
|
16
|
-
}.freeze
|
17
|
-
|
18
|
-
def add_listener(entity, action, listener)
|
19
|
-
return if listeners(entity, action).include?(listener)
|
20
|
-
|
21
|
-
listeners(entity, action) << listener.to_s
|
22
|
-
end
|
23
|
-
|
24
|
-
def trigger(entity, action, data)
|
25
|
-
event = EventsManager::Event.new(entity, action, data)
|
26
|
-
Rails.logger.debug("Event triggered: #{event}")
|
27
|
-
listeners(entity, action).each do |l|
|
28
|
-
Rails.logger.debug("Listener found: #{l}")
|
29
|
-
run_delayed_listener(event, l.constantize.new(event))
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def all_listeners
|
34
|
-
r = []
|
35
|
-
@listeners.each_value do |e|
|
36
|
-
e.each_value do |a|
|
37
|
-
r += a
|
38
|
-
end
|
39
|
-
end
|
40
|
-
r.uniq
|
41
|
-
end
|
42
|
-
|
43
|
-
private
|
44
|
-
|
45
|
-
def run_delayed_listener(event, listener)
|
46
|
-
return unless ::ListenerOption.listener_enabled?(listener.class)
|
47
|
-
|
48
|
-
if delay_disabled
|
49
|
-
run_listener(event, listener)
|
50
|
-
else
|
51
|
-
delay(run_at: ::ListenerOption.listener_delay(listener.class).seconds.from_now)
|
52
|
-
.run_listener(event, listener)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
def run_listener(event, listener)
|
57
|
-
previous_locale = I18n.locale
|
58
|
-
begin
|
59
|
-
Rails.logger.info("Running listener: #{listener}")
|
60
|
-
I18n.locale = Setting.default_language
|
61
|
-
listener.run
|
62
|
-
rescue StandardError => e
|
63
|
-
on_listener_exception(event, listener, e)
|
64
|
-
ensure
|
65
|
-
I18n.locale = previous_locale
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def on_listener_exception(event, listener, exception)
|
70
|
-
raise exception if log_exceptions_disabled
|
71
|
-
|
72
|
-
Rails.logger.warn(exception)
|
73
|
-
begin
|
74
|
-
EventsManager::Settings.event_exception_unchecked = true
|
75
|
-
EventException.create!(event_exception_data(event, listener, exception))
|
76
|
-
rescue StandardError => e
|
77
|
-
Rails.logger.warn(e)
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
def event_exception_data(event, listener, exception)
|
82
|
-
data = {}
|
83
|
-
EVENT_EXCEPTION_ATTRIBUTES.each do |a, p|
|
84
|
-
data[a] = begin
|
85
|
-
p.call(event, listener, exception)
|
86
|
-
rescue StandardError => e
|
87
|
-
e.to_s
|
88
|
-
end
|
89
|
-
end
|
90
|
-
data
|
91
|
-
end
|
92
|
-
|
93
|
-
def listeners(entity, action)
|
94
|
-
@listeners ||= {}
|
95
|
-
@listeners[entity] ||= {}
|
96
|
-
@listeners[entity][action] ||= []
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
data/lib/tasks/events.rake
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
namespace :events_manager do
|
4
|
-
namespace :events do
|
5
|
-
namespace :issue_relation do
|
6
|
-
desc 'Envia notificações da criação de um IssueRelation'
|
7
|
-
task :create, [:issue_relation_id] => :environment do |_t, args|
|
8
|
-
EventsManager.trigger(
|
9
|
-
IssueRelation,
|
10
|
-
:create,
|
11
|
-
IssueRelation.find(args.issue_relation_id)
|
12
|
-
)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
namespace :issue do
|
16
|
-
desc 'Envia notificações da criação de um Issue'
|
17
|
-
task :create, [:issue_id] => :environment do |_t, args|
|
18
|
-
EventsManager.trigger(
|
19
|
-
Issue,
|
20
|
-
:create,
|
21
|
-
Issue.find(args.issue_id)
|
22
|
-
)
|
23
|
-
end
|
24
|
-
|
25
|
-
desc 'Envia notificações da alteração de um Issue'
|
26
|
-
task :update, [:journal_id] => :environment do |_t, args|
|
27
|
-
EventsManager.trigger(
|
28
|
-
Issue,
|
29
|
-
:update,
|
30
|
-
Journal.find(args.journal_id)
|
31
|
-
)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
namespace :repository do
|
35
|
-
desc 'Ativa evento de recebimento de conteúdo por repositório'
|
36
|
-
task :receive, [:repository_id] => :environment do |_t, args|
|
37
|
-
EventsManager.delay_disabled = true
|
38
|
-
EventsManager.trigger(
|
39
|
-
Repository,
|
40
|
-
:receive,
|
41
|
-
Repository.find(args.repository_id)
|
42
|
-
)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|