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,188 @@
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 Groups within the module {Readiness::Repos}.
9
+ #
10
+ # @author Jason Colyer
11
+ # @since 1.0.12
12
+ class Groups < Readiness::Client
13
+ ##
14
+ # Compares the repo automation files to the Zendesk instance groups
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::Groups.compare(client, 'groups/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::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::Groups.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.dup
63
+ comparable.id = nil
64
+ diffs[:updates].push(update_object(repo, zd)) if to_clean_json(repo) != to_clean_json(comparable)
65
+ detailed_diff(repo, comparable) if verbose && to_clean_json(repo) != to_clean_json(comparable)
66
+ end
67
+ end
68
+ report_diffs(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
+ # @param diffs [Hash] The returned value of {compare}
78
+ def self.report_diffs(diffs)
79
+ puts 'Compare report:'
80
+ puts "- Creates: #{diffs[:creates].count}"
81
+ puts "- Updates: #{diffs[:updates].count}"
82
+ end
83
+
84
+ ##
85
+ # Outputs a comparison report
86
+ #
87
+ # @author Jason Colyer
88
+ # @since 1.0.12
89
+ # @param repo [Object] An instance of {Readiness::Zendesk::Groups}
90
+ # @param zendesk [Object] An instance of {Readiness::Zendesk::Groups}
91
+ def self.detailed_diff(repo, zendesk)
92
+ puts "Detailed diff of #{repo.title}"
93
+ repo.instance_variables.each do |v|
94
+ next if v == :@id
95
+
96
+ if repo.instance_variable_get(v) != zendesk.instance_variable_get(v)
97
+ puts "- #{v} Repo:"
98
+ pp repo.instance_variable_get(v)
99
+ puts " #{v} Zendesk:"
100
+ pp zendesk.instance_variable_get(v)
101
+ end
102
+ end
103
+ end
104
+
105
+ ##
106
+ # Creates an instance of {Readiness::Zendesk::Groups} to use for updates
107
+ #
108
+ # @author Jason Colyer
109
+ # @since 1.0.12
110
+ # @param repo [Object] An instance of {Readiness::Zendesk::Groups}
111
+ # @param zendesk [Object] An instance of {Readiness::Zendesk::Groups}
112
+ # @return [Object]
113
+ def self.update_object(repo, zendesk)
114
+ object = repo
115
+ object.id = zendesk.id
116
+ object
117
+ end
118
+
119
+ ##
120
+ # Parses repo group files
121
+ #
122
+ # @author Jason Colyer
123
+ # @since 1.0.12
124
+ # @param location [String] The location (relative or absolute) of the repo's data folder
125
+ # @return [Array]
126
+ # @example
127
+ # require 'support_readiness'
128
+ # repo = Readiness::Repos::Groups.gather('groups/data')
129
+ # pp repo.count
130
+ # # => 35
131
+ def self.gather(location = 'data')
132
+ @errors = []
133
+ @location = location
134
+ array = []
135
+ Dir["#{@location}/*.yaml"].each do |f|
136
+ object = YAML.safe_load_file(f)
137
+ validity_check(f, object)
138
+ object['id'] = nil
139
+ array.push(Zendesk::Groups.new(object))
140
+ end
141
+ repo_check(array)
142
+ report_errors unless @errors.count.zero?
143
+ array
144
+ end
145
+
146
+ ##
147
+ # Outputs an error report and exits with a status code of 1
148
+ #
149
+ # @author Jason Colyer
150
+ # @since 1.0.12
151
+ def self.report_errors
152
+ puts 'The following errors were found in the repo files:'
153
+ @errors.each do |e|
154
+ puts "- #{e}"
155
+ end
156
+ puts 'Rectify the errors and retry. We cannot proceed with those errors occurring.'
157
+ exit 1
158
+ end
159
+
160
+ ##
161
+ # Performs basic checks on a repo file
162
+ #
163
+ # @author Jason Colyer
164
+ # @since 1.0.12
165
+ # @param file [String] The path to the repo file
166
+ # @param object [Hash] The Hash derived from parsing a YAML file
167
+ def self.validity_check(file, object)
168
+ @errors.push("Missing name: #{file}") if object['name'].nil?
169
+ @errors.push("Deleted group file: #{file}") if object['deleted']
170
+ end
171
+
172
+ ##
173
+ # Performs basic checks on the repo
174
+ #
175
+ # @author Jason Colyer
176
+ # @since 1.0.12
177
+ # @param objects [Array] The Array of Hashes derived from parsing the repo files
178
+ def self.repo_check(objects)
179
+ duplicate_names = objects.group_by { |o| o.name }.select { |k, v| v.size > 1 }.map(&:first)
180
+ unless duplicate_names.count.zero?
181
+ duplicate_names.each do |d|
182
+ @errors.push("The name '#{d}' is used in multiple files")
183
+ end
184
+ end
185
+ end
186
+ end
187
+ end
188
+ end
@@ -0,0 +1,224 @@
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 Macros within the module {Readiness::Repos}.
9
+ #
10
+ # @author Jason Colyer
11
+ # @since 1.0.12
12
+ class Macros < Readiness::Client
13
+ ##
14
+ # Compares the repo automation files to the Zendesk instance macros
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::Macros.compare(client, 'macros/data', false)
30
+ # pp diffs[:updates.count]
31
+ # # => 5
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::Macros.compare(client, 'macros/data', true)
40
+ # # => Detailed diff of Status::Close::Close solved tickets after 7 days
41
+ # # => - @default Repo:
42
+ # # => false
43
+ # # => @default Zendesk:
44
+ # # => true
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::Macros.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.dup
63
+ comparable.id = nil
64
+ diffs[:updates].push(update_object(repo, zd)) if to_clean_json(repo) != to_clean_json(comparable)
65
+ detailed_diff(repo, comparable) if verbose && to_clean_json(repo) != to_clean_json(comparable)
66
+ end
67
+ end
68
+ report_diffs(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
+ # @param diffs [Hash] The returned value of {compare}
78
+ def self.report_diffs(diffs)
79
+ puts 'Compare report:'
80
+ puts "- Creates: #{diffs[:creates].count}"
81
+ puts "- Updates: #{diffs[:updates].count}"
82
+ end
83
+
84
+ ##
85
+ # Outputs a comparison report
86
+ #
87
+ # @author Jason Colyer
88
+ # @since 1.0.12
89
+ # @param repo [Object] An instance of {Readiness::Zendesk::Macros}
90
+ # @param zendesk [Object] An instance of {Readiness::Zendesk::Macros}
91
+ def self.detailed_diff(repo, zendesk)
92
+ puts "Detailed diff of #{repo.title}"
93
+ repo.instance_variables.each do |v|
94
+ next if v == :@id
95
+
96
+ if repo.instance_variable_get(v) != zendesk.instance_variable_get(v)
97
+ puts "- #{v} Repo:"
98
+ pp repo.instance_variable_get(v)
99
+ puts " #{v} Zendesk:"
100
+ pp zendesk.instance_variable_get(v)
101
+ end
102
+ end
103
+ end
104
+
105
+ ##
106
+ # Creates an instance of {Readiness::Zendesk::Macros} to use for updates
107
+ #
108
+ # @author Jason Colyer
109
+ # @since 1.0.12
110
+ # @param repo [Object] An instance of {Readiness::Zendesk::Macros}
111
+ # @param zendesk [Object] An instance of {Readiness::Zendesk::Macros}
112
+ # @return [Object]
113
+ def self.update_object(repo, zendesk)
114
+ object = repo
115
+ object.id = zendesk.id
116
+ object
117
+ end
118
+
119
+ ##
120
+ # Parses repo macro files
121
+ #
122
+ # @author Jason Colyer
123
+ # @since 1.0.12
124
+ # @param location [String] The location (relative or absolute) of the repo's data folder
125
+ # @return [Array]
126
+ # @example
127
+ # require 'support_readiness'
128
+ # repo = Readiness::Repos::Macros.gather('macros/data')
129
+ # pp repo.count
130
+ # # => 35
131
+ def self.gather(location = 'data')
132
+ @errors = []
133
+ @location = location
134
+ array = []
135
+ Dir["#{@location}/**/*.yaml"].each do |f|
136
+ object = YAML.safe_load_file(f)
137
+ object = convert_managed_content(object) if object['contains_managed_content']
138
+ validity_check(f, object)
139
+ object['id'] = nil
140
+ array.push(Zendesk::Macros.new(object))
141
+ end
142
+ repo_check(array)
143
+ report_errors unless @errors.count.zero?
144
+ array
145
+ end
146
+
147
+ ##
148
+ # Outputs an error report and exits with a status code of 1
149
+ #
150
+ # @author Jason Colyer
151
+ # @since 1.0.12
152
+ def self.report_errors
153
+ puts 'The following errors were found in the repo files:'
154
+ @errors.each do |e|
155
+ puts "- #{e}"
156
+ end
157
+ puts 'Rectify the errors and retry. We cannot proceed with those errors occurring.'
158
+ exit 1
159
+ end
160
+
161
+ ##
162
+ # Performs basic checks on a repo file
163
+ #
164
+ # @author Jason Colyer
165
+ # @since 1.0.12
166
+ # @param file [String] The path to the repo file
167
+ # @param object [Hash] The Hash derived from parsing a YAML file
168
+ def self.validity_check(file, object)
169
+ folder = file.split("#{@location}/").last.split('/').first
170
+ @errors.push("Missing title: #{file}") if object['title'].nil?
171
+ @errors.push("Inactive macro in active folder: #{file}") if folder == 'active' && !object['active']
172
+ @errors.push("Active macro in inactive folder: #{file}") if folder == 'inactive' && object['active']
173
+ end
174
+
175
+ ##
176
+ # Performs basic checks on the repo
177
+ #
178
+ # @author Jason Colyer
179
+ # @since 1.0.12
180
+ # @param objects [Array] The Array of Hashes derived from parsing the repo files
181
+ def self.repo_check(objects)
182
+ duplicate_names = objects.group_by { |o| o.title }.select { |k, v| v.size > 1 }.map(&:first)
183
+ unless duplicate_names.count.zero?
184
+ duplicate_names.each do |d|
185
+ @errors.push("The title '#{d}' is used in multiple files")
186
+ end
187
+ end
188
+ end
189
+
190
+ ##
191
+ # Performs conversions for a repo file if using managed content
192
+ #
193
+ # @author Jason Colyer
194
+ # @since 1.0.12
195
+ # @param object [Hash] The Hash derived from parsing a YAML file
196
+ def self.convert_managed_content(object)
197
+ path = "#{@location}/managed_content/#{object['active'] ? '' : 'in'}active/#{object['title'].gsub('::', '/')}.md"
198
+ handle_request_error(1, 'Repos', 404, { action: 'Get managed content', id: object['title'] }) unless File.exist?(path)
199
+ object['actions'].each_with_index do |action, index|
200
+ if action['value'].is_a?(String)
201
+ if action['value'] =~ /MANAGED_CONTENT/
202
+ if action['value'] == 'MANAGED_CONTENT'
203
+ object['actions'][index]['value'] = action['value'].gsub('MANAGED_CONTENT', File.read(path).chomp)
204
+ else
205
+ object['actions'][index]['value'] = action['value'].gsub('MANAGED_CONTENT', File.read(path).chomp.gsub("\n", '\\n'))
206
+ end
207
+ end
208
+ elsif action['value'].is_a?(Array)
209
+ action['value'].each_with_index do |value, sub_index|
210
+ if value =~ /MANAGED_CONTENT/
211
+ if value == 'MANAGED_CONTENT'
212
+ object['actions'][index]['value'][sub_index] = value.gsub('MANAGED_CONTENT', File.read(path).chomp)
213
+ else
214
+ object['actions'][index]['value'][sub_index] = value.gsub('MANAGED_CONTENT', File.read(path).chomp.gsub("\n", '\\n'))
215
+ end
216
+ end
217
+ end
218
+ end
219
+ end
220
+ object
221
+ end
222
+ end
223
+ end
224
+ end
@@ -0,0 +1,193 @@
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 OrganizationFields within the module {Readiness::Repos}.
9
+ #
10
+ # @author Jason Colyer
11
+ # @since 1.0.12
12
+ class OrganizationFields < Readiness::Client
13
+ ##
14
+ # Compares the repo automation files to the Zendesk instance organization 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
+ # @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::OrganizationFields.compare(client, 'organizations/fields/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::OrganizationFields.compare(client, 'organizations/fields/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::OrganizationFields.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.custom_field_options.map { |a| a.delete('raw_name') } unless comparable_zd.custom_field_options.nil?
66
+ diffs[:updates].push(update_object(repo, zd)) if to_clean_json(comparable_repo) != to_clean_json(comparable_zd)
67
+ detailed_diff(comparable_repo, comparable_zd) if verbose && to_clean_json(comparable_repo) != to_clean_json(comparable_zd)
68
+ end
69
+ end
70
+ report_diffs(diffs) if verbose
71
+ diffs
72
+ end
73
+
74
+ ##
75
+ # Outputs a comparison report
76
+ #
77
+ # @author Jason Colyer
78
+ # @since 1.0.12
79
+ # @param diffs [Hash] The returned value of {compare}
80
+ def self.report_diffs(diffs)
81
+ puts 'Compare report:'
82
+ puts "- Creates: #{diffs[:creates].count}"
83
+ puts "- Updates: #{diffs[:updates].count}"
84
+ end
85
+
86
+ ##
87
+ # Outputs a comparison report
88
+ #
89
+ # @author Jason Colyer
90
+ # @since 1.0.12
91
+ # @param repo [Object] An instance of {Readiness::Zendesk::OrganizationFields}
92
+ # @param zendesk [Object] An instance of {Readiness::Zendesk::OrganizationFields}
93
+ def self.detailed_diff(repo, zendesk)
94
+ puts "Detailed diff of #{repo.title}"
95
+ repo.instance_variables.each do |v|
96
+ next if v == :@id
97
+
98
+ if repo.instance_variable_get(v) != zendesk.instance_variable_get(v)
99
+ puts "- #{v} Repo:"
100
+ pp repo.instance_variable_get(v)
101
+ puts " #{v} Zendesk:"
102
+ pp zendesk.instance_variable_get(v)
103
+ end
104
+ end
105
+ end
106
+
107
+ ##
108
+ # Creates an instance of {Readiness::Zendesk::OrganizationFields} to use for updates
109
+ #
110
+ # @author Jason Colyer
111
+ # @since 1.0.12
112
+ # @param repo [Object] An instance of {Readiness::Zendesk::OrganizationFields}
113
+ # @param zendesk [Object] An instance of {Readiness::Zendesk::OrganizationFields}
114
+ # @return [Object]
115
+ def self.update_object(repo, zendesk)
116
+ object = repo
117
+ object.id = zendesk.id
118
+ object
119
+ end
120
+
121
+ ##
122
+ # Parses repo group files
123
+ #
124
+ # @author Jason Colyer
125
+ # @since 1.0.12
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
+ # repo = Readiness::Repos::OrganizationFields.gather('organizations/fields/data')
131
+ # pp repo.count
132
+ # # => 35
133
+ def self.gather(location = 'data')
134
+ @errors = []
135
+ @location = location
136
+ array = []
137
+ Dir["#{@location}/**/*.yaml"].each do |f|
138
+ object = YAML.safe_load_file(f)
139
+ validity_check(f, object)
140
+ object['id'] = nil
141
+ array.push(Zendesk::OrganizationFields.new(object))
142
+ end
143
+ repo_check(array)
144
+ report_errors unless @errors.count.zero?
145
+ array
146
+ end
147
+
148
+ ##
149
+ # Outputs an error report and exits with a status code of 1
150
+ #
151
+ # @author Jason Colyer
152
+ # @since 1.0.12
153
+ def self.report_errors
154
+ puts 'The following errors were found in the repo files:'
155
+ @errors.each do |e|
156
+ puts "- #{e}"
157
+ end
158
+ puts 'Rectify the errors and retry. We cannot proceed with those errors occurring.'
159
+ exit 1
160
+ end
161
+
162
+ ##
163
+ # Performs basic checks on a repo file
164
+ #
165
+ # @author Jason Colyer
166
+ # @since 1.0.12
167
+ # @param file [String] The path to the repo file
168
+ # @param object [Hash] The Hash derived from parsing a YAML file
169
+ def self.validity_check(file, object)
170
+ folder = file.split("#{@location}/").last.split('/').first
171
+ @errors.push("Missing title: #{file}") if object['title'].nil?
172
+ @errors.push("Missing position: #{file}") if object['position'].nil?
173
+ @errors.push("Inactive organization field in active folder: #{file}") if folder == 'active' && !object['active']
174
+ @errors.push("Active organization field in inactive folder: #{file}") if folder == 'inactive' && object['active']
175
+ end
176
+
177
+ ##
178
+ # Performs basic checks on the repo
179
+ #
180
+ # @author Jason Colyer
181
+ # @since 1.0.12
182
+ # @param objects [Array] The Array of Hashes derived from parsing the repo files
183
+ def self.repo_check(objects)
184
+ duplicate_names = objects.group_by { |o| o.title }.select { |k, v| v.size > 1 }.map(&:first)
185
+ unless duplicate_names.count.zero?
186
+ duplicate_names.each do |d|
187
+ @errors.push("The name '#{d}' is used in multiple files")
188
+ end
189
+ end
190
+ end
191
+ end
192
+ end
193
+ end