eco-helpers 3.0.18 → 3.0.20

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/CHANGELOG.md +34 -3
  4. data/eco-helpers.gemspec +3 -3
  5. data/lib/eco/api/common/loaders/config/session.rb +12 -0
  6. data/lib/eco/api/common/loaders/config/workflow/mailer.rb +17 -4
  7. data/lib/eco/api/common/loaders/config.rb +10 -2
  8. data/lib/eco/api/common/loaders/parser.rb +10 -0
  9. data/lib/eco/api/common/people/default_parsers/csv_parser.rb +21 -208
  10. data/lib/eco/api/common/people/default_parsers/helpers/expected_headers.rb +206 -0
  11. data/lib/eco/api/common/people/default_parsers/helpers/null_parsing.rb +36 -0
  12. data/lib/eco/api/common/people/default_parsers/helpers.rb +15 -0
  13. data/lib/eco/api/common/people/default_parsers/json_parser.rb +56 -0
  14. data/lib/eco/api/common/people/default_parsers/xls_parser.rb +13 -14
  15. data/lib/eco/api/common/people/default_parsers.rb +2 -0
  16. data/lib/eco/api/common/people/entry_factory.rb +15 -4
  17. data/lib/eco/api/common/session/sftp.rb +5 -0
  18. data/lib/eco/api/custom/mailer.rb +1 -0
  19. data/lib/eco/api/error.rb +4 -0
  20. data/lib/eco/api/session/batch/job.rb +14 -16
  21. data/lib/eco/api/session/batch/jobs.rb +6 -8
  22. data/lib/eco/api/session/batch/launcher/mode_size.rb +5 -2
  23. data/lib/eco/api/session/batch/launcher/retry.rb +6 -1
  24. data/lib/eco/api/session/batch/launcher/status_handling.rb +4 -2
  25. data/lib/eco/api/session/batch/launcher.rb +3 -3
  26. data/lib/eco/api/session/config/api.rb +1 -0
  27. data/lib/eco/api/session/config/apis/one_off.rb +6 -6
  28. data/lib/eco/api/session/config/workflow.rb +16 -3
  29. data/lib/eco/api/session.rb +13 -7
  30. data/lib/eco/api/usecases/default/locations/tagtree_extract_case.rb +1 -0
  31. data/lib/eco/api/usecases/default/locations/tagtree_upload_case.rb +2 -0
  32. data/lib/eco/api/usecases/default/utils/cli/group_csv_cli.rb +26 -0
  33. data/lib/eco/api/usecases/default/utils/cli/json_to_csv_cli.rb +10 -0
  34. data/lib/eco/api/usecases/default/utils/cli/sort_csv_cli.rb +17 -0
  35. data/lib/eco/api/usecases/default/utils/cli/split_json_cli.rb +15 -0
  36. data/lib/eco/api/usecases/default/utils/group_csv_case.rb +213 -0
  37. data/lib/eco/api/usecases/default/utils/json_to_csv_case.rb +71 -0
  38. data/lib/eco/api/usecases/default/utils/sort_csv_case.rb +127 -0
  39. data/lib/eco/api/usecases/default/utils/split_json_case.rb +224 -0
  40. data/lib/eco/api/usecases/default/utils.rb +4 -0
  41. data/lib/eco/api/usecases/default_cases/samples/sftp_case.rb +22 -15
  42. data/lib/eco/api/usecases/ooze_cases/export_register_case.rb +6 -6
  43. data/lib/eco/api/usecases/ooze_samples/helpers/exportable_register.rb +1 -0
  44. data/lib/eco/api/usecases/ooze_samples/ooze_base_case.rb +1 -1
  45. data/lib/eco/api/usecases/ooze_samples/ooze_run_base_case.rb +8 -5
  46. data/lib/eco/cli_default/workflow.rb +10 -4
  47. data/lib/eco/csv/stream.rb +2 -0
  48. data/lib/eco/csv.rb +3 -2
  49. data/lib/eco/language/methods/delegate_missing.rb +4 -3
  50. data/lib/eco/version.rb +1 -1
  51. metadata +22 -9
@@ -0,0 +1,206 @@
1
+ module Eco::API::Common::People
2
+ class DefaultParsers
3
+ module Helpers
4
+ module ExpectedHeaders
5
+ include Eco::Language::AuxiliarLogger
6
+
7
+ private
8
+
9
+ def require_headers!(raw_headers)
10
+ abort("Missing headers in CSV") unless raw_headers&.any?
11
+
12
+ empty = []
13
+ raw_headers.each_with_index do |header, idx|
14
+ empty << idx if header.to_s.strip.empty?
15
+ end
16
+
17
+ abort("Empty headers in column(s): #{empty.join(', ')}") if empty.any?
18
+
19
+ true
20
+ end
21
+
22
+ def check_headers!(raw_headers, order_check: false) # rubocop:disable Metrics/AbcSize
23
+ unmatch = []
24
+ unmatch = unmatched_headers(raw_headers) if order_check
25
+ missing = missing_headers(raw_headers)
26
+ unknown = unknown_headers(raw_headers)
27
+
28
+ criteria = [unknown, missing[:direct], missing[:indirect], unmatch]
29
+ return if criteria.all?(&:empty?)
30
+
31
+ msg = "Detected possible HEADER / FIELD ISSUES !!!\n"
32
+
33
+ # requires exact match
34
+ unless unmatch.empty?
35
+ msg << "File headers/fields do NOT exactly match the expected:\n"
36
+ msg << " * Expected: #{expected_headers}\n"
37
+
38
+ expected, given = unmatch.first
39
+ msg << " * First unmatch => Given: '#{given}' where expected '#{expected}'\n"
40
+
41
+ missed = expected_headers - raw_headers
42
+
43
+ unless missed.empty?
44
+ msg << " * Missing headers/fields:\n"
45
+ msg << " - #{missed.join("\n - ")}\n"
46
+ end
47
+ end
48
+
49
+ msg << "Missing or Wrong HEADER names in the file:\n"
50
+ msg << " * UNKNOWN (or not used?): #{unknown}\n" unless unknown.empty?
51
+ msg << " * MISSING HEADER/FIELD: #{missing[:direct]}\n" unless missing[:direct].empty?
52
+
53
+ unless (data = missing[:indirect]).empty?
54
+ msg << " * MISSING INDIRECTLY:\n"
55
+
56
+ data.each do |ext, info|
57
+ msg << " - '#{ext}' => "
58
+ msg << (info[:attrs] || {}).map do |status, attrs|
59
+ if status == :inactive
60
+ "makes inactive: #{attrs}"
61
+ elsif status == :active
62
+ "there could be missing info in: #{attrs}"
63
+ end
64
+ end.compact.join("; ")
65
+
66
+ msg << "\n"
67
+ end
68
+ end
69
+
70
+ log(:warn) { msg }
71
+
72
+ msg = "There were issues identified on the file header/field names. Aborting..."
73
+ abort(msg) if options.dig(:input, :header_check, :must_be_valid)
74
+
75
+ sleep(2)
76
+ end
77
+
78
+
79
+ # @return [Hash] with missing `:direct` and `:indirect` attrs, where
80
+ # - `:direct` [Array] refers to direct attrs
81
+ # - `:indirect` [Hash] refers to indirect attrs that are `:active` or `:inactive`.
82
+ def missing_headers(raw_headers) # rubocop:disable Metrics/AbcSize
83
+ int_head = internal_present_or_active(raw_headers)
84
+
85
+ external = raw_headers.select do |e|
86
+ i = fields_mapper.to_internal(e)
87
+ int_head.include?(i)
88
+ end
89
+
90
+ ext_present = present_internal_expected_headers(int_head) | external
91
+ ext_miss = expected_headers - ext_present
92
+
93
+ {
94
+ direct: [],
95
+ indirect: {}
96
+ }.tap do |missing|
97
+ ext_miss.each do |ext|
98
+ next unless (int = fields_mapper.to_internal(ext))
99
+
100
+ missing[:direct] << ext if all_internal_attrs.include?(int)
101
+
102
+ related_attrs_requirements = required_attrs.values.select do |req|
103
+ dep = req.dependant?(int)
104
+ affects = dep && !int_head.include?(int)
105
+ in_header = int_head.include?(req.attr)
106
+ affects || (dep && !in_header)
107
+ end
108
+
109
+ next if related_attrs_requirements.empty?
110
+
111
+ data = missing[:indirect][ext] = {}
112
+ data[:int] = int
113
+ data[:attrs] = {}
114
+
115
+ related_attrs_requirements.each_with_object(data[:attrs]) do |req, attrs|
116
+ status = req.active?(*int_head) ? :active : :inactive
117
+ attrs[status] ||= []
118
+ attrs[status] << req.attr
119
+ end
120
+ end
121
+ end
122
+ end
123
+
124
+
125
+ # The input file header names as expected
126
+ def expected_headers
127
+ @expected_headers ||= fields_mapper.list(:external).compact.uniq
128
+ end
129
+
130
+ def present_internal_expected_headers(internal_headers)
131
+ expected_headers.select do |ext|
132
+ int = fields_mapper.to_internal(ext)
133
+ internal_headers.include?(int)
134
+ end
135
+ end
136
+
137
+ def unmatched_headers(raw_headers)
138
+ expected_headers.zip(raw_headers).reject do |(expected, given)|
139
+ expected == given
140
+ end
141
+ end
142
+
143
+ def unknown_headers(raw_headers)
144
+ (raw_headers - expected_headers) - all_internal_attrs
145
+ end
146
+
147
+ def fields_mapper
148
+ session.fields_mapper
149
+ end
150
+
151
+ def required_attrs
152
+ @required_attrs ||= person_parser.required_attrs.to_h {|ra| [ra.attr, ra]}
153
+ end
154
+
155
+ def all_internal_attrs
156
+ @all_internal_attrs ||= [].tap do |int_attrs|
157
+ known_int_attrs = person_parser.all_attrs(include_defined_parsers: true)
158
+ known_int_attrs |= fields_mapper.list(:internal).compact
159
+ int_attrs.concat(known_int_attrs)
160
+ end
161
+ end
162
+
163
+ # Scopes what internal attrs appear in headers as they are
164
+ def internal_present_or_active(raw_headers, inactive_requirements = {}) # rubocop:disable Metrics/AbcSize
165
+ # internal attrs that are not being mapped
166
+ int_all = all_internal_attrs.reject {|i| fields_mapper.external?(i)}
167
+ hint = raw_headers & int_all
168
+ hext = raw_headers - hint
169
+ int_present = hint + hext.map {|e| fields_mapper.to_internal(e)}.compact
170
+
171
+ update_inactive = proc do
172
+ inactive_requirements.dup.each do |attr, req|
173
+ next unless req.active?(*int_present)
174
+
175
+ inactive_requirements.delete(attr)
176
+ int_present << attr
177
+ update_inactive.call
178
+ end
179
+ end
180
+
181
+ required_attrs.each_value do |req|
182
+ next if int_present.include?(req)
183
+
184
+ if req.active?(*int_present)
185
+ inactive_requirements.delete(req.attr)
186
+ int_present << req.attr
187
+ update_inactive.call
188
+ else
189
+ inactive_requirements[req.attr] = req
190
+ end
191
+ end
192
+
193
+ int_present
194
+ end
195
+
196
+ def person_parser
197
+ session.entry_factory.person_parser
198
+ end
199
+
200
+ def abort(msg)
201
+ super(msg, raising: false) if defined?(super)
202
+ end
203
+ end
204
+ end
205
+ end
206
+ end
@@ -0,0 +1,36 @@
1
+ module Eco::API::Common::People
2
+ class DefaultParsers
3
+ module Helpers
4
+ module NullParsing
5
+ private
6
+
7
+ def parse_null(value)
8
+ return if null?(value)
9
+ return parse_null_on_hash(value) if value.is_a?(Hash)
10
+ return value unless value.is_a?(Array)
11
+
12
+ value.map {|val| parse_null(val)}
13
+ end
14
+
15
+ def parse_null_on_hash(value)
16
+ return value unless value.is_a?(Hash)
17
+
18
+ value.dup do |out|
19
+ value.each do |key, val|
20
+ next out.delete(key) unless (out[key] = parse_null(val))
21
+ end
22
+ end
23
+ end
24
+
25
+ def null?(value)
26
+ return true if value.nil?
27
+ return false unless value.is_a?(String)
28
+ return true if value.strip.to_s.empty?
29
+
30
+ str = value.strip.upcase
31
+ ['NULL'].any? {|token| str == token}
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,15 @@
1
+ require_relative 'helpers/expected_headers'
2
+ require_relative 'helpers/null_parsing'
3
+
4
+ module Eco
5
+ module API
6
+ module Common
7
+ module People
8
+ class DefaultParsers
9
+ module Helpers
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,56 @@
1
+ class Eco::API::Common::People::DefaultParsers::JsonParser < Eco::API::Common::Loaders::Parser
2
+ attribute :json
3
+
4
+ include Eco::API::Common::People::DefaultParsers::Helpers::ExpectedHeaders
5
+ include Eco::API::Common::People::DefaultParsers::Helpers::NullParsing
6
+
7
+ def parser(filename, deps)
8
+ parse_json_file(filename).tap do |data|
9
+ # Don't enable header checks for now
10
+ next
11
+
12
+ puts 'Identifying unified json object keys...'
13
+ raw_headers = data.each_with_object([]) do |item, head|
14
+ head.concat(item.keys - head)
15
+ end
16
+
17
+ require_headers!(raw_headers)
18
+
19
+ next unless deps[:check_headers]
20
+ next unless check_headers?
21
+
22
+ check_headers!(
23
+ data,
24
+ order_check: false
25
+ )
26
+ end.each_with_object([]) do |item, arr_hash|
27
+ item_hash = item.keys.each_with_object({}) do |attr, hash|
28
+ next if attr.to_s.strip.empty?
29
+
30
+ hash[attr.strip] = parse_null(item[attr])
31
+ end
32
+
33
+ arr_hash.push(item_hash)
34
+ end
35
+ end
36
+
37
+ def serializer(array_hash, _deps)
38
+ array_hash.to_json
39
+ end
40
+
41
+ private
42
+
43
+ def check_headers?
44
+ !options.dig(:input, :header_check, :skip)
45
+ end
46
+
47
+ def parse_json_file(filename)
48
+ fd = File.open(filename)
49
+ JSON.load fd # rubocop:disable Security/JSONLoad
50
+ rescue JSON::ParserError => err
51
+ log(:error) { "Parsing error on file '#{filename}'" }
52
+ raise err
53
+ ensure
54
+ fd&.close
55
+ end
56
+ end
@@ -2,12 +2,9 @@ class Eco::API::Common::People::DefaultParsers::XLSParser < Eco::API::Common::Lo
2
2
  attribute :xls
3
3
 
4
4
  attr_accessor :already_required
5
- attr_reader :file
6
5
 
7
- def parser(file, _deps)
8
- @file = file
9
- rows.tap do |rws|
10
- @file = nil
6
+ def parser(filename, _deps)
7
+ rows(file: filename).tap do |rws|
11
8
  rws.each do |row|
12
9
  to_string!(row)
13
10
  end
@@ -22,13 +19,14 @@ class Eco::API::Common::People::DefaultParsers::XLSParser < Eco::API::Common::Lo
22
19
 
23
20
  def to_string!(row)
24
21
  row.transform_values! do |val|
25
- next nil unless val
22
+ next unless val
26
23
  next val if val.is_a?(String)
24
+
27
25
  val.to_s
28
26
  end
29
27
  end
30
28
 
31
- def headers
29
+ def expected_headers
32
30
  log(:warn) {
33
31
  "Headers detection is using your fields_map.json file (native behaviour)"
34
32
  }
@@ -39,30 +37,31 @@ class Eco::API::Common::People::DefaultParsers::XLSParser < Eco::API::Common::Lo
39
37
  0
40
38
  end
41
39
 
42
- def workbook
40
+ def workbook(file)
43
41
  require_reading_libs!
44
42
  Roo::Spreadsheet.open(file)
45
43
  end
46
44
 
47
- def spreadheet(name_or_index = sheet_name)
48
- workbook.sheet(name_or_index)
45
+ def spreadheet(name_or_index = sheet_name, file:)
46
+ workbook(file).sheet(name_or_index)
49
47
  end
50
48
 
51
- def rows(target = headers)
52
- spreadheet.parse(header_search: target, clean: true)
49
+ def rows(target = expected_headers, file:)
50
+ spreadheet(file: file).parse(header_search: target, clean: true)
53
51
  rescue Roo::HeaderRowNotFoundError => e
54
52
  missing = JSON.parse(e.message)
55
53
 
56
54
  log(:warn) {
57
- "The input file is missing these headers: #{missing}"
55
+ "The input file is missing these expected headers: #{missing}"
58
56
  }
59
57
 
60
58
  present = target - missing
61
- rows(present)
59
+ rows(present, file: file)
62
60
  end
63
61
 
64
62
  def require_reading_libs!
65
63
  return if already_required
64
+
66
65
  require 'roo'
67
66
  require 'roo-xls'
68
67
  self.already_required = true
@@ -12,6 +12,7 @@ module Eco
12
12
  end
13
13
  end
14
14
 
15
+ require_relative 'default_parsers/helpers'
15
16
  require_relative 'default_parsers/select_parser'
16
17
  require_relative 'default_parsers/boolean_parser'
17
18
  require_relative 'default_parsers/numeric_parser'
@@ -22,4 +23,5 @@ require_relative 'default_parsers/freemium_parser'
22
23
  require_relative 'default_parsers/policy_groups_parser'
23
24
  require_relative 'default_parsers/login_providers_parser'
24
25
  require_relative 'default_parsers/csv_parser'
26
+ require_relative 'default_parsers/json_parser'
25
27
  require_relative 'default_parsers/xls_parser'
@@ -28,6 +28,7 @@ module Eco
28
28
  # to translate external names into internal ones and _vice versa_.
29
29
  def initialize(e, schema:, person_parser: nil, default_parser: nil, attr_map: nil)
30
30
  super(e)
31
+
31
32
  msg = "Constructor needs a PersonSchema. Given: #{schema.class}"
32
33
  fatal msg unless schema.is_a?(Ecoportal::API::V1::PersonSchema)
33
34
 
@@ -133,9 +134,10 @@ module Eco
133
134
  out.concat(curr)
134
135
  end
135
136
  end
136
- # Get content only when it's not :xls
137
+
138
+ # Get content only when it's not :xls, nor :json
137
139
  # note: even if content was provided, file takes precedence
138
- if (format != :xls) && file # rubocop:disable Style/IfUnlessModifier
140
+ if get_content?(format) && file # rubocop:disable Style/IfUnlessModifier
139
141
  content = get_file_content(file, encoding: encoding)
140
142
  end
141
143
 
@@ -166,8 +168,10 @@ module Eco
166
168
  end
167
169
  end.tap do |out_array|
168
170
  start_from_two = (format == :csv) || format == :xls
169
- out_array.each_with_index do |entry_hash, i|
170
- entry_hash["idx"] = start_from_two ? i + 2 : i + 1
171
+ first_idx = start_from_two ? 2 : 1
172
+
173
+ out_array.each.with_index(first_idx) do |entry_hash, idx|
174
+ entry_hash["idx"] = idx
171
175
  entry_hash["source_file"] = file
172
176
  end
173
177
  end
@@ -222,6 +226,13 @@ module Eco
222
226
 
223
227
  private
224
228
 
229
+ def get_content?(format)
230
+ return false if format == :xls
231
+ return false if format == :json
232
+
233
+ true
234
+ end
235
+
225
236
  def abort(message)
226
237
  log(:error) { message }
227
238
  exit(1)
@@ -8,6 +8,7 @@ module Eco
8
8
  def initialize(enviro:)
9
9
  invalid_env = enviro && !enviro.is_a?(Eco::API::Common::Session::Environment)
10
10
  raise "Required Environment object (enviro:). Given: #{enviro}" if invalid_env
11
+
11
12
  @enviro = enviro
12
13
  end
13
14
 
@@ -103,6 +104,7 @@ module Eco
103
104
  def download(files, local_folder: nil, &block)
104
105
  puts "Creating local files:"
105
106
  created_files = []
107
+
106
108
  [files].flatten.compact.map do |fullname|
107
109
  basename = windows_basename(fullname)
108
110
  dest_fullname = File.join(local_folder || ".", basename)
@@ -110,6 +112,7 @@ module Eco
110
112
  created_files << dest_fullname
111
113
  sftp_session.download(fullname, dest_fullname)
112
114
  end.each(&:wait)
115
+
113
116
  # run SSH event loop while dw.active?
114
117
  created_files.tap { created_files.each(&block) }
115
118
  end
@@ -155,9 +158,11 @@ module Eco
155
158
  def windows_basename(remote_fullname)
156
159
  dir_sep = /[\\\/]/
157
160
  patr_re = /[<>:\\\/|?*]/
161
+
158
162
  parts = remote_fullname.split(dir_sep).map do |node|
159
163
  node.gsub(patr_re, '_')
160
164
  end
165
+
161
166
  local_fullname = File.join(*parts)
162
167
  File.basename(local_fullname)
163
168
  end
@@ -5,5 +5,6 @@
5
5
  # end
6
6
  class Eco::API::Custom::Mailer < Eco::API::Common::Loaders::Workflow::Mailer
7
7
  extend Eco::Language::Klass::WhenInherited
8
+
8
9
  when_inherited(&config_block)
9
10
  end
data/lib/eco/api/error.rb CHANGED
@@ -96,9 +96,11 @@ module Eco
96
96
  end.sort do |k_1, k_2|
97
97
  next -1 if k_2 < k_1
98
98
  next 1 if k_1 < k_2
99
+
99
100
  0
100
101
  end.tap do |siblings|
101
102
  siblings.delete(Unclassified)
103
+
102
104
  if direct
103
105
  siblings.reject! do |si|
104
106
  siblings.any? {|s| si < s}
@@ -120,8 +122,10 @@ module Eco
120
122
 
121
123
  descendants(direct: true).reverse.each do |klass|
122
124
  next unless klass.err_match?(err_msg)
125
+
123
126
  type = klass
124
127
  next unless klass.descendants?(direct: true)
128
+
125
129
  type = klass.get_type(err_msg, first: false) || type
126
130
  end
127
131
 
@@ -217,6 +217,7 @@ module Eco
217
217
  elsif !pqueue.empty?
218
218
  req_backup = as_update(pqueue, add_feedback: false)
219
219
  backup_update(req_backup)
220
+
220
221
  log(:debug) {
221
222
  "Job ('#{name}':#{type}): going to launch batch against #{pqueue.count} entries"
222
223
  }
@@ -246,28 +247,25 @@ module Eco
246
247
  # 3. error messages in case they were errors from the server
247
248
  # @note if `launch` was not invoked, it specifies so
248
249
  # @return [String] the summary
249
- def summary # rubocop:disable Metrics/AbcSize
250
+ def summary
250
251
  [].tap do |msg|
251
- if pending?
252
- msg << "PENDING - Batch #{type.to_s.upcase} - job '#{name}' - length: #{@queue.length}"
253
- else
254
- msg << feedback.generate(requests, only_stats: true)
252
+ msg << "PENDING Job -------->\n" if pending?
253
+ msg << feedback.generate(requests, only_stats: true)
255
254
 
256
- if batch_policy && !batch_policy.compliant?(request_stats)
257
- msg << "Batch Policy Uncompliance:"
258
- msg << batch_policy.uncompliance(request_stats)
259
- end
260
-
261
- msg << status.errors.message if status
262
- msg << subjobs_summary
255
+ if batch_policy && !batch_policy.compliant?(request_stats)
256
+ msg << 'Batch Policy Uncompliance:'
257
+ msg << batch_policy.uncompliance(request_stats)
263
258
  end
259
+
260
+ msg << status.errors.message if status
261
+ msg << subjobs_summary
264
262
  end.join("\n")
265
263
  end
266
264
 
267
265
  private
268
266
 
269
267
  def subjobs_summary
270
- return "" unless subjobs.count.positive?
268
+ return '' unless subjobs.count.positive?
271
269
 
272
270
  [].tap do |msg|
273
271
  subjobs.map {|subjob| msg << subjob.summary}
@@ -431,7 +429,7 @@ module Eco
431
429
  next unless status.success?(entry)
432
430
 
433
431
  if type == :create && entry.respond_to?(:id=)
434
- entry.id = status[entry].body["id"].tap do |id|
432
+ entry.id = status[entry].body['id'].tap do |id|
435
433
  next unless id.to_s.strip.empty?
436
434
 
437
435
  ref = Eco::API::Session::Batch::Feedback.person_ref(entry)
@@ -503,9 +501,9 @@ module Eco
503
501
 
504
502
  # Keep a copy of the requests for future reference
505
503
  def backup_update(requests, simulate: false)
506
- dry_run = simulate ? "_dry_run" : ""
504
+ dry_run = simulate ? '_dry_run' : ''
507
505
  dir = config.people.requests_folder
508
- filename = name.split(" ").join("-").gsub(/[=\\\/><,"-]+/, "_") # rubocop:disable Style/RedundantArgument
506
+ filename = name.split(' ').join('-').gsub(/[=\\\/><,"-]+/, "_") # rubocop:disable Style/RedundantArgument
509
507
  file = File.join(dir, "#{type}_data_#{filename}#{dry_run}.json")
510
508
  file_manager.save_json(requests, file, :timestamp)
511
509
  end
@@ -81,7 +81,7 @@ module Eco
81
81
  end
82
82
 
83
83
  def pending?
84
- any? {|job| job.pending?}
84
+ any?(&:pending?)
85
85
  end
86
86
 
87
87
  # Launches every `Batch::Job` in the group.
@@ -108,19 +108,17 @@ module Eco
108
108
  end
109
109
  end
110
110
 
111
- def status
111
+ def status(&block)
112
112
  if block_given?
113
- status.each do |job, job_status|
114
- yield(job, job_status)
115
- end
113
+ status.each(&block)
116
114
  self
117
- else # rubocop:disable Naming/MemoizedInstanceVariableName
118
- @jobs_status ||= {}
115
+ else
116
+ @jobs_status ||= {} # rubocop:disable Naming/MemoizedInstanceVariableName
119
117
  end
120
118
  end
121
119
 
122
120
  def errors?
123
- any? {|job| job.errors?}
121
+ any?(&:errors?)
124
122
  end
125
123
 
126
124
  def summary
@@ -18,14 +18,17 @@ module Eco
18
18
  private
19
19
 
20
20
  # Swaps to batch endpoint on specific errors
21
- def batch_mode_on(*error_types, options: self.options, allow_job_mode: true, &block)
21
+ def batch_mode_on(*error_types, options: self.options, allow_job_mode: true)
22
+ msg = "Expecting block. Non given"
23
+ raise ArgumentError, msg unless block_given?
24
+
22
25
  in_job_mode = allow_job_mode && job_mode?(options)
23
26
 
24
27
  yield(in_job_mode, batch_size(options))
25
28
  rescue *error_types
26
29
  raise unless in_job_mode
27
30
 
28
- yield(false , batch_mode_size)
31
+ yield(false, batch_mode_size)
29
32
  end
30
33
 
31
34
  # MODE
@@ -25,7 +25,12 @@ module Eco
25
25
  explanation << "You have #{retries_left} retries left."
26
26
  question = " Do you want to retry (y/N)?"
27
27
 
28
- prompt_user(question, default: "Y", explanation: explanation, timeout: 10) do |response|
28
+ prompt_user(
29
+ question,
30
+ default: "Y",
31
+ explanation: explanation,
32
+ timeout: 10
33
+ ) do |response|
29
34
  raise unless response.upcase.start_with?("Y")
30
35
 
31
36
  puts "\nOkay... let's retry!"
@@ -6,14 +6,16 @@ module Eco
6
6
  module StatusHandling
7
7
  private
8
8
 
9
- def tap_status(enviro:, queue:, method:, status: nil, &block)
9
+ def tap_status(enviro:, queue:, method:, status: nil)
10
10
  status ||= Eco::API::Session::Batch::Status.new(
11
11
  enviro,
12
12
  queue: queue,
13
13
  method: method
14
14
  )
15
15
 
16
- status.tap(&block)
16
+ status.tap do
17
+ yield(status) if block_given?
18
+ end
17
19
  end
18
20
  end
19
21
  end