eco-helpers 2.6.0 → 2.6.2

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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +91 -1
  3. data/README.md +5 -0
  4. data/eco-helpers.gemspec +1 -1
  5. data/lib/eco/api/common/class_helpers.rb +1 -1
  6. data/lib/eco/api/common/loaders/base.rb +5 -0
  7. data/lib/eco/api/common/loaders/case_base.rb +0 -2
  8. data/lib/eco/api/common/loaders/config/workflow/mailer.rb +78 -0
  9. data/lib/eco/api/common/loaders/config/workflow.rb +11 -0
  10. data/lib/eco/api/common/loaders/config.rb +29 -0
  11. data/lib/eco/api/common/loaders/error_handler.rb +0 -2
  12. data/lib/eco/api/common/loaders/parser.rb +0 -1
  13. data/lib/eco/api/common/loaders/policy.rb +0 -2
  14. data/lib/eco/api/common/loaders.rb +1 -0
  15. data/lib/eco/api/common/session/mailer.rb +3 -1
  16. data/lib/eco/api/common/version_patches/exception.rb +2 -2
  17. data/lib/eco/api/common/version_patches/ruby3/object.rb +18 -0
  18. data/lib/eco/api/common/version_patches/ruby3.rb +1 -0
  19. data/lib/eco/api/common/version_patches.rb +3 -0
  20. data/lib/eco/api/custom/config.rb +10 -0
  21. data/lib/eco/api/custom/mailer.rb +9 -0
  22. data/lib/eco/api/custom/namespace.rb +2 -0
  23. data/lib/eco/api/custom/workflow.rb +9 -0
  24. data/lib/eco/api/custom.rb +3 -0
  25. data/lib/eco/api/session/batch/base_policy.rb +13 -5
  26. data/lib/eco/api/session/batch/job.rb +10 -7
  27. data/lib/eco/api/session/config/tagtree.rb +15 -1
  28. data/lib/eco/api/session/config/workflow.rb +94 -58
  29. data/lib/eco/api/session/config.rb +2 -2
  30. data/lib/eco/api/usecases/base_io.rb +50 -4
  31. data/lib/eco/api/usecases/cli/dsl.rb +23 -13
  32. data/lib/eco/api/usecases/default/locations/cli/tagtree_extract_cli.rb +5 -0
  33. data/lib/eco/api/usecases/default/locations/tagtree_extract_case.rb +12 -4
  34. data/lib/eco/api/usecases/graphql/helpers/location/base.rb +1 -2
  35. data/lib/eco/api/usecases/ooze_samples/helpers/creatable.rb +62 -0
  36. data/lib/eco/api/usecases/ooze_samples/helpers/rescuable.rb +59 -0
  37. data/lib/eco/api/usecases/ooze_samples/helpers.rb +2 -0
  38. data/lib/eco/api/usecases/ooze_samples/ooze_base_case.rb +2 -1
  39. data/lib/eco/api/usecases/ooze_samples/register_migration_case.rb +2 -26
  40. data/lib/eco/api/usecases/ooze_samples/register_update_case.rb +64 -47
  41. data/lib/eco/api/usecases/ooze_samples/target_oozes_update_case.rb +8 -0
  42. data/lib/eco/api/usecases/use_case.rb +12 -2
  43. data/lib/eco/assets.rb +2 -2
  44. data/lib/eco/cli_default/workflow.rb +102 -120
  45. data/lib/eco/data/locations/node_base/tag_validations.rb +19 -9
  46. data/lib/eco/data/locations/node_base/treeify.rb +193 -18
  47. data/lib/eco/data/locations/node_diff/nodes_diff.rb +11 -9
  48. data/lib/eco/data/locations/node_diff/selectors.rb +1 -1
  49. data/lib/eco/data/locations/node_level.rb +1 -1
  50. data/lib/eco/data/locations/node_plain/parsing.rb +1 -1
  51. data/lib/eco/data/locations/node_plain/serial.rb +1 -1
  52. data/lib/eco/data/locations/node_plain.rb +4 -3
  53. data/lib/eco/language/klass/when_inherited.rb +17 -0
  54. data/lib/eco/language/klass.rb +8 -0
  55. data/lib/eco/language/methods/delegate_missing.rb +28 -0
  56. data/lib/eco/language/methods/dsl_able.rb +25 -0
  57. data/lib/eco/language/methods.rb +9 -0
  58. data/lib/eco/language.rb +2 -0
  59. data/lib/eco/version.rb +1 -1
  60. metadata +18 -3
@@ -11,7 +11,8 @@ module Eco
11
11
  :usecases, :launch_jobs,
12
12
  {post_launch: [:usecases, :launch_jobs]},
13
13
  :report,
14
- :end, :close
14
+ :end,
15
+ :close
15
16
  ]
16
17
 
17
18
  class << self
@@ -34,12 +35,10 @@ module Eco
34
35
  klass.model = model[key]
35
36
  end
36
37
  end
37
-
38
38
  end
39
39
 
40
40
  self.model = WORKFLOW_MODEL
41
41
  attr_reader :config
42
- attr_reader :name
43
42
 
44
43
  def initialize(name = nil, _parent: self, config:)
45
44
  @config = config
@@ -55,6 +54,11 @@ module Eco
55
54
  @after = []
56
55
  end
57
56
 
57
+ def name(with_path: false)
58
+ return @name if !with_path || root?
59
+ [@_parent.name(with_path: true), @name].compact.join('.')
60
+ end
61
+
58
62
  # Has this stage run yet?
59
63
  # @note it does **not** include _sub-stages_ that run `before`
60
64
  # @return [Boolean] `true` if it has run, `false` otherwise
@@ -80,23 +84,26 @@ module Eco
80
84
  end
81
85
 
82
86
  # Used in **configuration** time **to configure** the _workflow_ of the target (sub)stage `key`
83
- # @note if a `block` is provided it will `yield` the target stage immediately
87
+ # @note
88
+ # 1. if a `block` is provided it will `yield` the target stage immediately
89
+ # 2. a `block` is only required when `key` has not been specified.
84
90
  # @param key [Symbol, nil] cases:
85
91
  # - if `key` is not provided, it targets the _current stage_
86
92
  # - if `key` is provided, it targets the specific _sub-stage_
87
93
  # @yield [stage_workflow] further _workflow_ configuration `for` the target stage `key`
88
94
  # @yieldparam stage_workflow [Eco::API::Session::Config::Workflow] the _target stage_ referred by `key`
89
- # @return [Eco::API::Session::Config::Workflow] the current stage object (to ease chainig).
95
+ # @return [Eco::API::Session::Config::Workflow]
96
+ # 1. if block is provided provided, it returns the **current stage** object (to ease chainig).
97
+ # 2. if block is not provided, it returns the **stage** referred by `key`
90
98
  def for(key = nil, &block)
91
- raise "A block should be given." unless block_given?
92
- if !key
93
- yield(self)
94
- else
95
- stage(key).for(&block)
99
+ raise ArgumentError, "With no 'key', a block should be given." unless key || block_given?
100
+ self.tap do
101
+ next yield(self) unless key
102
+ next stage(key).for(&block) if block_given?
103
+ return stage(key)
96
104
  end
97
- self
98
105
  end
99
- alias_method :open, :for
106
+ alias_method :with, :for
100
107
 
101
108
  # Used in **configuration** time **to define** the **behaviour** the target (sub)stage `key`
102
109
  # @note if a `block` is provided it will **not** `yield` the target stage immediately, but when the _workflow_ reaches the stage
@@ -109,7 +116,7 @@ module Eco
109
116
  # @yieldreturn [Eco::API::UseCases::BaseIO] the `io` input/output object carried througout all the _workflow_
110
117
  # @return [Eco::API::Session::Config::Workflow] the current stage object (to ease chainig).
111
118
  def on(key = nil, &block)
112
- raise "A block should be given." unless block
119
+ raise ArgumentError, "A block should be given." unless block_given?
113
120
  if !key
114
121
  @on = block
115
122
  else
@@ -129,7 +136,10 @@ module Eco
129
136
  @rescue = block
130
137
  self
131
138
  end
139
+ # Prevent reserved word clash on DSL
140
+ alias_method :exception, :rescue
132
141
 
142
+ # Called on `SystemExit` exception
133
143
  def exit_handle(&block)
134
144
  return @exit_handle unless block
135
145
  @exit_handle = block
@@ -149,7 +159,7 @@ module Eco
149
159
  # @yieldreturn [Eco::API::UseCases::BaseIO] `io` the input/output object carried througout all the _workflow_
150
160
  # @return [Eco::API::Session::Config::Workflow] the current stage object (to ease chainig).
151
161
  def before(key = nil, &block)
152
- raise "A block should be given." unless block
162
+ raise ArgumentError, "A block should be given." unless block_given?
153
163
  if !key
154
164
  @before.push(block)
155
165
  else
@@ -171,7 +181,7 @@ module Eco
171
181
  # @yieldreturn [Eco::API::UseCases::BaseIO] `io` the input/output object carried througout all the _workflow_
172
182
  # @return [Eco::API::Session::Config::Workflow] the current stage object (to ease chainig).
173
183
  def after(key = nil, &block)
174
- raise "A block should be given." unless block
184
+ raise ArgumentError, "A block should be given." unless block_given?
175
185
  if !key
176
186
  @after.push(block)
177
187
  else
@@ -192,7 +202,8 @@ module Eco
192
202
  # - it will **not** run the `callback` for `on` defined during the configuration time
193
203
  # - it will rather `yield` the target stage after all the `before` _callbacks_ have been run
194
204
  # - aside of this, the rest will be the same as when the _block_ is provided (see previous note)
195
- # @raise [ArgumentError] if the object returned by `before` and `after` callbacks is not an `Eco::API::UseCases::BaseIO`.
205
+ # @note [if the object returned by `before`, `after` and `run` callbacks is not an `Eco::API::UseCases::BaseIO`,
206
+ # the original `io` object will be returned instead.
196
207
  # @param key [Symbol, nil] cases:
197
208
  # - if `key` is not provided, it targets the _current stage_
198
209
  # - if `key` is provided, it targets the specific _sub-stage_
@@ -204,62 +215,87 @@ module Eco
204
215
  # @return [Eco::API::Session::Config::Workflow] the current stage object (to ease chainig).
205
216
  def run(key = nil, io:, &block)
206
217
  raise "Missing BaseIO object" unless io.is_a?(Eco::API::UseCases::BaseIO)
207
- begin
208
- if key
209
- io = stage(key).run(io: io, &block)
210
- elsif pending?
211
- @before.each do |c|
212
- io = c.call(self, io).tap do |i_o|
213
- unless i_o.is_a?(Eco::API::UseCases::BaseIO)
214
- msg = "Workflow callaback before('#{name}') should return Eco::API::UseCases::BaseIO object."
215
- msg += " Given #{i_o.class}"
216
- msg += " • Callback source location: '#{c.source_location}'"
217
- raise ArgumentError.new(msg)
218
- end
219
- end
220
- end
221
218
 
222
- unless skip?
223
- io.session.logger.debug("(Workflow: #{path}) running now")
224
- if block
225
- io = block.call(self, io)
226
- else
227
- existing_stages.each {|stg| io = stg.run(io: io)}
219
+ if key
220
+ io = io_result(io: io) do
221
+ stage(key).run(io: io, &block)
222
+ end
223
+ elsif pending?
224
+ @before.each do |c|
225
+ io = io_result(io: io) do
226
+ io.evaluate(self, io, &c)
227
+ end
228
+ end
228
229
 
229
- unless ready?
230
- msg = "(Workflow: #{path}) 'on' callback is not defined, nor block given"
231
- io.session.logger.debug(msg)
230
+ unless skip?
231
+ io.session.logger.debug("(Workflow: #{path}) running now")
232
+ if block
233
+ io = io_result(io: io) do
234
+ io.evaluate(self, io, &block)
235
+ end
236
+ else
237
+ existing_stages.each do |stg|
238
+ io = io_result(io: io) do
239
+ stg.run(io: io)
232
240
  end
233
- io = @on.call(self, io) if ready?
234
241
  end
235
- @pending = false
236
- end
237
242
 
238
- @after.each do |c|
239
- io = c.call(self, io).tap do |i_o|
240
- unless i_o.is_a?(Eco::API::UseCases::BaseIO)
241
- msg = "Workflow callaback after('#{name}') should return Eco::API::UseCases::BaseIO object."
242
- msg += " Given #{i_o.class}"
243
- msg += " • Callback source location: '#{c.source_location}'"
244
- raise ArgumentError.new(msg)
245
- end
243
+ unless ready?
244
+ msg = "(Workflow: #{path}) 'on' callback is not defined, nor block given"
245
+ io.session.logger.debug(msg)
246
246
  end
247
+ io = io_result(io: io) do
248
+ io.evaluate(self, io, &@on)
249
+ end
250
+ end
251
+ @pending = false
252
+ end
253
+
254
+ @after.each do |c|
255
+ io = io_result(io: io) do
256
+ io.evaluate(self, io, &c)
247
257
  end
248
258
  end
249
- rescue SystemExit => e
250
- self.exit_handle.call(e, io) if self.exit_handle
251
- exit e.status
252
- rescue Interrupt => i
253
- raise
254
- rescue Exception => e
255
- self.rescue.call(e, io) if self.rescue
256
- raise
257
259
  end
258
260
  io
261
+ rescue SystemExit => e
262
+ io = io_result(io: io) do
263
+ io.evaluate(e, io, &self.exit_handle)
264
+ end
265
+ exit e.status
266
+ rescue Interrupt => i
267
+ raise
268
+ rescue Exception => e
269
+ # raise unless self.rescue
270
+ io = io_result(io: io) do
271
+ io.evaluate(e, io, &self.rescue)
272
+ end
273
+ raise
274
+ ensure
275
+ @pending = false
259
276
  end
260
277
 
261
278
  protected
262
279
 
280
+ def root?
281
+ @_parent == self
282
+ end
283
+
284
+ # It ensures an `Eco::API::UseCases::BaseIO` is returned
285
+ # @note it always brings the IO to be a `BaseIO`.
286
+ # As the `output` and the type is captured, it just cleans usecase related
287
+ # logic from the object.
288
+ # @raise ArgumentError if `klass` isn't child of `Eco::API::UseCases::BaseIO`
289
+ # @return [Eco::API::UseCases::BaseIO] the `io` input/output object carried througout the _workflow_
290
+ def io_result(io:, klass: Eco::API::UseCases::BaseIO)
291
+ msg = "Expecting class to be child of Eco::API::UseCases::BaseIO. Given: #{klass}"
292
+ raise ErrorArgument, msg unless klass <= Eco::API::UseCases::BaseIO
293
+
294
+ result = yield
295
+ io = result if result.is_a?(klass)
296
+ io.instance_of?(klass) ? io : io.base
297
+ end
298
+
263
299
  def path
264
300
  return name if root?
265
301
  "#{@_parent.path}:#{name}"
@@ -367,10 +367,10 @@ module Eco
367
367
  end
368
368
 
369
369
  # @return [Eco::API::Session::Batch::Policies]
370
- def batch_policies
370
+ def batch_policies(&block)
371
371
  @batch_policies = self["batch_policies"] ||= Eco::API::Session::Batch::Policies.new("batch_policy")
372
372
  if block_given?
373
- yield(@batch_policies)
373
+ @batch_policies.evaluate(@batch_policies, &block)
374
374
  self
375
375
  else
376
376
  @batch_policies
@@ -5,6 +5,9 @@ module Eco
5
5
  class BaseIO < BaseCase
6
6
  @types = BaseCase.types
7
7
 
8
+ include Eco::Language::Methods::DslAble
9
+ include Eco::Language::AuxiliarLogger
10
+
8
11
  class MissingParameter < StandardError
9
12
  attr_reader :type, :required, :given
10
13
 
@@ -37,14 +40,14 @@ module Eco
37
40
  # @param people [Eco::API::Organization::People] people object.
38
41
  # @param session [Eco::API:Session]
39
42
  # @param options [Hash] hash with symbol keys (i.e. behaviour modifiers, cli trackers, filters, etc.)
40
- def initialize(type: nil, input: nil, people: nil, session:, options: {}, validate: true)
41
- @output = nil
43
+ def initialize(type: nil, input: nil, people: nil, session:, options: {}, output: nil, validate: true)
42
44
  self.type = type if type
43
45
 
44
46
  if self.type && validate
45
47
  validate_args(input: input, people: people, session: session, options: options)
46
48
  end
47
49
 
50
+ @output = output
48
51
  @input = input
49
52
  @people = people
50
53
  @session = session
@@ -57,10 +60,13 @@ module Eco
57
60
  @type = value
58
61
  end
59
62
 
60
- # Helper to obtain an `BaseIO` objcect from any child class.
63
+ # Helper to obtain an `BaseIO` object from any child class.
61
64
  # @return [Eco::API::UseCases::BaseIO]
62
65
  def base
63
- kargs = params(keyed: true).merge(type: self.type).slice(:type, :input, :people, :session, :options)
66
+ kargs = params(keyed: true).merge({
67
+ type: self.type,
68
+ output: self.output,
69
+ }).slice(:type, :input, :people, :session, :options, :output) # :validate <- ?
64
70
  Eco::API::UseCases::BaseIO.new(**kargs)
65
71
  end
66
72
 
@@ -73,6 +79,7 @@ module Eco
73
79
  people: self.people,
74
80
  session: self.session,
75
81
  options: self.options,
82
+ output: self.output,
76
83
  validate: true
77
84
  }
78
85
  self.class.new(**default.merge(kargs))
@@ -87,6 +94,45 @@ module Eco
87
94
  keyed ? kargs : kargs.values
88
95
  end
89
96
 
97
+ # Shortcut to run a usecase passing this `io` as parameter
98
+ # @note
99
+ # 1. It swaps `output` to `input` or `people` depending on `self.type`
100
+ # 2. does this, **before** the target `case_name` launch and **after
101
+ # @return [Eco::API::UseCases::BaseIO]
102
+ def process_case(case_name, case_type, **params)
103
+ session.process_case(case_name, io: chained, type: case_type, **params).chained
104
+ end
105
+
106
+ # Does the switch from output to result in a new IO object.
107
+ # @note if there isn't `output` it doesn't do the switch,
108
+ # provided that it preserves the target parameter
109
+ # (otherise it would blank it)
110
+ # @return [Eco::API::UseCases::BaseIO]
111
+ def chained(as: self.type)
112
+ base.tap do |io_base|
113
+ next unless io_base.output
114
+ case as
115
+ when :import
116
+ io_base.output_be_input!
117
+ when :filter
118
+ io_base.output_be_people!
119
+ when :transform, :sync, :export, :error_handler, :other
120
+ end
121
+ end
122
+ end
123
+
124
+ protected
125
+
126
+ def output_be_input!
127
+ @input, @output = output, nil
128
+ input
129
+ end
130
+
131
+ def output_be_people!
132
+ @people, @output = output, nil
133
+ people
134
+ end
135
+
90
136
  private
91
137
 
92
138
  def validate_args(input:, people:, session:, options:)
@@ -3,20 +3,29 @@ module Eco
3
3
  class UseCases
4
4
  class Cli
5
5
  module DSL
6
- # Links the usecase to the Cli via `option_case`
7
- def apply!(option_case = cli_name)
8
- cli_config_case(option_case)
9
- apply_options(option_case)
10
- applied!
6
+ # Links the usecase to the Cli via `arg_case`
7
+ def apply!(arg_case = cli_name)
8
+ #puts "DEFINING CLI for '#{arg_case}' via #{self}"
9
+ if applied?(arg_case)
10
+ puts "Warning: (#{self}) Tried to call again cli.apply! on '#{arg_case}'"
11
+ return self
12
+ end
13
+ cli_config_case(arg_case)
14
+ apply_options(arg_case)
15
+ applied!(arg_case)
11
16
  self
12
17
  end
13
18
 
14
- def applied?
15
- @applied || false
19
+ def applied
20
+ @applied ||= {}
21
+ end
22
+
23
+ def applied?(arg_case)
24
+ applied[arg_case] || false
16
25
  end
17
26
 
18
- def applied!
19
- @applied = true
27
+ def applied!(arg_case)
28
+ applied[arg_case] = true
20
29
  end
21
30
 
22
31
  attr_writer :usecase
@@ -48,6 +57,7 @@ module Eco
48
57
  end
49
58
 
50
59
  def callback(&block)
60
+ return @callback unless block_given?
51
61
  @callback = block
52
62
  end
53
63
 
@@ -64,14 +74,14 @@ module Eco
64
74
 
65
75
  private
66
76
 
67
- def apply_options(option_case)
77
+ def apply_options(arg_case)
68
78
  options.each do |_key, option|
69
- option.link_case(cli_config_case(option_case))
79
+ option.link_case(cli_config_case(arg_case))
70
80
  end
71
81
  end
72
82
 
73
- def cli_config_case(option_case = nil)
74
- @cli_config_case ||= usecases.add(option_case, type, desc, case_name: name, &callback)
83
+ def cli_config_case(arg_case = nil)
84
+ @cli_config_case ||= usecases.add(arg_case, type, desc, case_name: name, &callback)
75
85
  end
76
86
 
77
87
  def usecases(&block)
@@ -20,5 +20,10 @@ class Eco::API::UseCases::Default::Locations::TagtreeExtract
20
20
  add_option("-with-ancestors", "Include ancestors in tree csv/excel_tree") do |options|
21
21
  options.deep_merge!(output: {include: {ancestors: true}})
22
22
  end
23
+
24
+ add_option("-indent", "Custom indentation (i.e. \"++\")") do |options|
25
+ indent = SCR.get_arg("-indent", with_param: true) || ""
26
+ options.deep_merge!(output: {indent: indent})
27
+ end
23
28
  end
24
29
  end
@@ -17,7 +17,7 @@ class Eco::API::UseCases::Default::Locations::TagtreeExtract < Eco::API::UseCase
17
17
  when :excel_tree, :excel_nodes
18
18
  excel(output_filename) do |workbook|
19
19
  tag_trees.each do |tree|
20
- excel_sheet(workbook, tree.name.gsub(/\s+/, "_"), header: format == :excel_nodes) do |sheet|
20
+ excel_sheet(workbook, compact_name(tree.name), header: format == :excel_nodes) do |sheet|
21
21
  tree_extract(tree).each_with_index do |row, idx|
22
22
  sheet.append_row(row)
23
23
  end
@@ -26,7 +26,7 @@ class Eco::API::UseCases::Default::Locations::TagtreeExtract < Eco::API::UseCase
26
26
  end
27
27
  when :list, :nodes, :csv_tree, :json
28
28
  tag_trees.each do |tree|
29
- file(output_filename(tree.name.gsub(/\s+/, "_"))) do |fd|
29
+ file(output_filename(compact_name(tree.name))) do |fd|
30
30
  fd << tree_extract(tree)
31
31
  end
32
32
  end
@@ -38,6 +38,10 @@ class Eco::API::UseCases::Default::Locations::TagtreeExtract < Eco::API::UseCase
38
38
 
39
39
  private
40
40
 
41
+ def compact_name(str)
42
+ str.gsub(/\s+/, "_")[0..30]
43
+ end
44
+
41
45
  def str_node_attrs
42
46
  options.dig(:output, :attrs) || [:id]
43
47
  end
@@ -75,6 +79,10 @@ class Eco::API::UseCases::Default::Locations::TagtreeExtract < Eco::API::UseCase
75
79
  options.dig(:output, :format)&.to_sym || :list
76
80
  end
77
81
 
82
+ def indentation
83
+ options.dig(:output, :indent) || " "
84
+ end
85
+
78
86
  def output_file_format
79
87
  case format
80
88
  when :list; 'txt'
@@ -97,7 +105,7 @@ class Eco::API::UseCases::Default::Locations::TagtreeExtract < Eco::API::UseCase
97
105
  end
98
106
 
99
107
  def include_ancestors?
100
- options.dit(:output, :include, :ancestors)
108
+ options.dig(:output, :include, :ancestors)
101
109
  end
102
110
 
103
111
  def include_archived?
@@ -117,7 +125,7 @@ class Eco::API::UseCases::Default::Locations::TagtreeExtract < Eco::API::UseCase
117
125
  end
118
126
 
119
127
  # Transforms the input `tree` into a String list of indented nodes
120
- def to_indented_list(tree, level: 0, attrs: str_node_attrs, indent: " ")
128
+ def to_indented_list(tree, level: 0, attrs: str_node_attrs, indent: indentation)
121
129
  ''.tap do |result|
122
130
  out_str = nil
123
131
  sublevel = tree.top?? 0 : level + 1
@@ -23,8 +23,7 @@ module Eco::API::UseCases::GraphQL::Helpers::Location
23
23
  return unless tree
24
24
  latest_tree = tree if tree.is_a?(Eco::API::Organization::TagTree)
25
25
  if tree.respond_to?(:treeify)
26
- args = { enviro: session.enviro, id: tree.id, name: tree.name}
27
- latest_tree ||= Eco::API::Organization::TagTree.new(tree.treeify, **args)
26
+ latest_tree ||= Eco::API::Organization::TagTree.new(tree.treeify, id: tree.id, name: tree.name)
28
27
  end
29
28
  latest_tree.tap do |_tree|
30
29
  next unless latest_tree
@@ -0,0 +1,62 @@
1
+ module Eco
2
+ module API
3
+ class UseCases
4
+ class OozeSamples
5
+ module Helpers
6
+ # set of helpers to create entries from a template
7
+ module Creatable
8
+ module InstanceMethods
9
+ private
10
+
11
+ def creating_new_page(draft_reference = "new entry", template_id:)
12
+ page_id = nil
13
+ drafting_entry(template_id) do |draft|
14
+ yield(draft) if block_given?
15
+
16
+ if page_id = create_entry(draft, reference: draft_reference)
17
+ log(:info) { "Page '#{page_id}' created successfully -- #{draft_reference}" }
18
+ elsif options.dig(:dry_run)
19
+ log(:info) { "Simulated launch for #{draft_reference}" }
20
+ end
21
+ end
22
+ page_id
23
+ end
24
+
25
+ # @return [Page] a draft of `template_id` (still not saved)
26
+ def drafting_entry(template_id)
27
+ raise ArgumentError, "Expecting block, but not given" unless block_given?
28
+ draft = apiv2.pages.get_new(template_id)
29
+ yield(draft)
30
+ end
31
+
32
+ # Does the actual creation of the entry
33
+ def create_entry(draft, reference: "new entry from #{draft&.template_id}")
34
+ with_rescue(reference) do
35
+ if result = create_ooze(draft, template_id: draft.template_id)
36
+ return result.page_id
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ class << self
43
+ def included(base)
44
+ super
45
+ validate_base_type!(base)
46
+ base.include(InstanceMethods)
47
+ end
48
+
49
+ def validate_base_type!(base)
50
+ return super if defined?(super)
51
+ msg = "#{self} can only be included in Eco::API::UseCases::OozeSamples::RegisterUpdateCase"
52
+ msg << "\nCan't be included in #{base}"
53
+ raise LoadError, msg unless base <= Eco::API::UseCases::OozeSamples::RegisterUpdateCase
54
+ true
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,59 @@
1
+ module Eco
2
+ module API
3
+ class UseCases
4
+ class OozeSamples
5
+ module Helpers
6
+ module Rescuable
7
+ module InstanceMethods
8
+ private
9
+
10
+ # Helper to prevent script from stopping
11
+ def with_rescue(reference)
12
+ raise ArgumentError, "Expecting block, but not given" unless block_given?
13
+ yield
14
+ rescue StandardError => e
15
+ log(:error) {
16
+ [reference, e.message].join(' => \n')
17
+ }
18
+ lines = []
19
+ lines << "\nThere was an error. Choose one option:\n"
20
+ lines << " (C) - Continue/resume. Just ignore this one."
21
+ lines << " (A) - Abort. Just break this run."
22
+
23
+ session.prompt_user('Type one option (C/a):', explanation: lines.join("\n"), default: 'C') do |res|
24
+ res = res.upcase
25
+ case
26
+ when res.start_with?("A")
27
+ raise
28
+ else res.start_with?("C")
29
+ log(:warn) {
30
+ msg = "Script resumed after error..."
31
+ msg << "\n • #{reference}"
32
+ }
33
+ nil
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ class << self
40
+ def included(base)
41
+ super
42
+ validate_base_type!(base)
43
+ base.include(InstanceMethods)
44
+ end
45
+
46
+ def validate_base_type!(base)
47
+ return super if defined?(super)
48
+ msg = "#{self} can only be included in Eco::API::Common::Loaders::Base"
49
+ msg << "\nCan't be included in #{base}"
50
+ raise LoadError, msg unless base <= Eco::API::Common::Loaders::Base
51
+ true
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -1,5 +1,7 @@
1
1
  require_relative 'helpers/shortcuts'
2
2
  require_relative 'helpers/filters'
3
+ require_relative 'helpers/rescuable'
4
+ require_relative 'helpers/creatable'
3
5
 
4
6
  module Eco
5
7
  module API
@@ -4,6 +4,7 @@ class Eco::API::UseCases::OozeSamples::OozeBaseCase < Eco::API::Common::Loaders:
4
4
  type :other
5
5
 
6
6
  include Eco::API::UseCases::OozeSamples::Helpers
7
+ include Eco::API::UseCases::OozeSamples::Helpers::Rescuable
7
8
 
8
9
  attr_reader :target
9
10
 
@@ -145,7 +146,7 @@ class Eco::API::UseCases::OozeSamples::OozeBaseCase < Eco::API::Common::Loaders:
145
146
  # It fill update the ooze only if it's dirty (it carries changes)
146
147
  # @return [Boolean, Response] `false` if there was not request against the server, `Response` otherwise
147
148
  def update_ooze(ooze = target)
148
- if options[:simulate]
149
+ if dry_run?
149
150
  dry_run_feedback(ooze)
150
151
  false
151
152
  else