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
@@ -4,6 +4,7 @@ module Eco
4
4
  module People
5
5
  # @attr_reader direct_attrs [Array<String>] only those internal attributes present in the person entry that do **not** have an internal/external name mapping.
6
6
  class PersonEntryAttributeMapper
7
+ DEBUG = false
7
8
  @@cached_warnings = {}
8
9
 
9
10
  attr_reader :aliased_attrs, :direct_attrs
@@ -182,22 +183,59 @@ module Eco
182
183
 
183
184
  private
184
185
 
186
+ # Whether the maps include this `attr` as mapped to itself
187
+ def self_mapped_attr?(attr)
188
+ return false if !@attr_map
189
+ @attr_map.self_mapped?(attr)
190
+ end
191
+
192
+ # Whether the maps include this `attr` as mapped from to some other or itself
193
+ def external_attr?(attr)
194
+ return false if !@attr_map
195
+ @attr_map.external?(attr)
196
+ end
197
+
185
198
  # when parsing:
186
199
  def init_attr_trackers
187
200
  # (def) all internal attributes we can expect
188
201
  def_all_attrs = @person_parser.all_model_attrs
189
202
  # (def) internal attrs with no aliasing nor parser definition (expected to be direct)
190
203
  def_unlinked = @person_parser.undefined_model_attrs.select { |attr| !to_external(attr) }
191
- # (def) those with parser or alias:
192
- def_linked = def_all_attrs - def_unlinked
204
+
205
+ debug(
206
+ def_unlinked,
207
+ "(def_unlinked) expected to be direct (not parser defined nor aliased)"
208
+ )
209
+
193
210
  # (data) data attributes (actual attributes of the entry)
194
211
  data_attrs = attributes(@external_entry)
212
+ # (data) attributes of the data that COULD come directly as internal attribute names
213
+ # => WARNING: this includes ext direct attrs that may be aliased to other int attrs
214
+ data_direct_attrs_raw = data_attrs & def_all_attrs
215
+ # (data) direct (int) ext data attrs mapped
216
+ data_direct_mapped = data_direct_attrs_raw.select { |attr| external_attr?(attr) }
217
+ # (data) direct (int) ext data attrs mapped to themselves
218
+ data_direct_self_mapped = data_direct_attrs_raw.select { |attr| self_mapped_attr?(attr) }
219
+ # (data) direct (int) ext data attrs mapped only to another attr
220
+ data_direct_renamed = data_direct_mapped - data_direct_self_mapped
195
221
  # (data) attributes of the data that come directly as internal attribute names
196
- data_direct_attrs = data_attrs & def_all_attrs
222
+ data_direct_attrs = data_direct_attrs_raw - data_direct_renamed
223
+
224
+ debug(
225
+ data_direct_attrs,
226
+ "(data_direct_attrs) attributes of the data that come directly as internal attribute names (data_direct_attrs_raw - data_direct_renamed)"
227
+ )
228
+
229
+ # (def) configured as alised (int <-> ext attrs) + accept/include int attrs as ext attrs
230
+ def_int_aliased_raw = def_all_attrs.select { |attr| to_external(attr) }
231
+ # (def) aliasable int attrs of the input data (excludes int attrs direct as ext attrs that got renamed)
232
+ def_int_aliased = def_int_aliased_raw - data_direct_renamed
233
+ # (def) ext attrs of the data's aliasable int attrs (def_int_aliased)
234
+ def_ext_alias = def_int_aliased.map { |attr| to_external(attr) }
235
+ # (def) those ext attrs that map to multiple int attrs
236
+ def_ext_multi_alias = def_ext_alias.detect { |attr| def_ext_alias.count(attr) > 1 }
237
+ # (def) those ext attrs that are direct, mapt to themselves and some other
197
238
 
198
- # (def) configured as alised (internal <-> external attributes)
199
- def_int_aliased = def_all_attrs.select { |attr| to_external(attr) }
200
- def_ext_alias = def_int_aliased.map { |attr| to_external(attr) }
201
239
 
202
240
  # (data) virtual attrs (external alias of non native internal attr in data):
203
241
  data_vi_ext_alias = data_attrs.select do |attr|
@@ -210,27 +248,78 @@ module Eco
210
248
  @attr_map.to_internal(attr)
211
249
  end.compact
212
250
 
213
- # (data) attrs that could come aliased in the current data
251
+ # (data) int attrs that come aliased in the current data
214
252
  # => modify aliased based on those that came directly as internal attrs in the entry
215
- data_def_int_aliased = def_int_aliased - data_direct_attrs
253
+ data_def_int_aliased = (def_int_aliased - data_direct_attrs) | data_direct_self_mapped
216
254
  data_def_ext_alias = data_def_int_aliased.map { |attr| to_external(attr) }
217
- # (data) actual attrs of the data that come aliased
255
+ # (data) ext attrs of the data that come aliased
218
256
  data_ext_alias = data_def_ext_alias & data_attrs
257
+ # (data) all internal attributes that come aliased, with given the entry
258
+ aliased_attrs = data_def_int_aliased | data_vi_int_aliased
259
+
260
+ # render in the order that defines the model
261
+ @aliased_attrs = (def_all_attrs & aliased_attrs) | (aliased_attrs - def_all_attrs)
262
+
263
+ debug(
264
+ data_vi_int_aliased,
265
+ "(data_vi_int_aliased) virtual internal attrs (internal names of those virtual attrs)"
266
+ )
267
+
268
+ debug(
269
+ def_int_aliased,
270
+ "(def_int_aliased) aliasable int attrs of the input data (excludes int attrs direct as ext attrs that got renamed)"
271
+ )
272
+
273
+ debug(
274
+ def_ext_alias,
275
+ "(def_ext_alias) ext attrs of the data's aliasable int attrs (def_int_aliased)"
276
+ )
277
+
278
+ debug(
279
+ data_def_int_aliased,
280
+ "(data_def_int_aliased) int attrs that come aliased in the current data ((def_int_aliased - data_direct_attrs) | data_direct_self_mapped)"
281
+ )
282
+
283
+ debug(
284
+ data_ext_alias,
285
+ "(data_ext_alias) ext attrs of the data that come aliased (data_def_ext_alias & data_attrs)"
286
+ )
287
+
288
+ debug(
289
+ aliased_attrs,
290
+ "(aliased_attrs) all internal attributes that come aliased, with given the entry (data_def_int_aliased | data_vi_int_aliased)"
291
+ )
219
292
 
220
- # (data) all internal attributes that could come aliased, with given the entry
221
- @aliased_attrs = data_def_int_aliased + data_vi_int_aliased
222
293
  # (data) all those ext attrs present that will require aliasing
223
294
  #data_ext_alias_all = data_def_ext_alias + data_vi_ext_alias
224
- data_ext_alias_all = data_ext_alias + data_vi_ext_alias
295
+ data_ext_alias_all = data_ext_alias | data_vi_ext_alias
296
+
297
+ debug(
298
+ data_ext_alias_all,
299
+ "(data_ext_alias_all) all those ext attrs present that will require aliasing (data_ext_alias | data_vi_ext_alias)"
300
+ )
225
301
 
226
302
  # those that are direct external to internal:
227
303
  data_ext_direct = data_attrs - data_ext_alias_all
228
-
229
304
  # (data) attributes that do not require aliasing
230
305
  # to avoid collisions between internal names:
231
- #@direct_attrs = data_ext_direct - def_linked
232
- @direct_attrs = data_ext_direct
233
- @internal_attrs = @aliased_attrs | @direct_attrs
306
+ direct_attrs = data_ext_direct
307
+ # render in the order that defines the model
308
+ @direct_attrs = (def_all_attrs & direct_attrs) | (direct_attrs - def_all_attrs)
309
+
310
+ # (data) attributes that are being aliased
311
+ internal_attrs = @aliased_attrs | @direct_attrs
312
+ # render in the order that defines the model
313
+ @internal_attrs = (def_all_attrs & internal_attrs) | (internal_attrs - def_all_attrs)
314
+
315
+ debug(
316
+ @direct_attrs,
317
+ "(@direct_attrs) attributes that do not require aliasing (data_attrs - data_ext_alias_all)"
318
+ )
319
+ debug(
320
+ @internal_attrs,
321
+ "(@internal_attrs) aliased_attrs | @direct_attrs"
322
+ )
234
323
  end
235
324
 
236
325
  def attributes(value)
@@ -265,6 +354,12 @@ module Eco
265
354
  logger.fatal(msg)
266
355
  raise msg
267
356
  end
357
+
358
+ def debug(var, msg)
359
+ return unless DEBUG
360
+ puts "\n • #{msg}:"
361
+ pp var
362
+ end
268
363
  end
269
364
  end
270
365
  end
@@ -35,6 +35,10 @@ module Eco
35
35
  enviro.api(version: version)
36
36
  end
37
37
 
38
+ def api?(version: nil)
39
+ enviro.api?(version: version)
40
+ end
41
+
38
42
  def file_manager
39
43
  enviro.file_manager
40
44
  end
@@ -53,6 +53,10 @@ module Eco
53
53
  def api(version: nil)
54
54
  config.api(logger, version: version)
55
55
  end
56
+
57
+ def api?(version:)
58
+ config.apis.active_api.version_available?(version)
59
+ end
56
60
  end
57
61
  end
58
62
  end
@@ -33,7 +33,9 @@ module Eco
33
33
  }
34
34
  }
35
35
  ).tap do |response|
36
- logger.debug("Sent email to #{to} (MessageId: #{response.message_id})")
36
+ msg = "Sent email (MessageId: #{response.message_id}) to #{fetch_destination(to: to, cc: cc, bcc: bcc)}"
37
+ puts msg
38
+ logger.debug(msg)
37
39
  end
38
40
  end
39
41
 
@@ -24,7 +24,7 @@ module Eco
24
24
  rescue Exception => e
25
25
  msg = "Could not open SFTP session. Possible misconfiguration: #{e}"
26
26
  logger.error(msg)
27
- raise msg
27
+ raise
28
28
  end
29
29
  @sftp_session
30
30
  end
@@ -1,9 +1,9 @@
1
1
  class ::Exception
2
- def patch_full_message
2
+ def patch_full_message(trace_count: -1)
3
3
  begin
4
4
  msg = []
5
5
  tracing = backtrace ? backtrace : []
6
- tracing = (self.class == SystemStackError) ? tracing[1..30] : tracing[1..-1]
6
+ tracing = (self.class == SystemStackError) ? tracing[1..30] : tracing[1..trace_count]
7
7
  tracing ||= []
8
8
  msg << "\n#{tracing.first} \n#{message} (#{self.class.to_s})"
9
9
  tracing.each_with_index {|bt, i| msg << "#{" "*8}#{i+1}: from #{bt}"}
@@ -0,0 +1,18 @@
1
+ class Object
2
+ # From ruby3
3
+ # `NameError` prints the internals of the object as well as subobjects
4
+ # which is really unnecessary
5
+ # @example
6
+ # class Foo; attr_writer :bar; end
7
+ # foo = Foo.new
8
+ # foo2 = Foo.new
9
+ # foo.bar = foo2
10
+ # h = {a: 1, b: 2, c: foo}
11
+ # foo2.bar = h
12
+ # h.foo
13
+ # #=> undefined method `foo' for {:a=>1, :b=>2, :c=>#<Foo:0x000002343276b520 @bar=#<Foo:0x0000023437e91ca0 @bar={...}>>}:Hash (NoMethodError)
14
+ # What's the use of such a detail when it's just a missing method at the top of it?
15
+ def inspect
16
+ to_s
17
+ end
18
+ end
@@ -0,0 +1 @@
1
+ require_relative 'ruby3/object'
@@ -7,6 +7,9 @@ module Eco
7
7
  end
8
8
  end
9
9
 
10
+ if Gem::Version.create('3.0.0') <= Gem::Version.create(RUBY_VERSION)
11
+ require_relative 'version_patches/ruby3'
12
+ end
10
13
  require_relative 'version_patches/object'
11
14
  require_relative 'version_patches/exception'
12
15
  require_relative 'version_patches/hash'
@@ -0,0 +1,10 @@
1
+ # Helper class to create a custom `Config`
2
+ # @example Example of usage:
3
+ # class Custom::Config::BatchPolicies < Eco::API::Custom::Config
4
+ # batch_policies do
5
+ # create.max = 5
6
+ # update.max = 20
7
+ # end
8
+ # end
9
+ class Eco::API::Custom::Config < Eco::API::Common::Loaders::Config
10
+ end
@@ -0,0 +1,9 @@
1
+ # Helper class to create a custom `Config`
2
+ # @example Example of usage:
3
+ # class Custom::Workflow::Mailer < Eco::API::Custom::Mailer
4
+ # ORG = "Org Name"
5
+ # end
6
+ class Eco::API::Custom::Mailer < Eco::API::Common::Loaders::Workflow::Mailer
7
+ extend Eco::Language::Klass::WhenInherited
8
+ when_inherited(&config_block)
9
+ end
@@ -4,4 +4,6 @@ module Custom
4
4
  module Policy; end
5
5
  module ErrorHandler; end
6
6
  module Parser; end
7
+ module Config; end
8
+ module Workflow; end
7
9
  end
@@ -0,0 +1,9 @@
1
+ # Helper class to create a custom `Config`
2
+ # @example Example of usage:
3
+ # class Custom::Config::DefaultOptions < Eco::API::Custom::Workflow
4
+ # after(:options) do
5
+ # options.deep_merge!(send_invites: false) unless options.dig(:send_invites)
6
+ # end
7
+ # end
8
+ class Eco::API::Custom::Workflow < Eco::API::Common::Loaders::Workflow
9
+ end
@@ -7,6 +7,9 @@ module Eco
7
7
  end
8
8
 
9
9
  require_relative 'custom/namespace'
10
+ require_relative 'custom/config'
11
+ require_relative 'custom/workflow'
12
+ require_relative 'custom/mailer'
10
13
  require_relative 'custom/use_case'
11
14
  require_relative 'custom/policy'
12
15
  require_relative 'custom/error_handler'
@@ -19,7 +19,6 @@ module Eco
19
19
  attr_reader :parent
20
20
  attr_reader :nodes, :children_count
21
21
  attr_reader :depth, :path
22
- attr_reader :enviro
23
22
 
24
23
  attr_reader :source
25
24
 
@@ -35,7 +34,7 @@ module Eco
35
34
  # ]}]
36
35
  # tree = TagTree.new(tree.to_json)
37
36
  # @param tagtree [String] representation of the tagtree in json.
38
- def initialize(tagtree = [], name: nil, id: nil, depth: -1, path: [], parent: nil, _weight: nil, enviro: nil)
37
+ def initialize(tagtree = [], name: nil, id: nil, depth: -1, path: [], parent: nil, _weight: nil)
39
38
  @depth = depth
40
39
  @parent = parent
41
40
 
@@ -45,9 +44,7 @@ module Eco
45
44
  else
46
45
  @source = tagtree
47
46
  end
48
- fatal("You are trying to initialize a TagTree with a null tagtree") if !@source
49
- fatal("Expecting Environment object. Given: #{enviro}") if enviro && !enviro.is_a?(API::Common::Session::Environment)
50
- @enviro = enviro
47
+ raise ArgumentError, "You are trying to initialize a TagTree with a null tagtree" if !@source
51
48
 
52
49
  if @source.is_a?(Array)
53
50
  @id = id
@@ -66,7 +63,7 @@ module Eco
66
63
  @path.push(@id) unless top?
67
64
 
68
65
  @nodes = @raw_nodes.map.with_index do |cnode, idx|
69
- TagTree.new(cnode, depth: depth + 1, path: @path.dup, parent: self, _weight: idx, enviro: @enviro)
66
+ self.class.new(cnode, depth: depth + 1, path: @path.dup, parent: self, _weight: idx)
70
67
  end
71
68
 
72
69
  init_hashes
@@ -80,11 +77,28 @@ module Eco
80
77
  !archived?
81
78
  end
82
79
 
80
+ # @note that archived nodes will also be passed over to the copy
83
81
  # @return [Eco::API::Organization::TagTree]
84
82
  def dup
85
83
  self.class.new(as_json, name: name, id: id)
86
84
  end
87
85
 
86
+ # @return [Array] with the differences
87
+ def diff(tagtree, differences: {}, level: 0, **options)
88
+ require 'hashdiff'
89
+ Hashdiff.diff(self.as_json, tagtree.as_json, **options.slice(:array_path, :similarity, :use_lcs))
90
+ end
91
+
92
+ # It generates a merged tagtree out of two sources
93
+ # @note it merges the first level nodes (and their children) as it comes
94
+ # @return [Eco::API::Organization::TagTree] result of merging both trees
95
+ def merge(other)
96
+ raise ArgumentError, "Expecting Eco::API::Organization::TagTree. Given: #{other.class}" unless other.is_a?(Eco::API::Organization::TagTree)
97
+ mid = [self.id, other.id].join('|')
98
+ mname = [self.name, other.name].join('|')
99
+ self.class.new(as_json | other.as_json, id: mid, name: mname)
100
+ end
101
+
88
102
  # @return [Eco::API::Organization::TagTree] with **non** `archived` nodes only
89
103
  def active_tree
90
104
  self.class.new(as_json(include_archived: false), name: name, id: id)
@@ -162,12 +176,6 @@ module Eco
162
176
  parent.name unless parent.top?
163
177
  end
164
178
 
165
- # @return [Array] with the differences
166
- def diff(tagtree, differences: {}, level: 0, **options)
167
- require 'hashdiff'
168
- Hashdiff.diff(self.as_json, tagtree.as_json, **options.slice(:array_path, :similarity, :use_lcs))
169
- end
170
-
171
179
  def top?
172
180
  depth == -1
173
181
  end
@@ -410,17 +418,6 @@ module Eco
410
418
  h.merge(n.hash_paths)
411
419
  end
412
420
  end
413
-
414
- def fatal(msg)
415
- raise msg if !@enviro
416
- @enviro.logger.fatal(msg)
417
- raise msg
418
- end
419
-
420
- def warn(msg)
421
- raise msg if !@enviro
422
- @enviro.logger.warn(msg)
423
- end
424
421
  end
425
422
  end
426
423
  end
@@ -20,9 +20,10 @@ module Eco
20
20
  # @attr_reader min [Integer] `min` **required** number of occurrences of the property
21
21
  class BasePolicy
22
22
  extend Eco::API::Common::ClassHierarchy
23
+ # adds evaluate method to enable block calls as DSL
24
+ include Eco::Language::Methods::DslAble
23
25
 
24
26
  class << self
25
-
26
27
  # If the class for `key` exists, it returns it. Otherwise it generates it.
27
28
  # @note for this to work, `key` should be one of the submodels of the current class' `model`
28
29
  # @return [Eco::API::Session::Batch::BasePolicy] or subclass thereof
@@ -52,16 +53,14 @@ module Eco
52
53
  end
53
54
 
54
55
  if block
55
- block.call(policy)
56
+ policy.evaluate(policy, &block)
56
57
  self
57
58
  else
58
59
  policy
59
60
  end
60
61
  end
61
-
62
62
  end
63
63
  end
64
-
65
64
  end
66
65
 
67
66
  include Enumerable
@@ -75,6 +74,16 @@ module Eco
75
74
  @policies = {}
76
75
  end
77
76
 
77
+ def max(value = :unused)
78
+ return @max if value == :unused
79
+ self.max = value
80
+ end
81
+
82
+ def min(value = :unused)
83
+ return @min if value == :unused
84
+ self.min = value
85
+ end
86
+
78
87
  def attr(as_namespace: false)
79
88
  return @attr if !as_namespace || root?
80
89
  "#{@_parent.attr(as_namespace: true)}:#{@attr}"
@@ -222,7 +231,6 @@ module Eco
222
231
  return model if model.is_a?(Hash)
223
232
  model.to_h if model.respond_to?(:to_h)
224
233
  end
225
-
226
234
  end
227
235
  end
228
236
  end
@@ -9,6 +9,8 @@ module Eco
9
9
  # @attr_reader status [Eco::API::Session::Batch::Status] if launched: the `status` of the `batch`
10
10
  # @attr_reader feedback [Eco::API::Session::Batch::Feedback] helper class for feedback and end-user decision making
11
11
  class Job < Eco::API::Common::Session::BaseSession
12
+ include Eco::Language::Methods::DslAble
13
+
12
14
  @types = [:get, :create, :update, :delete]
13
15
  @sets = [:core, :details, :account]
14
16
 
@@ -105,7 +107,7 @@ module Eco
105
107
  unless unique && @queue_hash.key?(entry)
106
108
  @queue_hash[entry] = true
107
109
  @queue.push(entry)
108
- @callbacks[entry] = Proc.new if block_given?
110
+ @callbacks[entry] = block if block_given?
109
111
  end
110
112
  end
111
113
  end
@@ -230,13 +232,13 @@ module Eco
230
232
  end.join("\n")
231
233
  end
232
234
 
233
- def as_update(data, *args)
235
+ def as_update(data, **kargs)
234
236
  if data.is_a?(Array)
235
237
  data.map do |e|
236
- feedback.as_update(e, *args)
238
+ feedback.as_update(e, **kargs)
237
239
  end.compact.select {|e| e && !e.empty?}
238
240
  else
239
- feedback.as_update(data, *args)
241
+ feedback.as_update(data, **kargs)
240
242
  end
241
243
  end
242
244
 
@@ -278,14 +280,15 @@ module Eco
278
280
  def api_included(full_queue)
279
281
  return full_queue if type == :create
280
282
  return full_queue unless excluded_callback = session.config.people.api_excluded
281
- excluded = options.dig(:include, :excluded)
282
- if excluded.is_a?(Hash) && excluded[:only]
283
- full_queue.select {|entry| excluded_callback.call(entry, session, options, self)}
284
- elsif options.dig(:include, :excluded)
285
- full_queue
286
- else
287
- full_queue.select {|entry| !excluded_callback.call(entry, session, options, self)}
283
+
284
+ inc_excluded = options.dig(:include, :excluded)
285
+ excluded_only = inc_excluded.is_a?(Hash) && excluded[:only]
286
+ is_excluded = Proc.new do |entry|
287
+ evaluate(entry, session, options, self, &excluded_callback)
288
288
  end
289
+ return full_queue.select(&is_excluded) if excluded_only
290
+ return full_queue if inc_excluded
291
+ full_queue.reject(&is_excluded)
289
292
  end
290
293
 
291
294
  # Applies the changes introduced by api policies
@@ -74,10 +74,10 @@ module Eco
74
74
  # @yieldparam job [Eco::API::Session::Batch::Job] the job we have launched against the server.
75
75
  # @yieldparam status [Eco::API::Session::Batch::Status] the status of the batch job launch.
76
76
  # @return [Eco::API::Session::Batch::Job]
77
- def add(job)
77
+ def add(job, &block)
78
78
  fatal "Expected Eco::API::Session::Batch::Job object. Given #{job.class}" unless job.is_a?(Eco::API::Session::Batch::Job)
79
79
  @jobs[job.name] = job
80
- @callbacks[job] = Proc.new if block_given?
80
+ @callbacks[job] = block if block_given?
81
81
  end
82
82
 
83
83
  def pending?
@@ -63,7 +63,7 @@ module Eco
63
63
  # @yieldparam group [Eco::API::Session::Batch::Jobs] the group of jobs we have launched against the server.
64
64
  # @yieldparam group_status [Hash<Eco::API::Session::Batch::Job, Eco::API::Session::Batch::Status>] the status of the launched batch jobs.
65
65
  # @return [Eco::API::Session::Batch::Jobs] the group of jobs.
66
- def new(name, order: :last)
66
+ def new(name, order: :last, &block)
67
67
  fatal "Can't create job group named '#{name}' because it already exists." if exists?(name)
68
68
 
69
69
  Batch::Jobs.new(enviro, name: name).tap do |group|
@@ -75,7 +75,7 @@ module Eco
75
75
  @order.unshift(group)
76
76
  end
77
77
 
78
- @callbacks[group] = Proc.new if block_given?
78
+ @callbacks[group] = block if block_given?
79
79
  end
80
80
  end
81
81
 
@@ -26,9 +26,9 @@ module Eco
26
26
 
27
27
  attr_key :timestamp_pattern
28
28
 
29
- def add_validation(format)
29
+ def add_validation(format, &block)
30
30
  raise "Block must be given" unless block_given?
31
- @validations[format] = Proc.new
31
+ @validations[format] = block
32
32
  end
33
33
 
34
34
  def validate(format, input)
@@ -48,9 +48,9 @@ module Eco
48
48
  end
49
49
 
50
50
  # with given a person what is the criteria of exclusion
51
- def api_excluded
51
+ def api_excluded(&block)
52
52
  return self["api_excluded"] unless block_given?
53
- self["api_excluded"] = Proc.new
53
+ self["api_excluded"] = block
54
54
  end
55
55
 
56
56
  # internal-external fields map
@@ -12,6 +12,10 @@ module Eco
12
12
  !!required
13
13
  end
14
14
 
15
+ def enviro_subpaths
16
+ self['enviro_subpaths'] ||= {}
17
+ end
18
+
15
19
  def enviro_subpath
16
20
  enviro_subpaths[config.active_enviro]
17
21
  end
@@ -8,6 +8,9 @@ module Eco
8
8
 
9
9
  attr_key :file, :structure_id
10
10
 
11
+ # @note it retrieves the tree this way:
12
+ # 1. If there's a file tagtree.json file, it uses it
13
+ # 2. If no file, retrieves `structure_id` (config)
11
14
  # @param include_archived [Boolean] whether or not it should include archived nodes.
12
15
  # @return [Eco::API::Organization::TagTree]
13
16
  def scope_tree(enviro: nil, include_archived: true, raise_on_missing: true)
@@ -20,7 +23,7 @@ module Eco
20
23
 
21
24
  if tree_file = self.file
22
25
  if (tree = file_manager.load_json(tree_file)) && !tree.empty?
23
- @tagtree = Eco::API::Organization::TagTree.new(tree, enviro: enviro)
26
+ @tagtree = Eco::API::Organization::TagTree.new(tree)
24
27
  end
25
28
  elsif self.structure_id
26
29
  kargs.merge(id: self.structure_id)
@@ -36,6 +39,7 @@ module Eco
36
39
 
37
40
  # Among all the locations structures it selects the one with more location nodes
38
41
  # If `id` is provided, it only retrieves this locations structure.
42
+ # @param [enviro] used for re-caching
39
43
  def live_tree(id: nil, enviro: nil, include_archived: false, **kargs, &block)
40
44
  existing_cache = !!@live_tree
41
45
  first_load = !existing_cache
@@ -47,7 +51,6 @@ module Eco
47
51
  refresh_cache = existing_cache && !switching_target
48
52
 
49
53
  kargs = {
50
- enviro: enviro,
51
54
  includeArchivedNodes: include_archived
52
55
  }.merge(kargs)
53
56
 
@@ -81,7 +84,7 @@ module Eco
81
84
  # @note it does not memoize
82
85
  # @param include_archived [Boolean] whether or not to include archived **nodes**
83
86
  # @return [Eco::API::Organization::TagTree, NilClass]
84
- def live_tree_get(id: nil, enviro: nil, include_archived: false, **kargs, &block)
87
+ def live_tree_get(id: nil, include_archived: false, **kargs, &block)
85
88
  return nil unless apis.active_api.version_available?(:graphql)
86
89
  return nil unless graphql = apis.api(version: :graphql)
87
90
 
@@ -92,14 +95,13 @@ module Eco
92
95
 
93
96
  return nil unless tree = graphql.currentOrganization.locationStructure(**kargs, &block)
94
97
 
95
- args = { enviro: enviro, id: tree.id, name: tree.name }
96
- Eco::API::Organization::TagTree.new(tree.treeify, **args)
98
+ Eco::API::Organization::TagTree.new(tree.treeify, id: tree.id, name: tree.name)
97
99
  end
98
100
 
99
101
  # Retrieves all the location structures of the organisation
100
102
  # @param include_archived [Boolean] whether or not to include archived **nodes**
101
103
  # @return [Array<Eco::API::Organization::TagTree>]
102
- def live_trees(enviro: nil, include_archived: false, **kargs, &block)
104
+ def live_trees(include_archived: false, **kargs, &block)
103
105
  [].tap do |eco_trees|
104
106
  next unless apis.active_api.version_available?(:graphql)
105
107
  next unless graphql = apis.api(version: :graphql)
@@ -110,8 +112,7 @@ module Eco
110
112
 
111
113
  next unless trees = graphql.currentOrganization.locationStructures(**kargs, &block)
112
114
  trees.each do |tree|
113
- args = { enviro: enviro, id: tree.id, name: tree.name }
114
- eco_tree = Eco::API::Organization::TagTree.new(tree.treeify, **args)
115
+ eco_tree = Eco::API::Organization::TagTree.new(tree.treeify, id: tree.id, name: tree.name)
115
116
  eco_trees.push(eco_tree)
116
117
  end
117
118
  end