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.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -40
  3. data/app/controllers/event_exceptions_controller.rb +3 -3
  4. data/app/models/listener_option.rb +2 -2
  5. data/config/initializers/001_requires.rb +8 -8
  6. data/db/migrate/20160509152749_create_delayed_jobs.rb +5 -5
  7. data/db/migrate/20160717222418_create_event_exceptions.rb +1 -1
  8. data/db/migrate/20180711170315_rename_plugin_events_manager_to_redmine_events_manager.rb +2 -2
  9. data/init.rb +5 -5
  10. data/lib/{events_manager → redmine_events_manager}/event.rb +1 -1
  11. data/lib/{events_manager → redmine_events_manager}/hooks/add_assets.rb +2 -2
  12. data/lib/{events_manager → redmine_events_manager}/patches/issue_patch.rb +5 -5
  13. data/lib/{events_manager → redmine_events_manager}/patches/issue_relation_patch.rb +5 -5
  14. data/lib/{events_manager → redmine_events_manager}/patches/journal_patch.rb +4 -4
  15. data/lib/redmine_events_manager/patches/repository/git_patch.rb +19 -0
  16. data/lib/redmine_events_manager/patches/test_case_patch.rb +16 -0
  17. data/lib/{events_manager → redmine_events_manager}/patches/time_entry_patch.rb +8 -8
  18. data/lib/{events_manager → redmine_events_manager}/removed_record.rb +1 -1
  19. data/lib/{events_manager → redmine_events_manager}/settings.rb +2 -2
  20. data/lib/redmine_events_manager/test_config.rb +3 -3
  21. data/lib/{events_manager → redmine_events_manager}/updated_record.rb +1 -1
  22. data/lib/redmine_events_manager/version.rb +1 -1
  23. data/lib/redmine_events_manager.rb +96 -0
  24. data/lib/tasks/redmine_events_manager.rake +45 -0
  25. data/redmine_events_manager.gemspec +7 -6
  26. data/spec/controllers/event_exceptions_controller_spec.rb +4 -4
  27. data/spec/lib/{events_manager_spec.rb → redmine_events_manager_spec.rb} +4 -4
  28. data/spec/models/event_exception_spec.rb +6 -6
  29. metadata +19 -28
  30. data/config/initializers/assets.rb +0 -0
  31. data/lib/events_manager/patches/repository/git_patch.rb +0 -18
  32. data/lib/events_manager/patches/test_case_patch.rb +0 -17
  33. data/lib/events_manager.rb +0 -99
  34. data/lib/tasks/events.rake +0 -46
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5bd571a9dee1c01ab18d6b86d079f91502c421c0f165842f3bbe3833446b1c7c
4
- data.tar.gz: 43e2b5f999bf79b79de143ae6c979cb50d2372e8c50ae9ec9b400a099a10eabc
3
+ metadata.gz: cb809ed55e74dcbc51efe7c054125cdf0f645ad57381f1937adde5fc0c9c7d00
4
+ data.tar.gz: e57c1ead5a2ff3c49ddd835e660c8022233eced7c1f8847ed0267f532a5afae5
5
5
  SHA512:
6
- metadata.gz: 103bf1ef57cea93c7cc8723b21ff27cf95c1b0ef11f22b3bf6e00aadffef003ead4df87c4bb4aa3613e67dfff5c7866feb5e954af2abaefb2219f07a51346c8a
7
- data.tar.gz: 8adf1f319812dbd6923672ac0651f19d46fdff329b07bdbc000a0001a7540ea58429ba9750c05596f001e3c5931424ec4979a85c35b79714356b5c427a6f92ac
6
+ metadata.gz: '096a4a71edb8b66915b731a027a1b5b5fde6890d0de719d97ec2b719896d775fa0b50b7cc6129746599f457fe356f095be53a99ba6cf17e02361ed75f15bd30a'
7
+ data.tar.gz: 255b9298aa2e98d1f52922e8fd6d958b611c9eedcb0ac7af0a26de43b048dcd4e666a8f217914a89fe81f63cf37e220884b3be493250ad5df708e8fe45367f8a
data/.rubocop.yml CHANGED
@@ -1,40 +1,3 @@
1
- require:
2
- - rubocop-rails
3
- - rubocop-rspec
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
- EventsManager::Settings.event_exception_unchecked = false if
30
- EventsManager::Settings.event_exception_unchecked
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 ||= ::EventsManager.all_listeners
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 'events_manager/patches/issue_patch'
4
- require 'events_manager/patches/issue_relation_patch'
5
- require 'events_manager/patches/journal_patch'
6
- require 'events_manager/patches/test_case_patch'
7
- require 'events_manager/patches/time_entry_patch'
8
- require 'events_manager/patches/repository/git_patch'
9
- require 'events_manager'
10
- require_dependency 'events_manager/hooks/add_assets'
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('events_manager', 'redmine_events_manager')
10
+ rename_plugin('redmine_events_manager', 'redmine_events_manager')
11
11
  end
12
12
 
13
13
  def down
14
- rename_plugin('redmine_events_manager', '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
- require_dependency 'redmine_events_manager/version'
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? && EventsManager::Settings.event_exception_unchecked
25
+ User.current.admin? && RedmineEventsManager::Settings.event_exception_unchecked
26
26
  }
27
27
  end
28
28
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module EventsManager
3
+ module RedmineEventsManager
4
4
  class Event
5
5
  attr_reader :entity, :action, :data
6
6
 
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module EventsManager
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') + "\n"
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 EventsManager
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
- EventsManager.trigger(Issue, :create, self)
19
+ RedmineEventsManager.trigger(Issue, :create, self)
20
20
  end
21
21
 
22
22
  def issue_destroy_event
23
- EventsManager.trigger(Issue, :delete, self)
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? EventsManager::Patches::IssuePatch
31
- Issue.include EventsManager::Patches::IssuePatch
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 EventsManager
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
- EventsManager.trigger(IssueRelation, :create, self)
19
+ RedmineEventsManager.trigger(IssueRelation, :create, self)
20
20
  end
21
21
 
22
22
  def issue_relation_destroy_event
23
- EventsManager.trigger(IssueRelation, :delete, self)
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? EventsManager::Patches::IssueRelationPatch
31
- IssueRelation.include EventsManager::Patches::IssueRelationPatch
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 EventsManager
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
- EventsManager.trigger(Issue, :update, self)
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? EventsManager::Patches::JournalPatch
28
- Journal.include EventsManager::Patches::JournalPatch
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 EventsManager
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
- EventsManager.trigger(TimeEntry, :create, self)
20
+ RedmineEventsManager.trigger(TimeEntry, :create, self)
21
21
  end
22
22
 
23
23
  def time_entry_destroy_event
24
- EventsManager.trigger(TimeEntry, :delete,
25
- EventsManager::RemovedRecord.new(self))
24
+ RedmineEventsManager.trigger(TimeEntry, :delete,
25
+ RedmineEventsManager::RemovedRecord.new(self))
26
26
  end
27
27
 
28
28
  def time_entry_update_event
29
- EventsManager.trigger(TimeEntry, :update,
30
- EventsManager::UpdatedRecord.new(self))
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? EventsManager::Patches::TimeEntryPatch
38
- TimeEntry.include EventsManager::Patches::TimeEntryPatch
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 EventsManager
3
+ module RedmineEventsManager
4
4
  class RemovedRecord
5
5
  def initialize(record)
6
6
  @attributes = record.attributes
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module EventsManager
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
- EventsManager.delay_disabled = true
7
- EventsManager.log_exceptions_disabled = true
8
- EventsManager::Settings.event_exception_unchecked = false
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
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module EventsManager
3
+ module RedmineEventsManager
4
4
  class UpdatedRecord
5
5
  attr_reader :record, :changes
6
6
 
@@ -4,7 +4,7 @@ module RedmineEventsManager
4
4
  AUTHOR = 'Eduardo Henrique Bogoni'
5
5
  HOMEPAGE = 'https://github.com/esquilo-azul/redmine_events_manager'
6
6
  SUMMARY = 'Management for events'
7
- VERSION = '0.4.15'
7
+ VERSION = '0.5.0'
8
8
 
9
9
  module Version
10
10
  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 'eac_ruby_gem_support', '~> 0.5', '>= 0.5.1'
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
- EventsManager::Settings.event_exception_unchecked = true
6
+ RedmineEventsManager::Settings.event_exception_unchecked = true
7
7
  end
8
8
 
9
- it { expect(EventsManager::Settings.event_exception_unchecked).to be_truthy }
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(EventsManager::Settings.event_exception_unchecked).to be_falsy }
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(::EventsManager) do
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
- EventsManager.log_exceptions_disabled = false
37
+ RedmineEventsManager.log_exceptions_disabled = false
38
38
  event_exception_count_start
39
- EventsManager.add_listener(DummyEntity, :create, 'DummyListener')
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
- EventsManager.trigger(DummyEntity, :create, DummyEntity.new(false))
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(EventsManager::Settings.event_exception_unchecked).to be_falsy }
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
- EventsManager.trigger(DummyEntity, :create, DummyEntity.new(true))
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(EventsManager::Settings.event_exception_unchecked).to be_truthy }
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.15
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 00:00:00.000000000 Z
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: eac_ruby_gem_support
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.5'
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.5'
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/events_manager_spec.rb
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: '0'
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/events_manager_spec.rb
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
@@ -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
@@ -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