eco-helpers 2.5.10 → 2.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (136) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -2
  3. data/CHANGELOG.md +132 -4
  4. data/README.md +5 -0
  5. data/eco-helpers.gemspec +20 -16
  6. data/lib/eco/api/common/class_helpers.rb +1 -1
  7. data/lib/eco/api/common/loaders/base.rb +2 -9
  8. data/lib/eco/api/common/loaders/case_base.rb +0 -2
  9. data/lib/eco/api/common/loaders/config/workflow/mailer.rb +78 -0
  10. data/lib/eco/api/common/loaders/config/workflow.rb +11 -0
  11. data/lib/eco/api/common/loaders/config.rb +29 -0
  12. data/lib/eco/api/common/loaders/error_handler.rb +0 -2
  13. data/lib/eco/api/common/loaders/parser.rb +0 -1
  14. data/lib/eco/api/common/loaders/policy.rb +0 -2
  15. data/lib/eco/api/common/loaders/use_case.rb +27 -1
  16. data/lib/eco/api/common/loaders.rb +1 -0
  17. data/lib/eco/api/common/people/default_parsers.rb +2 -2
  18. data/lib/eco/api/common/people/person_entry.rb +3 -0
  19. data/lib/eco/api/common/people/person_entry_attribute_mapper.rb +111 -16
  20. data/lib/eco/api/common/session/base_session.rb +4 -0
  21. data/lib/eco/api/common/session/environment.rb +4 -0
  22. data/lib/eco/api/common/session/mailer.rb +3 -1
  23. data/lib/eco/api/common/session/sftp.rb +1 -1
  24. data/lib/eco/api/common/version_patches/exception.rb +2 -2
  25. data/lib/eco/api/common/version_patches/ruby3/object.rb +18 -0
  26. data/lib/eco/api/common/version_patches/ruby3.rb +1 -0
  27. data/lib/eco/api/common/version_patches.rb +3 -0
  28. data/lib/eco/api/custom/config.rb +10 -0
  29. data/lib/eco/api/custom/mailer.rb +9 -0
  30. data/lib/eco/api/custom/namespace.rb +2 -0
  31. data/lib/eco/api/custom/workflow.rb +9 -0
  32. data/lib/eco/api/custom.rb +3 -0
  33. data/lib/eco/api/organization/tag_tree.rb +20 -23
  34. data/lib/eco/api/session/batch/base_policy.rb +13 -5
  35. data/lib/eco/api/session/batch/job.rb +14 -11
  36. data/lib/eco/api/session/batch/jobs.rb +2 -2
  37. data/lib/eco/api/session/batch/jobs_groups.rb +2 -2
  38. data/lib/eco/api/session/config/files.rb +2 -2
  39. data/lib/eco/api/session/config/people.rb +2 -2
  40. data/lib/eco/api/session/config/sftp.rb +4 -0
  41. data/lib/eco/api/session/config/tagtree.rb +9 -8
  42. data/lib/eco/api/session/config/workflow.rb +95 -58
  43. data/lib/eco/api/session/config.rb +9 -2
  44. data/lib/eco/api/session.rb +17 -2
  45. data/lib/eco/api/usecases/base_io.rb +50 -4
  46. data/lib/eco/api/usecases/cli/dsl.rb +94 -0
  47. data/lib/eco/api/usecases/cli/option.rb +19 -0
  48. data/lib/eco/api/usecases/cli.rb +13 -0
  49. data/lib/eco/api/usecases/default/locations/cli/tagtree_extract_cli.rb +29 -0
  50. data/lib/eco/api/usecases/{default_cases → default/locations}/codes_to_tags_case.rb +1 -1
  51. data/lib/eco/api/usecases/{default_cases → default/locations}/create_tag_paths_case.rb +1 -1
  52. data/lib/eco/api/usecases/{default_cases → default/locations}/csv_to_tree_case.rb +1 -1
  53. data/lib/eco/api/usecases/default/locations/tagtree_extract_case.rb +181 -0
  54. data/lib/eco/api/usecases/default/locations.rb +15 -0
  55. data/lib/eco/api/usecases/{default_cases → default/people}/analyse_people_case.rb +1 -1
  56. data/lib/eco/api/usecases/{default_cases → default/people}/change_email_case.rb +1 -1
  57. data/lib/eco/api/usecases/default/people/clean_unknown_tags_case.rb +66 -0
  58. data/lib/eco/api/usecases/{default_cases → default/people}/clear_abilities_case.rb +1 -1
  59. data/lib/eco/api/usecases/{default_cases → default/people}/org_data_convert_case.rb +1 -1
  60. data/lib/eco/api/usecases/{default_cases → default/people}/refresh_case.rb +1 -1
  61. data/lib/eco/api/usecases/{default_cases → default/people}/reinvite_sync_case.rb +1 -1
  62. data/lib/eco/api/usecases/{default_cases → default/people}/reinvite_trans_case.rb +1 -1
  63. data/lib/eco/api/usecases/default/people/reinvite_trans_cli.rb +5 -0
  64. data/lib/eco/api/usecases/{default_cases → default/people}/restore_db_case.rb +1 -1
  65. data/lib/eco/api/usecases/{default_cases → default/people}/set_default_tag_case.rb +1 -1
  66. data/lib/eco/api/usecases/{default_cases → default/people}/supers_cyclic_identify_case.rb +1 -1
  67. data/lib/eco/api/usecases/{default_cases → default/people}/supers_hierarchy_case.rb +1 -1
  68. data/lib/eco/api/usecases/{default_cases → default/people}/switch_supervisor_case.rb +1 -1
  69. data/lib/eco/api/usecases/{default_cases → default/people}/transfer_account_case.rb +1 -1
  70. data/lib/eco/api/usecases/default/people.rb +25 -0
  71. data/lib/eco/api/usecases/default.rb +16 -0
  72. data/lib/eco/api/usecases/default_cases/samples/cli/sftp_cli.rb +46 -0
  73. data/lib/eco/api/usecases/default_cases/samples/sftp_case.rb +21 -9
  74. data/lib/eco/api/usecases/default_cases.rb +2 -30
  75. data/lib/eco/api/usecases/graphql/helpers/location/base.rb +1 -2
  76. data/lib/eco/api/usecases/graphql/utils/sftp.rb +1 -1
  77. data/lib/eco/api/usecases/ooze_samples/register_update_case.rb +3 -3
  78. data/lib/eco/api/usecases/use_case.rb +31 -7
  79. data/lib/eco/api/usecases/use_case_chain.rb +2 -2
  80. data/lib/eco/api/usecases.rb +4 -1
  81. data/lib/eco/assets.rb +3 -5
  82. data/lib/eco/cli/config/filters/people_filters.rb +0 -1
  83. data/lib/eco/cli/config/filters.rb +2 -6
  84. data/lib/eco/cli/config/help.rb +0 -1
  85. data/lib/eco/cli/config/input.rb +0 -1
  86. data/lib/eco/cli/config/options_set.rb +3 -4
  87. data/lib/eco/cli/config/use_cases.rb +13 -6
  88. data/lib/eco/cli/config.rb +4 -5
  89. data/lib/eco/cli/scripting/args_helpers.rb +1 -1
  90. data/lib/eco/cli/scripting/argument.rb +0 -1
  91. data/lib/eco/cli/scripting/arguments.rb +0 -2
  92. data/lib/eco/cli.rb +0 -1
  93. data/lib/eco/{cli/config/default → cli_default}/input_filters.rb +0 -1
  94. data/lib/eco/{cli/config/default → cli_default}/people_filters.rb +0 -1
  95. data/lib/eco/{cli/config/default → cli_default}/usecases.rb +2 -52
  96. data/lib/eco/cli_default/workflow.rb +171 -0
  97. data/lib/eco/cli_default.rb +13 -0
  98. data/lib/eco/csv/table.rb +0 -1
  99. data/lib/eco/data/files/encoding.rb +1 -1
  100. data/lib/eco/data/files/helpers.rb +1 -1
  101. data/lib/eco/data/locations/convert.rb +8 -4
  102. data/lib/eco/data/locations/node_base/csv_convert.rb +4 -4
  103. data/lib/eco/data/locations/node_base/tag_validations.rb +19 -9
  104. data/lib/eco/data/locations/node_base/treeify.rb +193 -18
  105. data/lib/eco/data/locations/node_level.rb +1 -1
  106. data/lib/eco/data/locations/node_plain/parsing.rb +1 -1
  107. data/lib/eco/data/locations/node_plain/serial.rb +1 -1
  108. data/lib/eco/data/locations/node_plain.rb +4 -3
  109. data/lib/eco/data/mapper.rb +6 -1
  110. data/lib/eco/language/klass/when_inherited.rb +17 -0
  111. data/lib/eco/language/klass.rb +8 -0
  112. data/lib/eco/language/methods/delegate_missing.rb +28 -0
  113. data/lib/eco/language/methods/dsl_able.rb +25 -0
  114. data/lib/eco/language/methods.rb +9 -0
  115. data/lib/eco/language.rb +2 -0
  116. data/lib/eco/version.rb +1 -1
  117. metadata +169 -79
  118. data/lib/eco/api/usecases/default_cases/abstract_policygroup_abilities_case.rb +0 -160
  119. data/lib/eco/api/usecases/default_cases/append_usergroups_case.rb +0 -14
  120. data/lib/eco/api/usecases/default_cases/clean_unknown_tags_case.rb +0 -74
  121. data/lib/eco/api/usecases/default_cases/create_details_case.rb +0 -20
  122. data/lib/eco/api/usecases/default_cases/create_details_with_supervisor_case.rb +0 -21
  123. data/lib/eco/api/usecases/default_cases/email_as_id_case.rb +0 -12
  124. data/lib/eco/api/usecases/default_cases/new_email_case.rb +0 -13
  125. data/lib/eco/api/usecases/default_cases/new_id_case.rb +0 -12
  126. data/lib/eco/api/usecases/default_cases/remove_account_sync_case.rb +0 -10
  127. data/lib/eco/api/usecases/default_cases/remove_account_trans_case.rb +0 -16
  128. data/lib/eco/api/usecases/default_cases/reset_landing_page_case.rb +0 -18
  129. data/lib/eco/api/usecases/default_cases/set_supervisor_case.rb +0 -16
  130. data/lib/eco/api/usecases/default_cases/tagtree_case.rb +0 -42
  131. data/lib/eco/api/usecases/default_cases/update_details_case.rb +0 -15
  132. data/lib/eco/cli/config/default/workflow.rb +0 -188
  133. data/lib/eco/cli/config/default.rb +0 -16
  134. /data/lib/eco/{cli/config/default → cli_default}/input.rb +0 -0
  135. /data/lib/eco/{cli/config/default → cli_default}/options.rb +0 -0
  136. /data/lib/eco/{cli/config/default → cli_default}/people.rb +0 -0
@@ -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,22 +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).
90
- def for(key = nil)
91
- raise "A block should be given." unless block_given?
92
- if !key
93
- yield(self)
94
- else
95
- stage(key).for(&Proc.new)
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`
98
+ def for(key = nil, &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
106
+ alias_method :with, :for
99
107
 
100
108
  # Used in **configuration** time **to define** the **behaviour** the target (sub)stage `key`
101
109
  # @note if a `block` is provided it will **not** `yield` the target stage immediately, but when the _workflow_ reaches the stage
@@ -108,7 +116,7 @@ module Eco
108
116
  # @yieldreturn [Eco::API::UseCases::BaseIO] the `io` input/output object carried througout all the _workflow_
109
117
  # @return [Eco::API::Session::Config::Workflow] the current stage object (to ease chainig).
110
118
  def on(key = nil, &block)
111
- raise "A block should be given." unless block
119
+ raise ArgumentError, "A block should be given." unless block_given?
112
120
  if !key
113
121
  @on = block
114
122
  else
@@ -128,7 +136,10 @@ module Eco
128
136
  @rescue = block
129
137
  self
130
138
  end
139
+ # Prevent reserved word clash on DSL
140
+ alias_method :exception, :rescue
131
141
 
142
+ # Called on `SystemExit` exception
132
143
  def exit_handle(&block)
133
144
  return @exit_handle unless block
134
145
  @exit_handle = block
@@ -148,7 +159,7 @@ module Eco
148
159
  # @yieldreturn [Eco::API::UseCases::BaseIO] `io` the input/output object carried througout all the _workflow_
149
160
  # @return [Eco::API::Session::Config::Workflow] the current stage object (to ease chainig).
150
161
  def before(key = nil, &block)
151
- raise "A block should be given." unless block
162
+ raise ArgumentError, "A block should be given." unless block_given?
152
163
  if !key
153
164
  @before.push(block)
154
165
  else
@@ -170,7 +181,7 @@ module Eco
170
181
  # @yieldreturn [Eco::API::UseCases::BaseIO] `io` the input/output object carried througout all the _workflow_
171
182
  # @return [Eco::API::Session::Config::Workflow] the current stage object (to ease chainig).
172
183
  def after(key = nil, &block)
173
- raise "A block should be given." unless block
184
+ raise ArgumentError, "A block should be given." unless block_given?
174
185
  if !key
175
186
  @after.push(block)
176
187
  else
@@ -191,7 +202,8 @@ module Eco
191
202
  # - it will **not** run the `callback` for `on` defined during the configuration time
192
203
  # - it will rather `yield` the target stage after all the `before` _callbacks_ have been run
193
204
  # - aside of this, the rest will be the same as when the _block_ is provided (see previous note)
194
- # @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.
195
207
  # @param key [Symbol, nil] cases:
196
208
  # - if `key` is not provided, it targets the _current stage_
197
209
  # - if `key` is provided, it targets the specific _sub-stage_
@@ -203,62 +215,87 @@ module Eco
203
215
  # @return [Eco::API::Session::Config::Workflow] the current stage object (to ease chainig).
204
216
  def run(key = nil, io:, &block)
205
217
  raise "Missing BaseIO object" unless io.is_a?(Eco::API::UseCases::BaseIO)
206
- begin
207
- if key
208
- io = stage(key).run(io: io, &block)
209
- elsif pending?
210
- @before.each do |c|
211
- io = c.call(self, io).tap do |i_o|
212
- unless i_o.is_a?(Eco::API::UseCases::BaseIO)
213
- msg = "Workflow callaback before('#{name}') should return Eco::API::UseCases::BaseIO object."
214
- msg += " Given #{i_o.class}"
215
- msg += " • Callback source location: '#{c.source_location}'"
216
- raise ArgumentError.new(msg)
217
- end
218
- end
219
- end
220
218
 
221
- unless skip?
222
- io.session.logger.debug("(Workflow: #{path}) running now")
223
- if block
224
- io = block.call(self, io)
225
- else
226
- 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
227
229
 
228
- unless ready?
229
- msg = "(Workflow: #{path}) 'on' callback is not defined, nor block given"
230
- 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)
231
240
  end
232
- io = @on.call(self, io) if ready?
233
241
  end
234
- @pending = false
235
- end
236
242
 
237
- @after.each do |c|
238
- io = c.call(self, io).tap do |i_o|
239
- unless i_o.is_a?(Eco::API::UseCases::BaseIO)
240
- msg = "Workflow callaback after('#{name}') should return Eco::API::UseCases::BaseIO object."
241
- msg += " Given #{i_o.class}"
242
- msg += " • Callback source location: '#{c.source_location}'"
243
- raise ArgumentError.new(msg)
244
- end
243
+ unless ready?
244
+ msg = "(Workflow: #{path}) 'on' callback is not defined, nor block given"
245
+ io.session.logger.debug(msg)
245
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)
246
257
  end
247
258
  end
248
- rescue SystemExit => e
249
- self.exit_handle.call(e, io) if self.exit_handle
250
- exit e.status
251
- rescue Interrupt => i
252
- raise
253
- rescue Exception => e
254
- self.rescue.call(e, io) if self.rescue
255
- raise
256
259
  end
257
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
258
276
  end
259
277
 
260
278
  protected
261
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
+
262
299
  def path
263
300
  return name if root?
264
301
  "#{@_parent.path}:#{name}"
@@ -257,6 +257,13 @@ module Eco
257
257
  tagtree_config.live_tree(id: id, enviro: enviro, **kargs, &block)
258
258
  end
259
259
 
260
+ # Retrieves all the location structures of the organisation
261
+ # @param include_archived [Boolean] whether or not to include archived **nodes**
262
+ # @return [Array<Eco::API::Organization::TagTree>]
263
+ def live_trees(**kargs, &block)
264
+ tagtree_config.live_trees(**kargs, &block)
265
+ end
266
+
260
267
  # @return [Eco::API::Organization::PolicyGroups]
261
268
  def policy_groups
262
269
  return @policy_groups if instance_variable_defined?(:@policy_groups)
@@ -360,10 +367,10 @@ module Eco
360
367
  end
361
368
 
362
369
  # @return [Eco::API::Session::Batch::Policies]
363
- def batch_policies
370
+ def batch_policies(&block)
364
371
  @batch_policies = self["batch_policies"] ||= Eco::API::Session::Batch::Policies.new("batch_policy")
365
372
  if block_given?
366
- yield(@batch_policies)
373
+ @batch_policies.evaluate(@batch_policies, &block)
367
374
  self
368
375
  else
369
376
  @batch_policies
@@ -39,16 +39,31 @@ module Eco
39
39
  config.login_providers
40
40
  end
41
41
 
42
+ # @param live [Boolean] states preference of `live` tree if available over file.
43
+ # @param merge [Boolean] when in `live` mode, if mulitple trees, merge into one.
42
44
  # @see Eco::API::Session::Config#tagtree
43
- def tagtree
44
- config.tagtree(enviro: enviro)
45
+ # @see Eco::API::Session#live_trees
46
+ # @return [Eco::API::Organization::TagTree]
47
+ def tagtree(live: false, merge: false, include_archived: false, **kargs, &block)
48
+ if live && api?(version: :graphql)
49
+ return live_tree(include_archived: include_archived, **kargs, &block) unless merge
50
+ live_trees(include_archived: include_archived, **kargs, &block).inject(&:merge)
51
+ else
52
+ config.tagtree(enviro: enviro)
53
+ end
45
54
  end
46
55
 
47
56
  # @see Eco::API::Session::Config#live_tree
57
+ # @return [Eco::API::Organization::TagTree]
48
58
  def live_tree(id: nil, include_archived: false, **kargs, &block)
49
59
  config.live_tree(id: id, include_archived: include_archived, enviro: enviro, **kargs, &block)
50
60
  end
51
61
 
62
+ # @see Eco::API::Session::Config#live_tree
63
+ def live_trees(include_archived: false, **kargs, &block)
64
+ config.live_trees(include_archived: include_archived, **kargs, &block)
65
+ end
66
+
52
67
  # @see Eco::API::Session::Config#schemas
53
68
  def schemas
54
69
  config.schemas
@@ -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:)
@@ -0,0 +1,94 @@
1
+ module Eco
2
+ module API
3
+ class UseCases
4
+ class Cli
5
+ module DSL
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)
16
+ self
17
+ end
18
+
19
+ def applied
20
+ @applied ||= {}
21
+ end
22
+
23
+ def applied?(arg_case)
24
+ applied[arg_case] || false
25
+ end
26
+
27
+ def applied!(arg_case)
28
+ applied[arg_case] = true
29
+ end
30
+
31
+ attr_writer :usecase
32
+ # Unless specified, assume Cli class hangs from its case namespace
33
+ def usecase
34
+ raise "#{self} is to use to extend a class" unless self.is_a?(Class)
35
+ @usecase ||= Kernel.const_get(self.to_s.split('::')[0..-2].join('::'))
36
+ end
37
+
38
+ def description(value = nil)
39
+ @description = (value.nil? ? @description : value)
40
+ end
41
+ alias_method :desc, :description
42
+
43
+ def type
44
+ usecase.type
45
+ end
46
+
47
+ def name
48
+ usecase.name
49
+ end
50
+
51
+ # It defaults to the use case preceded by dash
52
+ def cli_name(arg_name = nil)
53
+ @cli_name = (arg_name.nil? ? @cli_name : arg_name).yield_self do |value|
54
+ value = "-#{name}" if value.nil?
55
+ value
56
+ end
57
+ end
58
+
59
+ def callback(&block)
60
+ return @callback unless block_given?
61
+ @callback = block
62
+ end
63
+
64
+ def options
65
+ @options ||= {}
66
+ end
67
+
68
+ def add_option(arg, desc = nil, &block)
69
+ self.tap do
70
+ "Overriding option '#{arg}' on case '#{name}'" if options.key?(arg)
71
+ @options[arg] = Eco::API::UseCases::Cli::Option.new(arg, desc, &block)
72
+ end
73
+ end
74
+
75
+ private
76
+
77
+ def apply_options(arg_case)
78
+ options.each do |_key, option|
79
+ option.link_case(cli_config_case(arg_case))
80
+ end
81
+ end
82
+
83
+ def cli_config_case(arg_case = nil)
84
+ @cli_config_case ||= usecases.add(arg_case, type, desc, case_name: name, &callback)
85
+ end
86
+
87
+ def usecases(&block)
88
+ ::ASSETS.cli.config.usecases(&block)
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,19 @@
1
+ # Class to delay the case options configuration (declaration vs configuration)
2
+ class Eco::API::UseCases::Cli
3
+ class Option
4
+ attr_accessor :name, :desc, :callback
5
+
6
+ def initialize(name, desc, &block)
7
+ @name, @desc, @callback = name, desc, block
8
+ end
9
+
10
+ def dup(name: self.name, desc: self.desc, &block)
11
+ self.class.new(name, desc, &(block || callback))
12
+ end
13
+
14
+ def link_case(cli_config_case)
15
+ raise ArgumentError, "cli_config_case must have an 'add_option' method. Given: #{cli_config_case.class}" unless cli_config_case.respond_to?(:add_option)
16
+ cli_config_case.add_option(name, desc, &callback)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ # Class to integrate with the Cli a use case
2
+ module Eco
3
+ module API
4
+ class UseCases
5
+ class Cli
6
+ require_relative 'cli/dsl'
7
+ extend DSL
8
+ end
9
+ end
10
+ end
11
+ end
12
+
13
+ require_relative 'cli/option'
@@ -0,0 +1,29 @@
1
+ class Eco::API::UseCases::Default::Locations::TagtreeExtract
2
+ # Class to define the CLI integration of a usecase anywhere it suits.
3
+ class Cli < Eco::API::UseCases::Cli
4
+ desc "Exports the tagtree in a specific format"
5
+
6
+ add_option("-include-archived", "Whether the archived nodes should be included") do |options|
7
+ options.deep_merge!(output: {include: {archived: true}})
8
+ end
9
+
10
+ add_option("-format", "Kind of extract (list | json | nodes | csv_tree | excel_tree | excel_nodes )") do |options|
11
+ format = SCR.get_arg("-format", with_param: true)
12
+ options.deep_merge!(output: {format: format})
13
+ end
14
+
15
+ add_option("-node-attrs", "Attributes to be dumped (i.e. name|id ). Default: id") do |options|
16
+ attrs = SCR.get_arg("-node-attrs", with_param: true)
17
+ options.deep_merge!(output: {attrs: attrs.split('|').map(&:to_sym)})
18
+ end
19
+
20
+ add_option("-with-ancestors", "Include ancestors in tree csv/excel_tree") do |options|
21
+ options.deep_merge!(output: {include: {ancestors: true}})
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
28
+ end
29
+ end
@@ -1,4 +1,4 @@
1
- class Eco::API::UseCases::DefaultCases::CodesToTagsCase < Eco::API::Common::Loaders::UseCase
1
+ class Eco::API::UseCases::Default::Locations::CodesToTagsCase < Eco::API::Common::Loaders::UseCase
2
2
  name "codes-to-tags-from"
3
3
  type :other
4
4
 
@@ -1,4 +1,4 @@
1
- class Eco::API::UseCases::DefaultCases::TagPaths < Eco::API::Common::Loaders::UseCase
1
+ class Eco::API::UseCases::Default::Locations::TagPaths < Eco::API::Common::Loaders::UseCase
2
2
  name "create-tag-paths"
3
3
  type :other
4
4
 
@@ -1,4 +1,4 @@
1
- class Eco::API::UseCases::DefaultCases::CsvToTree < Eco::API::Common::Loaders::UseCase
1
+ class Eco::API::UseCases::Default::Locations::CsvToTree < Eco::API::Common::Loaders::UseCase
2
2
  name "csv-to-tree"
3
3
  type :other
4
4