eco-helpers 2.6.4 → 2.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (167) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +95 -0
  4. data/CHANGELOG.md +128 -2
  5. data/Rakefile +13 -7
  6. data/eco-helpers.gemspec +2 -2
  7. data/lib/eco/api/common/loaders/base.rb +2 -2
  8. data/lib/eco/api/common/loaders/case_base.rb +1 -1
  9. data/lib/eco/api/common/loaders/config/workflow/mailer.rb +5 -5
  10. data/lib/eco/api/common/loaders/error_handler.rb +8 -5
  11. data/lib/eco/api/common/loaders/parser.rb +44 -22
  12. data/lib/eco/api/common/loaders/policy.rb +6 -4
  13. data/lib/eco/api/common/loaders/use_case.rb +13 -7
  14. data/lib/eco/api/common/people/base_parser.rb +0 -2
  15. data/lib/eco/api/common/people/default_parsers/boolean_parser.rb +0 -1
  16. data/lib/eco/api/common/people/default_parsers/csv_parser.rb +1 -1
  17. data/lib/eco/api/common/people/default_parsers/date_parser.rb +64 -12
  18. data/lib/eco/api/common/people/default_parsers/freemium_parser.rb +0 -1
  19. data/lib/eco/api/common/people/default_parsers/login_providers_parser.rb +13 -5
  20. data/lib/eco/api/common/people/default_parsers/multi_parser.rb +0 -1
  21. data/lib/eco/api/common/people/default_parsers/numeric_parser.rb +18 -5
  22. data/lib/eco/api/common/people/default_parsers/policy_groups_parser.rb +8 -8
  23. data/lib/eco/api/common/people/default_parsers/select_parser.rb +50 -26
  24. data/lib/eco/api/common/people/default_parsers/send_invites_parser.rb +6 -6
  25. data/lib/eco/api/common/people/default_parsers/xls_parser.rb +9 -12
  26. data/lib/eco/api/common/people/default_parsers.rb +1 -12
  27. data/lib/eco/api/common/people/entries.rb +13 -13
  28. data/lib/eco/api/common/people/entry_factory.rb +76 -45
  29. data/lib/eco/api/common/people/person_attribute_parser.rb +8 -12
  30. data/lib/eco/api/common/people/person_entry.rb +86 -75
  31. data/lib/eco/api/common/people/person_entry_attribute_mapper.rb +60 -44
  32. data/lib/eco/api/common/people/person_factory.rb +30 -22
  33. data/lib/eco/api/common/people/person_modifier.rb +11 -13
  34. data/lib/eco/api/common/people/person_parser.rb +101 -39
  35. data/lib/eco/api/common/people/supervisor_helpers.rb +25 -26
  36. data/lib/eco/api/common/session/base_session.rb +9 -9
  37. data/lib/eco/api/common/session/environment.rb +7 -5
  38. data/lib/eco/api/common/session/sftp.rb +59 -32
  39. data/lib/eco/api/common/version_patches/exception.rb +11 -13
  40. data/lib/eco/api/error.rb +32 -20
  41. data/lib/eco/api/organization/node_classifications.rb +82 -0
  42. data/lib/eco/api/organization/policy_groups.rb +4 -6
  43. data/lib/eco/api/organization/tag_tree.rb +169 -93
  44. data/lib/eco/api/organization.rb +1 -0
  45. data/lib/eco/api/session/batch/job.rb +1 -1
  46. data/lib/eco/api/session/config/tagtree.rb +41 -23
  47. data/lib/eco/api/session/config/workflow.rb +113 -88
  48. data/lib/eco/api/session/config.rb +6 -0
  49. data/lib/eco/api/session.rb +51 -29
  50. data/lib/eco/api/usecases/base_io.rb +28 -25
  51. data/lib/eco/api/usecases/default/locations/cli/tagtree_extract_cli.rb +7 -2
  52. data/lib/eco/api/usecases/default/locations/cli/tagtree_upload_cli.rb +21 -0
  53. data/lib/eco/api/usecases/default/locations/csv_to_tree_case.rb +3 -3
  54. data/lib/eco/api/usecases/default/locations/tagtree_extract_case.rb +54 -23
  55. data/lib/eco/api/usecases/default/locations/tagtree_upload_case.rb +87 -0
  56. data/lib/eco/api/usecases/default/locations.rb +1 -0
  57. data/lib/eco/api/usecases/default/people/analyse_people_case.rb +60 -56
  58. data/lib/eco/api/usecases/default/people/change_email_case.rb +8 -9
  59. data/lib/eco/api/usecases/default/people/clean_unknown_tags_case.rb +13 -11
  60. data/lib/eco/api/usecases/default/people/clear_abilities_case.rb +2 -2
  61. data/lib/eco/api/usecases/default/people/org_data_convert_case.rb +25 -27
  62. data/lib/eco/api/usecases/default/people/refresh_case.rb +2 -2
  63. data/lib/eco/api/usecases/default/people/reinvite_trans_case.rb +1 -1
  64. data/lib/eco/api/usecases/default/people/reinvite_trans_cli.rb +0 -1
  65. data/lib/eco/api/usecases/default/people/restore_db_case.rb +39 -34
  66. data/lib/eco/api/usecases/default/people/set_default_tag_case.rb +19 -15
  67. data/lib/eco/api/usecases/default/people/supers_cyclic_identify_case.rb +16 -12
  68. data/lib/eco/api/usecases/default_cases/hris_case.rb +17 -15
  69. data/lib/eco/api/usecases/default_cases/samples/sftp_case.rb +30 -16
  70. data/lib/eco/api/usecases/graphql/base.rb +5 -3
  71. data/lib/eco/api/usecases/graphql/helpers/base/case_env.rb +4 -1
  72. data/lib/eco/api/usecases/graphql/helpers/base/graphql_env.rb +14 -0
  73. data/lib/eco/api/usecases/graphql/helpers/base.rb +5 -4
  74. data/lib/eco/api/usecases/graphql/helpers/location/base/classifications_parser.rb +60 -0
  75. data/lib/eco/api/usecases/graphql/helpers/location/base/tree_tracking.rb +72 -0
  76. data/lib/eco/api/usecases/graphql/helpers/location/base.rb +25 -59
  77. data/lib/eco/api/usecases/graphql/helpers/location/command/diff/as_update.rb +59 -0
  78. data/lib/eco/api/usecases/graphql/helpers/location/command/diff/compare.rb +49 -0
  79. data/lib/eco/api/usecases/graphql/helpers/location/command/diff.rb +11 -0
  80. data/lib/eco/api/usecases/graphql/helpers/location/command/diffs/stages/commandable.rb +46 -0
  81. data/lib/eco/api/usecases/graphql/helpers/location/command/diffs/stages/diff_sortable/for_archive.rb +23 -0
  82. data/lib/eco/api/usecases/graphql/helpers/location/command/diffs/stages/diff_sortable/for_unarchive.rb +65 -0
  83. data/lib/eco/api/usecases/graphql/helpers/location/command/diffs/stages/diff_sortable.rb +49 -0
  84. data/lib/eco/api/usecases/graphql/helpers/location/command/diffs/stages/sortable/relation_safe_sort.rb +119 -0
  85. data/lib/eco/api/usecases/graphql/helpers/location/command/diffs/stages/sortable.rb +59 -0
  86. data/lib/eco/api/usecases/graphql/helpers/location/command/diffs/stages.rb +82 -0
  87. data/lib/eco/api/usecases/graphql/helpers/location/command/diffs.rb +20 -0
  88. data/lib/eco/api/usecases/graphql/helpers/location/command/optimizations.rb +84 -0
  89. data/lib/eco/api/usecases/graphql/helpers/location/command/result.rb +4 -4
  90. data/lib/eco/api/usecases/graphql/helpers/location/command/results.rb +24 -12
  91. data/lib/eco/api/usecases/graphql/helpers/location/command.rb +21 -24
  92. data/lib/eco/api/usecases/graphql/helpers/location/tags_remap/tags_map.rb +1 -1
  93. data/lib/eco/api/usecases/graphql/helpers/location/tags_remap/tags_set.rb +10 -11
  94. data/lib/eco/api/usecases/graphql/helpers/location/tags_remap.rb +8 -9
  95. data/lib/eco/api/usecases/graphql/samples/location/command/dsl.rb +41 -12
  96. data/lib/eco/api/usecases/graphql/samples/location/command/results.rb +11 -80
  97. data/lib/eco/api/usecases/graphql/samples/location/command/service/tree_update.rb +89 -0
  98. data/lib/eco/api/usecases/graphql/samples/location/command/service.rb +6 -0
  99. data/lib/eco/api/usecases/graphql/samples/location/command/track_changed_ids.rb +89 -0
  100. data/lib/eco/api/usecases/graphql/samples/location/command.rb +3 -0
  101. data/lib/eco/api/usecases/graphql/samples/location/service/base.rb +9 -0
  102. data/lib/eco/api/usecases/graphql/samples/location/service/tree_diff/convertible/heading.rb +18 -0
  103. data/lib/eco/api/usecases/graphql/samples/location/service/tree_diff/convertible/inputable.rb +53 -0
  104. data/lib/eco/api/usecases/graphql/samples/location/service/tree_diff/convertible/parsing/classifications.rb +34 -0
  105. data/lib/eco/api/usecases/graphql/samples/location/service/tree_diff/convertible/parsing/helpers.rb +28 -0
  106. data/lib/eco/api/usecases/graphql/samples/location/service/tree_diff/convertible/parsing.rb +46 -0
  107. data/lib/eco/api/usecases/graphql/samples/location/service/tree_diff/convertible.rb +38 -0
  108. data/lib/eco/api/usecases/graphql/samples/location/service/tree_diff.rb +105 -0
  109. data/lib/eco/api/usecases/graphql/samples/location/service/tree_to_list/converter/discarded.rb +16 -0
  110. data/lib/eco/api/usecases/graphql/samples/location/service/tree_to_list/converter/input.rb +15 -0
  111. data/lib/eco/api/usecases/graphql/samples/location/service/tree_to_list/converter/node_attr_maps.rb +22 -0
  112. data/lib/eco/api/usecases/graphql/samples/location/service/tree_to_list/converter/parser.rb +45 -0
  113. data/lib/eco/api/usecases/graphql/samples/location/service/tree_to_list/converter.rb +36 -0
  114. data/lib/eco/api/usecases/graphql/samples/location/service/tree_to_list/output.rb +56 -0
  115. data/lib/eco/api/usecases/graphql/samples/location/service/tree_to_list.rb +41 -0
  116. data/lib/eco/api/usecases/graphql/samples/location/service.rb +8 -0
  117. data/lib/eco/api/usecases/graphql/samples/location.rb +1 -0
  118. data/lib/eco/api/usecases/graphql/utils/sftp.rb +96 -36
  119. data/lib/eco/api/usecases/ooze_cases/export_register_case.rb +8 -6
  120. data/lib/eco/api/usecases/ooze_samples/helpers/creatable.rb +4 -3
  121. data/lib/eco/api/usecases/ooze_samples/helpers/exportable_ooze.rb +39 -25
  122. data/lib/eco/api/usecases/ooze_samples/helpers/exportable_register.rb +13 -15
  123. data/lib/eco/api/usecases/ooze_samples/helpers/filters.rb +50 -21
  124. data/lib/eco/api/usecases/ooze_samples/helpers/ooze_handlers.rb +21 -11
  125. data/lib/eco/api/usecases/ooze_samples/helpers/rescuable.rb +2 -0
  126. data/lib/eco/api/usecases/ooze_samples/helpers/shortcuts.rb +49 -43
  127. data/lib/eco/api/usecases/ooze_samples/ooze_base_case.rb +17 -19
  128. data/lib/eco/api/usecases/ooze_samples/register_export_case.rb +48 -43
  129. data/lib/eco/api/usecases/ooze_samples/register_update_case.rb +33 -34
  130. data/lib/eco/api/usecases/ooze_samples/target_oozes_update_case.rb +8 -10
  131. data/lib/eco/api/usecases.rb +0 -1
  132. data/lib/eco/cli/config/use_cases.rb +31 -29
  133. data/lib/eco/cli_default/workflow.rb +13 -14
  134. data/lib/eco/csv/table.rb +34 -25
  135. data/lib/eco/data/hashes/array_diff.rb +24 -35
  136. data/lib/eco/data/hashes/diff_result/meta.rb +131 -0
  137. data/lib/eco/data/hashes/diff_result.rb +65 -57
  138. data/lib/eco/data/hashes/sanke_camel_indifferent_access.rb +278 -0
  139. data/lib/eco/data/hashes.rb +1 -1
  140. data/lib/eco/data/locations/convert.rb +1 -1
  141. data/lib/eco/data/locations/node_base/csv_convert.rb +19 -9
  142. data/lib/eco/data/locations/node_base/parsing.rb +4 -2
  143. data/lib/eco/data/locations/node_base/treeify.rb +149 -132
  144. data/lib/eco/data/locations/node_base.rb +15 -4
  145. data/lib/eco/data/locations/node_diff/accessors.rb +13 -5
  146. data/lib/eco/data/locations/node_diff/nodes_diff/clustered_treeify.rb +101 -0
  147. data/lib/eco/data/locations/node_diff/nodes_diff/diffs_tree.rb +99 -0
  148. data/lib/eco/data/locations/node_diff/{selectors.rb → nodes_diff/selectors.rb} +1 -1
  149. data/lib/eco/data/locations/node_diff/nodes_diff.rb +50 -35
  150. data/lib/eco/data/locations/node_diff.rb +45 -17
  151. data/lib/eco/data/locations/node_level/parsing.rb +15 -21
  152. data/lib/eco/data/locations/node_level.rb +66 -22
  153. data/lib/eco/data/locations/node_plain/parsing.rb +1 -1
  154. data/lib/eco/data/locations/node_plain.rb +60 -7
  155. data/lib/eco/data/strings/camel_case.rb +35 -0
  156. data/lib/eco/data/strings/snake_case.rb +18 -0
  157. data/lib/eco/data/strings.rb +8 -0
  158. data/lib/eco/data.rb +1 -0
  159. data/lib/eco/language/methods/call_detector.rb +11 -0
  160. data/lib/eco/language/methods/dsl_able.rb +7 -1
  161. data/lib/eco/language/methods.rb +2 -1
  162. data/lib/eco/language/models/collection.rb +23 -25
  163. data/lib/eco/language/models/parser_serializer.rb +24 -5
  164. data/lib/eco/version.rb +1 -1
  165. data/lib/eco-helpers.rb +0 -1
  166. metadata +52 -7
  167. data/lib/eco/data/hashes/diff_meta.rb +0 -52
@@ -93,7 +93,7 @@ module Eco
93
93
  end
94
94
 
95
95
  # Adds an entry(ies) to the job queue.
96
- # @param entry [Ecoportal::API::V1::Person, Enumberable<Person>] the person(s) we want to update, carrying the changes to be done.
96
+ # @param entry [Ecoportal::API::V1::Person, Enumerable<Person>] the person(s) we want to update, carrying the changes to be done.
97
97
  # @param unique [Boolean] specifies if repeated entries should be avoided in the queue.
98
98
  # @yield [person] callback before launching the batch job request against the server.
99
99
  # @yieldparam person [Person] current person object that that should be treated by the callback before launching the batch.
@@ -8,12 +8,21 @@ module Eco
8
8
 
9
9
  attr_key :file, :structure_id
10
10
 
11
+ # The location node classifications of the organization
12
+ # @return [Eco::API::Organization::NodeClassifications]
13
+ def node_classifications(active: true)
14
+ return [] unless (graphql = graphql_api)
15
+
16
+ node_types = graphql.locationStructure.nodeClassifications(active: active)
17
+ Eco::API::Organization::NodeClassifications.new(node_types)
18
+ end
19
+
11
20
  # @note it retrieves the tree this way:
12
21
  # 1. If there's a file tagtree.json file, it uses it
13
22
  # 2. If no file, retrieves `structure_id` (config)
14
23
  # @param include_archived [Boolean] whether or not it should include archived nodes.
15
24
  # @return [Eco::API::Organization::TagTree]
16
- def scope_tree(enviro: nil, include_archived: true, raise_on_missing: true)
25
+ def scope_tree(enviro: nil, include_archived: true, raise_on_missing: true) # rubocop:disable Lint/UnusedMethodArgument
17
26
  return @tagtree if instance_variable_defined?(:@tagtree) && @tagtree.enviro == enviro
18
27
 
19
28
  kargs = {
@@ -21,34 +30,34 @@ module Eco
21
30
  includeArchivedNodes: include_archived
22
31
  }
23
32
 
24
- if tree_file = self.file
33
+ if (tree_file = file)
25
34
  if (tree = file_manager.load_json(tree_file)) && !tree.empty?
26
35
  @tagtree = Eco::API::Organization::TagTree.new(tree)
27
36
  end
28
- elsif self.structure_id
29
- kargs.merge(id: self.structure_id)
37
+ elsif structure_id
38
+ kargs.merge(id: structure_id)
30
39
  end
31
40
 
32
- @tagtree ||= live_tree(**kargs).tap do |tree|
33
- unless tree && !tree.empty?
34
- msg = "Could not find a local or live locations structure."
35
- raise MissingTagtree, msg
36
- end
41
+ @tagtree ||= live_tree(**kargs).tap do |tr| # rubocop:disable Naming/MemoizedInstanceVariableName
42
+ next if tr && !tr.empty?
43
+
44
+ msg = "Could not find a local or live locations structure."
45
+ raise MissingTagtree, msg
37
46
  end
38
47
  end
39
48
 
40
49
  # Among all the locations structures it selects the one with more location nodes
41
50
  # If `id` is provided, it only retrieves this locations structure.
42
51
  # @param [enviro] used for re-caching
43
- def live_tree(id: nil, enviro: nil, include_archived: false, **kargs, &block)
44
- existing_cache = !!@live_tree
52
+ def live_tree(id: nil, enviro: nil, include_archived: false, **kargs, &block) # rubocop:disable Metrics/AbcSize
53
+ existing_cache = !@live_tree.nil?
45
54
  first_load = !existing_cache
46
55
 
47
56
  target_change = existing_cache && id && @live_tree.id != id
48
57
  enviro_change = existing_cache && enviro && @live_tree.enviro != enviro
49
58
 
50
59
  switching_target = existing_cache && (target_change || enviro_change)
51
- refresh_cache = existing_cache && !switching_target
60
+ _refresh_cache = existing_cache && !switching_target
52
61
 
53
62
  kargs = {
54
63
  includeArchivedNodes: include_archived
@@ -59,10 +68,12 @@ module Eco
59
68
  @live_tree = live_tree_get(**args, &block)
60
69
  else
61
70
  trees = live_trees(**kargs, &block)
62
- @live_tree = trees.reject do |tree|
63
- tree.empty?
64
- end.max do |a,b|
65
- a.count <=> b.count
71
+ if trees.count > 1
72
+ @live_tree = trees.reject(&:empty?).max do |a, b|
73
+ a.count <=> b.count
74
+ end
75
+ else
76
+ @live_tree = trees.first
66
77
  end
67
78
  end.tap do |tree|
68
79
  if tree
@@ -85,8 +96,7 @@ module Eco
85
96
  # @param include_archived [Boolean] whether or not to include archived **nodes**
86
97
  # @return [Eco::API::Organization::TagTree, NilClass]
87
98
  def live_tree_get(id: nil, include_archived: false, **kargs, &block)
88
- return nil unless apis.active_api.version_available?(:graphql)
89
- return nil unless graphql = apis.api(version: :graphql)
99
+ return nil unless (graphql = graphql_api)
90
100
 
91
101
  kargs = {
92
102
  id: id,
@@ -94,9 +104,11 @@ module Eco
94
104
  }.merge(kargs)
95
105
 
96
106
  start = Time.now
97
- return nil unless tree = graphql.currentOrganization.locationStructure(**kargs, &block)
107
+ tree = graphql.currentOrganization.locationStructure(**kargs, &block)
108
+ return nil unless tree
109
+
98
110
  end_time = Time.now
99
- secs = (end_time - start).round(3)
111
+ secs = (end_time - start).round(3)
100
112
 
101
113
  Eco::API::Organization::TagTree.new(tree.treeify, id: tree.id, name: tree.name).tap do |eco_tree|
102
114
  cnt = eco_tree.count
@@ -110,15 +122,16 @@ module Eco
110
122
  # @return [Array<Eco::API::Organization::TagTree>]
111
123
  def live_trees(include_archived: false, **kargs, &block)
112
124
  [].tap do |eco_trees|
113
- next unless apis.active_api.version_available?(:graphql)
114
- next unless graphql = apis.api(version: :graphql)
125
+ next unless (graphql = graphql_api)
115
126
 
116
127
  kargs = {
117
128
  includeArchivedNodes: include_archived
118
129
  }.merge(kargs)
119
130
 
120
131
  start = Time.now
121
- next unless trees = graphql.currentOrganization.locationStructures(**kargs, &block)
132
+ trees = graphql.currentOrganization.locationStructures(**kargs, &block)
133
+ next unless trees
134
+
122
135
  end_time = Time.now
123
136
  secs = (end_time - start).round(3)
124
137
  cnt = 0
@@ -134,6 +147,11 @@ module Eco
134
147
 
135
148
  private
136
149
 
150
+ def graphql_api
151
+ return nil unless apis.active_api.version_available?(:graphql)
152
+ apis.api(version: :graphql)
153
+ end
154
+
137
155
  def session
138
156
  ASSETS.session
139
157
  end
@@ -7,13 +7,13 @@ module Eco
7
7
 
8
8
  WORKFLOW_MODEL = [
9
9
  :options,
10
- {load: [{input: [:get, :filter]}, {people: [:get, :filter]}, :filter]},
10
+ {load: [{input: %i[get filter]}, {people: %i[get filter]}, :filter]},
11
11
  :usecases, :launch_jobs,
12
- {post_launch: [:usecases, :launch_jobs]},
12
+ {post_launch: %i[usecases launch_jobs]},
13
13
  :report,
14
14
  :end,
15
15
  :close
16
- ]
16
+ ].freeze
17
17
 
18
18
  class << self
19
19
  def stages
@@ -40,7 +40,7 @@ module Eco
40
40
  self.model = WORKFLOW_MODEL
41
41
  attr_reader :config
42
42
 
43
- def initialize(name = nil, _parent: self, config:)
43
+ def initialize(name = nil, config:, _parent: self) # rubocop:disable Lint/UnderscorePrefixedVariableName
44
44
  @config = config
45
45
  @name = name
46
46
 
@@ -97,7 +97,7 @@ module Eco
97
97
  # 2. if block is not provided, it returns the **stage** referred by `key`
98
98
  def for(key = nil, &block)
99
99
  raise ArgumentError, "With no 'key', a block should be given." unless key || block_given?
100
- self.tap do
100
+ tap do
101
101
  next yield(self) unless key
102
102
  next stage(key).for(&block) if block_given?
103
103
  return stage(key)
@@ -106,7 +106,8 @@ module Eco
106
106
  alias_method :with, :for
107
107
 
108
108
  # Used in **configuration** time **to define** the **behaviour** the target (sub)stage `key`
109
- # @note if a `block` is provided it will **not** `yield` the target stage immediately, but when the _workflow_ reaches the stage
109
+ # @note if a `block` is provided it will **not** `yield` the target stage immediately,
110
+ # but when the _workflow_ reaches the stage
110
111
  # @param key [Symbol, nil] cases:
111
112
  # - if `key` is not provided, it targets the _current stage_
112
113
  # - if `key` is provided, it targets the specific _sub-stage_
@@ -117,16 +118,18 @@ module Eco
117
118
  # @return [Eco::API::Session::Config::Workflow] the current stage object (to ease chainig).
118
119
  def on(key = nil, &block)
119
120
  raise ArgumentError, "A block should be given." unless block_given?
120
- if !key
121
- @on = block
122
- else
121
+ if key
123
122
  stage(key).on(&block)
123
+ else
124
+ @on = block
124
125
  end
125
126
  self
126
127
  end
127
128
 
128
- # When there is an `Exception`, you might have defined some `callback` to do something with it (i.e. register, email)
129
- # @yield [exception, io] the `callback` to do something with an `Exception` raised within this _workflow_ stage
129
+ # When there is an `Exception`, you might have defined some `callback`
130
+ # to do something with it (i.e. register, email)
131
+ # @yield [exception, io] the `callback` to do something with
132
+ # an `Exception` raised within this _workflow_ stage
130
133
  # @yieldparam exception [Exception] the exception object that was raised
131
134
  # @yieldparam io [Eco::API::UseCases::BaseIO] the input/output object carried througout all the _workflow_
132
135
  # @yieldreturn [Eco::API::UseCases::BaseIO] the `io` input/output object carried througout all the _workflow_
@@ -146,46 +149,50 @@ module Eco
146
149
  self
147
150
  end
148
151
 
149
- # Used in **configuration** time **add previous** `callbacks` **before** the `on` _callback_ of the (sub)stage `key` is actually `run`
152
+ # Used in **configuration** time **add previous** `callbacks`
153
+ # **before** the `on` _callback_ of the (sub)stage `key` is actually `run`
150
154
  # @note
151
155
  # - it will **not** `yield` it immediately, but when the _workflow_ reaches the target stage
152
156
  # - in this case, you can define multiple `callbacks`
153
157
  # @param key [Symbol, nil] cases:
154
158
  # - if `key` is not provided, it targets the _current stage_
155
159
  # - if `key` is provided, it targets the specific _sub-stage_
156
- # @yield [stage_workflow, io] one of the things to do **before** the `on` _callback_ of the (sub)stage `key` is actually `run`
160
+ # @yield [stage_workflow, io] one of the things to do **before** the
161
+ # `on` _callback_ of the (sub)stage `key` is actually `run`
157
162
  # @yieldparam stage_workflow [Eco::API::Session::Config::Workflow] the _target stage_ referred by `key`
158
163
  # @yieldparam io [Eco::API::UseCases::BaseIO] the input/output object carried througout all the _workflow_
159
164
  # @yieldreturn [Eco::API::UseCases::BaseIO] `io` the input/output object carried througout all the _workflow_
160
165
  # @return [Eco::API::Session::Config::Workflow] the current stage object (to ease chainig).
161
166
  def before(key = nil, &block)
162
167
  raise ArgumentError, "A block should be given." unless block_given?
163
- if !key
164
- @before.push(block)
165
- else
168
+ if key
166
169
  stage(key).before(&block)
170
+ else
171
+ @before.push(block)
167
172
  end
168
173
  self
169
174
  end
170
175
 
171
- # Used in **configuration** time **add previous** `callbacks` **after** the `on` _callback_ of the (sub)stage `key` is actually `run`
176
+ # Used in **configuration** time **add previous** `callbacks` **after** the `on` _callback_
177
+ # of the (sub)stage `key` is actually `run`
172
178
  # @note
173
179
  # - it will **not** `yield` it immediately, but when the _workflow_ reaches the target stage
174
180
  # - in this case, you can define multiple `callbacks`
175
181
  # @param key [Symbol, nil] cases:
176
182
  # - if `key` is not provided, it targets the _current stage_
177
183
  # - if `key` is provided, it targets the specific _sub-stage_
178
- # @yield [stage_workflow, io] one of the things to do **after** the `on` _callback_ of the (sub)stage `key` is actually `run`
184
+ # @yield [stage_workflow, io] one of the things to do **after** the
185
+ # `on` _callback_ of the (sub)stage `key` is actually `run`
179
186
  # @yieldparam stage_workflow [Eco::API::Session::Config::Workflow] the _target stage_ referred by `key`
180
187
  # @yieldparam io [Eco::API::UseCases::BaseIO] the input/output object carried througout all the _workflow_
181
188
  # @yieldreturn [Eco::API::UseCases::BaseIO] `io` the input/output object carried througout all the _workflow_
182
189
  # @return [Eco::API::Session::Config::Workflow] the current stage object (to ease chainig).
183
190
  def after(key = nil, &block)
184
191
  raise ArgumentError, "A block should be given." unless block_given?
185
- if !key
186
- @after.push(block)
187
- else
192
+ if key
188
193
  stage(key).after(&block)
194
+ else
195
+ @after.push(block)
189
196
  end
190
197
  self
191
198
  end
@@ -202,8 +209,8 @@ module Eco
202
209
  # - it will **not** run the `callback` for `on` defined during the configuration time
203
210
  # - it will rather `yield` the target stage after all the `before` _callbacks_ have been run
204
211
  # - aside of this, the rest will be the same as when the _block_ is provided (see previous note)
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.
212
+ # @note [if the object returned by `before`, `after` and `run` callbacks
213
+ # is not an `Eco::API::UseCases::BaseIO`, the original `io` object will be returned instead.
207
214
  # @param key [Symbol, nil] cases:
208
215
  # - if `key` is not provided, it targets the _current stage_
209
216
  # - if `key` is provided, it targets the specific _sub-stage_
@@ -216,71 +223,81 @@ module Eco
216
223
  def run(key = nil, io:, &block)
217
224
  raise "Missing BaseIO object" unless io.is_a?(Eco::API::UseCases::BaseIO)
218
225
 
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|
226
+ rescuable(io) do
227
+ if key
225
228
  io = io_result(io: io) do
226
- io.evaluate(self, io, &c)
229
+ stage(key).run(io: io, &block)
227
230
  end
231
+ elsif pending?
232
+ io = run_before(io)
233
+ io = run_it(io, &block) unless skip?
234
+ io = run_after(io)
228
235
  end
236
+ io
237
+ ensure
238
+ @pending = false
239
+ end
240
+ end
229
241
 
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)
240
- end
241
- end
242
-
243
- unless ready?
244
- msg = "(Workflow: #{path}) 'on' callback is not defined, nor block given"
245
- io.session.logger.debug(msg)
246
- end
247
- io = io_result(io: io) do
248
- io.evaluate(self, io, &@on)
249
- end
250
- end
251
- @pending = false
242
+ protected
243
+
244
+ def root?
245
+ @_parent == self
246
+ end
247
+
248
+ def path
249
+ return name if root?
250
+ "#{@_parent.path}:#{name}"
251
+ end
252
+
253
+ def ready?
254
+ !!@on
255
+ end
256
+
257
+ def run_before(io)
258
+ @before.each do |c|
259
+ io = io_result(io: io) do
260
+ io.evaluate(self, io, &c)
252
261
  end
262
+ end
263
+ io
264
+ end
265
+
266
+ def run_after(io)
267
+ @after.each do |c|
268
+ io = io_result(io: io) do
269
+ io.evaluate(self, io, &c)
270
+ end
271
+ end
272
+ io
273
+ end
253
274
 
254
- @after.each do |c|
275
+ def run_it(io, &block)
276
+ io.session.logger.debug("(Workflow: #{path}) running now")
277
+ if block
278
+ io = io_result(io: io) do
279
+ io.evaluate(self, io, &block)
280
+ end
281
+ else
282
+ existing_stages.each do |stg|
255
283
  io = io_result(io: io) do
256
- io.evaluate(self, io, &c)
284
+ stg.run(io: io)
257
285
  end
258
286
  end
287
+
288
+ unless ready?
289
+ msg = "(Workflow: #{path}) 'on' callback is not defined, nor block given"
290
+ io.session.logger.debug(msg)
291
+ end
292
+ io = io_result(io: io) do
293
+ io.evaluate(self, io, &@on)
294
+ end
259
295
  end
260
296
  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
297
  ensure
275
298
  @pending = false
276
299
  end
277
300
 
278
- protected
279
-
280
- def root?
281
- @_parent == self
282
- end
283
-
284
301
  # It ensures an `Eco::API::UseCases::BaseIO` is returned
285
302
  # @note it always brings the IO to be a `BaseIO`.
286
303
  # As the `output` and the type is captured, it just cleans usecase related
@@ -296,19 +313,6 @@ module Eco
296
313
  io.instance_of?(klass) ? io : io.base
297
314
  end
298
315
 
299
- def path
300
- return name if root?
301
- "#{@_parent.path}:#{name}"
302
- end
303
-
304
- def root?
305
- @_parent == self
306
- end
307
-
308
- def ready?
309
- !!@on
310
- end
311
-
312
316
  def existing_stages
313
317
  # sort defined stages by stage order
314
318
  sorted_keys = self.class.stages & @stages.keys
@@ -316,17 +320,38 @@ module Eco
316
320
  end
317
321
 
318
322
  def ready_stages
319
- exiting_stages.select {|s| s.ready?}
323
+ exiting_stages.select(&:ready?)
320
324
  end
321
325
 
322
326
  def stages_ready?
323
- existing_stages.all? {|s| s.ready?}
327
+ existing_stages.all?(&:ready?)
324
328
  end
325
329
 
326
330
  def stage(key)
327
331
  self.class.validate_stage(key)
328
332
  @stages[key] ||= self.class.workflow_class(key).new(key, _parent: self, config: config)
329
333
  end
334
+
335
+ # helper to treat trigger the exit and rescue handlers
336
+ def rescuable(io)
337
+ yield
338
+ # rescue SystemStackError => err
339
+ # puts err.patch_full_message(trace_count: 100)
340
+ # exit 1
341
+ rescue SystemExit => err
342
+ io = io_result(io: io) do
343
+ io.evaluate(err, io, &exit_handle)
344
+ end
345
+ exit err.status
346
+ rescue Interrupt => _int
347
+ raise
348
+ rescue StandardError => err
349
+ # raise unless self.rescue
350
+ io = io_result(io: io) do
351
+ io.evaluate(err, io, &self.rescue)
352
+ end
353
+ raise
354
+ end
330
355
  end
331
356
  end
332
357
  end
@@ -238,6 +238,12 @@ module Eco
238
238
  tagtree_config.structure_id = value
239
239
  end
240
240
 
241
+ # The location node classifications of the organization
242
+ # @return [Eco::API::Organization::NodeClassifications]
243
+ def node_classifications(active: true)
244
+ tagtree_config.node_classifications(active: active)
245
+ end
246
+
241
247
  # It uses the `tagtree.json` file and in its absence, if `graphql` enabled, the largest `life_tagtree`
242
248
  # @note it does NOT include archived nodes by default.
243
249
  # - This is for legacy (most usecases don't)
@@ -5,16 +5,24 @@ module Eco
5
5
  class Session < Common::Session::BaseSession
6
6
  #@param init [Eco::API::Session::Config, Eco::API::Common::Session::Environment] object to ini the session
7
7
  def initialize(init = {})
8
- e = init
9
- msg = "Expected object Eco::API::Session::Config or Eco::API::Common::Session::Environment. Given: #{init}"
10
- raise msg unless e.is_a?(Session::Config) || e.is_a?(Eco::API::Common::Session::Environment)
11
- e = Eco::API::Common::Session::Environment.new(init, session: self) if !e.is_a?(Eco::API::Common::Session::Environment)
12
- super(e)
8
+ env = init
9
+
10
+ msg = "Expected object Eco::API::Session::Config or Eco::API::Common::Session::Environment. "
11
+ msg << " Given: #{init}"
12
+
13
+ correct_env = env.is_a?(Session::Config) || env.is_a?(Eco::API::Common::Session::Environment)
14
+ raise ArgumentError, msg unless correct_env
15
+
16
+ unless env.is_a?(Eco::API::Common::Session::Environment)
17
+ env = Eco::API::Common::Session::Environment.new(init, session: self)
18
+ end
19
+
20
+ super(env)
13
21
 
14
22
  @entry_factories = {}
15
23
  @person_factories = {}
16
24
 
17
- logger.debug("LINE COMMAND: #{$0} #{ARGV.join(" ")}")
25
+ logger.debug("LINE COMMAND: #{$0} #{ARGV.join(" ")}") # rubocop:disable Style/SpecialGlobalVars
18
26
  end
19
27
 
20
28
  # @retrun [String] the name of the current environment
@@ -24,7 +32,7 @@ module Eco
24
32
 
25
33
  # @return [Eco::API::Session::Batch] provides helper to launch batch operations.
26
34
  def batch
27
- @batch ||= Batch.new(enviro)
35
+ @batch ||= Batch.new(enviro)
28
36
  end
29
37
 
30
38
  # @!group Pure organization helpers
@@ -39,6 +47,12 @@ module Eco
39
47
  config.login_providers
40
48
  end
41
49
 
50
+ # The location node classifications of the organization
51
+ # @return [Eco::API::Organization::NodeClassifications]
52
+ def node_classifications(active: true)
53
+ config.node_classifications(active: active)
54
+ end
55
+
42
56
  # @param live [Boolean] states preference of `live` tree if available over file.
43
57
  # @param merge [Boolean] when in `live` mode, if mulitple trees, merge into one.
44
58
  # @see Eco::API::Session::Config#tagtree
@@ -79,11 +93,12 @@ module Eco
79
93
  end
80
94
 
81
95
  # Sets the current target `PersonSchema` of this session.
82
- # @note observe that it is essential for the parsers/serialisers to identify target/present attributes.
83
- # @param value [String, Ecoportal::API::V1::PersonSchema] where `String` can be the _name_ or the _id_ of the schema.
96
+ # @note observe that it is essential for the parsers/serialisers to identify
97
+ # target/present attributes.
98
+ # @param value [String, Ecoportal::API::V1::PersonSchema] where `String`
99
+ # can be the _name_ or the _id_ of the schema.
84
100
  def schema=(value)
85
101
  @schema = to_schema(value)
86
- self
87
102
  end
88
103
 
89
104
  # Helper to state the abilities that a person should have with given their usergroups
@@ -95,7 +110,7 @@ module Eco
95
110
  def fields_mapper
96
111
  return @fields_mapper if instance_variable_defined?(:@fields_mapper)
97
112
  mappings = []
98
- if map_file = config.people.fields_mapper
113
+ if (map_file = config.people.fields_mapper)
99
114
  mappings = map_file ? file_manager.load_json(map_file) : []
100
115
  end
101
116
  @fields_mapper = Eco::Data::Mapper.new(mappings)
@@ -140,7 +155,7 @@ module Eco
140
155
  # @param phase [Symbol] the phase when this parser should be active.
141
156
  # @return [Object] the parsed attribute.
142
157
  def parse_attribute(attr, source, phase = :internal, deps: {})
143
- unless parsers = entry_factory.person_parser
158
+ unless (parsers = entry_factory.person_parser)
144
159
  raise "There are no parsers defined"
145
160
  end
146
161
  parsers.parse(attr, source, phase, deps: deps)
@@ -182,10 +197,10 @@ module Eco
182
197
  # @return [Eco::API::Common::People::Entries] collection of entries.
183
198
  def csv_entries(file, **kargs)
184
199
  kargs.merge!({
185
- file: file,
200
+ file: file,
186
201
  format: :csv
187
202
  })
188
- return entries(**kargs)
203
+ entries(**kargs)
189
204
  end
190
205
 
191
206
  # Generates the collection of entries that should be discarded from an update.
@@ -193,8 +208,11 @@ module Eco
193
208
  # @return [Eco::API::Common::People::Entries] collection of entries.
194
209
  def discarded_entries
195
210
  return @discarded_entries if instance_variable_defined?(:@discarded_entries)
211
+
196
212
  file = config.people.discarded_file
197
- fatal("You have not specified the 'discarded_people_file'") unless file = file_manager.dir.file(file)
213
+ file = file_manager.dir.file(file)
214
+ fatal("You have not specified the 'discarded_people_file'") unless file
215
+
198
216
  @discarded_entries = csv_entries(file)
199
217
  end
200
218
  # @!endgroup
@@ -234,7 +252,7 @@ module Eco
234
252
  # @see Eco::API::MicroCases
235
253
  # @return [Eco::API::MicroCases]
236
254
  def micro
237
- @micro ||= Eco::API::MicroCases.new(enviro)
255
+ @micro ||= Eco::API::MicroCases.new(enviro)
238
256
  end
239
257
 
240
258
  def post_launch
@@ -255,18 +273,23 @@ module Eco
255
273
  # It retrives the group of `Batch::Jobs` named `name`. It creates it if it doesn't exist.
256
274
  # @return [Eco::API::Session::Batch::Jobs]
257
275
  def job_group(name, order: :last)
258
- case
259
- when job_groups.exists?(name)
260
- job_groups[name]
261
- else
262
- job_groups.new(name, order: order)
263
- end
276
+ return job_groups[name] if job_groups.exists?(name)
277
+
278
+ job_groups.new(name, order: order)
264
279
  end
265
280
 
266
281
  # Shortcut to create a job of certain type within a group
267
282
  # @param [see @Eco::API::Session::Batch::Jobs#new]
268
283
  # @return [Eco::API::Session::Batch::Job]
269
- def new_job(group, name, type, usecase, sets = [:core, :details, :account], accept_update_with_no_id = false, &block)
284
+ def new_job(
285
+ group,
286
+ name,
287
+ type,
288
+ usecase,
289
+ sets = %i[core details account],
290
+ accept_update_with_no_id = false, # rubocop:disable Style/OptionalBooleanParameter
291
+ &block
292
+ )
270
293
  job_group(group).new(name, usecase: usecase, type: type, sets: sets, accept_update_with_no_id: accept_update_with_no_id, &block)
271
294
  end
272
295
 
@@ -330,10 +353,10 @@ module Eco
330
353
  private
331
354
 
332
355
  # Comparer to state if 2 schemas are different
333
- def same_schema? (schema1, schema2)
334
- eq = schema1&.id == schema2&.id
335
- eq ||= schema1&.name&.downcase == schema2&.name&.downcase
336
- schema1 && schema2 && eq
356
+ def same_schema?(schema_1, schema_2)
357
+ eq = schema_1&.id == schema_2&.id
358
+ eq ||= schema_1&.name&.downcase == schema_2&.name&.downcase
359
+ schema_1 && schema_2 && eq
337
360
  end
338
361
 
339
362
  # from schema `id` or `name` to a PersonSchema object
@@ -342,7 +365,7 @@ module Eco
342
365
  sch = nil
343
366
  case value
344
367
  when String
345
- unless sch = schemas.schema(value)
368
+ unless (sch = schemas.schema(value))
346
369
  fatal "The schema with id or name '#{value}' does not exist."
347
370
  end
348
371
  when Ecoportal::API::V1::PersonSchema
@@ -352,7 +375,6 @@ module Eco
352
375
  end
353
376
  sch
354
377
  end
355
-
356
378
  end
357
379
  end
358
380
  end