eco-helpers 3.0.24 → 3.0.25
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/CHANGELOG.md +28 -1
- data/eco-helpers.gemspec +2 -2
- data/lib/eco/api/common/people/person_entry_attribute_mapper.rb +1 -1
- data/lib/eco/api/common/session/sftp.rb +1 -1
- data/lib/eco/api/microcases/person_update.rb +2 -2
- data/lib/eco/api/session/config.rb +1 -0
- data/lib/eco/api/usecases/cli/dsl.rb +3 -5
- data/lib/eco/api/usecases/default/locations/tagtree_extract_case.rb +1 -1
- data/lib/eco/api/usecases/default/people/amend/clean_unknown_tags_case.rb +2 -5
- data/lib/eco/api/usecases/default/people/amend/restore_db_case.rb +1 -1
- data/lib/eco/api/usecases/default/people/migrate/remap_tags_case.rb +4 -4
- data/lib/eco/api/usecases/default_cases/samples/sftp.rb +3 -2
- data/lib/eco/api/usecases/graphql/helpers/base/error_handling.rb +1 -65
- data/lib/eco/api/usecases/graphql/helpers/location/base.rb +2 -0
- data/lib/eco/api/usecases/graphql/helpers/location/command/diffs/stages.rb +2 -2
- data/lib/eco/api/usecases/graphql/helpers/location/command/result.rb +1 -1
- data/lib/eco/api/usecases/graphql/helpers/location/command/results.rb +3 -3
- data/lib/eco/api/usecases/graphql/helpers/location/tags_remap.rb +1 -1
- data/lib/eco/api/usecases/graphql/utils/sftp.rb +1 -129
- data/lib/eco/api/usecases/lib/error_handling.rb +70 -0
- data/lib/eco/api/usecases/lib/file_pattern.rb +37 -0
- data/lib/eco/api/usecases/lib/sftp.rb +173 -0
- data/lib/eco/api/usecases/lib.rb +12 -0
- data/lib/eco/api/usecases/ooze_samples/helpers/rescuable.rb +1 -1
- data/lib/eco/api/usecases/ooze_samples/helpers_migration/typed_fields_pairing.rb +4 -4
- data/lib/eco/api/usecases/ooze_samples/register_update_case.rb +8 -8
- data/lib/eco/api/usecases/samples/drivers/sftp_sample.rb +8 -95
- data/lib/eco/api/usecases/samples/drivers/url_pull_sample.rb +0 -1
- data/lib/eco/api/usecases/samples.rb +0 -1
- data/lib/eco/api/usecases.rb +1 -0
- data/lib/eco/data/locations/node_base/tag_validations.rb +2 -2
- data/lib/eco/data/locations/node_base/treeify.rb +17 -17
- data/lib/eco/data/locations/node_diff/nodes_diff.rb +8 -8
- data/lib/eco/data/locations/node_level/cleaner.rb +14 -9
- data/lib/eco/version.rb +1 -1
- metadata +10 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 209a98dac82894462d5ba24f82a85965cb10c14513d617e86d09fcfb96d3f81a
|
4
|
+
data.tar.gz: 288706b5a0f8a3aa81376edd2a42d61d690aae49cf6be6af9b7be5b52f34764a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3507855864665cf289361e803d5e9a835b9eb24d06e66a7249b4b8f9e0388eb65b51f5d8f634c0141a4562979dd69fb2df96c753de9325ef350351a6719be7f6
|
7
|
+
data.tar.gz: 8ef26aec84fd8ceb559fbf4a938f30f2b06f2abc73ce9fdf09b70e48fb3d4f7e0f0904ef65c5cd1dc81d1d143b1888d24c50e884884a34c321baf54022547dd4
|
data/CHANGELOG.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
4
4
|
|
5
|
-
## [3.0.
|
5
|
+
## [3.0.26] - 2025-03-xx
|
6
6
|
|
7
7
|
### Added
|
8
8
|
|
@@ -10,6 +10,33 @@ All notable changes to this project will be documented in this file.
|
|
10
10
|
|
11
11
|
### Fixed
|
12
12
|
|
13
|
+
## [3.0.25] - 2025-03-23
|
14
|
+
|
15
|
+
### Added
|
16
|
+
|
17
|
+
- `Session::Config#structure_id=`
|
18
|
+
- `Eco::API::UseCases::Lib`. Starting with:
|
19
|
+
- `Sftp` helpers
|
20
|
+
- `FilePattern` helper
|
21
|
+
- `ErrorHandling` helpers
|
22
|
+
|
23
|
+
### Changed
|
24
|
+
|
25
|
+
- upgraded `ecoportal-api-graphql`
|
26
|
+
- upgraded `ecoportal-api-v2`
|
27
|
+
- remove **warning** on `cli.apply!` against the same `cli` option.
|
28
|
+
- it is understandable it is called via inheritance.
|
29
|
+
|
30
|
+
### Fixed
|
31
|
+
|
32
|
+
- `clean-unknown-tags`: remove unused and undefined code.
|
33
|
+
- `UseCases::GraphQL::Location::Base#target_structure_id`
|
34
|
+
- Lookup should include `Session::Config#structure_id` as a fallback.
|
35
|
+
|
36
|
+
## [3.0.24] - 2025-03-11
|
37
|
+
|
38
|
+
### Fixed
|
39
|
+
|
13
40
|
- Preserve `structure_id` as target locations id
|
14
41
|
|
15
42
|
## [3.0.23] - 2025-03-10
|
data/eco-helpers.gemspec
CHANGED
@@ -41,8 +41,8 @@ Gem::Specification.new do |spec|
|
|
41
41
|
spec.add_dependency 'docx', '>= 0.8.0', '< 0.9'
|
42
42
|
spec.add_dependency 'dotenv', '~> 3'
|
43
43
|
spec.add_dependency 'ecoportal-api', '~> 0.10', '>= 0.10.8'
|
44
|
-
spec.add_dependency 'ecoportal-api-graphql', '~> 0.4', '>= 0.4.
|
45
|
-
spec.add_dependency 'ecoportal-api-v2', '~> 2.0', '>= 2.0.
|
44
|
+
spec.add_dependency 'ecoportal-api-graphql', '~> 0.4', '>= 0.4.5'
|
45
|
+
spec.add_dependency 'ecoportal-api-v2', '~> 2.0', '>= 2.0.16'
|
46
46
|
spec.add_dependency 'ed25519', '~> 1.2'
|
47
47
|
spec.add_dependency 'fast_excel', '>= 0.5.0', '< 0.6'
|
48
48
|
spec.add_dependency 'fuzzy_match', '>= 2.1.0', '< 2.2'
|
@@ -108,7 +108,7 @@ module Eco
|
|
108
108
|
[files].flatten.compact.map do |fullname|
|
109
109
|
basename = windows_basename(fullname)
|
110
110
|
dest_fullname = File.join(local_folder || ".", basename)
|
111
|
-
puts "
|
111
|
+
puts " * #{dest_fullname}"
|
112
112
|
created_files << dest_fullname
|
113
113
|
sftp_session.download(fullname, dest_fullname)
|
114
114
|
end.each(&:wait)
|
@@ -19,14 +19,14 @@ module Eco
|
|
19
19
|
else
|
20
20
|
msg = "#{context} Error #{response.status}: #{response.body}\n"
|
21
21
|
msg += " -- Failed to \"#{reason}\".\n"
|
22
|
-
msg += "
|
22
|
+
msg += " * Person: #{person_ref(person)}"
|
23
23
|
log(:error) { msg }
|
24
24
|
false
|
25
25
|
end
|
26
26
|
else
|
27
27
|
msg = "#{context} Error (connection error)\n"
|
28
28
|
msg += " -- Failed to \"#{reason}\".\n"
|
29
|
-
msg += "
|
29
|
+
msg += " * Person: #{person_ref(person)}"
|
30
30
|
|
31
31
|
log(:error) { msg }
|
32
32
|
false
|
@@ -249,6 +249,7 @@ module Eco
|
|
249
249
|
def tagtree_id=(value)
|
250
250
|
tagtree_config.structure_id = value
|
251
251
|
end
|
252
|
+
alias_method :structure_id=, :tagtree_id=
|
252
253
|
|
253
254
|
# The location node classifications of the organization
|
254
255
|
# @return [Eco::API::Organization::NodeClassifications]
|
@@ -5,11 +5,9 @@ module Eco
|
|
5
5
|
module DSL
|
6
6
|
# Links the usecase to the Cli via `arg_case`
|
7
7
|
def apply!(arg_case = cli_name)
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
return self
|
12
|
-
end
|
8
|
+
|
9
|
+
# puts "Debug: (#{self}) Tried to call again cli.apply! on '#{arg_case}'"
|
10
|
+
return self if applied?(arg_case)
|
13
11
|
|
14
12
|
cli_config_case(arg_case)
|
15
13
|
apply_options(arg_case)
|
@@ -65,7 +65,7 @@ class Eco::API::UseCases::Default::Locations::TagtreeExtract < Eco::API::UseCase
|
|
65
65
|
exit 1
|
66
66
|
end
|
67
67
|
rescue StandardError => err
|
68
|
-
log(:error) { "Something went wrong whene extracting '#{tree.name}':\n
|
68
|
+
log(:error) { "Something went wrong whene extracting '#{tree.name}':\n * #{err}" }
|
69
69
|
exit 1
|
70
70
|
end
|
71
71
|
|
@@ -19,9 +19,6 @@ class Eco::API::UseCases::Default::People::Amend::CleanUnknownTags < Eco::API::C
|
|
19
19
|
people.each do |person|
|
20
20
|
update_job.add(person)
|
21
21
|
|
22
|
-
update_filter_tags!(person)
|
23
|
-
update_default_tag!(person)
|
24
|
-
|
25
22
|
clean_unkown_tags!(person)
|
26
23
|
clean_archived_nodes!(person) if clean_archived?
|
27
24
|
end
|
@@ -92,10 +89,10 @@ class Eco::API::UseCases::Default::People::Amend::CleanUnknownTags < Eco::API::C
|
|
92
89
|
|
93
90
|
cleaned_sorted = data.sort_by {|tag, count| [count * -1, tag]}
|
94
91
|
|
95
|
-
msg << "\n
|
92
|
+
msg << "\n * "
|
96
93
|
msg += cleaned_sorted.map do |tag, count|
|
97
94
|
"'#{tag}' (#{count})"
|
98
|
-
end.join("\n
|
95
|
+
end.join("\n * ")
|
99
96
|
|
100
97
|
log(:info) { msg }
|
101
98
|
data.clear
|
@@ -94,7 +94,7 @@ class Eco::API::UseCases::Default::People::Amend::RestoreDBCase < Eco::API::Comm
|
|
94
94
|
msg << "There were #{re_starters.length} entries of the backup "
|
95
95
|
msg << "that do not exist in the (filtered?) people manager."
|
96
96
|
msg << "Some examples:"
|
97
|
-
msg << "
|
97
|
+
msg << " * #{examples.join("\n * ")}"
|
98
98
|
msg.join("\n")
|
99
99
|
}
|
100
100
|
end
|
@@ -96,8 +96,8 @@ class Eco::API::UseCases::Default::People::Migrate::RemapTags < Eco::API::Common
|
|
96
96
|
|
97
97
|
log(:info) {
|
98
98
|
msg = "Here list of the #{removed_src_tags.count} removed source-mapped tags..."
|
99
|
-
msg << "\n
|
100
|
-
msg << removed_src_tags.sort.join("\n
|
99
|
+
msg << "\n * "
|
100
|
+
msg << removed_src_tags.sort.join("\n * ")
|
101
101
|
msg
|
102
102
|
}
|
103
103
|
end
|
@@ -133,10 +133,10 @@ class Eco::API::UseCases::Default::People::Migrate::RemapTags < Eco::API::Common
|
|
133
133
|
|
134
134
|
cleared_sorted = data.sort_by {|tag, count| [count * -1, tag]}
|
135
135
|
|
136
|
-
msg << "\n
|
136
|
+
msg << "\n * "
|
137
137
|
msg += cleared_sorted.map do |tag, count|
|
138
138
|
"'#{tag}' (#{count})"
|
139
|
-
end.join("\n
|
139
|
+
end.join("\n * ")
|
140
140
|
|
141
141
|
log(:info) { msg }
|
142
142
|
data.clear
|
@@ -1,70 +1,6 @@
|
|
1
1
|
module Eco::API::UseCases::GraphQL::Helpers::Base
|
2
2
|
# Basic stuff you would need in any use case
|
3
3
|
module ErrorHandling
|
4
|
-
include Eco::
|
5
|
-
|
6
|
-
attr_reader :exception, :exiting
|
7
|
-
|
8
|
-
private
|
9
|
-
|
10
|
-
def exception_already_captured?(err)
|
11
|
-
err == exception
|
12
|
-
end
|
13
|
-
|
14
|
-
def interrupted?(err = exception)
|
15
|
-
interrupt_errors.any? {|klass| err.is_a?(klass)}
|
16
|
-
end
|
17
|
-
|
18
|
-
def error_raised?
|
19
|
-
exception && !interrupted?
|
20
|
-
end
|
21
|
-
|
22
|
-
def exiting?
|
23
|
-
@exiting
|
24
|
-
end
|
25
|
-
|
26
|
-
def exception?
|
27
|
-
error_raised? || exiting?
|
28
|
-
end
|
29
|
-
|
30
|
-
def rescued
|
31
|
-
yield
|
32
|
-
rescue StandardError => err
|
33
|
-
self.exception ||= err
|
34
|
-
|
35
|
-
return unless exception_already_captured?(err)
|
36
|
-
|
37
|
-
log(:error) { err.patch_full_message }
|
38
|
-
rescue SystemExit
|
39
|
-
@exiting = true
|
40
|
-
raise
|
41
|
-
end
|
42
|
-
|
43
|
-
def with_error_handling
|
44
|
-
@exception = nil
|
45
|
-
yield
|
46
|
-
rescue StandardError, SignalException => err
|
47
|
-
@exception = err
|
48
|
-
raise
|
49
|
-
rescue SystemExit
|
50
|
-
@exiting = true
|
51
|
-
raise
|
52
|
-
rescue *interrupt_errors
|
53
|
-
@exception = int
|
54
|
-
raise
|
55
|
-
rescue SystemStackError
|
56
|
-
puts $! # rubocop:disable Style/SpecialGlobalVars
|
57
|
-
puts caller[0..100]
|
58
|
-
raise
|
59
|
-
end
|
60
|
-
|
61
|
-
def interrupt_errors
|
62
|
-
return @interrupt_errors if @interrupt_errors
|
63
|
-
|
64
|
-
errs = [Interrupt]
|
65
|
-
errs << IRB::Abort if Object.const_defined?(:IRB) && IRB.const_defined?(:Abort)
|
66
|
-
|
67
|
-
@interrupt_errors = errs
|
68
|
-
end
|
4
|
+
include Eco::API::UseCases::Lib::ErrorHandling
|
69
5
|
end
|
70
6
|
end
|
@@ -12,6 +12,8 @@ module Eco::API::UseCases::GraphQL::Helpers::Location
|
|
12
12
|
@target_structure_id ||= tagtree_id
|
13
13
|
@target_structure_id ||= target_structure_id_const
|
14
14
|
@target_structure_id ||= current_tree.id if current_tree.respond_to?(:id)
|
15
|
+
@target_structure_id ||= config.tagtree_config.structure_id
|
16
|
+
|
15
17
|
return @target_structure_id if @target_structure_id
|
16
18
|
|
17
19
|
msg = 'Const TARGET_STRUCTURE_ID has not been defined, '
|
@@ -40,12 +40,12 @@
|
|
40
40
|
# * However, to build the remap tags table, it does matter: from bottom to top. Children should be
|
41
41
|
# retagged first because retagging first parents changes the path of their children retags.
|
42
42
|
# (5) ARCHIVE (bottom-top) should happen always LAST, after nodes have been MOVED.
|
43
|
-
#
|
43
|
+
# * The order of archiving should probably be:
|
44
44
|
# (a) although firstly thought go from leafs to root to prevent the `archiveToken`
|
45
45
|
# it should go from top-to-bottom, so precisely the `archiveToken` is generated and history well sorted.
|
46
46
|
# (b) to preventing `already archived node` errors, we should only include the parent
|
47
47
|
# (6) RE-ARCHIVE (bottom-top) see (1.b) all those that were automatically unarchived but should remain archived.
|
48
|
-
#
|
48
|
+
# * The neat solution is to recalculate changes with the live_tree and the final desired result,
|
49
49
|
# but perhaps only target those to be re-archived?
|
50
50
|
class Eco::API::UseCases::GraphQL::Helpers::Location::Command::Diffs
|
51
51
|
module Stages
|
@@ -49,7 +49,7 @@ module Eco::API::UseCases::GraphQL::Helpers::Location::Command
|
|
49
49
|
feed.concat(error.validationErrors.map(&:message)) unless error.validationErrors.empty?
|
50
50
|
feed << "Command: #{command_input_data.pretty_inspect}"
|
51
51
|
|
52
|
-
msg << "
|
52
|
+
msg << " * #{feed.join("\n * ")}"
|
53
53
|
msg.join("\n")
|
54
54
|
end
|
55
55
|
|
@@ -9,9 +9,9 @@ module Eco::API::UseCases::GraphQL::Helpers::Location::Command
|
|
9
9
|
|
10
10
|
def stats
|
11
11
|
msg = ''
|
12
|
-
msg << "
|
13
|
-
msg << "
|
14
|
-
msg << "
|
12
|
+
msg << " * Errored: #{errored.count} #{first_err_str}\n" if errored?
|
13
|
+
msg << " * Applied: #{errored.count} #{last_okay_str}\n" if some_applied?
|
14
|
+
msg << " * Pending: #{pending.count}\n" if some_pending?
|
15
15
|
msg
|
16
16
|
end
|
17
17
|
|
@@ -1,134 +1,6 @@
|
|
1
1
|
module Eco::API::UseCases::GraphQL::Utils
|
2
2
|
module Sftp
|
3
3
|
include Eco::API::UseCases::GraphQL::Helpers::Base::CaseEnv
|
4
|
-
|
5
|
-
def upload(local_file, subfolder: remote_subfolder, gid: sftp_group_id)
|
6
|
-
sftp_session.upload(
|
7
|
-
local_file,
|
8
|
-
remote_folder: remote_folder(subfolder),
|
9
|
-
gid: gid
|
10
|
-
)
|
11
|
-
end
|
12
|
-
alias_method :sftp_upload, :upload
|
13
|
-
|
14
|
-
def sftp_group_id
|
15
|
-
if self.class.const_defined?(:SFTP_GROUP)
|
16
|
-
self.class.const_get(:SFTP_GROUP)
|
17
|
-
elsif (group_id = options.dig(:sftp, :group))
|
18
|
-
group_id
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def sftp_download_files(subfolder: remote_subfolder, pattern: nil, local_folder: self.local_folder, &block)
|
23
|
-
remote_files = with_remote_files(subfolder: subfolder, pattern: pattern)
|
24
|
-
return [] if remote_files.empty?
|
25
|
-
|
26
|
-
file_names = remote_files.map {|file| to_remote_path(file.name, subfolder: subfolder)}
|
27
|
-
|
28
|
-
log(:info) {
|
29
|
-
msg = "Getting the following files into the local folder '#{local_folder}':\n"
|
30
|
-
msg << " • "
|
31
|
-
msg << file_names.join("\n • ")
|
32
|
-
msg
|
33
|
-
}
|
34
|
-
|
35
|
-
sftp.download(file_names, local_folder: local_folder, &block)
|
36
|
-
end
|
37
|
-
|
38
|
-
def sftp_move_file(source, dest)
|
39
|
-
sftp.move(source, dest, 0x0001) do |response|
|
40
|
-
if response.ok?
|
41
|
-
log(:info) { "#{source}\n -to-> #{dest}" }
|
42
|
-
else
|
43
|
-
log(:info) { "Could not move file #{source}" }
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def ensure_remote_empty(subfolder: remote_subfolder, pattern: nil)
|
49
|
-
files = with_remote_files(subfolder: subfolder, pattern: pattern)
|
50
|
-
return if files.empty?
|
51
|
-
|
52
|
-
msg = "There are still files in the remote folder that will be deleted: '#{subfolder}':\n"
|
53
|
-
msg << " • "
|
54
|
-
str = files.map(&:longname).join("\n • ")
|
55
|
-
str << "\n"
|
56
|
-
msg << str
|
57
|
-
|
58
|
-
session.prompt_user(
|
59
|
-
"Do you want to proceed to delete? (Y/n):",
|
60
|
-
explanation: msg,
|
61
|
-
default: "Y",
|
62
|
-
timeout: 3
|
63
|
-
) do |response|
|
64
|
-
next unless response.upcase.start_with?("Y")
|
65
|
-
|
66
|
-
files.each do |file|
|
67
|
-
remote_full_path = to_remote_path(file.name, subfolder: subfolder)
|
68
|
-
res = sftp_session.remove(remote_full_path)
|
69
|
-
log(:info) {
|
70
|
-
"Deleted remote file: '#{remote_full_path}' (#{res})"
|
71
|
-
}
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
# @param subfolder [String] the subfolder.
|
77
|
-
def with_remote_files(subfolder: remote_subfolder, pattern: nil)
|
78
|
-
sftp.files(remote_folder(subfolder), pattern: pattern).each do |remote_file|
|
79
|
-
yield(remote_file) if block_given?
|
80
|
-
end
|
81
|
-
rescue ArgumentError
|
82
|
-
raise
|
83
|
-
rescue ::Net::SFTP::StatusException => err
|
84
|
-
log(:error) {
|
85
|
-
msg = "(#{self.class}) There was an error trying to access "
|
86
|
-
msg << "the remote folder '#{subfolder}': #{err}"
|
87
|
-
msg
|
88
|
-
}
|
89
|
-
[]
|
90
|
-
end
|
91
|
-
|
92
|
-
def to_remote_path(file, subfolder: remote_subfolder)
|
93
|
-
[remote_folder(subfolder), file].join('/')
|
94
|
-
end
|
95
|
-
|
96
|
-
def remote_subfolder
|
97
|
-
if (remote_dir = options.dig(:sftp, :remote_subfolder))
|
98
|
-
remote_dir
|
99
|
-
elsif self.class.const_defined?(:REMOTE_FOLDER)
|
100
|
-
self.class::REMOTE_FOLDER
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
def remote_folder(subfolder = remote_subfolder)
|
105
|
-
[sftp_env_base_path, subfolder].compact.join('/')
|
106
|
-
end
|
107
|
-
|
108
|
-
def sftp_env_base_path
|
109
|
-
sftp_config.remote_folder
|
110
|
-
end
|
111
|
-
|
112
|
-
def local_folder
|
113
|
-
if (local_dir = options.dig(:sftp, :local_folder))
|
114
|
-
local_dir
|
115
|
-
elsif self.class.const_defined?(:LOCAL_FOLDER)
|
116
|
-
self.class::LOCAL_FOLDER
|
117
|
-
else
|
118
|
-
"."
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
def sftp_config
|
123
|
-
session.config.sftp
|
124
|
-
end
|
125
|
-
|
126
|
-
def sftp_session
|
127
|
-
sftp.sftp_session
|
128
|
-
end
|
129
|
-
|
130
|
-
def sftp
|
131
|
-
session.sftp
|
132
|
-
end
|
4
|
+
include Eco::API::UseCases::Lib::Sftp
|
133
5
|
end
|
134
6
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Eco::API::UseCases::Lib
|
2
|
+
# Basic stuff you would need in any use case
|
3
|
+
module ErrorHandling
|
4
|
+
include Eco::Language::AuxiliarLogger
|
5
|
+
|
6
|
+
attr_reader :exception, :exiting
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def exception_already_captured?(err)
|
11
|
+
err == exception
|
12
|
+
end
|
13
|
+
|
14
|
+
def interrupted?(err = exception)
|
15
|
+
interrupt_errors.any? {|klass| err.is_a?(klass)}
|
16
|
+
end
|
17
|
+
|
18
|
+
def error_raised?
|
19
|
+
exception && !interrupted?
|
20
|
+
end
|
21
|
+
|
22
|
+
def exiting?
|
23
|
+
@exiting
|
24
|
+
end
|
25
|
+
|
26
|
+
def exception?
|
27
|
+
error_raised? || exiting?
|
28
|
+
end
|
29
|
+
|
30
|
+
def rescued
|
31
|
+
yield
|
32
|
+
rescue StandardError => err
|
33
|
+
self.exception ||= err
|
34
|
+
|
35
|
+
return unless exception_already_captured?(err)
|
36
|
+
|
37
|
+
log(:error) { err.patch_full_message }
|
38
|
+
rescue SystemExit
|
39
|
+
@exiting = true
|
40
|
+
raise
|
41
|
+
end
|
42
|
+
|
43
|
+
def with_error_handling
|
44
|
+
@exception = nil
|
45
|
+
yield
|
46
|
+
rescue StandardError, SignalException => err
|
47
|
+
@exception = err
|
48
|
+
raise
|
49
|
+
rescue SystemExit
|
50
|
+
@exiting = true
|
51
|
+
raise
|
52
|
+
rescue *interrupt_errors
|
53
|
+
@exception = int
|
54
|
+
raise
|
55
|
+
rescue SystemStackError
|
56
|
+
puts $! # rubocop:disable Style/SpecialGlobalVars
|
57
|
+
puts caller[0..100]
|
58
|
+
raise
|
59
|
+
end
|
60
|
+
|
61
|
+
def interrupt_errors
|
62
|
+
return @interrupt_errors if @interrupt_errors
|
63
|
+
|
64
|
+
errs = [Interrupt]
|
65
|
+
errs << IRB::Abort if Object.const_defined?(:IRB) && IRB.const_defined?(:Abort)
|
66
|
+
|
67
|
+
@interrupt_errors = errs
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Eco::API::UseCases::Lib
|
2
|
+
module FilePattern
|
3
|
+
class WrongConst < ArgumentError; end
|
4
|
+
|
5
|
+
CONST_REFERRAL = /^(?:::)?(?:[A-Z][a-zA-Z0-9_]*(?:::[A-Z][a-zA-Z0-9_]*)*)$/
|
6
|
+
|
7
|
+
attr_reader :options
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
# Can't pass this via CLI option, as it breaks the regular expression
|
12
|
+
def file_pattern(required: true)
|
13
|
+
fpc = file_pattern_const
|
14
|
+
return fpc if fpc
|
15
|
+
return unless required
|
16
|
+
|
17
|
+
msg = "(#{self.class}) You should redefine the file_pattern function "
|
18
|
+
msg << 'as a RegEx expression that matches the target remote file'
|
19
|
+
raise WrongConst, msg
|
20
|
+
end
|
21
|
+
|
22
|
+
def file_pattern_const
|
23
|
+
if (fpc = options.dig(:sftp, :file_pattern_const))
|
24
|
+
msg = "(#{self.class}) Invalid file pattern const referral: #{fpc}"
|
25
|
+
raise WrongConst, msg unless fpc.match(CONST_REFERRAL)
|
26
|
+
|
27
|
+
begin
|
28
|
+
self.eval(fpc)
|
29
|
+
rescue NameError
|
30
|
+
self.class.const_get(fpc)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
rescue NameError
|
34
|
+
raise WrongConst, "(#{self.class}) Unknown constant: #{fpc}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|