redmine_remotes 0.14.0 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
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