gitlab_support_readiness 1.0.11 → 1.0.13

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 (74) hide show
  1. checksums.yaml +4 -4
  2. data/lib/support_readiness/calendly/client.rb +64 -0
  3. data/lib/support_readiness/calendly/configuration.rb +45 -0
  4. data/lib/support_readiness/calendly/organization_memberships.rb +67 -0
  5. data/lib/support_readiness/calendly/organizations.rb +123 -0
  6. data/lib/support_readiness/calendly/users.rb +105 -0
  7. data/lib/support_readiness/calendly.rb +16 -0
  8. data/lib/support_readiness/client.rb +88 -1
  9. data/lib/support_readiness/dates.rb +90 -0
  10. data/lib/support_readiness/gitlab/configuration.rb +0 -1
  11. data/lib/support_readiness/gitlab/groups.rb +35 -0
  12. data/lib/support_readiness/gitlab/jobs.rb +189 -0
  13. data/lib/support_readiness/gitlab/markdown.rb +37 -0
  14. data/lib/support_readiness/gitlab/merge_requests.rb +127 -0
  15. data/lib/support_readiness/gitlab/namespaces.rb +22 -0
  16. data/lib/support_readiness/gitlab/pipelines.rb +191 -0
  17. data/lib/support_readiness/gitlab/projects.rb +85 -1
  18. data/lib/support_readiness/gitlab/repositories.rb +174 -0
  19. data/lib/support_readiness/gitlab/users.rb +24 -0
  20. data/lib/support_readiness/gitlab.rb +4 -0
  21. data/lib/support_readiness/google_calendar/client.rb +59 -0
  22. data/lib/support_readiness/google_calendar/configuration.rb +39 -0
  23. data/lib/support_readiness/google_calendar/events.rb +169 -0
  24. data/lib/support_readiness/google_calendar.rb +14 -0
  25. data/lib/support_readiness/mailgun/bounces.rb +103 -0
  26. data/lib/support_readiness/mailgun/client.rb +65 -0
  27. data/lib/support_readiness/mailgun/configuration.rb +46 -0
  28. data/lib/support_readiness/mailgun/emails.rb +95 -0
  29. data/lib/support_readiness/mailgun.rb +15 -0
  30. data/lib/support_readiness/pagerduty/escalation_policies.rb +1 -1
  31. data/lib/support_readiness/pagerduty/schedules.rb +27 -3
  32. data/lib/support_readiness/pagerduty/services.rb +1 -1
  33. data/lib/support_readiness/pagerduty/users.rb +197 -0
  34. data/lib/support_readiness/pagerduty.rb +1 -0
  35. data/lib/support_readiness/repos/articles.rb +335 -0
  36. data/lib/support_readiness/repos/automations.rb +247 -0
  37. data/lib/support_readiness/repos/groups.rb +188 -0
  38. data/lib/support_readiness/repos/macros.rb +224 -0
  39. data/lib/support_readiness/repos/organization_fields.rb +193 -0
  40. data/lib/support_readiness/repos/sla_policies.rb +192 -0
  41. data/lib/support_readiness/repos/ticket_fields.rb +200 -0
  42. data/lib/support_readiness/repos/ticket_forms.rb +200 -0
  43. data/lib/support_readiness/repos/triggers.rb +255 -0
  44. data/lib/support_readiness/repos/user_fields.rb +201 -0
  45. data/lib/support_readiness/repos/views.rb +362 -0
  46. data/lib/support_readiness/repos.rb +22 -0
  47. data/lib/support_readiness/salesforce/accounts.rb +109 -0
  48. data/lib/support_readiness/salesforce/cases.rb +109 -0
  49. data/lib/support_readiness/salesforce/client.rb +64 -0
  50. data/lib/support_readiness/salesforce/configuration.rb +49 -0
  51. data/lib/support_readiness/salesforce/queries.rb +62 -0
  52. data/lib/support_readiness/salesforce.rb +16 -0
  53. data/lib/support_readiness/slack/client.rb +63 -0
  54. data/lib/support_readiness/slack/configuration.rb +43 -0
  55. data/lib/support_readiness/slack/messages.rb +37 -0
  56. data/lib/support_readiness/slack.rb +14 -0
  57. data/lib/support_readiness/zendesk/app_job_statuses.rb +140 -0
  58. data/lib/support_readiness/zendesk/apps.rb +209 -0
  59. data/lib/support_readiness/zendesk/automations.rb +1 -2
  60. data/lib/support_readiness/zendesk/macros.rb +1 -3
  61. data/lib/support_readiness/zendesk/organization_fields.rb +1 -1
  62. data/lib/support_readiness/zendesk/theme_job_statuses.rb +136 -0
  63. data/lib/support_readiness/zendesk/themes.rb +303 -0
  64. data/lib/support_readiness/zendesk/ticket_field_options.rb +110 -0
  65. data/lib/support_readiness/zendesk/ticket_fields.rb +85 -16
  66. data/lib/support_readiness/zendesk/ticket_forms.rb +65 -2
  67. data/lib/support_readiness/zendesk/tickets.rb +77 -0
  68. data/lib/support_readiness/zendesk/triggers.rb +1 -2
  69. data/lib/support_readiness/zendesk/user_field_options.rb +110 -0
  70. data/lib/support_readiness/zendesk/user_fields.rb +257 -0
  71. data/lib/support_readiness/zendesk/views.rb +49 -2
  72. data/lib/support_readiness/zendesk.rb +7 -0
  73. data/lib/support_readiness.rb +16 -0
  74. metadata +122 -2
@@ -0,0 +1,192 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Defines the module Readiness.
4
+ module Readiness
5
+ # Defines the module Repos
6
+ module Repos
7
+ ##
8
+ # Defines the class SLAs within the module {Readiness::Repos}.
9
+ #
10
+ # @author Jason Colyer
11
+ # @since 1.0.12
12
+ class SLAs < Readiness::Client
13
+ ##
14
+ # Compares the repo automation files to the Zendesk instance SLA policies
15
+ #
16
+ # @author Jason Colyer
17
+ # @since 1.0.12
18
+ # @param zendesk_client [Object] An instance of {Readiness::Zendesk::Client}
19
+ # @param location [String] The location (relative or absolute) of the repo's data folder
20
+ # @param verbose [Boolean] Whether you want a detailed report or not
21
+ # @return [Hash]
22
+ # @example
23
+ # require 'support_readiness'
24
+ # config = Readiness::Zendesk::Configuration.new
25
+ # config.username = 'alice@example.com'
26
+ # config.token = 'test123abc'
27
+ # config.url = 'https://example.zendesk.com/api/v2'
28
+ # client = Readiness::Zendesk::Client.new(config)
29
+ # diffs = Readiness::Repos::SLAs.compare(client, 'sla-polcies/data', false)
30
+ # pp diffs[:updates.count]
31
+ # # => 1
32
+ # @example
33
+ # require 'support_readiness'
34
+ # config = Readiness::Zendesk::Configuration.new
35
+ # config.username = 'alice@example.com'
36
+ # config.token = 'test123abc'
37
+ # config.url = 'https://example.zendesk.com/api/v2'
38
+ # client = Readiness::Zendesk::Client.new(config)
39
+ # diffs = Readiness::Repos::SLAs.compare(client, 'sla-polcies/data', true)
40
+ # # => Detailed diff of Support Ops
41
+ # # => - @description Repo:
42
+ # # => "For GitLab Support Operations"
43
+ # # => @description Zendesk:
44
+ # # => "For GitLab Support Ops"
45
+ # # => Compare report:
46
+ # # => - Creates: 0
47
+ # # => - Updates: 1
48
+ # pp diffs[:updates.count]
49
+ # # => 1
50
+ def self.compare(zendesk_client, location = 'data', verbose = false)
51
+ diffs = {
52
+ updates: [],
53
+ creates: []
54
+ }
55
+ from_repo = gather(location)
56
+ from_zendesk = Zendesk::SLAs.list(zendesk_client)
57
+ from_repo.each do |repo|
58
+ zd = from_zendesk.detect { |z| z.title == repo.title }
59
+ if zd.nil?
60
+ diffs[:creates].push(repo)
61
+ else
62
+ comparable_zd = zd.dup
63
+ comparable_repo = repo.dup
64
+ comparable_zd.id = nil
65
+ comparable_zd.policy_metrics.map { |a| a.delete('target_in_seconds') }
66
+ comparable_zd.policy_metrics.sort_by! { |a| [a['priority'], a['metric']] }
67
+ comparable_repo.policy_metrics.sort_by! { |a| [a['priority'], a['metric']] }
68
+ diffs[:updates].push(update_object(repo, zd)) if to_clean_json(comparable_repo) != to_clean_json(comparable_zd)
69
+ detailed_diff(repo, comparable) if verbose && to_clean_json(comparable_repo) != to_clean_json(comparable_zd)
70
+ end
71
+ end
72
+ report_diffs(diffs) if verbose
73
+ diffs
74
+ end
75
+
76
+ ##
77
+ # Outputs a comparison report
78
+ #
79
+ # @author Jason Colyer
80
+ # @since 1.0.12
81
+ # @param diffs [Hash] The returned value of {compare}
82
+ def self.report_diffs(diffs)
83
+ puts 'Compare report:'
84
+ puts "- Creates: #{diffs[:creates].count}"
85
+ puts "- Updates: #{diffs[:updates].count}"
86
+ end
87
+
88
+ ##
89
+ # Outputs a comparison report
90
+ #
91
+ # @author Jason Colyer
92
+ # @since 1.0.12
93
+ # @param repo [Object] An instance of {Readiness::Zendesk::SLAs}
94
+ # @param zendesk [Object] An instance of {Readiness::Zendesk::SLAs}
95
+ def self.detailed_diff(repo, zendesk)
96
+ puts "Detailed diff of #{repo.title}"
97
+ repo.instance_variables.each do |v|
98
+ next if v == :@id
99
+
100
+ if repo.instance_variable_get(v) != zendesk.instance_variable_get(v)
101
+ puts "- #{v} Repo:"
102
+ pp repo.instance_variable_get(v)
103
+ puts " #{v} Zendesk:"
104
+ pp zendesk.instance_variable_get(v)
105
+ end
106
+ end
107
+ end
108
+
109
+ ##
110
+ # Creates an instance of {Readiness::Zendesk::Groups} to use for updates
111
+ #
112
+ # @author Jason Colyer
113
+ # @since 1.0.12
114
+ # @param repo [Object] An instance of {Readiness::Zendesk::Groups}
115
+ # @param zendesk [Object] An instance of {Readiness::Zendesk::Groups}
116
+ # @return [Object]
117
+ def self.update_object(repo, zendesk)
118
+ object = repo
119
+ object.id = zendesk.id
120
+ object
121
+ end
122
+
123
+ ##
124
+ # Parses repo group files
125
+ #
126
+ # @author Jason Colyer
127
+ # @since 1.0.12
128
+ # @param location [String] The location (relative or absolute) of the repo's data folder
129
+ # @return [Array]
130
+ # @example
131
+ # require 'support_readiness'
132
+ # repo = Readiness::Repos::Groups.gather('groups/data')
133
+ # pp repo.count
134
+ # # => 35
135
+ def self.gather(location = 'data')
136
+ @errors = []
137
+ @location = location
138
+ array = []
139
+ Dir["#{@location}/*.yaml"].each do |f|
140
+ object = YAML.safe_load_file(f)
141
+ validity_check(f, object)
142
+ object['id'] = nil
143
+ array.push(Zendesk::SLAs.new(object))
144
+ end
145
+ repo_check(array)
146
+ report_errors unless @errors.count.zero?
147
+ array
148
+ end
149
+
150
+ ##
151
+ # Outputs an error report and exits with a status code of 1
152
+ #
153
+ # @author Jason Colyer
154
+ # @since 1.0.12
155
+ def self.report_errors
156
+ puts 'The following errors were found in the repo files:'
157
+ @errors.each do |e|
158
+ puts "- #{e}"
159
+ end
160
+ puts 'Rectify the errors and retry. We cannot proceed with those errors occurring.'
161
+ exit 1
162
+ end
163
+
164
+ ##
165
+ # Performs basic checks on a repo file
166
+ #
167
+ # @author Jason Colyer
168
+ # @since 1.0.12
169
+ # @param file [String] The path to the repo file
170
+ # @param object [Hash] The Hash derived from parsing a YAML file
171
+ def self.validity_check(file, object)
172
+ @errors.push("Missing title: #{file}") if object['title'].nil?
173
+ @errors.push("Missing position: #{file}") if object['position'].nil?
174
+ end
175
+
176
+ ##
177
+ # Performs basic checks on the repo
178
+ #
179
+ # @author Jason Colyer
180
+ # @since 1.0.12
181
+ # @param objects [Array] The Array of Hashes derived from parsing the repo files
182
+ def self.repo_check(objects)
183
+ duplicate_names = objects.group_by { |o| o.title }.select { |k, v| v.size > 1 }.map(&:first)
184
+ unless duplicate_names.count.zero?
185
+ duplicate_names.each do |d|
186
+ @errors.push("The name '#{d}' is used in multiple files")
187
+ end
188
+ end
189
+ end
190
+ end
191
+ end
192
+ end
@@ -0,0 +1,200 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Defines the module Readiness.
4
+ module Readiness
5
+ # Defines the module Repos
6
+ module Repos
7
+ ##
8
+ # Defines the class TicketFields within the module {Readiness::Repos}.
9
+ #
10
+ # @author Jason Colyer
11
+ # @since 1.0.12
12
+ class TicketFields < Readiness::Client
13
+ ##
14
+ # Compares the repo ticket fields files to the Zendesk instance ticket fields
15
+ #
16
+ # @author Jason Colyer
17
+ # @since 1.0.12
18
+ # @param zendesk_client [Object] An instance of {Readiness::Zendesk::Client}
19
+ # @param location [String] The location (relative or absolute) of the repo's data folder
20
+ # @param verbose [Boolean] Whether you want a detailed report or not
21
+ # @return [Hash]
22
+ def self.compare(zendesk_client, location = 'data', verbose = false)
23
+ @from_repo = gather(zendesk_client, location)
24
+ @from_zendesk = Zendesk::TicketFields.list(zendesk_client)
25
+ @diffs = {
26
+ field_updates: [],
27
+ field_creates: [],
28
+ option_updates: [],
29
+ option_deletes: []
30
+ }
31
+ @from_repo.each do |repo|
32
+ zd = @from_zendesk.detect { |z| z.title == repo.title }
33
+ if zd.nil?
34
+ @diffs[:field_creates].push(repo)
35
+ unless repo.custom_field_options.nil?
36
+ repo.custom_field_options.each do |o|
37
+ @diffs[:option_updates].push({ "#{repo.title}" => o })
38
+ end
39
+ end
40
+ break
41
+ else
42
+ comparable_zd = zd.dup
43
+ comparable_repo = repo.dup
44
+ comparable_zd.id = nil
45
+ comparable_zd.custom_field_options = nil
46
+ comparable_repo.custom_field_options = nil
47
+ @diffs[:field_updates].push(update_object(repo, zd)) if to_clean_json(comparable_zd) != to_clean_json(comparable_repo)
48
+ detailed_diff(comparable_repo, comparable_zd) if verbose && to_clean_json(comparable_repo) != to_clean_json(comparable_zd)
49
+ next if repo.custom_field_options.nil?
50
+
51
+ zd_options = @from_zendesk.detect { |z| z.title == repo.title }.custom_field_options
52
+ repo.custom_field_options.map! { |o| Zendesk::TicketFieldOptions.new(o) } unless repo.custom_field_options.first.is_a? Object
53
+ repo.custom_field_options.each do |repo_option|
54
+ repo_option.position = repo.custom_field_options.index(repo_option) if repo_option.position.nil?
55
+ zd_option = zd_options.detect { |zd_o| zd_o.name == repo_option.name }
56
+ if zd_option.nil? || to_clean_json(zd_option) != to_clean_json(repo_option)
57
+ @diffs[:option_updates].push({ "#{repo.title}" => repo_option })
58
+ end
59
+ end
60
+ zd_options.each do |zd_option|
61
+ repo_option = repo.custom_field_options.detect { |rp_o| rp_o.name == zd_option.name }
62
+ if repo_option.nil?
63
+ @diffs[:option_deletes].push({ "#{repo.title}" => zd_option })
64
+ end
65
+ end
66
+ end
67
+ end
68
+ report_diffs if verbose
69
+ @diffs
70
+ end
71
+
72
+ ##
73
+ # Outputs a comparison report
74
+ #
75
+ # @author Jason Colyer
76
+ # @since 1.0.12
77
+ def self.report_diffs
78
+ puts 'Compare report:'
79
+ puts "- Field Creates: #{@diffs[:field_creates].count}"
80
+ puts "- Field Updates: #{@diffs[:field_updates].count}"
81
+ puts "- Option Updates: #{@diffs[:option_updates].count}"
82
+ puts "- Option Deletes: #{@diffs[:option_deletes].count}"
83
+ end
84
+
85
+ ##
86
+ # Outputs a comparison report
87
+ #
88
+ # @author Jason Colyer
89
+ # @since 1.0.12
90
+ # @param repo [Object] An instance of {Readiness::Zendesk::TicketFields}
91
+ # @param zendesk [Object] An instance of {Readiness::Zendesk::TicketFields}
92
+ def self.detailed_diff(repo, zendesk)
93
+ puts "Detailed diff of #{repo.title}"
94
+ repo.instance_variables.each do |v|
95
+ next if v == :@id
96
+
97
+ if repo.instance_variable_get(v) != zendesk.instance_variable_get(v)
98
+ puts "- #{v} Repo:"
99
+ pp repo.instance_variable_get(v)
100
+ puts " #{v} Zendesk:"
101
+ pp zendesk.instance_variable_get(v)
102
+ end
103
+ end
104
+ end
105
+
106
+ ##
107
+ # Creates an instance of {Readiness::Zendesk::TicketFields} to use for updates
108
+ #
109
+ # @author Jason Colyer
110
+ # @since 1.0.12
111
+ # @param repo [Object] An instance of {Readiness::Zendesk::TicketFields}
112
+ # @param zendesk [Object] An instance of {Readiness::Zendesk::TicketFields}
113
+ # @return [Object]
114
+ def self.update_object(repo, zendesk)
115
+ object = repo
116
+ object.id = zendesk.id
117
+ object
118
+ end
119
+
120
+ ##
121
+ # Parses repo ticket field files
122
+ #
123
+ # @author Jason Colyer
124
+ # @since 1.0.12
125
+ # @param client [Object] An instance of {Readiness::Zendesk::Client}
126
+ # @param location [String] The location (relative or absolute) of the repo's data folder
127
+ # @return [Array]
128
+ # @example
129
+ # require 'support_readiness'
130
+ # config = Readiness::Zendesk::Configuration.new
131
+ # config.username = 'alice@example.com'
132
+ # config.token = 'test123abc'
133
+ # config.url = 'https://example.zendesk.com/api/v2'
134
+ # client = Readiness::Zendesk::Client.new(config)
135
+ # repo = Readiness::Repos::TicketFields.gather(client, 'tickets/forms-and-fields/data/fields')
136
+ # pp repo.count
137
+ # # => 170
138
+ def self.gather(client, location = 'data')
139
+ @errors = []
140
+ @location = location
141
+ array = []
142
+ Dir["#{@location}/**/*.yaml"].each do |f|
143
+ object = YAML.safe_load_file(f)
144
+ validity_check(f, object)
145
+ object['id'] = nil
146
+ object['title_in_portal'] = (object['visible_in_portal'] ? object['title_in_portal'] : object['title'])
147
+ array.push(Zendesk::TicketFields.new(client, object))
148
+ end
149
+ repo_check(array)
150
+ report_errors unless @errors.count.zero?
151
+ array
152
+ end
153
+
154
+ ##
155
+ # Outputs an error report and exits with a status code of 1
156
+ #
157
+ # @author Jason Colyer
158
+ # @since 1.0.12
159
+ def self.report_errors
160
+ puts 'The following errors were found in the repo files:'
161
+ @errors.each do |e|
162
+ puts "- #{e}"
163
+ end
164
+ puts 'Rectify the errors and retry. We cannot proceed with those errors occurring.'
165
+ exit 1
166
+ end
167
+
168
+ ##
169
+ # Performs basic checks on a repo file
170
+ #
171
+ # @author Jason Colyer
172
+ # @since 1.0.12
173
+ # @param file [String] The path to the repo file
174
+ # @param object [Hash] The Hash derived from parsing a YAML file
175
+ def self.validity_check(file, object)
176
+ folder = file.split("#{@location}/").last.split('/').first
177
+ @errors.push("Missing type: #{file}") if object['type'].nil?
178
+ @errors.push("Missing title: #{file}") if object['title'].nil?
179
+ @errors.push("Missing position: #{file}") if object['position'].nil?
180
+ @errors.push("Inactive ticket field in active folder: #{file}") if folder == 'active' && !object['active']
181
+ @errors.push("Active ticket field in inactive folder: #{file}") if folder == 'inactive' && object['active']
182
+ end
183
+
184
+ ##
185
+ # Performs basic checks on the repo
186
+ #
187
+ # @author Jason Colyer
188
+ # @since 1.0.12
189
+ # @param objects [Array] The Array of Hashes derived from parsing the repo files
190
+ def self.repo_check(objects)
191
+ duplicate_names = objects.group_by { |o| o.title }.select { |k, v| v.size > 1 }.map(&:first)
192
+ unless duplicate_names.count.zero?
193
+ duplicate_names.each do |d|
194
+ @errors.push("The title '#{d}' is used in multiple files")
195
+ end
196
+ end
197
+ end
198
+ end
199
+ end
200
+ end
@@ -0,0 +1,200 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Defines the module Readiness.
4
+ module Readiness
5
+ # Defines the module Repos
6
+ module Repos
7
+ ##
8
+ # Defines the class TicketForms within the module {Readiness::Repos}.
9
+ #
10
+ # @author Jason Colyer
11
+ # @since 1.0.12
12
+ class TicketForms < Readiness::Client
13
+ ##
14
+ # Compares the repo ticket forms files to the Zendesk instance ticket forms
15
+ #
16
+ # @author Jason Colyer
17
+ # @since 1.0.12
18
+ # @param zendesk_client [Object] An instance of {Readiness::Zendesk::Client}
19
+ # @param location [String] The location (relative or absolute) of the repo's data folder
20
+ # @param verbose [Boolean] Whether you want a detailed report or not
21
+ # @return [Hash]
22
+ # @example
23
+ # require 'support_readiness'
24
+ # config = Readiness::Zendesk::Configuration.new
25
+ # config.username = 'alice@example.com'
26
+ # config.token = 'test123abc'
27
+ # config.url = 'https://example.zendesk.com/api/v2'
28
+ # client = Readiness::Zendesk::Client.new(config)
29
+ # diffs = Readiness::Repos::TicketForms.compare(client, 'tickets/forms-and-fields/data/forms', false)
30
+ # pp diffs[:updates.count]
31
+ # # => 1
32
+ # @example
33
+ # require 'support_readiness'
34
+ # config = Readiness::Zendesk::Configuration.new
35
+ # config.username = 'alice@example.com'
36
+ # config.token = 'test123abc'
37
+ # config.url = 'https://example.zendesk.com/api/v2'
38
+ # client = Readiness::Zendesk::Client.new(config)
39
+ # diffs = Readiness::Repos::Groups.compare(client, 'groups/data', true)
40
+ # # => Detailed diff of Support Ops
41
+ # # => - @description Repo:
42
+ # # => "For GitLab Support Operations"
43
+ # # => @description Zendesk:
44
+ # # => "For GitLab Support Ops"
45
+ # # => Compare report:
46
+ # # => - Creates: 0
47
+ # # => - Updates: 1
48
+ # pp diffs[:updates.count]
49
+ # # => 1
50
+ def self.compare(zendesk_client, location = 'data', verbose = false)
51
+ diffs = {
52
+ updates: [],
53
+ creates: []
54
+ }
55
+ from_repo = gather(location)
56
+ from_zendesk = Zendesk::TicketForms.list(zendesk_client)
57
+ from_repo.each do |repo|
58
+ zd = from_zendesk.detect { |z| z.name == repo.name }
59
+ if zd.nil?
60
+ diffs[:creates].push(repo)
61
+ else
62
+ comparable_zd = zd.dup
63
+ comparable_repo = repo.dup
64
+ comparable_zd.id = nil
65
+ comparable_zd.agent_conditions.sort_by! { |a| [a['parent_field_id'], a['value']] }
66
+ comparable_zd.agent_conditions.map { |a| a['child_fields'].sort_by! { |c| c['id'] }}
67
+ comparable_zd.end_user_conditions.sort_by! { |a| [a['parent_field_id'], a['value']] }
68
+ comparable_zd.end_user_conditions.map { |a| a['child_fields'].sort_by! { |c| c['id'] }}
69
+ comparable_repo.agent_conditions.sort_by! { |a| [a['parent_field_id'], a['value']] }
70
+ comparable_repo.agent_conditions.map { |a| a['child_fields'].sort_by! { |c| c['id'] }}
71
+ comparable_repo.end_user_conditions.sort_by! { |a| [a['parent_field_id'], a['value']] }
72
+ comparable_repo.end_user_conditions.map { |a| a['child_fields'].sort_by! { |c| c['id'] }}
73
+ diffs[:updates].push(update_object(repo, zd)) if to_clean_json(comparable_repo) != to_clean_json(comparable_zd)
74
+ detailed_diff(comparable_repo, comparable_zd) if verbose && to_clean_json(comparable_repo) != to_clean_json(comparable_zd)
75
+ end
76
+ end
77
+ report_diffs(diffs) if verbose
78
+ diffs
79
+ end
80
+
81
+ ##
82
+ # Outputs a comparison report
83
+ #
84
+ # @author Jason Colyer
85
+ # @since 1.0.12
86
+ # @param diffs [Hash] The returned value of {compare}
87
+ def self.report_diffs(diffs)
88
+ puts 'Compare report:'
89
+ puts "- Creates: #{diffs[:creates].count}"
90
+ puts "- Updates: #{diffs[:updates].count}"
91
+ end
92
+
93
+ ##
94
+ # Outputs a comparison report
95
+ #
96
+ # @author Jason Colyer
97
+ # @since 1.0.12
98
+ # @param repo [Object] An instance of {Readiness::Zendesk::TicketForms}
99
+ # @param zendesk [Object] An instance of {Readiness::Zendesk::TicketForms}
100
+ def self.detailed_diff(repo, zendesk)
101
+ puts "Detailed diff of #{repo.name}"
102
+ repo.instance_variables.each do |v|
103
+ next if v == :@id
104
+
105
+ if repo.instance_variable_get(v) != zendesk.instance_variable_get(v)
106
+ puts "- #{v} Repo:"
107
+ pp repo.instance_variable_get(v)
108
+ puts " #{v} Zendesk:"
109
+ pp zendesk.instance_variable_get(v)
110
+ end
111
+ end
112
+ end
113
+
114
+ ##
115
+ # Creates an instance of {Readiness::Zendesk::TicketForms} to use for updates
116
+ #
117
+ # @author Jason Colyer
118
+ # @since 1.0.12
119
+ # @param repo [Object] An instance of {Readiness::Zendesk::TicketForms}
120
+ # @param zendesk [Object] An instance of {Readiness::Zendesk::TicketForms}
121
+ # @return [Object]
122
+ def self.update_object(repo, zendesk)
123
+ object = repo
124
+ object.id = zendesk.id
125
+ object
126
+ end
127
+
128
+ ##
129
+ # Parses repo ticket form files
130
+ #
131
+ # @author Jason Colyer
132
+ # @since 1.0.12
133
+ # @param location [String] The location (relative or absolute) of the repo's data folder
134
+ # @return [Array]
135
+ # @example
136
+ # require 'support_readiness'
137
+ # repo = Readiness::Repos::TicketForms.gather('groups/data')
138
+ # pp repo.count
139
+ # # => 35
140
+ def self.gather(location = 'data')
141
+ @errors = []
142
+ @location = location
143
+ array = []
144
+ Dir["#{@location}/**/*.yaml"].each do |f|
145
+ object = YAML.safe_load_file(f)
146
+ validity_check(f, object)
147
+ object['id'] = nil
148
+ array.push(Zendesk::TicketForms.new(object))
149
+ end
150
+ repo_check(array)
151
+ report_errors unless @errors.count.zero?
152
+ array
153
+ end
154
+
155
+ ##
156
+ # Outputs an error report and exits with a status code of 1
157
+ #
158
+ # @author Jason Colyer
159
+ # @since 1.0.12
160
+ def self.report_errors
161
+ puts 'The following errors were found in the repo files:'
162
+ @errors.each do |e|
163
+ puts "- #{e}"
164
+ end
165
+ puts 'Rectify the errors and retry. We cannot proceed with those errors occurring.'
166
+ exit 1
167
+ end
168
+
169
+ ##
170
+ # Performs basic checks on a repo file
171
+ #
172
+ # @author Jason Colyer
173
+ # @since 1.0.12
174
+ # @param file [String] The path to the repo file
175
+ # @param object [Hash] The Hash derived from parsing a YAML file
176
+ def self.validity_check(file, object)
177
+ folder = file.split("#{@location}/").last.split('/').first
178
+ @errors.push("Missing name: #{file}") if object['name'].nil?
179
+ @errors.push("Missing position: #{file}") if object['position'].nil?
180
+ @errors.push("Inactive form in active folder: #{file}") if folder == 'active' && !object['active']
181
+ @errors.push("Active form in inactive folder: #{file}") if folder == 'inactive' && object['active']
182
+ end
183
+
184
+ ##
185
+ # Performs basic checks on the repo
186
+ #
187
+ # @author Jason Colyer
188
+ # @since 1.0.12
189
+ # @param objects [Array] The Array of Hashes derived from parsing the repo files
190
+ def self.repo_check(objects)
191
+ duplicate_names = objects.group_by { |o| o.name }.select { |k, v| v.size > 1 }.map(&:first)
192
+ unless duplicate_names.count.zero?
193
+ duplicate_names.each do |d|
194
+ @errors.push("The name '#{d}' is used in multiple files")
195
+ end
196
+ end
197
+ end
198
+ end
199
+ end
200
+ end