eco-helpers 3.0.4 → 3.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -0
  3. data/CHANGELOG.md +55 -4
  4. data/eco-helpers.gemspec +1 -1
  5. data/lib/eco/api/common/class_helpers.rb +24 -23
  6. data/lib/eco/api/common/class_meta_basics.rb +0 -2
  7. data/lib/eco/api/common/loaders/use_case.rb +1 -0
  8. data/lib/eco/api/common/people/entry_factory.rb +6 -4
  9. data/lib/eco/api/common/people/person_entry.rb +4 -6
  10. data/lib/eco/api/common/people/person_entry_attribute_mapper.rb +25 -12
  11. data/lib/eco/api/common/people/person_parser.rb +8 -0
  12. data/lib/eco/api/common/session/base_session.rb +1 -1
  13. data/lib/eco/api/common/session/environment.rb +7 -0
  14. data/lib/eco/api/common/session/file_manager.rb +15 -8
  15. data/lib/eco/api/common/session/logger/cache.rb +14 -10
  16. data/lib/eco/api/common/session/logger/log.rb +8 -7
  17. data/lib/eco/api/common/session/mailer.rb +22 -13
  18. data/lib/eco/api/common/session/s3_uploader.rb +29 -20
  19. data/lib/eco/api/microcases/people_search.rb +1 -1
  20. data/lib/eco/api/organization/login_providers.rb +11 -4
  21. data/lib/eco/api/organization/node_classifications.rb +3 -0
  22. data/lib/eco/api/organization/presets_factory.rb +37 -31
  23. data/lib/eco/api/organization/tag_tree.rb +14 -5
  24. data/lib/eco/api/policies/default_policies/99_user_access_policy.rb +28 -18
  25. data/lib/eco/api/session/batch/errors.rb +38 -20
  26. data/lib/eco/api/session/batch/job.rb +252 -135
  27. data/lib/eco/api/session/batch/status.rb +55 -36
  28. data/lib/eco/api/session/batch.rb +2 -2
  29. data/lib/eco/api/session/config/base_config.rb +12 -11
  30. data/lib/eco/api/session/config/tagtree.rb +10 -14
  31. data/lib/eco/api/session/config/workflow.rb +15 -3
  32. data/lib/eco/api/session/config.rb +19 -26
  33. data/lib/eco/api/session.rb +13 -4
  34. data/lib/eco/api/usecases/cli.rb +4 -0
  35. data/lib/eco/api/usecases/default/locations/cli/codes_to_tags_cli.rb +18 -0
  36. data/lib/eco/api/usecases/default/locations/cli/csv_to_tree_cli.rb +12 -0
  37. data/lib/eco/api/usecases/default/locations/cli/tagtree_paths_cli.rb +12 -0
  38. data/lib/eco/api/usecases/default/locations/codes_to_tags_case.rb +32 -13
  39. data/lib/eco/api/usecases/default/locations/csv_to_tree_case.rb +15 -5
  40. data/lib/eco/api/usecases/default/locations/tagtree_extract_case.rb +6 -0
  41. data/lib/eco/api/usecases/default/locations/tagtree_paths_case.rb +51 -0
  42. data/lib/eco/api/usecases/default/locations.rb +1 -1
  43. data/lib/eco/api/usecases/default/people/amend/cli/reinvite_sync_cli.rb +8 -0
  44. data/lib/eco/api/usecases/default/people/amend/cli/reinvite_trans_cli.rb +11 -0
  45. data/lib/eco/api/usecases/default/people/amend/cli/restore_db_cli.rb +26 -0
  46. data/lib/eco/api/usecases/default/people/amend/reinvite_sync_case.rb +2 -0
  47. data/lib/eco/api/usecases/default/people/amend/reinvite_trans_case.rb +2 -0
  48. data/lib/eco/api/usecases/default/people/amend/restore_db_case.rb +3 -0
  49. data/lib/eco/api/usecases/default/people/treat/analyse_people_case.rb +15 -5
  50. data/lib/eco/api/usecases/default/people/treat/cli/analyse_people_cli.rb +66 -0
  51. data/lib/eco/api/usecases/default/people/treat/cli/org_data_convert_cli.rb +35 -0
  52. data/lib/eco/api/usecases/default/people/treat/cli/supers_cyclic_identify_cli.rb +15 -0
  53. data/lib/eco/api/usecases/default/people/treat/cli/supers_hierachy_cli.rb +15 -0
  54. data/lib/eco/api/usecases/default/people/treat/org_data_convert_case.rb +11 -5
  55. data/lib/eco/api/usecases/default/people/treat/supers_cyclic_identify_case.rb +28 -7
  56. data/lib/eco/api/usecases/default/people/treat/supers_hierarchy_case.rb +32 -9
  57. data/lib/eco/api/usecases/default/people/utils/set_default_tag_case.rb +2 -1
  58. data/lib/eco/api/usecases/default_cases/to_csv_case.rb +2 -2
  59. data/lib/eco/api/usecases/graphql/helpers/base/case_env.rb +1 -0
  60. data/lib/eco/api/usecases/graphql/helpers/base/error_handling.rb +52 -0
  61. data/lib/eco/api/usecases/graphql/helpers/base.rb +1 -0
  62. data/lib/eco/api/usecases/graphql/helpers/location/base/classifications_parser.rb +5 -0
  63. data/lib/eco/api/usecases/graphql/helpers/location/command/diffs/stages/commandable.rb +2 -0
  64. data/lib/eco/api/usecases/graphql/helpers/location/command/diffs/stages/diff_sortable.rb +2 -0
  65. data/lib/eco/api/usecases/graphql/helpers/location/command/result.rb +2 -1
  66. data/lib/eco/api/usecases/graphql/helpers/location/command/results.rb +3 -0
  67. data/lib/eco/api/usecases/graphql/helpers/location/command.rb +1 -0
  68. data/lib/eco/api/usecases/graphql/helpers/location/tags_remap.rb +3 -0
  69. data/lib/eco/api/usecases/graphql/samples/location/command/dsl.rb +19 -18
  70. data/lib/eco/api/usecases/graphql/samples/location/command/results.rb +1 -7
  71. data/lib/eco/api/usecases/graphql/samples/location/command/service/tree_update.rb +11 -6
  72. data/lib/eco/api/usecases/graphql/samples/location/command/track_changed_ids.rb +3 -8
  73. data/lib/eco/api/usecases/graphql/samples/location/service/tree_diff/convertible/parsing/classifications.rb +2 -0
  74. data/lib/eco/api/usecases/graphql/samples/location/service/tree_diff/convertible.rb +5 -2
  75. data/lib/eco/api/usecases/graphql/samples/location/service/tree_diff.rb +10 -4
  76. data/lib/eco/api/usecases/graphql/samples/location/service/tree_to_list/converter/parser.rb +6 -2
  77. data/lib/eco/api/usecases/graphql/samples/location/service/tree_to_list/converter.rb +2 -0
  78. data/lib/eco/api/usecases/graphql/samples/location/service/tree_to_list.rb +5 -3
  79. data/lib/eco/api/usecases/ooze_cases/export_register_case.rb +1 -0
  80. data/lib/eco/api/usecases/ooze_samples/helpers_migration/copying.rb +66 -29
  81. data/lib/eco/api/usecases/ooze_samples/ooze_base_case.rb +25 -3
  82. data/lib/eco/api/usecases/ooze_samples/register_update_case.rb +10 -0
  83. data/lib/eco/api/usecases/use_case.rb +3 -1
  84. data/lib/eco/cli/config/use_cases.rb +4 -0
  85. data/lib/eco/cli/scripting/args_helpers.rb +3 -2
  86. data/lib/eco/cli/scripting/argument.rb +2 -2
  87. data/lib/eco/cli_default/input.rb +49 -45
  88. data/lib/eco/cli_default/input_filters.rb +32 -17
  89. data/lib/eco/cli_default/options.rb +8 -4
  90. data/lib/eco/cli_default/people.rb +1 -1
  91. data/lib/eco/cli_default/people_filters.rb +32 -24
  92. data/lib/eco/cli_default/usecases.rb +8 -121
  93. data/lib/eco/cli_default/workflow.rb +6 -4
  94. data/lib/eco/csv/split.rb +2 -0
  95. data/lib/eco/csv/table.rb +13 -0
  96. data/lib/eco/data/files/encoding.rb +15 -8
  97. data/lib/eco/data/files/helpers.rb +6 -2
  98. data/lib/eco/data/hashes/diff_result.rb +5 -0
  99. data/lib/eco/data/locations/node_diff/nodes_diff.rb +13 -0
  100. data/lib/eco/data/locations/node_diff.rb +4 -0
  101. data/lib/eco/data/locations/node_level.rb +6 -0
  102. data/lib/eco/language/auxiliar_logger.rb +2 -0
  103. data/lib/eco/version.rb +1 -1
  104. data/lib/eco-helpers.rb +1 -1
  105. metadata +16 -6
  106. data/lib/eco/api/usecases/default/locations/create_tag_paths_case.rb +0 -25
  107. data/lib/eco/api/usecases/default/people/amend/reinvite_trans_cli.rb +0 -4
@@ -1,55 +1,5 @@
1
- ASSETS.cli.config do |cnf|
2
- cnf.usecases do |cases|
3
-
4
- desc = "Draws the Supervisors hiearchy in a file"
5
- cases.add("-supers-hierarchy", :export, desc, case_name: "supers-hierarchy") do |people, session, options|
6
- options.deep_merge!(output: {file: "supers_hierarchy.txt"}) unless options.dig(:output, :file)
7
- end.add_option("-to", "Specify the output file") do |options|
8
- file = SCR.get_file("-to", required: true, should_exist: false)
9
- options.deep_merge!(output: {file: file})
10
- end
11
-
12
- desc = "Draws the Cyclic Supervisors when identified"
13
- cases.add("-identify-cyclic-supers", :export, desc, case_name: "identify-cyclic-supers") do |people, session, options|
14
- options.deep_merge!(output: {file: "cyclic_supers.txt"}) unless options.dig(:output, :file)
15
- end.add_option("-to", "Specify the output file") do |options|
16
- file = SCR.get_file("-to", required: true, should_exist: false)
17
- options.deep_merge!(output: {file: file})
18
- end
19
-
20
- desc = "Provides a set of tools to analyse a set of people (i.e. detect duplicates)"
21
- cases.add("-analyse-people", :export, desc, case_name: "analyse-people") do |people, session, options|
22
- options.deep_merge!(output: {file: "people_analysis.txt"}) unless options.dig(:output, :file)
23
- #unless options.dig(:usecase, :analyse_people, :use_field)
24
- # options.deep_merge!(usecase: {analyse_people: {use_field: :name}})
25
- #end
26
- end.add_option("-to", "Specify the output file.") do |options|
27
- file = SCR.get_file("-to", required: true, should_exist: false)
28
- options.deep_merge!(output: {file: file})
29
- end.add_option("-identify-duplicates", "Generates a list of people with possible duplicates.") do |options|
30
- options.deep_merge!(usecase: {analyse_people: {identify_duplicates: true}})
31
- end.add_option("-use-field", "Works with -identify-duplicates. Sets field to be used in the comparison.") do |options|
32
- expression = SCR.get_arg("-use-field", with_param: true)
33
- options.deep_merge!(usecase: {analyse_people: {use_field: expression}})
34
- end.add_option("-facet-field", "Works with -identify-duplicates. Adds an additional layer of comparison.") do |options|
35
- expression = SCR.get_arg("-facet-field", with_param: true)
36
- options.deep_merge!(usecase: {analyse_people: {facet_field: expression}})
37
- end.add_option("-only-screening", "Works with -identify-duplicates. Skips the rearrangement stage.") do |options|
38
- options.deep_merge!(usecase: {analyse_people: {only_screening: true}})
39
- end.add_option("-ignore-matching-words", "Works with -identify-duplicates. Re-adjust scores ignoring matching words.") do |options|
40
- options.deep_merge!(usecase: {analyse_people: {ignore_matching_words: true}})
41
- end.add_option("-unique-words", "Works with -identify-duplicates. Re-adjust the comparing strings to do not have repeated words.") do |options|
42
- options.deep_merge!(usecase: {analyse_people: {unique_words: true}})
43
- end.add_option("-identify-unnamed", "Identifies all people with no names.") do |options|
44
- options.deep_merge!(usecase: {analyse_people: {identify_unnamed: true}})
45
- end.add_option("-backup-people-results", "Generates a json file with all the people involved in the final results of the analysis.") do |options|
46
- file = SCR.get_file("-backup-people-results", required: true, should_exist: false)
47
- options.deep_merge!(usecase: {analyse_people: {backup_people: File.expand_path(file)}})
48
- end.add_option("-to-csv", "Genarates a CSV file with all people of the final results.") do |options|
49
- file = SCR.get_file("-to-csv", required: true, should_exist: false) || "Results.csv"
50
- options.deep_merge!(usecase: {analyse_people: {csv_file: File.expand_path(file)}})
51
- end
52
-
1
+ ASSETS.cli.config do |cnf| # rubocop:disable Metrics/BlockLength
2
+ cnf.usecases do |cases| # rubocop:disable Metrics/BlockLength
53
3
  desc = "It exports to a CSV the (filtered) people"
54
4
  cases.add("-people-to-csv", :export, desc) do |people, session, options|
55
5
  file = SCR.get_file("-people-to-csv", required: true, should_exist: false)
@@ -69,25 +19,6 @@ ASSETS.cli.config do |cnf|
69
19
  options.deep_merge!(export: {options: {split_schemas: true}})
70
20
  end
71
21
 
72
- desc = "Adds a column 'ecoPortalTag' to the input CSV with the tags that the location codes map to"
73
- cases.add("-codes-to-tags-from", :other, desc, case_name: "codes-to-tags-from")
74
- .add_option("-codes-to-tags-from", "Specify the input 'csv' file") do |options|
75
- file = SCR.get_file("-codes-to-tags-from", required: true, should_exist: true)
76
- options.deep_merge!(other: {file: {name: file, format: :csv}})
77
- end.add_option("-column", "Specify the input column header with the codes") do |options|
78
- col_codes = SCR.get_arg("-column", with_param: true)
79
- options.deep_merge!(other: {file: {codes_column: col_codes}})
80
- end
81
-
82
- desc = "Creates a CSV with the paths to each tag"
83
- cases.add("-create-tag-paths", :other, desc, case_name: "create-tag-paths")
84
-
85
- desc = "Creates a JSON file with the tagtree from a CSV file"
86
- cases.add("-csv-to-tree", :other, desc, case_name: "csv-to-tree") do |session, options, usecase|
87
- file = SCR.get_file("-csv-to-tree", required: true, should_exist: true)
88
- options.deep_merge!(source: {file: file})
89
- end
90
-
91
22
  desc = "Forces a change of email in the same org. It won't succeed if email taken by an org member user"
92
23
  cases.add("-change-email-from", :sync, desc, case_name: "change-email")
93
24
 
@@ -95,12 +26,12 @@ ASSETS.cli.config do |cnf|
95
26
  cases.add("-switch-supervisor", :transform, desc, case_name: "switch-supervisor") do |people, session, options|
96
27
  unless options[:super]&.key?(:old)
97
28
  msg = "You must specify an -old-super to target whose supervisor is changing"
98
- session.logger.error(msg)
29
+ session.log(:error) { msg }
99
30
  exit(1)
100
31
  end
101
32
  unless options[:super]&.key?(:new)
102
33
  msg = "You must specify the -new-super id. To reset to nil the supervisor, please, specify nil."
103
- session.logger.error(msg)
34
+ session.log(:error) { msg }
104
35
  exit(1)
105
36
  end
106
37
  end.add_option("-old-super", "The supervisor id to be replaced on the subordinates") do |options|
@@ -115,59 +46,13 @@ ASSETS.cli.config do |cnf|
115
46
  end
116
47
  end
117
48
 
118
- desc = "Input file dump into a CSV as is."
49
+ desc = "Input file dump into a CSV as is."
119
50
  cases.add("-entries-to-csv", :import, desc, case_name: "entries-to-csv")
120
51
  .add_option("-out") do |options|
121
52
  file = SCR.get_file("-out")
122
53
  options.deep_merge!(export: {file: file})
123
54
  end
124
55
 
125
- desc = "Usage '-org-data-convert backup.json -restore-db-from'."
126
- desc += " Transforms an input .json file to the values of the destination environment "
127
- desc += " (names missmatch won't solve: i.e. usergroups)"
128
- cases.add("-org-data-convert", :import, desc, case_name: "org-data-convert") do |input, session, options|
129
- unless input && input.is_a?(Eco::API::Organization::People)
130
- file = SCR.get_file("-org-data-convert", required: true)
131
- input = Eco::API::Organization::People.new(JSON.parse(File.read(file)))
132
- session.logger.info("Source DB: loaded #{input.length} entries.")
133
- end
134
-
135
- unless options[:source_enviro]
136
- session.logger.error("You need to specify a -source-enviro for the conversion to work out")
137
- exit(1)
138
- end
139
-
140
- end.add_option("-source-enviro", "The defined -source-enviro API configuration that the backup file was generated from") do |options|
141
- options.merge!(source_enviro: SCR.get_arg("-source-enviro", with_param: true))
142
- end.add_option("-ignore-missing-policy-groups", "Prevents the script to crash when backup file has missing usergroups in the org") do |options|
143
- options.deep_merge!(ignore: {missing: {policy_groups: true}})
144
- end
145
-
146
- desc = "Restores the people manager by using a backup.json file"
147
- cases.add("-restore-db-from", :sync, desc, case_name: "restore-db") do |input, people, session, options|
148
- unless input && input.is_a?(Eco::API::Organization::People)
149
- file = SCR.get_file("-restore-db-from", required: true)
150
- input = Eco::API::Organization::People.new(JSON.parse(File.read(file)))
151
- session.logger.info("Source DB: loaded #{input.length} entries.")
152
- end
153
- end.add_option("-include-delete", "If it should DELETE people that do not exist in the backup file") do |options|
154
- options.deep_merge!(include: {delete: true})
155
- end.add_option("-include-create", "If it should CREATE people that do not exist in the people manager") do |options|
156
- options.deep_merge!(include: {create: true})
157
- end
158
-
159
- desc = "Re-sends invites to all filtered users that have not accepted the invite as yet"
160
- cases.add("-reinvite", :transform, desc, case_name: "reinvite")
161
- .add_option("-force", "If also send an invite email to those that have accepted the invite") do |options|
162
- options.deep_merge!(force: {invite: true})
163
- end
164
-
165
- desc = "Re-sends invites to target users that have not accepted the invite as yet"
166
- cases.add("-reinvite-from", :sync, desc, case_name: "reinvite")
167
- .add_option("-force", "If also send an invite email to those that have accepted the invite") do |options|
168
- options.deep_merge!(force: {invite: true})
169
- end
170
-
171
56
  desc = "Clears the `permissions_custom`, provided that Policy Group abilities alone apply."
172
57
  desc += " Please be mindfull if you use this option (there may be users that have been upgraded in ad-hoc manner)."
173
58
  cases.add("-clear-abilities", :transform, desc, case_name: "clear-abilities")
@@ -219,7 +104,9 @@ ASSETS.cli.config do |cnf|
219
104
  options.deep_merge!(export: {file: {name: file || "RegisterExport.csv", format: :csv}})
220
105
 
221
106
  unless options.dig(:source, :register_id)
222
- session.logger.error "You should specify the target register id"
107
+ session.log(:error) {
108
+ "You should specify the target register id"
109
+ }
223
110
  exit(1)
224
111
  end
225
112
  end.add_option("-register-id", "Target register id") do |options|
@@ -38,6 +38,7 @@ ASSETS.cli do |cli| # rubocop:disable Metrics/BlockLength
38
38
 
39
39
  wf_in.on(:filter) do |_wf_if, io|
40
40
  next unless input && !input.empty?
41
+
41
42
  io.new(input: cli.config.input_filters.process(io: io))
42
43
  end
43
44
  end
@@ -47,6 +48,7 @@ ASSETS.cli do |cli| # rubocop:disable Metrics/BlockLength
47
48
  cases_with_people = cli.config.usecases.active(io: io).select do |usecase, _data|
48
49
  io.class.people_required?(usecase.type)
49
50
  end
51
+
50
52
  next if cases_with_people.empty? && !options.dig(:people, :get)
51
53
 
52
54
  io.new(people: cli.config.people(io: io))
@@ -78,7 +80,7 @@ ASSETS.cli do |cli| # rubocop:disable Metrics/BlockLength
78
80
  end
79
81
  end
80
82
 
81
- wf.before(:launch_jobs) do |_wf_jobs, io|
83
+ wf.before(:launch_jobs) do |_wf_jobs, _io|
82
84
  available_args = cli.config.available_option_args
83
85
  SCR.stop_on_unknown!(all_available: available_args)
84
86
  end
@@ -95,7 +97,7 @@ ASSETS.cli do |cli| # rubocop:disable Metrics/BlockLength
95
97
  wf_post.skip!
96
98
  log(:info) {
97
99
  msg = "Although there are post_launch cases, they will NOT be RUN"
98
- msg += ", because we are in dry-run (simulate)." if options[:dry_run]
100
+ msg << ", because we are in dry-run (simulate)." if options[:dry_run]
99
101
  msg
100
102
  }
101
103
  next
@@ -109,9 +111,9 @@ ASSETS.cli do |cli| # rubocop:disable Metrics/BlockLength
109
111
  log(:info) {
110
112
  msg = "Although there are post_launch cases, data will not be refreshed before their run"
111
113
  if io.options[:dry_run]
112
- msg += ", because we are in dry-run (simulate)."
114
+ msg << ", because we are in dry-run (simulate)."
113
115
  elsif !partial_update
114
- msg += ", because it is not a partial update (-get-partial option not present)."
116
+ msg << ", because it is not a partial update (-get-partial option not present)."
115
117
  end
116
118
  msg
117
119
  }
data/lib/eco/csv/split.rb CHANGED
@@ -21,11 +21,13 @@ module Eco
21
21
  def copy_count
22
22
  @copy_count ||= 0
23
23
  end
24
+ attr_writer :copy_count
24
25
 
25
26
  # @return [Integer] number of total input rows
26
27
  def total_count
27
28
  @total_count ||= 0
28
29
  end
30
+ attr_writer :total_count
29
31
 
30
32
  # @return [Array<String>] list of created files
31
33
  def out_files
data/lib/eco/csv/table.rb CHANGED
@@ -5,6 +5,7 @@ module Eco
5
5
  # - when `Array<Array>` => all `rows` as arrays where first array is the **header**
6
6
  def initialize(input)
7
7
  super(to_rows_array(input))
8
+
8
9
  delete_if do |row|
9
10
  values = row.fields
10
11
  values.all?(&:nil?) || values.map(&:to_s).all?(&:empty?)
@@ -21,6 +22,7 @@ module Eco
21
22
  row[header] = value.empty?? nil : value
22
23
  end
23
24
  end
25
+
24
26
  self
25
27
  end
26
28
 
@@ -41,9 +43,11 @@ module Eco
41
43
  # @return [Eco::CSV::Table]
42
44
  def transform_headers
43
45
  cols = columns
46
+
44
47
  cols.each do |col|
45
48
  col[0] = yield(col.first)
46
49
  end
50
+
47
51
  columns_to_table(cols)
48
52
  end
49
53
 
@@ -70,6 +74,7 @@ module Eco
70
74
  end
71
75
  end
72
76
  end
77
+
73
78
  self.class.new(out_rows)
74
79
  end
75
80
 
@@ -83,6 +88,7 @@ module Eco
83
88
  def transform_values
84
89
  transformed_rows = rows.map do |row|
85
90
  res = yield(row)
91
+
86
92
  case res
87
93
  when Array
88
94
  ::CSV::Row.new(row.headers, res)
@@ -90,6 +96,7 @@ module Eco
90
96
  res
91
97
  end
92
98
  end
99
+
93
100
  self.class.new(transformed_rows)
94
101
  end
95
102
 
@@ -136,6 +143,7 @@ module Eco
136
143
  def add_column(header_name, pos: -1)
137
144
  header_name = header_name.to_s.strip
138
145
  raise ArgumentError, "header_name can't be blank" if header_name.empty?
146
+
139
147
  new_col = Array.new(length).unshift(header_name)
140
148
  columns_to_table(columns.insert(pos, new_col))
141
149
  end
@@ -146,6 +154,7 @@ module Eco
146
154
  # @return [Eco::CSV::Table] with a new column named `name` with the row number
147
155
  def add_index_column(header_name = 'idx', pos: 0)
148
156
  header_name = header_name.to_s.strip
157
+
149
158
  add_column(header_name, pos: pos).tap do |table|
150
159
  table.each.with_index do |row, idx|
151
160
  row[header_name] = idx + 2
@@ -163,6 +172,7 @@ module Eco
163
172
  # It removes all rows where all columns' values are the same
164
173
  def delete_duplicates!
165
174
  unique_rows = []
175
+
166
176
  by_row!.delete_if do |row|
167
177
  unique_rows.any? {|done| equal_rows?(row, done)}.tap do |found|
168
178
  unique_rows << row unless found
@@ -218,6 +228,7 @@ module Eco
218
228
  def columns_to_table(columns_array)
219
229
  rows_data = columns_array.transpose
220
230
  return self.class.new(rows_data) if rows_data.length.positive?
231
+
221
232
  raise ArgumentError, "Expecting 'columns_array' to at least have header. Given: #{columns_array}"
222
233
  end
223
234
 
@@ -232,6 +243,7 @@ module Eco
232
243
  when Enumerable
233
244
  data = data.dup.compact
234
245
  return data unless data.count.positive?
246
+
235
247
  sample = data.first
236
248
 
237
249
  case sample
@@ -264,6 +276,7 @@ module Eco
264
276
 
265
277
  def if_array_to_pipe_string(value)
266
278
  return value unless value.is_a?(Array)
279
+
267
280
  value.join('|')
268
281
  end
269
282
  end
@@ -4,7 +4,7 @@ module Eco
4
4
  module Encoding
5
5
  include Eco::Language::AuxiliarLogger
6
6
 
7
- BOM_BYTES = [239, 187, 191]
7
+ BOM_BYTES = [239, 187, 191].freeze
8
8
 
9
9
  def has_bom?(path)
10
10
  return false if !path || file_empty?(path)
@@ -16,9 +16,10 @@ module Eco
16
16
 
17
17
  def get_file_content_with_encoding(file, encoding: nil)
18
18
  encoding ||= scoped_encoding(file)
19
+
19
20
  unless !encoding || encoding == 'utf-8'
20
21
  msg = "File encoding: '#{encoding}'"
21
- logger.debug(msg)
22
+ log(:debug) { msg }
22
23
  puts msg
23
24
  end
24
25
 
@@ -29,7 +30,9 @@ module Eco
29
30
  else
30
31
  content = File.read(file, encoding: encoding)
31
32
  end
32
- return nil unless content
33
+
34
+ return unless content
35
+
33
36
  content = content.encode("utf-8") unless encoding.include?('utf-8')
34
37
  content
35
38
  end
@@ -42,6 +45,7 @@ module Eco
42
45
  content = content.sub(bom, '')
43
46
  content.force_encoding('utf-8')
44
47
  end
48
+
45
49
  content
46
50
  end
47
51
 
@@ -52,21 +56,24 @@ module Eco
52
56
  # Gives the parameter as it should
53
57
  def scoped_encoding(path)
54
58
  unless file_exists?(path)
55
- logger.error("File does not exist: #{path}")
59
+ log(:error) { "File does not exist: #{path}" }
56
60
  return nil
57
61
  end
62
+
58
63
  encoding ||= encoding(path)
59
- encoding = (encoding == "bom") ? "#{encoding}|utf-8": encoding
64
+ encoding = "#{encoding}|utf-8" if encoding == "bom"
60
65
  encoding
61
66
  end
62
67
 
63
68
  def file_exists?(file)
64
- return false if !file
65
- return File.exist?(file) || File.exist?(File.expand_path(file))
69
+ return false unless file
70
+
71
+ File.exist?(file) || File.exist?(File.expand_path(file))
66
72
  end
67
73
 
68
74
  def file_empty?(path)
69
- return true if !File.file?(path)
75
+ return true unless File.file?(path)
76
+
70
77
  File.zero?(path)
71
78
  end
72
79
  end
@@ -30,11 +30,15 @@ module Eco
30
30
  replacement = "<#{bytes.unpack1('H*')}>"
31
31
 
32
32
  if tolerance <= 0
33
- logger.error("There were more than 5 encoding errors in the file '#{file}'.")
33
+ log(:error) {
34
+ "There were more than 5 encoding errors in the file '#{file}'."
35
+ }
34
36
  return content
35
37
  else
36
38
  tolerance -= 1
37
- logger.error("Encoding problem in file '#{file}': '#{replacement}'.")
39
+ log(:error) {
40
+ "Encoding problem in file '#{file}': '#{replacement}'."
41
+ }
38
42
  replacement
39
43
  end
40
44
  end
@@ -48,8 +48,10 @@ module Eco
48
48
  # between `src_1` and `src_2`.
49
49
  def diff_attrs
50
50
  return (@diff_attrs = []) if new? || del?
51
+
51
52
  @diff_attrs ||= all_compared_attrs.each_with_object([]) do |kattr, out|
52
53
  next unless comparable_attr?(kattr)
54
+
53
55
  out << kattr unless eq?(attr_prev(kattr), attr(kattr))
54
56
  end
55
57
  end
@@ -71,6 +73,7 @@ module Eco
71
73
  def diff_attr?(attr)
72
74
  return true if new?
73
75
  return true if del?
76
+
74
77
  diff_attrs.include?(attr.to_s)
75
78
  end
76
79
 
@@ -80,6 +83,7 @@ module Eco
80
83
  target_attrs = [key] | all_compared_attrs
81
84
  return slice_attrs(src_2, *target_attrs) if new?
82
85
  return slice_attrs(src_1, key) if del?
86
+
83
87
  slice_attrs(src_2, key, *diff_attrs)
84
88
  end
85
89
 
@@ -109,6 +113,7 @@ module Eco
109
113
  attr = attr.to_s
110
114
  return false unless all_compared_attrs.include?(attr)
111
115
  return true unless self.class.compared_attr_when_present?(attr)
116
+
112
117
  key_present_in_both?(attr)
113
118
  end
114
119
 
@@ -28,6 +28,7 @@ class Eco::Data::Locations::NodeDiff
28
28
  @diffs ||= super.select do |dff|
29
29
  # discard entries that are to be inserted and archived at the same time
30
30
  next false if dff.insert? && dff.archive?(validate: false)
31
+
31
32
  dff.unarchive? || dff.id_name? || dff.insert? ||
32
33
  dff.move? || dff.archive?
33
34
  end
@@ -67,32 +68,42 @@ class Eco::Data::Locations::NodeDiff
67
68
  def diffs_summary # rubocop:disable Metrics/AbcSize
68
69
  comp = "(#{source_2.count} input nodes VS #{source_1.count} live nodes)"
69
70
  return "There were no differences identified #{comp}" if diffs.empty?
71
+
70
72
  msg = []
73
+
71
74
  msg << "Identified #{diffs.count} differences #{comp}:"
72
75
  msg << when_present(insert) do |count|
73
76
  " • #{count} nodes to insert"
74
77
  end
78
+
75
79
  msg << when_present(update) do |count|
76
80
  " • #{count} nodes to update"
77
81
  end
82
+
78
83
  msg << when_present(unarchive) do |count|
79
84
  " • #{count} nodes to unarchive (includes ancestors of target nodes)"
80
85
  end
86
+
81
87
  msg << when_present(id) do |count|
82
88
  " • #{count} nodes to change id\n"
83
89
  end
90
+
84
91
  msg << when_present(name) do |count|
85
92
  " • #{count} nodes to change name"
86
93
  end
94
+
87
95
  msg << when_present(classifications) do |count|
88
96
  " • #{count} nodes to change classifications"
89
97
  end
98
+
90
99
  msg << when_present(move) do |count|
91
100
  " • #{count} nodes to move"
92
101
  end
102
+
93
103
  msg << when_present(archive) do |count|
94
104
  " • #{count} nodes to archive"
95
105
  end
106
+
96
107
  msg.compact.join("\n")
97
108
  end
98
109
 
@@ -108,8 +119,10 @@ class Eco::Data::Locations::NodeDiff
108
119
 
109
120
  def when_present(list, default = nil)
110
121
  raise ArgumentError, "Expecting block but not given" unless block_given?
122
+
111
123
  count = list.count
112
124
  return yield(count) if count&.positive?
125
+
113
126
  default
114
127
  end
115
128
 
@@ -50,12 +50,14 @@ module Eco::Data::Locations
50
50
  def id_name?
51
51
  return true if id?
52
52
  return true if name?
53
+
53
54
  classifications?
54
55
  end
55
56
 
56
57
  # Has the parent id changed?
57
58
  def move?
58
59
  return false unless update?
60
+
59
61
  parent_id?
60
62
  end
61
63
 
@@ -72,6 +74,7 @@ module Eco::Data::Locations
72
74
  return true if marked_for_unarchive?
73
75
  return false if archived
74
76
  return false unless update?
77
+
75
78
  archived?
76
79
  end
77
80
 
@@ -86,6 +89,7 @@ module Eco::Data::Locations
86
89
  raise msg if validate && archived && insert?
87
90
 
88
91
  return true if del?
92
+
89
93
  archived
90
94
  end
91
95
  end
@@ -70,6 +70,7 @@ module Eco::Data::Locations
70
70
 
71
71
  def classifications
72
72
  return [] unless (al = actual_level).positive?
73
+
73
74
  original_headers[al - 1]
74
75
  end
75
76
 
@@ -111,8 +112,10 @@ module Eco::Data::Locations
111
112
  # Requires that all upper levels (lower positions) are filled-in
112
113
  def common_level_with(other)
113
114
  return nil unless other
115
+
114
116
  otags_array = other.tags_array.compact
115
117
  stags_array = tags_array.compact
118
+
116
119
  raise "Missing lower levels for #{other.id}: #{other.tags_array.pretty_inspect}" unless other.highest_levels_set?
117
120
  raise "Missing lower levels for #{id}: #{tags_array.pretty_inspect}" unless highest_levels_set?
118
121
 
@@ -174,6 +177,7 @@ module Eco::Data::Locations
174
177
  def highest_levels_set?
175
178
  return true if raw_level == 1
176
179
  return true unless raw_prev_empty_level?
180
+
177
181
  !!@highest_levels_set
178
182
  end
179
183
 
@@ -194,10 +198,12 @@ module Eco::Data::Locations
194
198
  target = i.to_a
195
199
  when Integer
196
200
  return false unless i >= 1 && i <= tag_attrs_count
201
+
197
202
  target = Array(i..tag_attrs_count)
198
203
  else
199
204
  return false
200
205
  end
206
+
201
207
  return false if target.empty?
202
208
 
203
209
  target.each do |n|
@@ -22,6 +22,8 @@ module Eco
22
22
 
23
23
  # Shortcut to logger.
24
24
  def log(level, &block)
25
+ return unless logger.respond_to?(:level)
26
+
25
27
  logger&.send(level, &block)
26
28
  end
27
29
  end
data/lib/eco/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Eco
2
- VERSION = '3.0.4'.freeze
2
+ VERSION = '3.0.7'.freeze
3
3
  end
data/lib/eco-helpers.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # rubocop:disable Naming/FileName
2
2
  require 'csv'
3
3
  require 'json'
4
- require 'pp'
4
+ require 'pp' # rubocop:disable Lint/RedundantRequireStatement
5
5
  require 'dotenv'
6
6
  require 'dotenv/load'
7
7