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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +28 -1
  3. data/eco-helpers.gemspec +2 -2
  4. data/lib/eco/api/common/people/person_entry_attribute_mapper.rb +1 -1
  5. data/lib/eco/api/common/session/sftp.rb +1 -1
  6. data/lib/eco/api/microcases/person_update.rb +2 -2
  7. data/lib/eco/api/session/config.rb +1 -0
  8. data/lib/eco/api/usecases/cli/dsl.rb +3 -5
  9. data/lib/eco/api/usecases/default/locations/tagtree_extract_case.rb +1 -1
  10. data/lib/eco/api/usecases/default/people/amend/clean_unknown_tags_case.rb +2 -5
  11. data/lib/eco/api/usecases/default/people/amend/restore_db_case.rb +1 -1
  12. data/lib/eco/api/usecases/default/people/migrate/remap_tags_case.rb +4 -4
  13. data/lib/eco/api/usecases/default_cases/samples/sftp.rb +3 -2
  14. data/lib/eco/api/usecases/graphql/helpers/base/error_handling.rb +1 -65
  15. data/lib/eco/api/usecases/graphql/helpers/location/base.rb +2 -0
  16. data/lib/eco/api/usecases/graphql/helpers/location/command/diffs/stages.rb +2 -2
  17. data/lib/eco/api/usecases/graphql/helpers/location/command/result.rb +1 -1
  18. data/lib/eco/api/usecases/graphql/helpers/location/command/results.rb +3 -3
  19. data/lib/eco/api/usecases/graphql/helpers/location/tags_remap.rb +1 -1
  20. data/lib/eco/api/usecases/graphql/utils/sftp.rb +1 -129
  21. data/lib/eco/api/usecases/lib/error_handling.rb +70 -0
  22. data/lib/eco/api/usecases/lib/file_pattern.rb +37 -0
  23. data/lib/eco/api/usecases/lib/sftp.rb +173 -0
  24. data/lib/eco/api/usecases/lib.rb +12 -0
  25. data/lib/eco/api/usecases/ooze_samples/helpers/rescuable.rb +1 -1
  26. data/lib/eco/api/usecases/ooze_samples/helpers_migration/typed_fields_pairing.rb +4 -4
  27. data/lib/eco/api/usecases/ooze_samples/register_update_case.rb +8 -8
  28. data/lib/eco/api/usecases/samples/drivers/sftp_sample.rb +8 -95
  29. data/lib/eco/api/usecases/samples/drivers/url_pull_sample.rb +0 -1
  30. data/lib/eco/api/usecases/samples.rb +0 -1
  31. data/lib/eco/api/usecases.rb +1 -0
  32. data/lib/eco/data/locations/node_base/tag_validations.rb +2 -2
  33. data/lib/eco/data/locations/node_base/treeify.rb +17 -17
  34. data/lib/eco/data/locations/node_diff/nodes_diff.rb +8 -8
  35. data/lib/eco/data/locations/node_level/cleaner.rb +14 -9
  36. data/lib/eco/version.rb +1 -1
  37. metadata +10 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e82c49ee783ef70db3f477e8e340dfe54f7b8afb086402cede5ea1efc78da93b
4
- data.tar.gz: 62137fa5d90eea73bfe07e7bf27f2d8d566feee689183abf0400423ba6774793
3
+ metadata.gz: 209a98dac82894462d5ba24f82a85965cb10c14513d617e86d09fcfb96d3f81a
4
+ data.tar.gz: 288706b5a0f8a3aa81376edd2a42d61d690aae49cf6be6af9b7be5b52f34764a
5
5
  SHA512:
6
- metadata.gz: 530137a689b4894697cb7cb7f0cd0d436d65576c486bf56bc614a2798d3ee6fb603abc90530524365e822e33060d8eb008197dce7f1d432d170be80f033d1975
7
- data.tar.gz: 31079964777cb0a632f4f401a210915289e91c31335bf47641b58574c32d6074aaa3f3643b8708608ebff19e4572938c7c2c3bba32c12e576b26f9ccbacfb03b
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.24] - 2025-03-xx
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.4'
45
- spec.add_dependency 'ecoportal-api-v2', '~> 2.0', '>= 2.0.15'
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'
@@ -386,7 +386,7 @@ module Eco
386
386
 
387
387
  def debug(var, msg)
388
388
  return unless DEBUG
389
- puts "\n #{msg}:"
389
+ puts "\n * #{msg}:"
390
390
  pp var
391
391
  end
392
392
  end
@@ -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 " #{dest_fullname}"
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 += " Person: #{person_ref(person)}"
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 += " Person: #{person_ref(person)}"
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
- #puts "DEFINING CLI for '#{arg_case}' via #{self}"
9
- if applied?(arg_case)
10
- puts "Warning: (#{self}) Tried to call again cli.apply! on '#{arg_case}'"
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 #{err}" }
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 << " #{examples.join("\n ")}"
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,3 +1,4 @@
1
- class Eco::API::UseCases::DefaultCases::Samples::Sftp < Eco::API::UseCases::Samples::Drivers::Sftp
1
+ module Eco::API::UseCases::DefaultCases::Samples
2
+ class Sftp < Eco::API::UseCases::Samples::Drivers::Sftp
3
+ end
2
4
  end
3
-
@@ -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::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
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
- # The order of archiving should probably be:
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
- # The neat solution is to recalculate changes with the live_tree and the final desired result,
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 << " #{feed.join("\n ")}"
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 << " 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?
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
 
@@ -32,7 +32,7 @@ module Eco::API::UseCases::GraphQL::Helpers::Location
32
32
  "".tap do |str|
33
33
  each.map do |tags_map|
34
34
  from, to = tags_map.to_csv_row
35
- str << " '#{from}' => '#{to}'\n"
35
+ str << " * '#{from}' => '#{to}'\n"
36
36
  end
37
37
  end
38
38
  end
@@ -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