eco-helpers 3.0.19 → 3.0.20
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.md +17 -3
- data/lib/eco/api/common/loaders/config/session.rb +12 -0
- data/lib/eco/api/common/loaders/config/workflow/mailer.rb +17 -4
- data/lib/eco/api/common/loaders/config.rb +10 -2
- data/lib/eco/api/common/session/sftp.rb +5 -0
- data/lib/eco/api/custom/mailer.rb +1 -0
- data/lib/eco/api/error.rb +4 -0
- data/lib/eco/api/session/batch/job.rb +14 -16
- data/lib/eco/api/session/batch/jobs.rb +6 -8
- data/lib/eco/api/session/batch/launcher/mode_size.rb +5 -2
- data/lib/eco/api/session/batch/launcher/retry.rb +6 -1
- data/lib/eco/api/session/config/api.rb +1 -0
- data/lib/eco/api/session/config/apis/one_off.rb +6 -6
- data/lib/eco/api/session/config/workflow.rb +16 -3
- data/lib/eco/api/session.rb +11 -7
- data/lib/eco/api/usecases/default/locations/tagtree_extract_case.rb +1 -0
- data/lib/eco/api/usecases/default/locations/tagtree_upload_case.rb +2 -0
- data/lib/eco/api/usecases/default_cases/samples/sftp_case.rb +22 -15
- data/lib/eco/api/usecases/ooze_cases/export_register_case.rb +6 -6
- data/lib/eco/api/usecases/ooze_samples/helpers/exportable_register.rb +1 -0
- data/lib/eco/api/usecases/ooze_samples/ooze_base_case.rb +1 -1
- data/lib/eco/api/usecases/ooze_samples/ooze_run_base_case.rb +8 -5
- data/lib/eco/cli_default/workflow.rb +10 -4
- data/lib/eco/csv/stream.rb +2 -0
- data/lib/eco/csv.rb +3 -2
- data/lib/eco/language/methods/delegate_missing.rb +4 -3
- data/lib/eco/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 96eaee3dd7897d77b22857cf8f812ce6d0639af324565c54f649c1e8068b7fb4
|
|
4
|
+
data.tar.gz: c9af686fe8f01d45eb3ea6a0dc89de276b789dfd6e3f64b515e17107b233b2d3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 66bdc8b7c98b2aa0e60e205ac64b47a302e2cd8dbe1efd1720ad36c04a4f4c1a70b2cbb4d4978c67a17bd0f86893d34b47ff809f95a3e06952c002b872872553
|
|
7
|
+
data.tar.gz: f205d190dc159c0218bc1cafa52f139a6faaa133a01190ae1b189d2b8b6ef2470f49b634169effcf2021023803ec58f1793b8ce4c019db9d1dd025df7bbf5493
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -2,7 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
-
## [3.0.
|
|
5
|
+
## [3.0.20] - 2024-12-xx
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Mailer: to specify non-default `space` in the subject, when used.
|
|
10
|
+
- `Eco::API::Common::Loaders::Config`
|
|
11
|
+
- Can call config with params
|
|
12
|
+
- `Eco::API::Common::Loaders::Session`
|
|
13
|
+
- Which switches the configuration to that of the specific environment
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- On failure, `Eco::API::Session::Job#summary` to give precise estimates on what is pending to be run.
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
## [3.0.19] - 2024-11-21
|
|
6
22
|
|
|
7
23
|
### Added
|
|
8
24
|
|
|
@@ -21,8 +37,6 @@ All notable changes to this project will be documented in this file.
|
|
|
21
37
|
- `ecoportal-api-v2`
|
|
22
38
|
- `ecoportal-api-graphql`
|
|
23
39
|
|
|
24
|
-
### Fixed
|
|
25
|
-
|
|
26
40
|
## [3.0.18] - 2024-10-28
|
|
27
41
|
|
|
28
42
|
### Changed
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
class Eco::API::Common::Loaders::Session < Eco::API::Common::Loaders::Config
|
|
2
|
+
class << self
|
|
3
|
+
# This is a config tied to the current environment session.
|
|
4
|
+
def config
|
|
5
|
+
return @config if instance_variable_defined?(:@config)
|
|
6
|
+
|
|
7
|
+
@config = super(key: super.apis.active_root_name)
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
delegate_missing_to :workflow
|
|
12
|
+
end
|
|
@@ -18,9 +18,8 @@ class Eco::API::Common::Loaders::Workflow::Mailer < Eco::API::Common::Loaders::W
|
|
|
18
18
|
next if session.config.dry_run?
|
|
19
19
|
next unless session.config.run_mode_remote?
|
|
20
20
|
|
|
21
|
-
# temporary contingency
|
|
22
|
-
|
|
23
|
-
next unless some_update?(io) || maybe_error_pages_or_tree_updates
|
|
21
|
+
# temporary contingency: maybe_error_or_tree_updates?
|
|
22
|
+
next unless some_update?(io) || maybe_error_pages_or_tree_updates?(io)
|
|
24
23
|
|
|
25
24
|
subject = base_subject
|
|
26
25
|
|
|
@@ -47,7 +46,15 @@ class Eco::API::Common::Loaders::Workflow::Mailer < Eco::API::Common::Loaders::W
|
|
|
47
46
|
end
|
|
48
47
|
|
|
49
48
|
def base_subject
|
|
50
|
-
"#{org_name} (#{
|
|
49
|
+
"#{org_name} (#{active_enviro_desc}) at #{Time.now.iso8601}"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def active_enviro_desc
|
|
53
|
+
space_desc = config.active_enviro_space.to_s.strip
|
|
54
|
+
space_desc = '' if space_desc == 'default'
|
|
55
|
+
space_desc = " - space: '#{space_desc}'" unless space_desc.empty?
|
|
56
|
+
|
|
57
|
+
"#{active_enviro}#{space_desc}"
|
|
51
58
|
end
|
|
52
59
|
|
|
53
60
|
def some_update?(io)
|
|
@@ -66,6 +73,11 @@ class Eco::API::Common::Loaders::Workflow::Mailer < Eco::API::Common::Loaders::W
|
|
|
66
73
|
!!error
|
|
67
74
|
end
|
|
68
75
|
|
|
76
|
+
# @note at some stage, tree cases should have their own case type
|
|
77
|
+
def maybe_error_pages_or_tree_updates?(io)
|
|
78
|
+
other_case?(io) && error?
|
|
79
|
+
end
|
|
80
|
+
|
|
69
81
|
def errors_n_warnings(io)
|
|
70
82
|
[error_message, log_err_n_warn(io)].join("\n")
|
|
71
83
|
end
|
|
@@ -73,6 +85,7 @@ class Eco::API::Common::Loaders::Workflow::Mailer < Eco::API::Common::Loaders::W
|
|
|
73
85
|
def log_err_n_warn(io)
|
|
74
86
|
warn_errors = io.logger.cache.logs(level: %i[error warn])
|
|
75
87
|
return if warn_errors.empty?
|
|
88
|
+
|
|
76
89
|
"ALL WARNINGS & ERRORS:\n#{warn_errors.join}\n"
|
|
77
90
|
end
|
|
78
91
|
|
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
class Eco::API::Common::Loaders::Config
|
|
2
2
|
extend Eco::API::Common::ClassHelpers
|
|
3
3
|
extend Eco::Language::Methods::DelegateMissing
|
|
4
|
+
|
|
4
5
|
inheritable_class_vars :delegate_missing_to
|
|
5
6
|
|
|
6
7
|
class << self
|
|
7
8
|
# To create samples of configurations
|
|
8
9
|
def config_block(&block)
|
|
9
10
|
return @config_block unless block_given?
|
|
11
|
+
|
|
12
|
+
unless @config_block.nil?
|
|
13
|
+
msg = "Reconfiguring config_block on #{self}"
|
|
14
|
+
session.log(:warn) { msg }
|
|
15
|
+
end
|
|
16
|
+
|
|
10
17
|
@config_block = block
|
|
11
18
|
end
|
|
12
19
|
|
|
13
|
-
def config
|
|
14
|
-
ASSETS.config
|
|
20
|
+
def config(...)
|
|
21
|
+
ASSETS.config(...)
|
|
15
22
|
end
|
|
16
23
|
|
|
17
24
|
def cli
|
|
@@ -27,3 +34,4 @@ class Eco::API::Common::Loaders::Config
|
|
|
27
34
|
end
|
|
28
35
|
|
|
29
36
|
require_relative 'config/workflow'
|
|
37
|
+
require_relative 'config/session'
|
|
@@ -8,6 +8,7 @@ module Eco
|
|
|
8
8
|
def initialize(enviro:)
|
|
9
9
|
invalid_env = enviro && !enviro.is_a?(Eco::API::Common::Session::Environment)
|
|
10
10
|
raise "Required Environment object (enviro:). Given: #{enviro}" if invalid_env
|
|
11
|
+
|
|
11
12
|
@enviro = enviro
|
|
12
13
|
end
|
|
13
14
|
|
|
@@ -103,6 +104,7 @@ module Eco
|
|
|
103
104
|
def download(files, local_folder: nil, &block)
|
|
104
105
|
puts "Creating local files:"
|
|
105
106
|
created_files = []
|
|
107
|
+
|
|
106
108
|
[files].flatten.compact.map do |fullname|
|
|
107
109
|
basename = windows_basename(fullname)
|
|
108
110
|
dest_fullname = File.join(local_folder || ".", basename)
|
|
@@ -110,6 +112,7 @@ module Eco
|
|
|
110
112
|
created_files << dest_fullname
|
|
111
113
|
sftp_session.download(fullname, dest_fullname)
|
|
112
114
|
end.each(&:wait)
|
|
115
|
+
|
|
113
116
|
# run SSH event loop while dw.active?
|
|
114
117
|
created_files.tap { created_files.each(&block) }
|
|
115
118
|
end
|
|
@@ -155,9 +158,11 @@ module Eco
|
|
|
155
158
|
def windows_basename(remote_fullname)
|
|
156
159
|
dir_sep = /[\\\/]/
|
|
157
160
|
patr_re = /[<>:\\\/|?*]/
|
|
161
|
+
|
|
158
162
|
parts = remote_fullname.split(dir_sep).map do |node|
|
|
159
163
|
node.gsub(patr_re, '_')
|
|
160
164
|
end
|
|
165
|
+
|
|
161
166
|
local_fullname = File.join(*parts)
|
|
162
167
|
File.basename(local_fullname)
|
|
163
168
|
end
|
data/lib/eco/api/error.rb
CHANGED
|
@@ -96,9 +96,11 @@ module Eco
|
|
|
96
96
|
end.sort do |k_1, k_2|
|
|
97
97
|
next -1 if k_2 < k_1
|
|
98
98
|
next 1 if k_1 < k_2
|
|
99
|
+
|
|
99
100
|
0
|
|
100
101
|
end.tap do |siblings|
|
|
101
102
|
siblings.delete(Unclassified)
|
|
103
|
+
|
|
102
104
|
if direct
|
|
103
105
|
siblings.reject! do |si|
|
|
104
106
|
siblings.any? {|s| si < s}
|
|
@@ -120,8 +122,10 @@ module Eco
|
|
|
120
122
|
|
|
121
123
|
descendants(direct: true).reverse.each do |klass|
|
|
122
124
|
next unless klass.err_match?(err_msg)
|
|
125
|
+
|
|
123
126
|
type = klass
|
|
124
127
|
next unless klass.descendants?(direct: true)
|
|
128
|
+
|
|
125
129
|
type = klass.get_type(err_msg, first: false) || type
|
|
126
130
|
end
|
|
127
131
|
|
|
@@ -217,6 +217,7 @@ module Eco
|
|
|
217
217
|
elsif !pqueue.empty?
|
|
218
218
|
req_backup = as_update(pqueue, add_feedback: false)
|
|
219
219
|
backup_update(req_backup)
|
|
220
|
+
|
|
220
221
|
log(:debug) {
|
|
221
222
|
"Job ('#{name}':#{type}): going to launch batch against #{pqueue.count} entries"
|
|
222
223
|
}
|
|
@@ -246,28 +247,25 @@ module Eco
|
|
|
246
247
|
# 3. error messages in case they were errors from the server
|
|
247
248
|
# @note if `launch` was not invoked, it specifies so
|
|
248
249
|
# @return [String] the summary
|
|
249
|
-
def summary
|
|
250
|
+
def summary
|
|
250
251
|
[].tap do |msg|
|
|
251
|
-
if pending?
|
|
252
|
-
|
|
253
|
-
else
|
|
254
|
-
msg << feedback.generate(requests, only_stats: true)
|
|
252
|
+
msg << "PENDING Job -------->\n" if pending?
|
|
253
|
+
msg << feedback.generate(requests, only_stats: true)
|
|
255
254
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
end
|
|
260
|
-
|
|
261
|
-
msg << status.errors.message if status
|
|
262
|
-
msg << subjobs_summary
|
|
255
|
+
if batch_policy && !batch_policy.compliant?(request_stats)
|
|
256
|
+
msg << 'Batch Policy Uncompliance:'
|
|
257
|
+
msg << batch_policy.uncompliance(request_stats)
|
|
263
258
|
end
|
|
259
|
+
|
|
260
|
+
msg << status.errors.message if status
|
|
261
|
+
msg << subjobs_summary
|
|
264
262
|
end.join("\n")
|
|
265
263
|
end
|
|
266
264
|
|
|
267
265
|
private
|
|
268
266
|
|
|
269
267
|
def subjobs_summary
|
|
270
|
-
return
|
|
268
|
+
return '' unless subjobs.count.positive?
|
|
271
269
|
|
|
272
270
|
[].tap do |msg|
|
|
273
271
|
subjobs.map {|subjob| msg << subjob.summary}
|
|
@@ -431,7 +429,7 @@ module Eco
|
|
|
431
429
|
next unless status.success?(entry)
|
|
432
430
|
|
|
433
431
|
if type == :create && entry.respond_to?(:id=)
|
|
434
|
-
entry.id = status[entry].body[
|
|
432
|
+
entry.id = status[entry].body['id'].tap do |id|
|
|
435
433
|
next unless id.to_s.strip.empty?
|
|
436
434
|
|
|
437
435
|
ref = Eco::API::Session::Batch::Feedback.person_ref(entry)
|
|
@@ -503,9 +501,9 @@ module Eco
|
|
|
503
501
|
|
|
504
502
|
# Keep a copy of the requests for future reference
|
|
505
503
|
def backup_update(requests, simulate: false)
|
|
506
|
-
dry_run = simulate ?
|
|
504
|
+
dry_run = simulate ? '_dry_run' : ''
|
|
507
505
|
dir = config.people.requests_folder
|
|
508
|
-
filename = name.split(
|
|
506
|
+
filename = name.split(' ').join('-').gsub(/[=\\\/><,"-]+/, "_") # rubocop:disable Style/RedundantArgument
|
|
509
507
|
file = File.join(dir, "#{type}_data_#{filename}#{dry_run}.json")
|
|
510
508
|
file_manager.save_json(requests, file, :timestamp)
|
|
511
509
|
end
|
|
@@ -81,7 +81,7 @@ module Eco
|
|
|
81
81
|
end
|
|
82
82
|
|
|
83
83
|
def pending?
|
|
84
|
-
any?
|
|
84
|
+
any?(&:pending?)
|
|
85
85
|
end
|
|
86
86
|
|
|
87
87
|
# Launches every `Batch::Job` in the group.
|
|
@@ -108,19 +108,17 @@ module Eco
|
|
|
108
108
|
end
|
|
109
109
|
end
|
|
110
110
|
|
|
111
|
-
def status
|
|
111
|
+
def status(&block)
|
|
112
112
|
if block_given?
|
|
113
|
-
status.each
|
|
114
|
-
yield(job, job_status)
|
|
115
|
-
end
|
|
113
|
+
status.each(&block)
|
|
116
114
|
self
|
|
117
|
-
else
|
|
118
|
-
@jobs_status ||= {}
|
|
115
|
+
else
|
|
116
|
+
@jobs_status ||= {} # rubocop:disable Naming/MemoizedInstanceVariableName
|
|
119
117
|
end
|
|
120
118
|
end
|
|
121
119
|
|
|
122
120
|
def errors?
|
|
123
|
-
any?
|
|
121
|
+
any?(&:errors?)
|
|
124
122
|
end
|
|
125
123
|
|
|
126
124
|
def summary
|
|
@@ -18,14 +18,17 @@ module Eco
|
|
|
18
18
|
private
|
|
19
19
|
|
|
20
20
|
# Swaps to batch endpoint on specific errors
|
|
21
|
-
def batch_mode_on(*error_types, options: self.options, allow_job_mode: true
|
|
21
|
+
def batch_mode_on(*error_types, options: self.options, allow_job_mode: true)
|
|
22
|
+
msg = "Expecting block. Non given"
|
|
23
|
+
raise ArgumentError, msg unless block_given?
|
|
24
|
+
|
|
22
25
|
in_job_mode = allow_job_mode && job_mode?(options)
|
|
23
26
|
|
|
24
27
|
yield(in_job_mode, batch_size(options))
|
|
25
28
|
rescue *error_types
|
|
26
29
|
raise unless in_job_mode
|
|
27
30
|
|
|
28
|
-
yield(false
|
|
31
|
+
yield(false, batch_mode_size)
|
|
29
32
|
end
|
|
30
33
|
|
|
31
34
|
# MODE
|
|
@@ -25,7 +25,12 @@ module Eco
|
|
|
25
25
|
explanation << "You have #{retries_left} retries left."
|
|
26
26
|
question = " Do you want to retry (y/N)?"
|
|
27
27
|
|
|
28
|
-
prompt_user(
|
|
28
|
+
prompt_user(
|
|
29
|
+
question,
|
|
30
|
+
default: "Y",
|
|
31
|
+
explanation: explanation,
|
|
32
|
+
timeout: 10
|
|
33
|
+
) do |response|
|
|
29
34
|
raise unless response.upcase.start_with?("Y")
|
|
30
35
|
|
|
31
36
|
puts "\nOkay... let's retry!"
|
|
@@ -4,14 +4,14 @@ module Eco
|
|
|
4
4
|
class Config
|
|
5
5
|
class Apis
|
|
6
6
|
module OneOff
|
|
7
|
-
private
|
|
8
|
-
|
|
9
7
|
def one_off?
|
|
10
|
-
@is_one_off ||=
|
|
8
|
+
@is_one_off ||= # rubocop:disable Naming/MemoizedInstanceVariableName
|
|
11
9
|
SCR.get_arg('-api-key') ||
|
|
12
10
|
SCR.get_arg('-one-off')
|
|
13
11
|
end
|
|
14
12
|
|
|
13
|
+
private
|
|
14
|
+
|
|
15
15
|
def one_off_key
|
|
16
16
|
return @one_off_key if instance_variable_defined?(:@one_off_key)
|
|
17
17
|
|
|
@@ -48,10 +48,10 @@ module Eco
|
|
|
48
48
|
return @one_off_org if instance_variable_defined?(:@one_off_org)
|
|
49
49
|
|
|
50
50
|
msg = "You should specify -org NAME when using -api-key or -one-off"
|
|
51
|
-
raise msg unless org = SCR.get_arg('-org', with_param: true)
|
|
51
|
+
raise msg unless (org = SCR.get_arg('-org', with_param: true))
|
|
52
52
|
|
|
53
53
|
str_org = "#{org.downcase.split(/[^a-z]+/).join('_')}_#{one_off_enviro.gsub('.', '_')}"
|
|
54
|
-
@one_off_org
|
|
54
|
+
@one_off_org ||= str_org.to_sym
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
def one_off_enviro
|
|
@@ -83,7 +83,7 @@ module Eco
|
|
|
83
83
|
|
|
84
84
|
true
|
|
85
85
|
rescue StandardError => err
|
|
86
|
-
puts
|
|
86
|
+
puts err.to_s
|
|
87
87
|
false
|
|
88
88
|
end
|
|
89
89
|
end
|
|
@@ -141,7 +141,8 @@ module Eco
|
|
|
141
141
|
# @yieldreturn [Eco::API::UseCases::BaseIO] the `io` input/output object carried througout all the _workflow_
|
|
142
142
|
# @return [Eco::API::Session::Config::Workflow] the current stage object (to ease chainig).
|
|
143
143
|
def rescue(&block)
|
|
144
|
-
return @rescue unless
|
|
144
|
+
return @rescue unless block_given?
|
|
145
|
+
|
|
145
146
|
@rescue = block
|
|
146
147
|
self
|
|
147
148
|
end
|
|
@@ -150,7 +151,8 @@ module Eco
|
|
|
150
151
|
|
|
151
152
|
# Called on `SystemExit` exception
|
|
152
153
|
def exit_handle(&block)
|
|
153
|
-
return @exit_handle unless
|
|
154
|
+
return @exit_handle unless block_given?
|
|
155
|
+
|
|
154
156
|
@exit_handle = block
|
|
155
157
|
self
|
|
156
158
|
end
|
|
@@ -171,6 +173,7 @@ module Eco
|
|
|
171
173
|
# @return [Eco::API::Session::Config::Workflow] the current stage object (to ease chainig).
|
|
172
174
|
def before(key = nil, &block)
|
|
173
175
|
raise ArgumentError, "A block should be given." unless block_given?
|
|
176
|
+
|
|
174
177
|
if key
|
|
175
178
|
stage(key).before(&block)
|
|
176
179
|
else
|
|
@@ -195,6 +198,7 @@ module Eco
|
|
|
195
198
|
# @return [Eco::API::Session::Config::Workflow] the current stage object (to ease chainig).
|
|
196
199
|
def after(key = nil, &block)
|
|
197
200
|
raise ArgumentError, "A block should be given." unless block_given?
|
|
201
|
+
|
|
198
202
|
if key
|
|
199
203
|
stage(key).after(&block)
|
|
200
204
|
else
|
|
@@ -267,6 +271,7 @@ module Eco
|
|
|
267
271
|
io.evaluate(self, io, &c)
|
|
268
272
|
end
|
|
269
273
|
end
|
|
274
|
+
|
|
270
275
|
io
|
|
271
276
|
end
|
|
272
277
|
|
|
@@ -276,6 +281,7 @@ module Eco
|
|
|
276
281
|
io.evaluate(self, io, &c)
|
|
277
282
|
end
|
|
278
283
|
end
|
|
284
|
+
|
|
279
285
|
io
|
|
280
286
|
end
|
|
281
287
|
|
|
@@ -305,6 +311,7 @@ module Eco
|
|
|
305
311
|
io.evaluate(self, io, &@on)
|
|
306
312
|
end
|
|
307
313
|
end
|
|
314
|
+
|
|
308
315
|
io
|
|
309
316
|
ensure
|
|
310
317
|
@pending = false
|
|
@@ -341,7 +348,11 @@ module Eco
|
|
|
341
348
|
|
|
342
349
|
def stage(key)
|
|
343
350
|
self.class.validate_stage(key)
|
|
344
|
-
@stages[key] ||= self.class.workflow_class(key).new(
|
|
351
|
+
@stages[key] ||= self.class.workflow_class(key).new(
|
|
352
|
+
key,
|
|
353
|
+
_parent: self,
|
|
354
|
+
config: config
|
|
355
|
+
)
|
|
345
356
|
end
|
|
346
357
|
|
|
347
358
|
# helper to treat trigger the exit and rescue handlers
|
|
@@ -354,6 +365,7 @@ module Eco
|
|
|
354
365
|
io = io_result(io: io) do
|
|
355
366
|
io.evaluate(err, io, &exit_handle)
|
|
356
367
|
end
|
|
368
|
+
|
|
357
369
|
exit err.status
|
|
358
370
|
rescue Interrupt => _int
|
|
359
371
|
raise
|
|
@@ -362,6 +374,7 @@ module Eco
|
|
|
362
374
|
io = io_result(io: io) do
|
|
363
375
|
io.evaluate(err, io, &self.rescue)
|
|
364
376
|
end
|
|
377
|
+
|
|
365
378
|
raise
|
|
366
379
|
end
|
|
367
380
|
end
|
data/lib/eco/api/session.rb
CHANGED
|
@@ -70,6 +70,7 @@ module Eco
|
|
|
70
70
|
)
|
|
71
71
|
if live && api?(version: :graphql)
|
|
72
72
|
return live_tree(include_archived: include_archived, **kargs, &block) unless merge
|
|
73
|
+
|
|
73
74
|
live_trees(include_archived: include_archived, **kargs, &block).inject(&:merge)
|
|
74
75
|
else
|
|
75
76
|
config.tagtree(recache: recache)
|
|
@@ -118,10 +119,12 @@ module Eco
|
|
|
118
119
|
# @return [Eco::Data::Mapper] the mappings between the internal and external attribute/property names.
|
|
119
120
|
def fields_mapper
|
|
120
121
|
return @fields_mapper if instance_variable_defined?(:@fields_mapper)
|
|
122
|
+
|
|
121
123
|
mappings = []
|
|
122
124
|
if (map_file = config.people.fields_mapper)
|
|
123
125
|
mappings = map_file ? file_manager.load_json(map_file) : []
|
|
124
126
|
end
|
|
127
|
+
|
|
125
128
|
@fields_mapper = Eco::Data::Mapper.new(mappings)
|
|
126
129
|
end
|
|
127
130
|
|
|
@@ -166,9 +169,9 @@ module Eco
|
|
|
166
169
|
# @param phase [Symbol] the phase when this parser should be active.
|
|
167
170
|
# @return [Object] the parsed attribute.
|
|
168
171
|
def parse_attribute(attr, source, phase = :internal, deps: {})
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
+
msg = "There are no parsers defined"
|
|
173
|
+
raise msg unless (parsers = entry_factory.person_parser)
|
|
174
|
+
|
|
172
175
|
parsers.parse(attr, source, phase, deps: deps)
|
|
173
176
|
end
|
|
174
177
|
|
|
@@ -390,18 +393,19 @@ module Eco
|
|
|
390
393
|
|
|
391
394
|
# from schema `id` or `name` to a PersonSchema object
|
|
392
395
|
def to_schema(value)
|
|
393
|
-
return nil unless value
|
|
394
396
|
sch = nil
|
|
397
|
+
return unless value
|
|
398
|
+
|
|
395
399
|
case value
|
|
396
400
|
when String
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
end
|
|
401
|
+
msg = "The schema with id or name '#{value}' does not exist."
|
|
402
|
+
fatal msg unless (sch = schemas.schema(value))
|
|
400
403
|
when Ecoportal::API::V1::PersonSchema
|
|
401
404
|
sch = value
|
|
402
405
|
else
|
|
403
406
|
fatal "Required String or Ecoportal::API::V1::PersonSchema. Given: #{value}"
|
|
404
407
|
end
|
|
408
|
+
|
|
405
409
|
sch
|
|
406
410
|
end
|
|
407
411
|
end
|
|
@@ -27,6 +27,7 @@ class Eco::API::UseCases::Default::Locations::TagtreeUpload < Eco::API::UseCases
|
|
|
27
27
|
comms << insert_command(tree, pid: pid) unless top_id?(tree.id)
|
|
28
28
|
pid = tree.id
|
|
29
29
|
end
|
|
30
|
+
|
|
30
31
|
tree.nodes.map do |node|
|
|
31
32
|
insert_commands(node, pid: pid)
|
|
32
33
|
end.flatten(1).tap do |subs|
|
|
@@ -54,6 +55,7 @@ class Eco::API::UseCases::Default::Locations::TagtreeUpload < Eco::API::UseCases
|
|
|
54
55
|
|
|
55
56
|
def top_id?(node_id = nil)
|
|
56
57
|
return top_id.is_a?(String) if node_id.nil?
|
|
58
|
+
|
|
57
59
|
node_id == top_id
|
|
58
60
|
end
|
|
59
61
|
|
|
@@ -7,7 +7,7 @@ class Eco::API::UseCases::DefaultCases::Samples::Sftp < Eco::API::Common::Loader
|
|
|
7
7
|
name "sftp"
|
|
8
8
|
type :other
|
|
9
9
|
|
|
10
|
-
CONST_REFERRAL = /^(?:::)?(?:[A-Z][a-zA-Z0-9_]*(?:::[A-Z][a-zA-Z0-9_]*)*)
|
|
10
|
+
CONST_REFERRAL = /^(?:::)?(?:[A-Z][a-zA-Z0-9_]*(?:::[A-Z][a-zA-Z0-9_]*)*)$/
|
|
11
11
|
|
|
12
12
|
def main(session, options, _usecase)
|
|
13
13
|
options[:end_get] = false
|
|
@@ -31,7 +31,7 @@ class Eco::API::UseCases::DefaultCases::Samples::Sftp < Eco::API::Common::Loader
|
|
|
31
31
|
def file_pattern(require: true)
|
|
32
32
|
fpc = file_pattern_const
|
|
33
33
|
return fpc if fpc
|
|
34
|
-
return
|
|
34
|
+
return unless require
|
|
35
35
|
|
|
36
36
|
msg = "(#{self.class}) You should redefine the file_pattern function "
|
|
37
37
|
msg << "as a RegEx expression that matches the target remote file"
|
|
@@ -41,6 +41,7 @@ class Eco::API::UseCases::DefaultCases::Samples::Sftp < Eco::API::Common::Loader
|
|
|
41
41
|
def file_pattern_const
|
|
42
42
|
if (fpc = options.dig(:sftp, :file_pattern_const))
|
|
43
43
|
raise WrongConst, "(#{self.class}) Invalid file pattern const referral: #{fpc}" unless fpc.match(CONST_REFERRAL)
|
|
44
|
+
|
|
44
45
|
begin
|
|
45
46
|
self.eval(fpc)
|
|
46
47
|
rescue NameError
|
|
@@ -54,6 +55,7 @@ class Eco::API::UseCases::DefaultCases::Samples::Sftp < Eco::API::Common::Loader
|
|
|
54
55
|
# Ex: "/IN/Personnel"
|
|
55
56
|
def remote_subfolder(require: true)
|
|
56
57
|
rm_sf = options.dig(:sftp, :remote_subfolder)
|
|
58
|
+
|
|
57
59
|
return rm_sf if rm_sf
|
|
58
60
|
return unless require
|
|
59
61
|
|
|
@@ -78,7 +80,7 @@ class Eco::API::UseCases::DefaultCases::Samples::Sftp < Eco::API::Common::Loader
|
|
|
78
80
|
options.dig(:sftp, :local_folder) || "."
|
|
79
81
|
end
|
|
80
82
|
|
|
81
|
-
def with_remote_files(folder:
|
|
83
|
+
def with_remote_files(folder: remote_folder, pattern: file_pattern)
|
|
82
84
|
sftp.files(folder, pattern: pattern).each do |remote_file|
|
|
83
85
|
yield(remote_file) if block_given?
|
|
84
86
|
end
|
|
@@ -100,22 +102,25 @@ class Eco::API::UseCases::DefaultCases::Samples::Sftp < Eco::API::Common::Loader
|
|
|
100
102
|
|
|
101
103
|
def get_files
|
|
102
104
|
with_remote_files.tap do |files|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
105
|
+
next if files.empty?
|
|
106
|
+
|
|
107
|
+
file_names = files.map {|file| to_remote_path(file.name)}
|
|
108
|
+
|
|
109
|
+
puts "Getting the following files into the local folder '#{local_folder}':"
|
|
110
|
+
puts file_names
|
|
111
|
+
|
|
112
|
+
sftp.download(file_names, local_folder: local_folder)
|
|
109
113
|
end
|
|
110
114
|
end
|
|
111
115
|
|
|
112
116
|
def get_last
|
|
113
117
|
with_remote_files.last.tap do |file|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
118
|
+
next unless file
|
|
119
|
+
|
|
120
|
+
file_name = to_remote_path(file.name)
|
|
121
|
+
puts "Getting the following file: #{file_name}"
|
|
122
|
+
|
|
123
|
+
sftp.download(file_name, local_folder: local_folder)
|
|
119
124
|
end
|
|
120
125
|
end
|
|
121
126
|
|
|
@@ -125,7 +130,9 @@ class Eco::API::UseCases::DefaultCases::Samples::Sftp < Eco::API::Common::Loader
|
|
|
125
130
|
dest = to_remote_path("#{archive_subfolder}/#{file.name}")
|
|
126
131
|
move_file(source, dest)
|
|
127
132
|
end.tap do |files|
|
|
128
|
-
|
|
133
|
+
next if files.empty?
|
|
134
|
+
|
|
135
|
+
puts "Moved the file(s) to the #{archive_subfolder} folder"
|
|
129
136
|
end
|
|
130
137
|
end
|
|
131
138
|
|
|
@@ -40,7 +40,7 @@ class Eco::API::UseCases::OozeCases::ExportRegisterCase < Eco::API::UseCases::Oo
|
|
|
40
40
|
|
|
41
41
|
def build_tags_filter(mode = :any)
|
|
42
42
|
tags = option_tags(mode)
|
|
43
|
-
return
|
|
43
|
+
return if !tags || tags.empty?
|
|
44
44
|
|
|
45
45
|
tags_filter(tags, any: mode == :any)
|
|
46
46
|
end
|
|
@@ -48,7 +48,7 @@ class Eco::API::UseCases::OozeCases::ExportRegisterCase < Eco::API::UseCases::Oo
|
|
|
48
48
|
def build_range_filter(key = :update_at)
|
|
49
49
|
from = from_date(key)
|
|
50
50
|
to = to_date(key)
|
|
51
|
-
return
|
|
51
|
+
return unless from || to
|
|
52
52
|
|
|
53
53
|
date_range_filter(from: from, to: to, key: key)
|
|
54
54
|
end
|
|
@@ -92,10 +92,10 @@ class Eco::API::UseCases::OozeCases::ExportRegisterCase < Eco::API::UseCases::Oo
|
|
|
92
92
|
|
|
93
93
|
def filename
|
|
94
94
|
@filename ||= (options[:file] || options.dig(:export, :file, :name)).tap do |filename|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
95
|
+
next if filename
|
|
96
|
+
|
|
97
|
+
log(:error) { "Destination file not specified" }
|
|
98
|
+
return false
|
|
99
99
|
end
|
|
100
100
|
end
|
|
101
101
|
end
|
|
@@ -3,17 +3,19 @@ class Eco::API::UseCases::OozeSamples::OozeRunBaseCase < Eco::API::UseCases::Ooz
|
|
|
3
3
|
name "ooze-run-base"
|
|
4
4
|
type :other
|
|
5
5
|
|
|
6
|
-
SAVE_PATCH = "ooze_patch_update.json"
|
|
6
|
+
SAVE_PATCH = "ooze_patch_update.json".freeze
|
|
7
7
|
|
|
8
8
|
def main(session, options, usecase)
|
|
9
9
|
super(session, options, usecase) do
|
|
10
|
-
if method(:process_ooze).parameters.count
|
|
10
|
+
if method(:process_ooze).parameters.count.zero?
|
|
11
11
|
ooze # retrieve ooze
|
|
12
12
|
process_ooze
|
|
13
13
|
else
|
|
14
14
|
process_ooze(ooze)
|
|
15
15
|
end
|
|
16
|
+
|
|
16
17
|
yield(target) if block_given?
|
|
18
|
+
|
|
17
19
|
exit_if_no_changes!
|
|
18
20
|
update_ooze(target)
|
|
19
21
|
end
|
|
@@ -30,7 +32,7 @@ class Eco::API::UseCases::OozeSamples::OozeRunBaseCase < Eco::API::UseCases::Ooz
|
|
|
30
32
|
end
|
|
31
33
|
|
|
32
34
|
def stage(stage_id_name = stage_id, ooze: target)
|
|
33
|
-
super
|
|
35
|
+
super
|
|
34
36
|
end
|
|
35
37
|
|
|
36
38
|
def ooze_id
|
|
@@ -43,11 +45,12 @@ class Eco::API::UseCases::OozeSamples::OozeRunBaseCase < Eco::API::UseCases::Ooz
|
|
|
43
45
|
|
|
44
46
|
def update_ooze(ooz = target)
|
|
45
47
|
prompt_to_confirm!
|
|
46
|
-
|
|
48
|
+
|
|
49
|
+
super
|
|
47
50
|
end
|
|
48
51
|
|
|
49
52
|
def exit_if_no_changes!
|
|
50
|
-
return if
|
|
53
|
+
return if !!patch_doc["page"]
|
|
51
54
|
|
|
52
55
|
log(:info) { "No Changes!!" }
|
|
53
56
|
exit(0)
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
ASSETS.cli do |cli| # rubocop:disable Metrics/BlockLength
|
|
2
2
|
ASSETS.config.workflow do |wf| # rubocop:disable Metrics/BlockLength
|
|
3
3
|
rescued = false
|
|
4
|
+
|
|
4
5
|
# default rescue
|
|
5
6
|
wf.rescue do |err, io|
|
|
6
7
|
next io if rescued
|
|
7
8
|
|
|
8
9
|
rescued = true
|
|
9
10
|
log(:debug) { err.patch_full_message }
|
|
11
|
+
|
|
10
12
|
wf.run(:close, io: io)
|
|
11
13
|
rescue StandardError => e
|
|
12
14
|
puts "Some problem in workflow.rescue: #{e}"
|
|
@@ -74,10 +76,10 @@ ASSETS.cli do |cli| # rubocop:disable Metrics/BlockLength
|
|
|
74
76
|
end
|
|
75
77
|
|
|
76
78
|
wf.on(:usecases) do |_wf_ca, io|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
next if cli.config.usecases.process(io: io)
|
|
80
|
+
|
|
81
|
+
log(:info) { "No update operation specified... quitting" }
|
|
82
|
+
exit 0
|
|
81
83
|
end
|
|
82
84
|
|
|
83
85
|
wf.before(:launch_jobs) do |_wf_jobs, _io|
|
|
@@ -95,11 +97,13 @@ ASSETS.cli do |cli| # rubocop:disable Metrics/BlockLength
|
|
|
95
97
|
run_it = !options[:dry_run] || options.dig(:post_launch, :run)
|
|
96
98
|
unless run_it
|
|
97
99
|
wf_post.skip!
|
|
100
|
+
|
|
98
101
|
log(:info) {
|
|
99
102
|
msg = "Although there are post_launch cases, they will NOT be RUN"
|
|
100
103
|
msg << ", because we are in dry-run (simulate)." if options[:dry_run]
|
|
101
104
|
msg
|
|
102
105
|
}
|
|
106
|
+
|
|
103
107
|
next
|
|
104
108
|
end
|
|
105
109
|
|
|
@@ -117,6 +121,7 @@ ASSETS.cli do |cli| # rubocop:disable Metrics/BlockLength
|
|
|
117
121
|
end
|
|
118
122
|
msg
|
|
119
123
|
}
|
|
124
|
+
|
|
120
125
|
next
|
|
121
126
|
end
|
|
122
127
|
|
|
@@ -131,6 +136,7 @@ ASSETS.cli do |cli| # rubocop:disable Metrics/BlockLength
|
|
|
131
136
|
use.launch(io: io).base
|
|
132
137
|
rescue Eco::API::UseCases::BaseIO::MissingParameter => e
|
|
133
138
|
raise unless e.required == :people
|
|
139
|
+
|
|
134
140
|
log(:debug) {
|
|
135
141
|
"Skipping use case '#{use.name}' -- no base people detected for the current run"
|
|
136
142
|
}
|
data/lib/eco/csv/stream.rb
CHANGED
|
@@ -7,6 +7,7 @@ module Eco
|
|
|
7
7
|
|
|
8
8
|
def initialize(filename, **kargs)
|
|
9
9
|
raise ArgumentError, "File '#{filename}' does not exist" unless ::File.exist?(filename)
|
|
10
|
+
|
|
10
11
|
@filename = filename
|
|
11
12
|
@params = {
|
|
12
13
|
headers: true,
|
|
@@ -55,6 +56,7 @@ module Eco
|
|
|
55
56
|
# see https://dalibornasevic.com/posts/68-processing-large-csv-files-with-ruby
|
|
56
57
|
def csv
|
|
57
58
|
return @csv if instance_variable_defined?(:@csv)
|
|
59
|
+
|
|
58
60
|
@fd = ::File.open(filename, 'r')
|
|
59
61
|
@csv = Eco::CSV.new(fd, **params)
|
|
60
62
|
end
|
data/lib/eco/csv.rb
CHANGED
|
@@ -5,9 +5,9 @@ module Eco
|
|
|
5
5
|
include Eco::Data::Files
|
|
6
6
|
|
|
7
7
|
# @return [Eco::CSV::Table]
|
|
8
|
-
def parse(data, **kargs
|
|
8
|
+
def parse(data, **kargs)
|
|
9
9
|
kargs = {headers: true, skip_blanks: true}.merge(kargs)
|
|
10
|
-
Eco::CSV::Table.new(super
|
|
10
|
+
Eco::CSV::Table.new(super)
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
# @return [Eco::CSV::Table]
|
|
@@ -51,6 +51,7 @@ module Eco
|
|
|
51
51
|
included = yield(row) if block_given?
|
|
52
52
|
count += 1 if included
|
|
53
53
|
end
|
|
54
|
+
|
|
54
55
|
count
|
|
55
56
|
end
|
|
56
57
|
end
|
|
@@ -7,7 +7,7 @@ module Eco
|
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
def method_missing(method_name, *args, **kargs, &block)
|
|
10
|
-
super unless receiver = object_missing_delegated_to
|
|
10
|
+
super unless (receiver = object_missing_delegated_to)
|
|
11
11
|
receiver.send(method_name, *args, **kargs, &block)
|
|
12
12
|
end
|
|
13
13
|
|
|
@@ -19,8 +19,9 @@ module Eco
|
|
|
19
19
|
|
|
20
20
|
# retrieve the delegate_missing_to object
|
|
21
21
|
def object_missing_delegated_to
|
|
22
|
-
return
|
|
23
|
-
|
|
22
|
+
return unless @delegate_missing_to
|
|
23
|
+
|
|
24
|
+
method(@delegate_missing_to).call
|
|
24
25
|
end
|
|
25
26
|
end
|
|
26
27
|
end
|
data/lib/eco/version.rb
CHANGED
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.0.
|
|
4
|
+
version: 3.0.20
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Oscar Segura
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2024-
|
|
11
|
+
date: 2024-12-07 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rake
|
|
@@ -538,6 +538,7 @@ files:
|
|
|
538
538
|
- lib/eco/api/common/loaders/base.rb
|
|
539
539
|
- lib/eco/api/common/loaders/case_base.rb
|
|
540
540
|
- lib/eco/api/common/loaders/config.rb
|
|
541
|
+
- lib/eco/api/common/loaders/config/session.rb
|
|
541
542
|
- lib/eco/api/common/loaders/config/workflow.rb
|
|
542
543
|
- lib/eco/api/common/loaders/config/workflow/mailer.rb
|
|
543
544
|
- lib/eco/api/common/loaders/error_handler.rb
|