eco-helpers 2.5.1 → 2.5.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +52 -1
  3. data/eco-helpers.gemspec +2 -2
  4. data/lib/eco/api/common/loaders/parser.rb +0 -1
  5. data/lib/eco/api/common/loaders/use_case.rb +0 -2
  6. data/lib/eco/api/common/people/person_entry_attribute_mapper.rb +0 -2
  7. data/lib/eco/api/common/session/logger.rb +22 -77
  8. data/lib/eco/api/microcases/with_each.rb +0 -1
  9. data/lib/eco/api/organization/tag_tree.rb +64 -15
  10. data/lib/eco/api/session/config/tagtree.rb +32 -10
  11. data/lib/eco/api/session/config/workflow.rb +9 -3
  12. data/lib/eco/api/session/config.rb +6 -2
  13. data/lib/eco/api/session.rb +2 -2
  14. data/lib/eco/api/usecases/default_cases/abstract_policygroup_abilities_case.rb +2 -3
  15. data/lib/eco/api/usecases/default_cases/analyse_people_case.rb +2 -3
  16. data/lib/eco/api/usecases/default_cases/append_usergroups_case.rb +0 -1
  17. data/lib/eco/api/usecases/default_cases/change_email_case.rb +1 -2
  18. data/lib/eco/api/usecases/default_cases/clean_unknown_tags_case.rb +0 -5
  19. data/lib/eco/api/usecases/default_cases/clear_abilities_case.rb +2 -2
  20. data/lib/eco/api/usecases/default_cases/codes_to_tags_case.rb +5 -7
  21. data/lib/eco/api/usecases/default_cases/create_case.rb +0 -5
  22. data/lib/eco/api/usecases/default_cases/create_details_case.rb +0 -5
  23. data/lib/eco/api/usecases/default_cases/create_details_with_supervisor_case.rb +0 -5
  24. data/lib/eco/api/usecases/default_cases/csv_to_tree_case/helper.rb +1 -1
  25. data/lib/eco/api/usecases/default_cases/csv_to_tree_case.rb +0 -4
  26. data/lib/eco/api/usecases/default_cases/delete_sync_case.rb +2 -4
  27. data/lib/eco/api/usecases/default_cases/delete_trans_case.rb +2 -3
  28. data/lib/eco/api/usecases/default_cases/email_as_id_case.rb +0 -1
  29. data/lib/eco/api/usecases/default_cases/entries_to_csv_case.rb +0 -4
  30. data/lib/eco/api/usecases/default_cases/hris_case.rb +2 -3
  31. data/lib/eco/api/usecases/default_cases/new_email_case.rb +0 -2
  32. data/lib/eco/api/usecases/default_cases/new_id_case.rb +0 -2
  33. data/lib/eco/api/usecases/default_cases/org_data_convert_case.rb +0 -5
  34. data/lib/eco/api/usecases/default_cases/refresh_case.rb +0 -1
  35. data/lib/eco/api/usecases/default_cases/reinvite_sync_case.rb +1 -3
  36. data/lib/eco/api/usecases/default_cases/reinvite_trans_case.rb +2 -2
  37. data/lib/eco/api/usecases/default_cases/remove_account_sync_case.rb +1 -2
  38. data/lib/eco/api/usecases/default_cases/remove_account_trans_case.rb +2 -3
  39. data/lib/eco/api/usecases/default_cases/reset_landing_page_case.rb +1 -7
  40. data/lib/eco/api/usecases/default_cases/restore_db_case.rb +0 -10
  41. data/lib/eco/api/usecases/default_cases/set_default_tag_case.rb +0 -1
  42. data/lib/eco/api/usecases/default_cases/set_supervisor_case.rb +0 -1
  43. data/lib/eco/api/usecases/default_cases/supers_cyclic_identify_case.rb +2 -3
  44. data/lib/eco/api/usecases/default_cases/supers_hierarchy_case.rb +2 -3
  45. data/lib/eco/api/usecases/default_cases/switch_supervisor_case.rb +2 -4
  46. data/lib/eco/api/usecases/default_cases/tagtree_case.rb +0 -2
  47. data/lib/eco/api/usecases/default_cases/to_csv_case.rb +4 -5
  48. data/lib/eco/api/usecases/default_cases/to_csv_detailed_case.rb +0 -1
  49. data/lib/eco/api/usecases/default_cases/transfer_account_case.rb +0 -2
  50. data/lib/eco/api/usecases/default_cases/update_case.rb +0 -2
  51. data/lib/eco/api/usecases/default_cases/update_details_case.rb +0 -2
  52. data/lib/eco/api/usecases/default_cases/upsert_case.rb +0 -4
  53. data/lib/eco/api/usecases/graphql/base.rb +6 -18
  54. data/lib/eco/api/usecases/graphql/helpers/base.rb +31 -0
  55. data/lib/eco/api/usecases/graphql/helpers/location/base.rb +87 -0
  56. data/lib/eco/api/usecases/graphql/helpers/location/command/result.rb +69 -0
  57. data/lib/eco/api/usecases/graphql/helpers/location/command/results.rb +126 -0
  58. data/lib/eco/api/usecases/graphql/helpers/location/command.rb +84 -0
  59. data/lib/eco/api/usecases/graphql/helpers/location.rb +7 -0
  60. data/lib/eco/api/usecases/graphql/helpers.rb +2 -1
  61. data/lib/eco/api/usecases/graphql/samples/location/command/dsl.rb +54 -0
  62. data/lib/eco/api/usecases/graphql/samples/location/command/results.rb +125 -0
  63. data/lib/eco/api/usecases/graphql/samples/location/command.rb +10 -0
  64. data/lib/eco/api/usecases/graphql/samples/location/dsl.rb +6 -0
  65. data/lib/eco/api/usecases/graphql/samples/location.rb +10 -0
  66. data/lib/eco/api/usecases/graphql/samples.rb +6 -0
  67. data/lib/eco/api/usecases/graphql.rb +2 -1
  68. data/lib/eco/api/usecases/ooze_cases/export_register_case.rb +0 -1
  69. data/lib/eco/api/usecases/ooze_samples/ooze_base_case.rb +0 -2
  70. data/lib/eco/api/usecases/ooze_samples/register_migration_case.rb +0 -2
  71. data/lib/eco/api/usecases/use_case.rb +2 -2
  72. data/lib/eco/cli/config/default/workflow.rb +3 -5
  73. data/lib/eco/cli/scripting/args_helpers.rb +0 -2
  74. data/lib/eco/csv/table.rb +39 -3
  75. data/lib/eco/data/files/helpers.rb +1 -0
  76. data/lib/eco/data/hashes/array_diff.rb +12 -6
  77. data/lib/eco/data/hashes/diff_result.rb +1 -2
  78. data/lib/eco/data/locations/convert.rb +92 -0
  79. data/lib/eco/data/locations/dsl.rb +35 -0
  80. data/lib/eco/data/locations/node_base/builder.rb +26 -0
  81. data/lib/eco/data/locations/node_base/csv_convert.rb +57 -0
  82. data/lib/eco/data/locations/node_base/parsing.rb +30 -0
  83. data/lib/eco/data/locations/node_base/serial.rb +26 -0
  84. data/lib/eco/data/locations/node_base/tag_validations.rb +52 -0
  85. data/lib/eco/data/locations/node_base/treeify.rb +150 -0
  86. data/lib/eco/data/locations/node_base.rb +48 -0
  87. data/lib/eco/data/locations/node_level/builder.rb +6 -0
  88. data/lib/eco/data/locations/node_level/cleaner.rb +74 -0
  89. data/lib/eco/data/locations/node_level/parsing.rb +63 -0
  90. data/lib/eco/data/locations/node_level/serial.rb +37 -0
  91. data/lib/eco/data/locations/node_level.rb +156 -0
  92. data/lib/eco/data/locations/node_plain/builder.rb +6 -0
  93. data/lib/eco/data/locations/node_plain/parsing.rb +36 -0
  94. data/lib/eco/data/locations/node_plain/serial.rb +14 -0
  95. data/lib/eco/data/locations/node_plain.rb +34 -0
  96. data/lib/eco/data/locations.rb +12 -0
  97. data/lib/eco/data.rb +1 -0
  98. data/lib/eco/language/auxiliar_logger.rb +9 -1
  99. data/lib/eco/language/basic_logger.rb +74 -0
  100. data/lib/eco/language.rb +2 -1
  101. data/lib/eco/version.rb +1 -1
  102. metadata +37 -8
  103. data/lib/eco/api/usecases/default_cases/new_id_case0.rb +0 -14
  104. data/lib/eco/api/usecases/graphql/helpers/locations/commands.rb +0 -4
  105. data/lib/eco/api/usecases/graphql/helpers/locations.rb +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b15015d62d69b57bfaef2e33cb9800786806f1796621f8a7c3fdc570bec81c99
4
- data.tar.gz: 046b93c466ef6999e97c2d17584d4e760c3d6592783448c4fed3aed2edd3a0d2
3
+ metadata.gz: adb24d7f2036b028bdd81302479211ea745e82abdb6b3a69afa2253e3f8fe444
4
+ data.tar.gz: 4d149fa100a5a661e4b019aa601c0da3af051ba6e019c77e22b6599c312a4fcb
5
5
  SHA512:
6
- metadata.gz: '079b89d982758de246c8f81fcc5e8853fdcc75c217f1b7e417408b9234a8a942aa874e77705fe62c0863699bf72dcf666297894b6febdb3f47bcb740af2d438e'
7
- data.tar.gz: 7feaa9e6022432a50c3fab188283e6af6566a8fe9de7b84fd3dcfba4584c64fd02cc5d926f3f50db8a44f139138844438345222d941b7407a6f4369b257ca070
6
+ metadata.gz: 8583dc7689de13744421db380f3193072f754091a1db6434010568907ff2f4e39d5ed3146b045ab47632cdf0bc5bc8c7e3fe326be466e7b4926f8c8c41344b31
7
+ data.tar.gz: b34c886f7cde59854838a087fcb10442f14835a87bf3a264534a4a4641a3a1ca2b302352a920f37536cb0686a213ce7d2d06949c2c2bc89e31f3c8e7650ab32e
data/CHANGELOG.md CHANGED
@@ -1,11 +1,62 @@
1
1
  # Change Log
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
- ## [2.5.2] - 2023-06-xx
4
+ ## [2.5.3] - 2023-07-xx
5
+
6
+ ### Added
7
+ - _GraphQL base case_ for **locations structure update**.
8
+ - Refer to `Eco::API::UseCases::GraphQL::Samples::LocationCommands`
9
+ - See also `Eco::API::UseCases::GraphQL`. **Added** `Helpers` and `Samples`
10
+ - `Eco::Data::Locations` helpers
11
+ - **Converters**: it offers a `DSL` (see `Eco::Data::Locations::DSL`) manage as input/output:
12
+ 1. CSV files with locations in two basic formats (list of nodes and hierarchy of locations)
13
+ 2. This comes with integrity checkers to ensure the input data files are correct (warnings)
14
+ 3. It also allows to convert to/from an organization locations structure and csv files.
15
+ - Making generic the helpers of `Eco::API::UseCases::DefaultCases::CsvToTree`
16
+ - The prospect is to move to the new/reviewed helpers at some stage (so remove the old helpers)
17
+ - This comes with a series of **converters** and **parsers** to allow two basic forms of input/output:
18
+ - CSV with list of nodes (`id`, `name`, `parent_id`)
19
+ - CSV of the actual tree (each column is one level of the tree)
20
+ - `Eco::API::Organization::TagTree` - **added/improved methods**
21
+ - **added** shortcuts: `parent_id`, `parent_name`
22
+ - **added** filters: `select`, `reject`
23
+ - **improved** `as_json`:
24
+ 1. new parameter `include_children`
25
+ 2. Hash keys | Header names to `HEADER` column
26
+ - **added** `as_nodes_json` to obtain a plain list (rather than hierarchical `as_json`)
27
+ - `Eco::CSV::Table`
28
+ - **added** `#add_index_column` to numerate the rows in a new column
29
+ - **improved** `#add_column` with new parameter `pos`
30
+ - **added** `#nil_blank_cells` and `#nil_blank_cells!`
31
+ - `Eco::Language::BasicLogger` brief extensible logger.
32
+
33
+ ### Changed
34
+ - Refactored `Eco::API::Session::Logger` inheriting from `Eco::Language::BasicLogger`
35
+
36
+ ### Fixed
37
+ - Live tree retrieval. Allow to specify locations structure `id`, `kargs` & `block`.
38
+ - `Eco::API::Session#live_tree` allow `id`, `kargs` & `block`, **fix** pass `include_archived`
39
+ - `Eco::API::Session::Config#live_tree` allow `id`, `kargs` & `block`
40
+ - When `id` is given, it uses `tagtree_config#live_tree_get`
41
+ - **fixed** neither `kargs` nor `include_archived` where defined
42
+ - `Eco::API::Session::Config::Tagtree` methods
43
+ - `#live_trees` allow `kargs`
44
+ - `#live_tree_get` **added**: it does not memoize
45
+ - `#live_tree` allow `id` and `kargs`
46
+ - **fixed** `include_archived` nodes should not be redirected to `live_trees` as in the latter this parameter has a different meaning (it refers to archived structures).
47
+ - **Important note**: the `ecoportal-api-graphql` gem, at the moment always retrieves archived nodes. This makes the `include_archived` argument non-functional. However, at some stage this will be changed and everything should be sorted out by then.
48
+
49
+ ## [2.5.2] - 2023-06-23
5
50
 
6
51
  ### Added
52
+ - `Eco::API::Session::Config::Workflow#exit_handle`
53
+ - Allows to define a callback on `SystemExit` (`exit` call).
54
+
7
55
  ### Changed
8
56
  ### Fixed
57
+ - `Eco::API::Session::Config::Workflow` on `SystemExit` preserve original exit `status` value (i.e. `0`, `1`)
58
+ - It was changing an `exit 1` to be an `exit 0`
59
+ - Default Workflow. `exit 0` when no operation specified (rather than `exit 1`).
9
60
 
10
61
  ## [2.5.1] - 2023-06-06
11
62
 
data/eco-helpers.gemspec CHANGED
@@ -31,8 +31,8 @@ Gem::Specification.new do |spec|
31
31
  spec.add_development_dependency "redcarpet", ">= 3.5.1", "< 4"
32
32
 
33
33
  spec.add_dependency 'ecoportal-api', '>= 0.9.4', '< 0.10'
34
- spec.add_dependency 'ecoportal-api-v2', '>= 1.1.2', '< 1.2'
35
- spec.add_dependency 'ecoportal-api-graphql', '>= 0.3.7', '< 0.4'
34
+ spec.add_dependency 'ecoportal-api-v2', '>= 1.1.3', '< 1.2'
35
+ spec.add_dependency 'ecoportal-api-graphql', '>= 0.3.8', '< 0.4'
36
36
  spec.add_dependency 'aws-sdk-s3', '>= 1.83.0', '< 2'
37
37
  spec.add_dependency 'aws-sdk-ses', '>= 1.36.0', '< 2'
38
38
  spec.add_dependency 'dotenv', '>= 2.7.6', '< 3'
@@ -149,7 +149,6 @@ module Eco
149
149
  def _define_serializer(attr_parser)
150
150
  attr_parser.def_serializer(self.class.serializing_phase, &self.method(:serializer))
151
151
  end
152
-
153
152
  end
154
153
  end
155
154
  end
@@ -3,7 +3,6 @@ module Eco
3
3
  module Common
4
4
  module Loaders
5
5
  class UseCase < Eco::API::Common::Loaders::CaseBase
6
-
7
6
  class << self
8
7
  # @return [Symbol] the `type` of usecase (i.e. `:sync`, `:transform`, `:import`, `:other`)
9
8
  def type(value = nil)
@@ -34,7 +33,6 @@ module Eco
34
33
  def type
35
34
  self.class.type
36
35
  end
37
-
38
36
  end
39
37
  end
40
38
  end
@@ -2,7 +2,6 @@ module Eco
2
2
  module API
3
3
  module Common
4
4
  module People
5
-
6
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.
7
6
  class PersonEntryAttributeMapper
8
7
  @@cached_warnings = {}
@@ -266,7 +265,6 @@ module Eco
266
265
  logger.fatal(msg)
267
266
  raise msg
268
267
  end
269
-
270
268
  end
271
269
  end
272
270
  end
@@ -2,111 +2,56 @@ module Eco
2
2
  module API
3
3
  module Common
4
4
  module Session
5
- class Logger
6
- DEFAULT_TIMESTAMP_PATTERN = '%Y-%m-%dT%H:%M:%S'
5
+ class Logger < Eco::Language::BasicLogger
6
+ TIMESTAMP_PATTERN = '%Y-%m-%dT%H:%M:%S'
7
7
 
8
8
  attr_reader :cache
9
9
 
10
- def initialize(console_level: nil, file_level: ::Logger::DEBUG, log_file: nil, timestamp_console: false, enviro: nil)
10
+ def initialize(file_level: ::Logger::DEBUG, log_file: nil, enviro: nil, **kargs)
11
+ super(**kargs)
11
12
  raise "Required Environment object (enviro:). Given: #{enviro}" if enviro && !enviro.is_a?(Eco::API::Common::Session::Environment)
12
13
  @enviro = enviro
13
14
  @cache = Logger::Cache.new
14
15
 
15
- timestamp_console = fetch_timestamp_console(timestamp_console)
16
- @console_logger = ::Logger.new(STDOUT).tap do |_logger|
17
- _logger.formatter = proc do |severity, datetime, progname, msg|
18
- str_timestamp = timestamp_console ? "#{datetime.strftime(DEFAULT_TIMESTAMP_PATTERN)} >" : ""
19
- "#{severity.to_s[0]}: #{str_timestamp} #{msg}\n"
20
- end
21
- _logger.level = fetch_console_level(console_level)
22
- end
23
-
24
16
  if log_file = fetch_log_file(log_file)
25
- @file_logger = ::Logger.new(log_file).tap do |_logger|
26
- _logger.formatter = proc do |severity, datetime, progname, msg|
27
- "#{severity.to_s[0]}: #{datetime.strftime(DEFAULT_TIMESTAMP_PATTERN)} > #{msg}\n".tap do |formatted|
28
- cache.add(severity, datetime, msg, formatted)
29
- end
17
+ loggers[:file] = ::Logger.new(log_file).tap do |logger|
18
+ logger.formatter = format_proc(console: false) do |severity, datetime, msg, formatted_msg|
19
+ cache.add(severity, datetime, msg, formatted_msg)
30
20
  end
31
- _logger.level = fetch_file_level(file_level)
21
+ logger.level = file_level
32
22
  end
33
23
  end
34
- end
35
-
36
- def level=(value)
37
- @console_logger.level = value
38
- end
39
-
40
- def debug(*args, &block)
41
- log(:debug, *args, &block)
42
- end
43
-
44
- def info(*args, &block)
45
- log(:info, *args, &block)
46
- end
47
-
48
- def warn(*args, &block)
49
- return log(:warn, *args, &block)
50
- end
51
-
52
- def error(*args, &block)
53
- return log(:error, *args, &block)
54
- end
55
24
 
56
- def fatal(*args, &block)
57
- return log(:fatal, *args, &block)
25
+ if_config(:timestamp_console) { |value| self.timestamp = value }
26
+ if_config(:console_level) { |value| self.level = value }
27
+ if_config(:file_level) { |value| self.file_level = value }
58
28
  end
59
29
 
60
- def unknown(msg, &block)
61
- return log(:unknown, *args, &block)
62
- end
63
-
64
- def << (msg)
65
- @console_logger << msg unless !@console_logger
66
- @file_logger << msg unless !@file_logger
67
- end
68
-
69
- def close()
70
- @console_logger.close unless !@console_logger
71
- @file_logger.close unless !@file_logger
72
- end
73
-
74
- def add(*args)
75
- @console_logger.add(*args) unless !@console_logger
76
- @file_logger.add(*args) unless !@file_logger
30
+ def file_level=(value)
31
+ loggers[:file]&.level = value
77
32
  end
78
33
 
79
34
  private
80
35
 
81
- def log(level, *args, &block)
82
- @console_logger.send(level, *args, &block) unless !@console_logger
83
- @file_logger.send(level, *args, &block) unless !@file_logger
84
- end
85
-
86
- def config
87
- @enviro.config || {}
88
- end
89
-
90
- def fetch_timestamp_console(value)
91
- value || config.logger.timestamp_console
36
+ def config(attr)
37
+ return nil unless cnf = @enviro&.config&.logger
38
+ cnf.send(attr) if cnf.respond_to?(attr)
92
39
  end
93
40
 
94
- def fetch_console_level(value)
95
- value || config.logger.console_level || ::Logger::INFO
96
- end
97
-
98
- def fetch_file_level(value)
99
- value || config.logger.file_level || ::Logger::DEBUG
41
+ def if_config(attr)
42
+ unless (value = config(attr)).nil?
43
+ yield(value) if block_given?
44
+ value
45
+ end
100
46
  end
101
47
 
102
48
  def fetch_log_file(log_file)
103
- if log_file ||= config.logger.file
49
+ if log_file ||= config(:file)
104
50
  log_file = @enviro.file_manager.dir.file(log_file) if @enviro
105
51
  FileManager.create_directory(log_file, includes_file: true)
106
52
  end
107
53
  log_file
108
54
  end
109
-
110
55
  end
111
56
  end
112
57
  end
@@ -86,7 +86,6 @@ module Eco
86
86
  end
87
87
  end
88
88
  end
89
-
90
89
  end
91
90
  end
92
91
  end
@@ -2,7 +2,15 @@ module Eco
2
2
  module API
3
3
  module Organization
4
4
  # Provides helpers to deal with tagtrees.
5
+ # @note that currenlty the parsing assumes top level to be array.
6
+ # This does not allow to capture the `name` and `id` of the locations
7
+ # structure itself into the json storing model.
5
8
  class TagTree
9
+ HEADER = [
10
+ 'id', 'name', 'weight', 'parent_id',
11
+ 'archived', 'archived_token'
12
+ ].freeze
13
+
6
14
  attr_accessor :id
7
15
  alias_method :tag, :id
8
16
  attr_accessor :name, :weight
@@ -82,6 +90,27 @@ module Eco
82
90
  all_nodes.each(&block)
83
91
  end
84
92
 
93
+ # @note rejected nodes will not include their children nodes
94
+ # @return [Array<TagTree>] plain list of nodes
95
+ def select(when_is: true, &block)
96
+ raise ArgumentError, "Missing block" unless block_given?
97
+ [].tap do |out_nodes|
98
+ selected = false
99
+ selected = (yield(self) == when_is) unless top?
100
+ out_nodes.push(self) if selected
101
+ next unless selected || top?
102
+ nodes.each do |nd|
103
+ out_nodes.concat(nd.select(when_is: when_is, &block))
104
+ end
105
+ end
106
+ end
107
+
108
+ # @note rejected nodes will not include their children nodes
109
+ # @return [Array<TagTree>] plain list of nodes
110
+ def reject(&block)
111
+ select(when_is: false, &block)
112
+ end
113
+
85
114
  # All actual nodes of this tree
86
115
  # @note order is that of the parent to child relationships
87
116
  # @return [Array<TagTree>]
@@ -91,8 +120,8 @@ module Eco
91
120
  out_nodes.push(self)
92
121
  yield(self) if block_given?
93
122
  end
94
- nodes.each do |node|
95
- out_nodes.concat(node.all_nodes(&block))
123
+ nodes.each do |nd|
124
+ out_nodes.concat(nd.all_nodes(&block))
96
125
  end
97
126
  end
98
127
  end
@@ -109,6 +138,16 @@ module Eco
109
138
  end
110
139
  end
111
140
 
141
+ # @return [String] the `id` of the parent (unless we are on a top level node)
142
+ def parent_id
143
+ parent.id unless parent.top?
144
+ end
145
+
146
+ # @return [String] the `name` of the parent (unless we are on a top level node)
147
+ def parent_name
148
+ parent.name unless parent.top?
149
+ end
150
+
112
151
  # @return [Array] with the differences
113
152
  def diff(tagtree, differences: {}, level: 0, **options)
114
153
  require 'hashdiff'
@@ -119,22 +158,32 @@ module Eco
119
158
  depth == -1
120
159
  end
121
160
 
122
- # @return [Array[Hash]] where `Hash` is a `node` `{"tag" => TAG, "nodes": Array[Hash]}`
123
- def as_json
124
- nodes_json = nodes.map {|node| node.as_json}
161
+ # Returns a tree of Hashes form nested via `nodes` (or just a list of hash nodes)
162
+ # @yield [node_json, node] block for custom output json model
163
+ # @yiledreturn [Hash] the custom json model.
164
+ # @include_children [Boolean] whether it should return a tree hash or just a list of hash nodes.
165
+ # @return [Array[Hash]] where `Hash` is a `node` (i.e. `{"tag" => TAG, "nodes": Array[Hash]}`)
166
+ def as_json(include_children: true, &block)
167
+ return [] if top? && !include_children
168
+ children_json = nodes.map {|nd| nd.as_json(include_children: true, &block)} if include_children
169
+
125
170
  if top?
126
- nodes_json
171
+ children_json
127
172
  else
128
- {
129
- "id" => tag,
130
- "archived" => archived,
131
- "archived_token" => archived_token,
132
- "weight" => weight,
133
- "nodes" => nodes_json
134
- }
173
+ values = [id, name, weight, parent_id, archived, archived_token]
174
+ node_json = self.class::HEADER.zip(values).to_h
175
+ node_json["nodes"] = children_json if include_children
176
+ node_json = yield(node_json, self) if block_given?
177
+ node_json
135
178
  end
136
179
  end
137
180
 
181
+ # Returns a plain list form of hash nodes.
182
+ # @return [Array[Hash]] where `Hash` is a plain `node`
183
+ def as_nodes_json
184
+ all_nodes.map {|nd| nd.as_json(include_children: false)}
185
+ end
186
+
138
187
  # @return [Boolean] `true` if there are tags in the node, `false` otherwise.
139
188
  def empty?
140
189
  count <= 1
@@ -148,8 +197,8 @@ module Eco
148
197
  # @return [Integer] the highest `depth` of all the children.
149
198
  def total_depth
150
199
  @total_depth ||= if has_children?
151
- deepest_node = nodes.max_by do |node|
152
- node.total_depth
200
+ deepest_node = nodes.max_by do |nd|
201
+ nd.total_depth
153
202
  end
154
203
  deepest_node.total_depth
155
204
  else
@@ -20,33 +20,55 @@ module Eco
20
20
  end
21
21
 
22
22
  # Among all the locations structures it selects the one with more location nodes
23
- def live_tree(enviro: nil, include_archived: false, &block)
23
+ # If `id` is provided, it only retrieves this locations structure.
24
+ def live_tree(id: nil, enviro: nil, include_archived: false, **kargs, &block)
24
25
  return @live_tree if instance_variable_defined?(:@live_tree) && @live_tree.enviro == enviro
25
- trees = live_trees(enviro: enviro, include_archived: include_archived, &block)
26
- @live_tree = trees.reject do |tree|
27
- tree.empty?
28
- end.max do |a,b|
29
- a.count <=> b.count
26
+ if id
27
+ args = {id: id, enviro: enviro, include_archived: include_archived}.merge(kargs)
28
+ @live_tree = live_tree_get(**args, &block)
29
+ else
30
+ # note that `include_archived` nodes is NOT the same as including archived structures
31
+ # => In `live_tree` the paramter refers to nodes
32
+ trees = live_trees(enviro: enviro, &block)
33
+ @live_tree = trees.reject do |tree|
34
+ tree.empty?
35
+ end.max do |a,b|
36
+ a.count <=> b.count
37
+ end
30
38
  end.tap do |tree|
31
39
  if tree
32
- msg ="Using LIVE LOCATIONS Structure: '#{tree.name}' (#{tree.count} nodes)"
40
+ msg = "Using LIVE LOCATIONS Structure: '#{tree.name}' (#{tree.count} nodes)"
33
41
  session_logger.info(msg)
34
42
  end
35
43
  end
36
44
  end
37
45
 
46
+ # Gets a single locations structure
47
+ # @note it does not memoize
48
+ def live_tree_get(id: nil, enviro: nil, include_archived: false, **kargs, &block)
49
+ return nil unless apis.active_api.version_available?(:graphql)
50
+ return nil unless graphql = apis.api(version: :graphql)
51
+ #kargs = { includeArchived: include_archived }.merge(kargs).slice(:includeArchived)
52
+ # For now, this endpoint only accepts `id` as a parameter. It is pending to
53
+ # expose further parameters via query
54
+ return nil unless tree = graphql.currentOrganization.locationStructure(id: id, &block)
55
+ args = { enviro: enviro, id: tree.id, name: tree.name }
56
+ Eco::API::Organization::TagTree.new(tree.treeify, **args)
57
+ end
58
+
38
59
  # Retrieves all the location structures of the organisation
39
- def live_trees(enviro: nil, include_archived: false, &block)
60
+ def live_trees(enviro: nil, include_archived: false, **kargs, &block)
40
61
  [].tap do |eco_trees|
41
62
  next unless apis.active_api.version_available?(:graphql)
42
63
  next unless graphql = apis.api(version: :graphql)
43
64
  kargs = {
44
65
  includeArchived: include_archived,
45
66
  includeUnpublished: false
46
- }
67
+ }.merge(kargs).slice(:includeArchived, :includeUnpublished)
68
+
47
69
  next unless trees = graphql.currentOrganization.locationStructures(**kargs, &block)
48
70
  trees.each do |tree|
49
- args = { enviro: enviro, id: tree.id, name: tree.name}
71
+ args = { enviro: enviro, id: tree.id, name: tree.name }
50
72
  eco_tree = Eco::API::Organization::TagTree.new(tree.treeify, **args)
51
73
  eco_trees.push(eco_tree)
52
74
  end
@@ -129,6 +129,12 @@ module Eco
129
129
  self
130
130
  end
131
131
 
132
+ def exit_handle(&block)
133
+ return @exit_handle unless block
134
+ @exit_handle = block
135
+ self
136
+ end
137
+
132
138
  # Used in **configuration** time **add previous** `callbacks` **before** the `on` _callback_ of the (sub)stage `key` is actually `run`
133
139
  # @note
134
140
  # - it will **not** `yield` it immediately, but when the _workflow_ reaches the target stage
@@ -239,8 +245,9 @@ module Eco
239
245
  end
240
246
  end
241
247
  end
242
- rescue SystemExit
243
- exit
248
+ rescue SystemExit => e
249
+ self.exit_handle.call(e, io) if self.exit_handle
250
+ exit e.status
244
251
  rescue Interrupt => i
245
252
  raise
246
253
  rescue Exception => e
@@ -283,7 +290,6 @@ module Eco
283
290
  self.class.validate_stage(key)
284
291
  @stages[key] ||= self.class.workflow_class(key).new(key, _parent: self, config: config)
285
292
  end
286
-
287
293
  end
288
294
  end
289
295
  end
@@ -243,8 +243,12 @@ module Eco
243
243
  # It obtains the first of the live tagtree in the org
244
244
  # @note it requires graphql connection configuration parameters
245
245
  # @return [Eco::API::Organization::TagTree]
246
- def live_tree(enviro: nil)
247
- @live_tree ||= tagtree_config.live_tree(enviro: enviro)
246
+ def live_tree(id: nil, enviro: nil, **kargs, &block)
247
+ if id
248
+ tagtree_config.live_tree_get(id: id, enviro: enviro, **kargs, &block)
249
+ else
250
+ tagtree_config.live_tree(enviro: enviro, **kargs, &block)
251
+ end
248
252
  end
249
253
 
250
254
  # @return [Eco::API::Organization::PolicyGroups]
@@ -45,8 +45,8 @@ module Eco
45
45
  end
46
46
 
47
47
  # @see Eco::API::Session::Config#live_tree
48
- def live_tree(include_archived: false, &block)
49
- config.live_tree(enviro: enviro, &block)
48
+ def live_tree(id: nil, include_archived: false, **kargs, &block)
49
+ config.live_tree(id: nil, include_archived: include_archived, enviro: enviro, **kargs, &block)
50
50
  end
51
51
 
52
52
  # @see Eco::API::Session::Config#schemas
@@ -2,11 +2,11 @@ class Eco::API::UseCases::DefaultCases::AbstractPolicyGroupAbilities < Eco::API:
2
2
  name "abstract-policygroup-abilities"
3
3
  type :export
4
4
 
5
- attr_reader :session, :people, :options
5
+ attr_reader :people
6
6
 
7
7
  def main(people, session, options, usecase)
8
8
  options[:end_get] = false
9
- @session = session; @options = options; @people = people
9
+ @people = people
10
10
 
11
11
  generate_csv!
12
12
  end
@@ -157,5 +157,4 @@ class Eco::API::UseCases::DefaultCases::AbstractPolicyGroupAbilities < Eco::API:
157
157
  def percent(num, total)
158
158
  (100 * num.to_f / total).round(2)
159
159
  end
160
-
161
160
  end
@@ -2,11 +2,11 @@ class Eco::API::UseCases::DefaultCases::AnalysePeople < Eco::API::Common::Loader
2
2
  name "analyse-people"
3
3
  type :export
4
4
 
5
- attr_reader :session, :people, :options
5
+ attr_reader :people
6
6
 
7
7
  def main(people, session, options, usecase)
8
8
  options[:end_get] = false
9
- @session = session; @options = options; @people = people
9
+ @people = people
10
10
 
11
11
  case
12
12
  when case_options[:identify_duplicates]
@@ -219,5 +219,4 @@ class Eco::API::UseCases::DefaultCases::AnalysePeople < Eco::API::Common::Loader
219
219
  raise "Review your expression. Cannot recognize '#{part}' as part of '#{obj.class}'"
220
220
  end
221
221
  end
222
-
223
222
  end
@@ -11,5 +11,4 @@ class Eco::API::UseCases::DefaultCases::AppendUsergroupsCase < Eco::API::Common:
11
11
  micro.append_usergroups(entry, person, options)
12
12
  end
13
13
  end
14
-
15
14
  end
@@ -1,7 +1,7 @@
1
1
  class Eco::API::UseCases::DefaultCases::ChangeEMailCase < Eco::API::Common::Loaders::UseCase
2
2
  name "change-email"
3
3
  type :sync
4
-
4
+
5
5
  # Target people with non-up-to-date emails will be updated to the new email
6
6
  def main(entries, people, session, options, usecase)
7
7
  micro = session.micro
@@ -24,5 +24,4 @@ class Eco::API::UseCases::DefaultCases::ChangeEMailCase < Eco::API::Common::Load
24
24
  end
25
25
  end
26
26
  end
27
-
28
27
  end
@@ -13,11 +13,7 @@ class Eco::API::UseCases::DefaultCases::CleanUnknownTags < Eco::API::Common::Loa
13
13
  "POLICY", "IDEA", "REPORTS"
14
14
  ]
15
15
 
16
- attr_reader :session, :options
17
-
18
16
  def main(people, session, options, usecase)
19
- @session = session; @options = options
20
-
21
17
  update = session.new_job("main", "update", :update, usecase)
22
18
  people.each do |person|
23
19
  unknown_tags = person.filter_tags.select {|tag| !tag?(tag)}
@@ -75,5 +71,4 @@ class Eco::API::UseCases::DefaultCases::CleanUnknownTags < Eco::API::Common::Loa
75
71
  def clean_register_tags?
76
72
  !options.dig(:usecase, :include_register_tags)
77
73
  end
78
-
79
74
  end
@@ -3,12 +3,12 @@ class Eco::API::UseCases::DefaultCases::ClearAbilitiesTransCase < Eco::API::Comm
3
3
  type :transform
4
4
 
5
5
  def main(people, session, options, usecase)
6
- clear_abilities(people.users, session, options, usecase)
6
+ clear_abilities(people.users)
7
7
  end
8
8
 
9
9
  private
10
10
 
11
- def clear_abilities(users, session, options, usecase)
11
+ def clear_abilities(users)
12
12
  update = session.new_job("main", "clear-abilities", :update, usecase, :account)
13
13
  users.each do |person|
14
14
  person.account.permissions_custom = nil_abilities.dup