eco-helpers 3.2.2 → 3.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/CHANGELOG.md +16 -1
  4. data/eco-helpers.gemspec +2 -2
  5. data/lib/eco/api/common/loaders/config/workflow/mailer.rb +1 -0
  6. data/lib/eco/api/common/people/person_entry.rb +1 -1
  7. data/lib/eco/api/common/people/person_parser.rb +1 -0
  8. data/lib/eco/api/organization/tag_tree.rb +11 -4
  9. data/lib/eco/api/usecases/default/locations/tagtree_upload_case.rb +20 -2
  10. data/lib/eco/api/usecases/graphql/helpers/location/base/tree_tracking.rb +14 -7
  11. data/lib/eco/api/usecases/graphql/helpers/location/base.rb +1 -1
  12. data/lib/eco/api/usecases/graphql/helpers/location/command/diff/as_update.rb +0 -1
  13. data/lib/eco/api/usecases/graphql/helpers/location/command/diffs/stages/diff_sortable/for_archive.rb +0 -1
  14. data/lib/eco/api/usecases/graphql/helpers/location/command/end_points/optimizations.rb +64 -0
  15. data/lib/eco/api/usecases/graphql/helpers/location/command/end_points.rb +96 -0
  16. data/lib/eco/api/usecases/graphql/helpers/location/command/input_unit_response.rb +69 -0
  17. data/lib/eco/api/usecases/graphql/helpers/location/command/result.rb +11 -10
  18. data/lib/eco/api/usecases/graphql/helpers/location/command/results.rb +120 -63
  19. data/lib/eco/api/usecases/graphql/helpers/location/command.rb +26 -26
  20. data/lib/eco/api/usecases/graphql/samples/location/command/dsl.rb +195 -37
  21. data/lib/eco/api/usecases/graphql/samples/location/command/results.rb +45 -13
  22. data/lib/eco/api/usecases/graphql/samples/location/command/service/tree_update.rb +0 -51
  23. data/lib/eco/api/usecases/graphql/samples/location/command/track_changed_ids.rb +6 -14
  24. data/lib/eco/api/usecases/graphql/samples/location/command.rb +1 -1
  25. data/lib/eco/api/usecases/graphql/samples/location/service/tree_diff/convertible/inputable.rb +4 -1
  26. data/lib/eco/api/usecases/graphql/samples/location/service/tree_diff.rb +6 -0
  27. data/lib/eco/api/usecases/graphql/samples/location/service/tree_to_list/converter/input.rb +1 -0
  28. data/lib/eco/api/usecases/lib/error_handling.rb +1 -1
  29. data/lib/eco/api/usecases/ooze_samples/helpers/creatable.rb +1 -0
  30. data/lib/eco/api/usecases/ooze_samples/helpers/rescuable.rb +1 -0
  31. data/lib/eco/data/hashes/array_diff.rb +14 -4
  32. data/lib/eco/data/locations/node_base/csv_convert.rb +9 -1
  33. data/lib/eco/data/locations/node_diff/nodes_diff.rb +6 -0
  34. data/lib/eco/version.rb +1 -1
  35. metadata +9 -7
  36. data/lib/eco/api/usecases/graphql/helpers/location/command/optimizations.rb +0 -84
@@ -9,7 +9,6 @@ class Eco::API::UseCases::GraphQL::Samples::Location
9
9
  def included(base)
10
10
  super
11
11
 
12
- base.send :include, Eco::API::UseCases::GraphQL::Samples::Location::Service::TreeDiff
13
12
  base.send :include, Eco::API::UseCases::GraphQL::Samples::Location::Command::DSL
14
13
  base.send :include, Eco::API::UseCases::GraphQL::Utils::Sftp
15
14
  base.send :include, InstanceMethods
@@ -22,43 +21,9 @@ class Eco::API::UseCases::GraphQL::Samples::Location
22
21
  super
23
22
  end
24
23
  ensure
25
- rescued { re_archive } unless exception?
26
24
  rescued { email_digest('TagTree Update') }
27
25
  end
28
26
 
29
- # Before closing, run RE-ARCHIVE: those that where unarchived via archivedToken
30
- # that should remain archived.
31
- # @note this is an additional necessary step
32
- def re_archive
33
- return if simulate?
34
- return if exception?
35
-
36
- stage = :rearchive
37
-
38
- nodes_diff_class.new(
39
- hash_list(current_tree),
40
- file_nodes_list,
41
- original_tree: current_tree,
42
- logger: logger
43
- ).tap do |nodes_diff|
44
- archive_input = input(
45
- nodes_diff.stage_commands(:archive),
46
- force_continue: true
47
- )
48
-
49
- sliced_batches(
50
- archive_input,
51
- desc: stage,
52
- track_tree_mode: :once
53
- ) do |sliced_input, response, page, pages, count, total| # rubocop:disable Metrics/ParameterLists
54
- page_results = request_results_class.new(sliced_input, response)
55
- (results[stage] ||= []) << page_results
56
-
57
- self.error ||= page_errors?(page_results, page, pages, count, total, stage: stage)
58
- end
59
- end
60
- end
61
-
62
27
  private
63
28
 
64
29
  # Work with adapted diff builders.
@@ -66,18 +31,6 @@ class Eco::API::UseCases::GraphQL::Samples::Location
66
31
  Eco::API::UseCases::GraphQL::Helpers::Location::Command::Diffs
67
32
  end
68
33
 
69
- def inputs(nodes_diff = comparer, force_continue: force_continue?)
70
- {}.tap do |sequence|
71
- nodes_diff.commands do |comms, stage|
72
- sequence[stage] = input(comms, force_continue: force_continue)
73
- end
74
- end.tap do |sequence|
75
- sequence.each do |stage, input|
76
- yield(input, stage) if block_given?
77
- end
78
- end
79
- end
80
-
81
34
  # Generates the file and pushes to the SFTP folder
82
35
  # @note it also displays the mappings on screen
83
36
  # @note the SFTP push only happens if `remote_subfolder` is defined, via:
@@ -106,10 +59,6 @@ class Eco::API::UseCases::GraphQL::Samples::Location
106
59
  options.deep_merge!({worfklow: {no_email: true}})
107
60
  end
108
61
  end
109
-
110
- def print_diff_details?
111
- false
112
- end
113
62
  end
114
63
  end
115
64
  end
@@ -28,7 +28,7 @@ class Eco::API::UseCases::GraphQL::Samples::Location
28
28
  # @note this method used to only work if we could run cummulative dry-runs to the back-end.
29
29
  # However, after RS P3, as mappings are one-to-one (not many-to-many per row),
30
30
  # we can just display the mappings in dry-run as well.
31
- def close_handling_tags_remap_csv
31
+ def close_handling_tags_remap_csv # rubocop:disable Naming/PredicateMethod
32
32
  if tags_remap_table.any?
33
33
  puts "REMAP LOC IDs CSV (content):"
34
34
  puts tags_remap_table
@@ -44,21 +44,13 @@ class Eco::API::UseCases::GraphQL::Samples::Location
44
44
  # @note The only update operation that generate tag remaps
45
45
  # is `:id` (or `:id_name`).
46
46
  # @return [Boolean] whether new maps were inserted to the tracking table
47
- def update_tags_remap_table(results, stage, ref_tree = nil)
48
- return false unless %i[id id_name].include?(stage)
47
+ def update_tags_remap_table(command)
48
+ prev_id, new_id = command.values_at(:nodeId, :newId)
49
49
 
50
- msg = "Expecting CommandResults object. Given: #{results.class}"
51
- raise msg unless results.is_a?(request_results_class)
50
+ return if new_id.nil? # not an id change
51
+ return if prev_id == new_id
52
52
 
53
- target = simulate?? results.results : results.applied
54
-
55
- target.each do |result|
56
- prev_id, new_id = result.command_input_data.values_at(:nodeId, :newId)
57
- next if new_id.nil? # not an id change
58
- next if prev_id == new_id
59
-
60
- tags_remap_table << [[prev_id], [new_id]]
61
- end
53
+ tags_remap_table << [[prev_id], [new_id]]
62
54
  end
63
55
 
64
56
  # Generates the final tags remap file
@@ -1,7 +1,7 @@
1
1
  # Use case to launch updates to a tagtree (i.e. upload new locations)
2
2
  module Eco::API::UseCases::GraphQL::Samples
3
3
  class Location::Command < Eco::API::UseCases::GraphQL::Samples::Location
4
- name "location-command"
4
+ name 'location-command'
5
5
 
6
6
  require_relative 'command/results'
7
7
  require_relative 'command/track_changed_ids'
@@ -38,7 +38,10 @@ module Eco::API::UseCases::GraphQL::Samples::Location::Service
38
38
 
39
39
  #@note via Eco::Data::Files
40
40
  def csv_files
41
- self.class.csv_files(input_folder, regexp: input_file_pattern)
41
+ self.class.csv_files(
42
+ input_folder,
43
+ regexp: input_file_pattern
44
+ )
42
45
  end
43
46
 
44
47
  def input_file_pattern
@@ -53,6 +53,8 @@ module Eco::API::UseCases::GraphQL::Samples
53
53
 
54
54
  def process
55
55
  with_error_handling do
56
+ next unless compare_live_with_file?
57
+
56
58
  compare
57
59
  end
58
60
  end
@@ -87,6 +89,10 @@ module Eco::API::UseCases::GraphQL::Samples
87
89
  Eco::Data::Locations::NodeDiff::NodesDiff
88
90
  end
89
91
 
92
+ def compare_live_with_file?
93
+ true
94
+ end
95
+
90
96
  def print_diff_details?
91
97
  true
92
98
  end
@@ -6,6 +6,7 @@ module Eco::API::UseCases::GraphQL::Samples::Location::Service
6
6
 
7
7
  private
8
8
 
9
+ # @todo this name is confusing. It is actually the `current_tagtree` :D
9
10
  def input_tagtree
10
11
  @input_tagtree ||= live_tree
11
12
  end
@@ -30,7 +30,7 @@ module Eco::API::UseCases::Lib
30
30
  def rescued
31
31
  yield
32
32
  rescue StandardError => err
33
- self.exception ||= err
33
+ @exception ||= err
34
34
 
35
35
  return unless exception_already_captured?(err)
36
36
 
@@ -42,6 +42,7 @@ module Eco
42
42
  class << self
43
43
  def included(base)
44
44
  super
45
+
45
46
  validate_base_type!(base)
46
47
  base.include(InstanceMethods)
47
48
  end
@@ -40,6 +40,7 @@ module Eco
40
40
  class << self
41
41
  def included(base)
42
42
  super
43
+
43
44
  validate_base_type!(base)
44
45
  base.include(InstanceMethods)
45
46
  end
@@ -95,14 +95,24 @@ module Eco
95
95
  when String
96
96
  to_array_of_hashes(Eco::CSV.parse(content))
97
97
  when Enumerable
98
- sample = content.to_a.first
98
+ content_ary = content.to_a
99
+ content_cnt = content_ary.count
100
+ sample = content_ary.first
101
+
99
102
  case sample
100
103
  when Hash, Array, ::CSV::Row
101
104
  Eco::CSV::Table.new(content).to_array_of_hashes
102
105
  else
103
- log(:error) {
104
- "(ArrayDiff) Input content 'Array' of '#{sample.class}' is not supported."
105
- }
106
+ if content_cnt.zero?
107
+ log(:error) {
108
+ "Inpout should not be empty"
109
+ }
110
+ else
111
+ log(:error) {
112
+ "(ArrayDiff) Input content 'Array' of '#{sample.class}' is not supported."
113
+ }
114
+ end
115
+
106
116
  exit(1)
107
117
  end
108
118
  else
@@ -15,6 +15,7 @@ module Eco::Data::Locations::NodeBase
15
15
  def hash_list(value, &block)
16
16
  return hash_list(org_tree(value), &block) if value.is_a?(::CSV::Table)
17
17
  return value.as_nodes_json(&block) if value.is_a?(tree_class)
18
+
18
19
  raise ArgumentError, "Expecting Eco::API::Organization::TagTree or CSV::Table. Given: #{value.class}"
19
20
  end
20
21
 
@@ -28,6 +29,7 @@ module Eco::Data::Locations::NodeBase
28
29
  def hash_tree(value, &block)
29
30
  return hash_tree_from_csv(value, &block) if value.is_a?(::CSV::Table)
30
31
  return value.as_json(&block) if value.is_a?(tree_class)
32
+
31
33
  raise ArgumentError, "Expecting Eco::API::Organization::TagTree or CSV::Table. Given: #{value.class}"
32
34
  end
33
35
 
@@ -40,6 +42,7 @@ module Eco::Data::Locations::NodeBase
40
42
  def org_tree(value, &block)
41
43
  return tree_class.new(hash_tree(value), &block) if value.is_a?(::CSV::Table)
42
44
  return tree_class.new(value.as_json) if value.is_a?(tree_class)
45
+
43
46
  raise ArgumentError, "Expecting Eco::API::Organization::TagTree or CSV::Table. Given: #{value.class}"
44
47
  end
45
48
 
@@ -49,7 +52,12 @@ module Eco::Data::Locations::NodeBase
49
52
  # @yieldreturn [Hash] the serialized Node
50
53
  # @return [CSV::Table] a table with L1 to Ln columns ready for dump to csv
51
54
  def csv_tree(value, encoding: 'utf-8', attrs: [:id], &block) # rubocop:disable Lint/UnusedMethodArgument
52
- Eco::CSV::Table.new(hash_tree_to_tree_csv(hash_tree(value, &block), attrs: attrs))
55
+ Eco::CSV::Table.new(
56
+ hash_tree_to_tree_csv(
57
+ hash_tree(value, &block),
58
+ attrs: attrs
59
+ )
60
+ )
53
61
  end
54
62
 
55
63
  # @note it just converts to an organizational tagtree and uses a helper method.
@@ -20,10 +20,16 @@ class Eco::Data::Locations::NodeDiff
20
20
 
21
21
  def initialize(*args, original_tree:, **kargs, &block)
22
22
  super(*args, **kargs, &block)
23
+
23
24
  @original_tree = original_tree
24
25
  mark_implicit_unarchive!
25
26
  end
26
27
 
28
+ def any?
29
+ diffs.any?
30
+ end
31
+ alias_method :any_diff?, :any?
32
+
27
33
  def diffs
28
34
  @diffs ||= super.select do |dff|
29
35
  # discard entries that are to be inserted and archived at the same time
data/lib/eco/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Eco
2
- VERSION = '3.2.2'.freeze
2
+ VERSION = '3.2.3'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eco-helpers
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.2
4
+ version: 3.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oscar Segura
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-06-11 00:00:00.000000000 Z
11
+ date: 2025-08-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: byebug
@@ -243,7 +243,7 @@ dependencies:
243
243
  version: '0.10'
244
244
  - - ">="
245
245
  - !ruby/object:Gem::Version
246
- version: 0.10.11
246
+ version: 0.10.14
247
247
  type: :runtime
248
248
  prerelease: false
249
249
  version_requirements: !ruby/object:Gem::Requirement
@@ -253,7 +253,7 @@ dependencies:
253
253
  version: '0.10'
254
254
  - - ">="
255
255
  - !ruby/object:Gem::Version
256
- version: 0.10.11
256
+ version: 0.10.14
257
257
  - !ruby/object:Gem::Dependency
258
258
  name: ecoportal-api-graphql
259
259
  requirement: !ruby/object:Gem::Requirement
@@ -263,7 +263,7 @@ dependencies:
263
263
  version: '1.3'
264
264
  - - ">="
265
265
  - !ruby/object:Gem::Version
266
- version: 1.3.1
266
+ version: 1.3.2
267
267
  type: :runtime
268
268
  prerelease: false
269
269
  version_requirements: !ruby/object:Gem::Requirement
@@ -273,7 +273,7 @@ dependencies:
273
273
  version: '1.3'
274
274
  - - ">="
275
275
  - !ruby/object:Gem::Version
276
- version: 1.3.1
276
+ version: 1.3.2
277
277
  - !ruby/object:Gem::Dependency
278
278
  name: ecoportal-api-v2
279
279
  requirement: !ruby/object:Gem::Requirement
@@ -845,7 +845,9 @@ files:
845
845
  - lib/eco/api/usecases/graphql/helpers/location/command/diffs/stages/diff_sortable/for_unarchive.rb
846
846
  - lib/eco/api/usecases/graphql/helpers/location/command/diffs/stages/sortable.rb
847
847
  - lib/eco/api/usecases/graphql/helpers/location/command/diffs/stages/sortable/relation_safe_sort.rb
848
- - lib/eco/api/usecases/graphql/helpers/location/command/optimizations.rb
848
+ - lib/eco/api/usecases/graphql/helpers/location/command/end_points.rb
849
+ - lib/eco/api/usecases/graphql/helpers/location/command/end_points/optimizations.rb
850
+ - lib/eco/api/usecases/graphql/helpers/location/command/input_unit_response.rb
849
851
  - lib/eco/api/usecases/graphql/helpers/location/command/result.rb
850
852
  - lib/eco/api/usecases/graphql/helpers/location/command/results.rb
851
853
  - lib/eco/api/usecases/graphql/helpers/location/tags_remap.rb
@@ -1,84 +0,0 @@
1
- module Eco::API::UseCases::GraphQL::Helpers::Location
2
- module Command::Optimizations
3
- DEFAULT_COMMANDS_PER_PAGE = 45
4
- DEFAULT_FORCE_CONTINUE = false
5
-
6
- # Available options are:
7
- # - :per_request -> on each request
8
- # - :per_batch -> at the end of each batch / stage (on last page)
9
- # - :once -> only when the script starts to run
10
- def default_tree_tracking_mode
11
- :per_request
12
- end
13
-
14
- # Helper to identify the commands payload block
15
- # @note
16
- # 1. Gives flexibility on at what time the structure should be retrieved
17
- # 2. This increases performacne, as we don't retrieve the full tree on
18
- # each request unless necessary/specified
19
- # 3. `nil` falls the block back to the `ecoportal-api-graphql` gem, which
20
- # has a default block that retrieves the structure
21
- # @return [Proc, NilClass] the payload block
22
- def scope_commands_block(idx, total, track_tree_mode: default_tree_tracking_mode)
23
- case track_tree_mode
24
- when :per_request
25
- nil
26
- when :once
27
- commands_payload_without_structure_block
28
- when :per_batch
29
- return nil if idx == total
30
- commands_payload_without_structure_block
31
- end
32
- end
33
-
34
- # Prevents each request from timing out
35
- def commands_per_page
36
- if self.class.const_defined?(:COMMANDS_PER_PAGE)
37
- self.class::COMMANDS_PER_PAGE
38
- else
39
- DEFAULT_COMMANDS_PER_PAGE
40
- end
41
- end
42
-
43
- # Whether to stop or continue on command fail
44
- def force_continue?
45
- if self.class.const_defined?(:FORCE_CONTINUE)
46
- self.class::FORCE_CONTINUE
47
- else
48
- DEFAULT_FORCE_CONTINUE
49
- end
50
- end
51
-
52
- # Commands payload without querying Structure
53
- # @note this servces the purpose of optimizing/speeding up the requests.
54
- def commands_payload_without_structure_block
55
- proc {
56
- clientMutationId
57
- error { # rubocop:disable Style/BlockDelimiters
58
- message
59
- conflictingIds
60
- validationErrors { # rubocop:disable Style/BlockDelimiters
61
- error
62
- message
63
- }
64
- }
65
- results { # rubocop:disable Style/BlockDelimiters
66
- command { # rubocop:disable Style/BlockDelimiters
67
- id
68
- state
69
- __typename
70
- }
71
- ok
72
- error { # rubocop:disable Style/BlockDelimiters
73
- conflictingIds
74
- message
75
- validationErrors { # rubocop:disable Style/BlockDelimiters
76
- error
77
- message
78
- }
79
- }
80
- }
81
- }
82
- end
83
- end
84
- end