redmine_remotes 0.14.0 → 0.15.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 (45) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/project_remote_issues_controller/create.rb +1 -1
  3. data/app/controllers/project_remote_issues_controller/update.rb +1 -1
  4. data/app/models/remote_issue_fetch/base.rb +45 -0
  5. data/app/models/remote_issue_fetch/base/_local_issue.rb +77 -0
  6. data/app/models/remote_issue_fetch/base/_provider_issue.rb +18 -0
  7. data/app/models/remote_issue_fetch/base/_remote_issue.rb +19 -0
  8. data/app/models/remote_issue_fetch/create.rb +44 -0
  9. data/app/models/remote_issue_fetch/create/_local_issue.rb +21 -0
  10. data/app/models/remote_issue_fetch/create/_remote_issue.rb +21 -0
  11. data/app/models/remote_issue_fetch/update.rb +18 -0
  12. data/app/models/remote_issue_fetch/update/_local_issue.rb +15 -0
  13. data/app/models/remote_issue_fetch/update/_remote_issue.rb +15 -0
  14. data/app/models/remote_tracker.rb +1 -1
  15. data/app/models/remote_tracker/find_issue_local_status.rb +1 -1
  16. data/app/models/remote_tracker_fetch.rb +47 -0
  17. data/app/models/remote_tracker_fetch/provider.rb +13 -0
  18. data/app/models/remote_tracker_fetch/remote_issues.rb +27 -0
  19. data/app/models/remote_tracker_fetch/remote_tracker.rb +16 -0
  20. data/app/models/remote_user/find_local_user.rb +3 -3
  21. data/config/routes.rb +6 -5
  22. data/db/migrate/20190531171641_create_remote_trackers.rb +1 -1
  23. data/db/migrate/20190910182842_create_remote_users.rb +1 -1
  24. data/db/migrate/20190910203552_create_remote_issue_statuses.rb +1 -1
  25. data/db/migrate/20190912000000_create_remote_issues.rb +1 -1
  26. data/lib/redmine_remotes/esosti/entities/issue.rb +32 -1
  27. data/lib/redmine_remotes/jobs/fetch_issues.rb +1 -1
  28. data/lib/redmine_remotes/jobs/fetch_trackers.rb +1 -1
  29. data/lib/redmine_remotes/version.rb +1 -1
  30. data/lib/tasks/redmine_remotes.rake +4 -11
  31. metadata +37 -17
  32. data/app/models/redmine_remotes/tableless/remote_issue_fetch/base.rb +0 -49
  33. data/app/models/redmine_remotes/tableless/remote_issue_fetch/base/_local_issue.rb +0 -73
  34. data/app/models/redmine_remotes/tableless/remote_issue_fetch/base/_provider_issue.rb +0 -22
  35. data/app/models/redmine_remotes/tableless/remote_issue_fetch/base/_remote_issue.rb +0 -23
  36. data/app/models/redmine_remotes/tableless/remote_issue_fetch/create.rb +0 -48
  37. data/app/models/redmine_remotes/tableless/remote_issue_fetch/create/_local_issue.rb +0 -25
  38. data/app/models/redmine_remotes/tableless/remote_issue_fetch/create/_remote_issue.rb +0 -25
  39. data/app/models/redmine_remotes/tableless/remote_issue_fetch/update.rb +0 -22
  40. data/app/models/redmine_remotes/tableless/remote_issue_fetch/update/_local_issue.rb +0 -19
  41. data/app/models/redmine_remotes/tableless/remote_issue_fetch/update/_remote_issue.rb +0 -19
  42. data/app/models/redmine_remotes/tableless/remote_tracker_fetch.rb +0 -51
  43. data/app/models/redmine_remotes/tableless/remote_tracker_fetch/provider.rb +0 -17
  44. data/app/models/redmine_remotes/tableless/remote_tracker_fetch/remote_issues.rb +0 -31
  45. data/app/models/redmine_remotes/tableless/remote_tracker_fetch/remote_tracker.rb +0 -20
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8b69ffeb75da1b7cdee13641076954cbbab68343584a359b213a607918eb619e
4
- data.tar.gz: 890479aa66e8d40a76809386d34f56d823c644d0a21aade8e9aaa5308fe05046
3
+ metadata.gz: 6f6710957b993d233b258cc399182801aaf348281e51df537cf4d10721309154
4
+ data.tar.gz: f9fc4342d569bf8359696a330eddb9c980293ee17f3e2a72be03c5fa6c0b5103
5
5
  SHA512:
6
- metadata.gz: ea705a044abece2d36ea6332ec1b11d28020195c7779e6ca4dc98b5f0d127f97763689bba612e28f281a2fd65522cfcf4adc5b8784e12d896604f0a8e02bef21
7
- data.tar.gz: ce32ae83e8430cef00ed296e67a0fa905adf33583ffee1869e09a4582ac265c8a7660cad52a0f00868966338bb61ef636cf26c7d31abad2107ddb2e9930a3497
6
+ metadata.gz: 27bb24d1b92d9c58e388cd0b14bf150e0ffa09d3a540baf41a5417eb6318ee707a4a18bbc59fc4fbd60d01e2924c0ce432741d8c9b630634852a8600101eec74
7
+ data.tar.gz: ea5eae31d4a6eff4e51d6b72428b798302bab4c49120ad2635c119313928234e4a82f0e43f658f79b80077449604f91efa92d1d5529747c5bf3757e80aa109ea
@@ -30,7 +30,7 @@ class ProjectRemoteIssuesController < ApplicationController
30
30
  end
31
31
 
32
32
  def create_model_class
33
- ::RedmineRemotes::Tableless::RemoteIssueFetch::Create
33
+ ::RemoteIssueFetch::Create
34
34
  end
35
35
 
36
36
  def create_params
@@ -14,7 +14,7 @@ class ProjectRemoteIssuesController < ApplicationController
14
14
  private
15
15
 
16
16
  def update_model_class
17
- ::RedmineRemotes::Tableless::RemoteIssueFetch::Update
17
+ ::RemoteIssueFetch::Update
18
18
  end
19
19
 
20
20
  def update_params
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_rails_utils/models/fetch_errors'
4
+ require 'eac_ruby_utils/core_ext'
5
+
6
+ module RemoteIssueFetch
7
+ class Base < ::EacRailsUtils::Models::Tableless
8
+ enable_simple_cache
9
+ require_sub __FILE__
10
+ include ::EacRailsUtils::Models::FetchErrors
11
+
12
+ validates :fetched_at, presence: true
13
+ validates :local_tracker, presence: true
14
+ validates :remote_tracker, presence: true
15
+ validates :issue_remote_code, presence: true
16
+
17
+ validate :author_present
18
+ validate :provider_issue_present
19
+
20
+ def author_present
21
+ return if provider_issue.blank?
22
+ return if local_issue_author.present?
23
+
24
+ errors.add(:remote_code,
25
+ "Usuário local não encontrado para \"#{provider_issue.author_login}\"")
26
+ end
27
+
28
+ def provider_issue_present
29
+ return if issue_remote_code.blank?
30
+ return if provider_issue.present?
31
+
32
+ errors.add(:remote_code,
33
+ "Demanda remota não encontrada com o código \"#{issue_remote_code}\"")
34
+ end
35
+
36
+ def save
37
+ ::Issue.transaction do
38
+ return false unless valid?
39
+ return false unless save_local_issue
40
+ return false unless save_remote_issue
41
+ end
42
+ true
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RemoteIssueFetch
4
+ class Base < ::EacRailsUtils::Models::Tableless
5
+ private
6
+
7
+ DESCRIPTION_SECTION_SEPARATOR = "\n\n"
8
+
9
+ def save_local_issue
10
+ save_local_issue_except_create_on && save_local_issue_created_on
11
+ end
12
+
13
+ def save_local_issue_created_on
14
+ local_issue_provider_attributes[:created_on].if_present do |created_on|
15
+ if created_on.present? && local_issue.created_on != created_on
16
+ local_issue.update_column( # rubocop:disable Rails/SkipsModelValidations
17
+ :created_on, created_on
18
+ )
19
+ end
20
+ end
21
+
22
+ true
23
+ end
24
+
25
+ def save_local_issue_except_create_on
26
+ local_issue_provider_attributes.except(:created_on)
27
+ .each { |attr, value| local_issue.send("#{attr}=", value) }
28
+ return true if local_issue.save
29
+
30
+ fetch_record_errors(local_issue, default_column: default_error_column)
31
+ false
32
+ end
33
+
34
+ def local_issue_provider_attributes
35
+ {
36
+ subject: local_issue_subject, author: local_issue_author, status: local_issue_status,
37
+ description: local_issue_description,
38
+ created_on: provider_issue.created_on
39
+ }
40
+ end
41
+
42
+ def local_issue_subject
43
+ "[#{provider_issue.code}] #{provider_issue.subject}".truncate(100)
44
+ end
45
+
46
+ def local_issue_author_uncached
47
+ return nil if provider_issue.blank?
48
+
49
+ ::RemoteUser.find_local_user(
50
+ provider_issue.author_login,
51
+ remote_tracker,
52
+ true
53
+ )
54
+ end
55
+
56
+ def local_issue_status
57
+ remote_tracker.try(:find_local_issue_status, local_tracker, provider_issue.status_name, true)
58
+ end
59
+
60
+ def local_issue_description
61
+ [local_issue_extra_description(:before), provider_issue.description,
62
+ local_issue_extra_description(:after), local_issue_import_footer]
63
+ .reject(&:blank?).map(&:strip).join("\n\n----\n\n") + "\n"
64
+ end
65
+
66
+ def local_issue_extra_description(position)
67
+ extra = provider_issue.try("extra_description_#{position}").if_present('')
68
+ extra = extra.map { |k, v| "* *#{k}:* #{v}" } if extra.is_a?(::Hash)
69
+ extra = extra.map { |v| "#{v}\n" }.join if extra.is_a?(::Enumerable)
70
+ extra.to_s
71
+ end
72
+
73
+ def local_issue_import_footer
74
+ "_Demanda remota importada de #{provider_issue.human_view_url}._"
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RemoteIssueFetch
4
+ class Base < ::EacRailsUtils::Models::Tableless
5
+ private
6
+
7
+ def provider_issue_uncached
8
+ return nil if [remote_tracker, issue_remote_code].any?(&:blank?)
9
+
10
+ remote_tracker.find_remote_issue(issue_remote_code)
11
+ rescue ::Avmtrf1::RestProvider::Response => e
12
+ errors.add(default_error_column,
13
+ "Requisição a \"#{e.url}\" retornou com status #{e.status}")
14
+ ::Rails.logger.warn(e.body)
15
+ nil
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RemoteIssueFetch
4
+ class Base < ::EacRailsUtils::Models::Tableless
5
+ private
6
+
7
+ def fetched_at_uncached
8
+ ::Time.zone.now
9
+ end
10
+
11
+ def save_remote_issue
12
+ remote_issue.fetched_at = fetched_at
13
+ return true if remote_issue.save
14
+
15
+ fetch_record_errors(remote_issue, default_column: default_error_column)
16
+ false
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RemoteIssueFetch
4
+ class Create < ::RemoteIssueFetch::Base
5
+ require_sub __FILE__
6
+
7
+ attribute :issue_remote_code, ::String
8
+ attribute :local_tracker_id, ::Integer
9
+ attribute :project_id, ::Integer
10
+ attribute :remote_tracker_id, ::Integer
11
+
12
+ belongs_to :local_tracker, class_name: 'Tracker'
13
+ belongs_to :project, class_name: 'Project'
14
+ belongs_to :remote_tracker, class_name: 'RemoteTracker'
15
+
16
+ validates :project, presence: true
17
+
18
+ validate :tracker_in_project
19
+
20
+ def default_error_column
21
+ :issue_remote_code
22
+ end
23
+
24
+ def save
25
+ remote_issue_by_remote_code.present? ? update : super
26
+ end
27
+
28
+ def tracker_in_project
29
+ return unless local_tracker.present? && project.present?
30
+ return if project.trackers.include?(local_tracker)
31
+
32
+ errors.add(:local_tracker, 'is not a tracker of project')
33
+ end
34
+
35
+ def update
36
+ update_record = ::RemoteIssueFetch::Update
37
+ .new(remote_issue: remote_issue_by_remote_code)
38
+ return true if update_record.save
39
+
40
+ fetch_record_errors(update_record, default_column: default_error_column)
41
+ false
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RemoteIssueFetch
4
+ class Create < ::RemoteIssueFetch::Base
5
+ private
6
+
7
+ def local_issue_provider_attributes
8
+ super.merge(
9
+ project: project, tracker: local_tracker, priority: local_issue_priority
10
+ )
11
+ end
12
+
13
+ def local_issue_uncached
14
+ remote_issue_by_remote_code.if_present(&:local_issue) || ::Issue.new
15
+ end
16
+
17
+ def local_issue_priority
18
+ ::IssuePriority.default
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RemoteIssueFetch
4
+ class Create < ::RemoteIssueFetch::Base
5
+ private
6
+
7
+ def remote_issue_uncached
8
+ remote_issue_by_remote_code.if_blank do
9
+ ::RemoteIssue.new(remote_tracker: remote_tracker, remote_code: issue_remote_code,
10
+ local_issue: local_issue)
11
+ end
12
+ end
13
+
14
+ def remote_issue_by_remote_code_uncached
15
+ ::RemoteIssue.find_by(
16
+ remote_tracker: remote_tracker,
17
+ remote_code: ::RemoteIssue.remote_code_sanitize(issue_remote_code)
18
+ )
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module RemoteIssueFetch
6
+ class Update < ::RemoteIssueFetch::Base
7
+ require_sub __FILE__
8
+
9
+ attribute :remote_issue_id, ::Integer
10
+ belongs_to :remote_issue
11
+
12
+ validates :remote_issue, presence: true
13
+
14
+ def default_error_column
15
+ :remote_issue_id
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RemoteIssueFetch
4
+ class Update < ::RemoteIssueFetch::Base
5
+ private
6
+
7
+ def local_issue
8
+ remote_issue.local_issue
9
+ end
10
+
11
+ def local_tracker
12
+ local_issue.if_present(&:tracker)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RemoteIssueFetch
4
+ class Update < ::RemoteIssueFetch::Base
5
+ private
6
+
7
+ def issue_remote_code
8
+ remote_issue.remote_code
9
+ end
10
+
11
+ def remote_tracker
12
+ remote_issue.remote_tracker
13
+ end
14
+ end
15
+ end
@@ -43,6 +43,6 @@ class RemoteTracker < ActiveRecord::Base
43
43
  end
44
44
 
45
45
  def setting_value(name)
46
- ::RemoteTrackerSetting.where(remote_tracker: self, name: name).first.if_present(&:value)
46
+ ::RemoteTrackerSetting.find_by(remote_tracker: self, name: name).if_present(&:value)
47
47
  end
48
48
  end
@@ -22,7 +22,7 @@ class RemoteTracker < ActiveRecord::Base
22
22
  end
23
23
 
24
24
  def result_by_remote_issue_status
25
- ::RemoteIssueStatus.where(remote_issue_status_find_attributes).first.try(:local_issue_status)
25
+ ::RemoteIssueStatus.find_by(remote_issue_status_find_attributes).try(:local_issue_status)
26
26
  end
27
27
 
28
28
  def result_by_local_issue_status
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ class RemoteTrackerFetch < ::EacRailsUtils::Models::Tableless
6
+ require_sub __FILE__, include_modules: true, require_dependency: true
7
+ enable_simple_cache
8
+ include ::EacRailsUtils::Models::FetchErrors
9
+
10
+ attribute :remote_tracker_id, ::Integer
11
+ belongs_to :remote_tracker, class_name: 'RemoteTracker'
12
+
13
+ validates :remote_tracker, presence: true
14
+ validates :start_time, presence: true
15
+ validates :end_time, presence: true
16
+ validate :remote_tracker_fetchable_validation
17
+
18
+ def save
19
+ ::Issue.transaction do
20
+ return false unless valid?
21
+ return false unless save_remote_issues
22
+ return false unless save_remote_tracker
23
+ end
24
+ true
25
+ end
26
+
27
+ def default_error_column
28
+ :remote_tracker_id
29
+ end
30
+
31
+ private
32
+
33
+ def end_time_uncached
34
+ ::Time.zone.now
35
+ end
36
+
37
+ def start_time_uncached
38
+ remote_tracker.try(:fetched_at) || end_time
39
+ end
40
+
41
+ def remote_tracker_fetchable_validation
42
+ return if remote_tracker.blank?
43
+ return if remote_tracker.fetchable?
44
+
45
+ errors.add(:remote_tracker, "Remote tracker \"#{remote_tracker}\" is not fetchable")
46
+ end
47
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ class RemoteTrackerFetch < ::EacRailsUtils::Models::Tableless
6
+ module Provider
7
+ private
8
+
9
+ def provider_issues_codes
10
+ remote_tracker.remote_instance.fetch_issues_changed(start_time, end_time)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ class RemoteTrackerFetch < ::EacRailsUtils::Models::Tableless
6
+ module RemoteIssues
7
+ private
8
+
9
+ def save_remote_issues
10
+ remote_issues.all? { |remote_issue| save_remote_issue(remote_issue) }
11
+ end
12
+
13
+ def save_remote_issue(remote_issue)
14
+ return true if remote_issue.update(outdated_at: end_time)
15
+
16
+ fetch_record_errors(remote_issue, default_column: default_error_column)
17
+ false
18
+ end
19
+
20
+ def remote_issues_uncached
21
+ provider_issues_codes.map do |code|
22
+ ::RemoteIssue.find_by(remote_tracker: remote_tracker,
23
+ remote_code: ::RemoteIssue.remote_code_sanitize(code))
24
+ end.reject(&:blank?)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ class RemoteTrackerFetch < ::EacRailsUtils::Models::Tableless
6
+ module RemoteTracker
7
+ private
8
+
9
+ def save_remote_tracker
10
+ return true if remote_tracker.update(fetched_at: end_time)
11
+
12
+ fetch_record_errors(remote_tracker, default_column: default_error_column)
13
+ false
14
+ end
15
+ end
16
+ end
@@ -25,7 +25,7 @@ class RemoteUser < ActiveRecord::Base
25
25
 
26
26
  def result_by_local_user_mail_address
27
27
  condition = ::EmailAddress.arel_table[:address].matches("#{remote_login}@%")
28
- ::EmailAddress.where(condition).first.try(:user)
28
+ ::EmailAddress.find_by(condition).try(:user)
29
29
  end
30
30
 
31
31
  def result_by_register_not_found
@@ -47,10 +47,10 @@ class RemoteUser < ActiveRecord::Base
47
47
  end
48
48
 
49
49
  def remote_tracker_result(remote_tracker)
50
- ::RemoteUser.where(
50
+ ::RemoteUser.find_by(
51
51
  remote_tracker: remote_tracker,
52
52
  remote_login: remote_login
53
- ).first.try(:local_user)
53
+ ).try(:local_user)
54
54
  end
55
55
 
56
56
  def remote_trackers_to_search
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  RedmineApp::Application.routes.draw do
4
+ concern :active_scaffold, ActiveScaffold::Routing::Basic.new(association: true)
4
5
  get '/projects/:id/remotes', to: 'project_remote_issues#index'
5
6
  get '/projects/:id/tracker/:tracker_id/new_issue', to: 'project_remote_issues#new',
6
7
  as: 'new_project_remote_issue'
@@ -9,9 +10,9 @@ RedmineApp::Application.routes.draw do
9
10
  put '/projects/:id/remote_issue/:remote_issue_id/update', to: 'project_remote_issues#update',
10
11
  as: 'update_project_remote_issue'
11
12
  resources(:project_remote_issues, only: [:index])
12
- resources(:remote_trackers) { as_routes }
13
- resources(:remote_tracker_settings) { as_routes }
14
- resources(:remote_issues) { as_routes }
15
- resources(:remote_issue_statuses) { as_routes }
16
- resources(:remote_users) { as_routes }
13
+ resources(:remote_trackers, concerns: :active_scaffold)
14
+ resources(:remote_tracker_settings, concerns: :active_scaffold)
15
+ resources(:remote_issues, concerns: :active_scaffold)
16
+ resources(:remote_issue_statuses, concerns: :active_scaffold)
17
+ resources(:remote_users, concerns: :active_scaffold)
17
18
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  class CreateRemoteTrackers < ActiveRecord::Migration
4
4
  def change
5
- create_table :remote_trackers do |t|
5
+ create_table :remote_trackers do |t| # rubocop:disable Rails/CreateTableWithTimestamps
6
6
  t.string :profile
7
7
  t.string :root_url
8
8
  t.string :username
@@ -2,7 +2,7 @@
2
2
 
3
3
  class CreateRemoteUsers < ActiveRecord::Migration
4
4
  def change
5
- create_table :remote_users do |t|
5
+ create_table :remote_users do |t| # rubocop:disable Rails/CreateTableWithTimestamps
6
6
  t.references :remote_tracker, index: true
7
7
  t.string :remote_login
8
8
  t.references :local_user, index: true
@@ -2,7 +2,7 @@
2
2
 
3
3
  class CreateRemoteIssueStatuses < ActiveRecord::Migration
4
4
  def change
5
- create_table :remote_issue_statuses do |t|
5
+ create_table :remote_issue_statuses do |t| # rubocop:disable Rails/CreateTableWithTimestamps
6
6
  t.references :remote_tracker, index: true
7
7
  t.references :local_tracker, index: true
8
8
  t.string :remote_name
@@ -2,7 +2,7 @@
2
2
 
3
3
  class CreateRemoteIssues < ActiveRecord::Migration
4
4
  def change
5
- create_table :remote_issues do |t|
5
+ create_table :remote_issues do |t| # rubocop:disable Rails/CreateTableWithTimestamps
6
6
  t.references :remote_tracker, index: true
7
7
  t.references :local_issue, index: true, nullable: true
8
8
  t.string :remote_code
@@ -6,12 +6,19 @@ module RedmineRemotes
6
6
  module Esosti
7
7
  module Entities
8
8
  class Issue < ::Avmtrf1::Esosti::Entities::Issue
9
+ EXTRA_DESCRIPTION_BEFORE = { reported_by: 'Relatado por', affected_person: 'Pessoa afetada',
10
+ type_description: 'Tipo de solicitação' }.freeze
11
+
9
12
  def human_view_url
10
13
  instance.issue_human_view_url(uid)
11
14
  end
12
15
 
13
16
  def author_login
14
- attributes.fetch('CREATEDBY').if_present { |v| v.gsub(/@[^@]+\z/, '') }
17
+ mail_local_part(attributes.fetch('CREATEDBY'))
18
+ end
19
+
20
+ def affected_person
21
+ mail_local_part(attributes.fetch('AFFECTEDPERSON'))
15
22
  end
16
23
 
17
24
  def attributes
@@ -32,21 +39,45 @@ module RedmineRemotes
32
39
  )
33
40
  end
34
41
 
42
+ def extra_description_before
43
+ {
44
+ 'Relatado por' => "user:#{reported_by}",
45
+ 'Pessoa afetada' => "user:#{affected_person}",
46
+ 'Tipo de solicitação' => type_description
47
+ }
48
+ end
49
+
35
50
  def related_mbos
36
51
  data.first.fetch('RelatedMbos')
37
52
  end
38
53
 
54
+ def reported_by
55
+ mail_local_part(attributes.fetch('REPORTEDBY'))
56
+ end
57
+
39
58
  def status_name
40
59
  attributes.fetch('STATUS')
41
60
  end
42
61
 
43
62
  def subject
63
+ description.gsub(/\s+/, ' ')
64
+ end
65
+
66
+ def type_description
44
67
  attributes.fetch('DESCRIPTION')
45
68
  end
46
69
 
47
70
  def uid
48
71
  attributes.fetch('TICKETUID').fetch('content')
49
72
  end
73
+
74
+ private
75
+
76
+ def mail_local_part(mail_address)
77
+ mail_address.if_present do |v|
78
+ /\A([^@]+)@/.if_match(v, false) { |m| m[1].downcase }.if_present(mail_address)
79
+ end
80
+ end
50
81
  end
51
82
  end
52
83
  end
@@ -19,7 +19,7 @@ module RedmineRemotes
19
19
  def fetch_issue(remote_issue)
20
20
  ::Rails.logger.info 'Fetching remote issue ' \
21
21
  "\"#{remote_issue}|\##{remote_issue.local_issue.id}\""
22
- record = ::RedmineRemotes::Tableless::RemoteIssueFetch::Update.new(
22
+ record = ::RemoteIssueFetch::Update.new(
23
23
  remote_issue: remote_issue
24
24
  )
25
25
  return if record.save
@@ -14,7 +14,7 @@ module RedmineRemotes
14
14
 
15
15
  def fetch_tracker(remote_tracker)
16
16
  ::Rails.logger.info "Fetch remote tracker \"#{remote_tracker}\"..."
17
- record = ::RedmineRemotes::Tableless::RemoteTrackerFetch.new(
17
+ record = ::RemoteTrackerFetch.new(
18
18
  remote_tracker: remote_tracker
19
19
  )
20
20
  return if record.save
@@ -3,7 +3,7 @@
3
3
  module RedmineRemotes
4
4
  SLUG = 'redmine_remotes'
5
5
  NAME = 'Redmine Remotes'
6
- VERSION = '0.14.0'
6
+ VERSION = '0.15.0'
7
7
  AUTHOR = 'Eduardo Henrique Bogoni'
8
8
  SUMMARY = 'Integração do Redmine com trackers diversos.'
9
9
  end
@@ -1,16 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- namespace :redmine_remotes do
4
- Rake::TestTask.new(test: 'db:test:prepare') do |t|
5
- plugin_root = ::File.dirname(::File.dirname(__dir__))
6
-
7
- t.description = 'Run plugin redmine_remotes\'s tests.'
8
- t.libs << 'test'
9
- t.test_files = FileList["#{plugin_root}/test/**/*_test.rb"]
10
- t.verbose = false
11
- t.warning = false
12
- end
3
+ require 'redmine_plugins_helper/plugin_rake_task'
4
+ ::RedminePluginsHelper::PluginRakeTask.register(:redmine_remotes, :test)
13
5
 
6
+ namespace :redmine_remotes do
14
7
  namespace :issues do
15
8
  desc 'Adds a remote issue.'
16
9
  task :add, %i[remote_tracker_id issue_remote_code project_identifier local_tracker_id] =>
@@ -28,7 +21,7 @@ namespace :redmine_remotes do
28
21
  end
29
22
  ::Rails.logger.info("Local tracker: #{local_tracker}")
30
23
 
31
- add = ::RedmineRemotes::Tableless::RemoteIssueFetch::Create.new(
24
+ add = ::RemoteIssueFetch::Create.new(
32
25
  remote_tracker: remote_tracker, project: project, local_tracker: local_tracker,
33
26
  issue_remote_code: args.issue_remote_code
34
27
  )
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redmine_remotes
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.14.0
4
+ version: 0.15.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: 2020-07-24 00:00:00.000000000 Z
11
+ date: 2020-11-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aranha-parsers
@@ -106,6 +106,26 @@ dependencies:
106
106
  - - ">="
107
107
  - !ruby/object:Gem::Version
108
108
  version: 1.0.8
109
+ - !ruby/object:Gem::Dependency
110
+ name: eac_ruby_gem_support
111
+ requirement: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - "~>"
114
+ - !ruby/object:Gem::Version
115
+ version: '0.1'
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: 0.1.2
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - "~>"
124
+ - !ruby/object:Gem::Version
125
+ version: '0.1'
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: 0.1.2
109
129
  description:
110
130
  email:
111
131
  executables: []
@@ -121,25 +141,25 @@ files:
121
141
  - app/controllers/remote_tracker_settings_controller.rb
122
142
  - app/controllers/remote_trackers_controller.rb
123
143
  - app/controllers/remote_users_controller.rb
124
- - app/models/redmine_remotes/tableless/remote_issue_fetch/base.rb
125
- - app/models/redmine_remotes/tableless/remote_issue_fetch/base/_local_issue.rb
126
- - app/models/redmine_remotes/tableless/remote_issue_fetch/base/_provider_issue.rb
127
- - app/models/redmine_remotes/tableless/remote_issue_fetch/base/_remote_issue.rb
128
- - app/models/redmine_remotes/tableless/remote_issue_fetch/create.rb
129
- - app/models/redmine_remotes/tableless/remote_issue_fetch/create/_local_issue.rb
130
- - app/models/redmine_remotes/tableless/remote_issue_fetch/create/_remote_issue.rb
131
- - app/models/redmine_remotes/tableless/remote_issue_fetch/update.rb
132
- - app/models/redmine_remotes/tableless/remote_issue_fetch/update/_local_issue.rb
133
- - app/models/redmine_remotes/tableless/remote_issue_fetch/update/_remote_issue.rb
134
- - app/models/redmine_remotes/tableless/remote_tracker_fetch.rb
135
- - app/models/redmine_remotes/tableless/remote_tracker_fetch/provider.rb
136
- - app/models/redmine_remotes/tableless/remote_tracker_fetch/remote_issues.rb
137
- - app/models/redmine_remotes/tableless/remote_tracker_fetch/remote_tracker.rb
138
144
  - app/models/remote_issue.rb
145
+ - app/models/remote_issue_fetch/base.rb
146
+ - app/models/remote_issue_fetch/base/_local_issue.rb
147
+ - app/models/remote_issue_fetch/base/_provider_issue.rb
148
+ - app/models/remote_issue_fetch/base/_remote_issue.rb
149
+ - app/models/remote_issue_fetch/create.rb
150
+ - app/models/remote_issue_fetch/create/_local_issue.rb
151
+ - app/models/remote_issue_fetch/create/_remote_issue.rb
152
+ - app/models/remote_issue_fetch/update.rb
153
+ - app/models/remote_issue_fetch/update/_local_issue.rb
154
+ - app/models/remote_issue_fetch/update/_remote_issue.rb
139
155
  - app/models/remote_issue_status.rb
140
156
  - app/models/remote_tracker.rb
141
157
  - app/models/remote_tracker/find_issue_local_status.rb
142
158
  - app/models/remote_tracker/remote.rb
159
+ - app/models/remote_tracker_fetch.rb
160
+ - app/models/remote_tracker_fetch/provider.rb
161
+ - app/models/remote_tracker_fetch/remote_issues.rb
162
+ - app/models/remote_tracker_fetch/remote_tracker.rb
143
163
  - app/models/remote_tracker_setting.rb
144
164
  - app/models/remote_user.rb
145
165
  - app/models/remote_user/find_local_user.rb
@@ -202,7 +222,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
202
222
  - !ruby/object:Gem::Version
203
223
  version: '0'
204
224
  requirements: []
205
- rubygems_version: 3.0.6
225
+ rubygems_version: 3.0.8
206
226
  signing_key:
207
227
  specification_version: 4
208
228
  summary: Integração do Redmine com trackers diversos.
@@ -1,49 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'eac_rails_utils/models/fetch_errors'
4
- require 'eac_ruby_utils/core_ext'
5
-
6
- module RedmineRemotes
7
- module Tableless
8
- module RemoteIssueFetch
9
- class Base < ::EacRailsUtils::Models::Tableless
10
- enable_simple_cache
11
- require_sub __FILE__
12
- include ::EacRailsUtils::Models::FetchErrors
13
-
14
- validates :fetched_at, presence: true
15
- validates :local_tracker, presence: true
16
- validates :remote_tracker, presence: true
17
- validates :issue_remote_code, presence: true
18
-
19
- validate :author_present
20
- validate :provider_issue_present
21
-
22
- def author_present
23
- return if provider_issue.blank?
24
- return if local_issue_author.present?
25
-
26
- errors.add(:remote_code,
27
- "Usuário local não encontrado para \"#{provider_issue.author_login}\"")
28
- end
29
-
30
- def provider_issue_present
31
- return if issue_remote_code.blank?
32
- return if provider_issue.present?
33
-
34
- errors.add(:remote_code,
35
- "Demanda remota não encontrada com o código \"#{issue_remote_code}\"")
36
- end
37
-
38
- def save
39
- ::Issue.transaction do
40
- return false unless valid?
41
- return false unless save_local_issue
42
- return false unless save_remote_issue
43
- end
44
- true
45
- end
46
- end
47
- end
48
- end
49
- end
@@ -1,73 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RedmineRemotes
4
- module Tableless
5
- module RemoteIssueFetch
6
- class Base < ::EacRailsUtils::Models::Tableless
7
- private
8
-
9
- def save_local_issue
10
- save_local_issue_except_create_on && save_local_issue_created_on
11
- end
12
-
13
- def save_local_issue_created_on
14
- local_issue_provider_attributes[:created_on].if_present do |created_on|
15
- if created_on.present? && local_issue.created_on != created_on
16
- local_issue.update_column( # rubocop:disable Rails/SkipsModelValidations
17
- :created_on, created_on
18
- )
19
- end
20
- end
21
-
22
- true
23
- end
24
-
25
- def save_local_issue_except_create_on
26
- local_issue_provider_attributes.except(:created_on)
27
- .each { |attr, value| local_issue.send("#{attr}=", value) }
28
- return true if local_issue.save
29
-
30
- fetch_record_errors(local_issue, default_column: default_error_column)
31
- false
32
- end
33
-
34
- def local_issue_provider_attributes
35
- {
36
- subject: local_issue_subject, author: local_issue_author, status: local_issue_status,
37
- description: local_issue_description,
38
- created_on: provider_issue.created_on
39
- }
40
- end
41
-
42
- def local_issue_subject
43
- "[#{provider_issue.code}] #{provider_issue.subject}"
44
- end
45
-
46
- def local_issue_author_uncached
47
- return nil if provider_issue.blank?
48
-
49
- ::RemoteUser.find_local_user(
50
- provider_issue.author_login,
51
- remote_tracker,
52
- true
53
- )
54
- end
55
-
56
- def local_issue_status
57
- remote_tracker.try(:find_local_issue_status, local_tracker, provider_issue.status_name,
58
- true)
59
- end
60
-
61
- def local_issue_description
62
- <<~DESCRIPTION
63
- #{provider_issue.description}
64
-
65
- ----
66
-
67
- _Demanda remota importada de #{provider_issue.human_view_url}._
68
- DESCRIPTION
69
- end
70
- end
71
- end
72
- end
73
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RedmineRemotes
4
- module Tableless
5
- module RemoteIssueFetch
6
- class Base < ::EacRailsUtils::Models::Tableless
7
- private
8
-
9
- def provider_issue_uncached
10
- return nil if [remote_tracker, issue_remote_code].any?(&:blank?)
11
-
12
- remote_tracker.find_remote_issue(issue_remote_code)
13
- rescue ::Avmtrf1::RestProvider::Response => e
14
- errors.add(default_error_column,
15
- "Requisição a \"#{e.url}\" retornou com status #{e.status}")
16
- ::Rails.logger.warn(e.body)
17
- nil
18
- end
19
- end
20
- end
21
- end
22
- end
@@ -1,23 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RedmineRemotes
4
- module Tableless
5
- module RemoteIssueFetch
6
- class Base < ::EacRailsUtils::Models::Tableless
7
- private
8
-
9
- def fetched_at_uncached
10
- ::Time.zone.now
11
- end
12
-
13
- def save_remote_issue
14
- remote_issue.fetched_at = fetched_at
15
- return true if remote_issue.save
16
-
17
- fetch_record_errors(remote_issue, default_column: default_error_column)
18
- false
19
- end
20
- end
21
- end
22
- end
23
- end
@@ -1,48 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RedmineRemotes
4
- module Tableless
5
- module RemoteIssueFetch
6
- class Create < ::RedmineRemotes::Tableless::RemoteIssueFetch::Base
7
- require_sub __FILE__
8
-
9
- attribute :issue_remote_code, ::String
10
- attribute :local_tracker_id, ::Integer
11
- attribute :project_id, ::Integer
12
- attribute :remote_tracker_id, ::Integer
13
-
14
- belongs_to :local_tracker, class_name: 'Tracker'
15
- belongs_to :project, class_name: 'Project'
16
- belongs_to :remote_tracker, class_name: 'RemoteTracker'
17
-
18
- validates :project, presence: true
19
-
20
- validate :tracker_in_project
21
-
22
- def default_error_column
23
- :issue_remote_code
24
- end
25
-
26
- def save
27
- remote_issue_by_remote_code.present? ? update : super
28
- end
29
-
30
- def tracker_in_project
31
- return unless local_tracker.present? && project.present?
32
- return if project.trackers.include?(local_tracker)
33
-
34
- errors.add(:local_tracker, 'is not a tracker of project')
35
- end
36
-
37
- def update
38
- update_record = ::RedmineRemotes::Tableless::RemoteIssueFetch::Update
39
- .new(remote_issue: remote_issue_by_remote_code)
40
- return true if update_record.save
41
-
42
- fetch_record_errors(update_record, default_column: default_error_column)
43
- false
44
- end
45
- end
46
- end
47
- end
48
- end
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RedmineRemotes
4
- module Tableless
5
- module RemoteIssueFetch
6
- class Create < ::RedmineRemotes::Tableless::RemoteIssueFetch::Base
7
- private
8
-
9
- def local_issue_provider_attributes
10
- super.merge(
11
- project: project, tracker: local_tracker, priority: local_issue_priority
12
- )
13
- end
14
-
15
- def local_issue_uncached
16
- remote_issue_by_remote_code.if_present(&:local_issue) || ::Issue.new
17
- end
18
-
19
- def local_issue_priority
20
- ::IssuePriority.default
21
- end
22
- end
23
- end
24
- end
25
- end
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RedmineRemotes
4
- module Tableless
5
- module RemoteIssueFetch
6
- class Create < ::RedmineRemotes::Tableless::RemoteIssueFetch::Base
7
- private
8
-
9
- def remote_issue_uncached
10
- remote_issue_by_remote_code.if_blank do
11
- ::RemoteIssue.new(remote_tracker: remote_tracker, remote_code: issue_remote_code,
12
- local_issue: local_issue)
13
- end
14
- end
15
-
16
- def remote_issue_by_remote_code_uncached
17
- ::RemoteIssue.where(
18
- remote_tracker: remote_tracker,
19
- remote_code: ::RemoteIssue.remote_code_sanitize(issue_remote_code)
20
- ).first
21
- end
22
- end
23
- end
24
- end
25
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'eac_ruby_utils/core_ext'
4
-
5
- module RedmineRemotes
6
- module Tableless
7
- module RemoteIssueFetch
8
- class Update < ::RedmineRemotes::Tableless::RemoteIssueFetch::Base
9
- require_sub __FILE__
10
-
11
- attribute :remote_issue_id, ::Integer
12
- belongs_to :remote_issue
13
-
14
- validates :remote_issue, presence: true
15
-
16
- def default_error_column
17
- :remote_issue_id
18
- end
19
- end
20
- end
21
- end
22
- end
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RedmineRemotes
4
- module Tableless
5
- module RemoteIssueFetch
6
- class Update < ::RedmineRemotes::Tableless::RemoteIssueFetch::Base
7
- private
8
-
9
- def local_issue
10
- remote_issue.local_issue
11
- end
12
-
13
- def local_tracker
14
- local_issue.if_present(&:tracker)
15
- end
16
- end
17
- end
18
- end
19
- end
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RedmineRemotes
4
- module Tableless
5
- module RemoteIssueFetch
6
- class Update < ::RedmineRemotes::Tableless::RemoteIssueFetch::Base
7
- private
8
-
9
- def issue_remote_code
10
- remote_issue.remote_code
11
- end
12
-
13
- def remote_tracker
14
- remote_issue.remote_tracker
15
- end
16
- end
17
- end
18
- end
19
- end
@@ -1,51 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'eac_ruby_utils/core_ext'
4
-
5
- module RedmineRemotes
6
- module Tableless
7
- class RemoteTrackerFetch < ::EacRailsUtils::Models::Tableless
8
- require_sub __FILE__, include_modules: true, require_dependency: true
9
- enable_simple_cache
10
- include ::EacRailsUtils::Models::FetchErrors
11
-
12
- attribute :remote_tracker_id, ::Integer
13
- belongs_to :remote_tracker, class_name: 'RemoteTracker'
14
-
15
- validates :remote_tracker, presence: true
16
- validates :start_time, presence: true
17
- validates :end_time, presence: true
18
- validate :remote_tracker_fetchable_validation
19
-
20
- def save
21
- ::Issue.transaction do
22
- return false unless valid?
23
- return false unless save_remote_issues
24
- return false unless save_remote_tracker
25
- end
26
- true
27
- end
28
-
29
- def default_error_column
30
- :remote_tracker_id
31
- end
32
-
33
- private
34
-
35
- def end_time_uncached
36
- ::Time.zone.now
37
- end
38
-
39
- def start_time_uncached
40
- remote_tracker.try(:fetched_at) || end_time
41
- end
42
-
43
- def remote_tracker_fetchable_validation
44
- return if remote_tracker.blank?
45
- return if remote_tracker.fetchable?
46
-
47
- errors.add(:remote_tracker, "Remote tracker \"#{remote_tracker}\" is not fetchable")
48
- end
49
- end
50
- end
51
- end
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'eac_ruby_utils/core_ext'
4
-
5
- module RedmineRemotes
6
- module Tableless
7
- class RemoteTrackerFetch < ::EacRailsUtils::Models::Tableless
8
- module Provider
9
- private
10
-
11
- def provider_issues_codes
12
- remote_tracker.remote_instance.fetch_issues_changed(start_time, end_time)
13
- end
14
- end
15
- end
16
- end
17
- end
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'eac_ruby_utils/core_ext'
4
-
5
- module RedmineRemotes
6
- module Tableless
7
- class RemoteTrackerFetch < ::EacRailsUtils::Models::Tableless
8
- module RemoteIssues
9
- private
10
-
11
- def save_remote_issues
12
- remote_issues.all? { |remote_issue| save_remote_issue(remote_issue) }
13
- end
14
-
15
- def save_remote_issue(remote_issue)
16
- return true if remote_issue.update(outdated_at: end_time)
17
-
18
- fetch_record_errors(remote_issue, default_column: default_error_column)
19
- false
20
- end
21
-
22
- def remote_issues_uncached
23
- provider_issues_codes.map do |code|
24
- ::RemoteIssue.where(remote_tracker: remote_tracker,
25
- remote_code: ::RemoteIssue.remote_code_sanitize(code)).first
26
- end.reject(&:blank?)
27
- end
28
- end
29
- end
30
- end
31
- end
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'eac_ruby_utils/core_ext'
4
-
5
- module RedmineRemotes
6
- module Tableless
7
- class RemoteTrackerFetch < ::EacRailsUtils::Models::Tableless
8
- module RemoteTracker
9
- private
10
-
11
- def save_remote_tracker
12
- return true if remote_tracker.update(fetched_at: end_time)
13
-
14
- fetch_record_errors(remote_tracker, default_column: default_error_column)
15
- false
16
- end
17
- end
18
- end
19
- end
20
- end