eco-helpers 3.0.28 → 3.0.29

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3f36ef48b8d70b2ac8b50e32a823d99d8bec5e32a76975357cf2298a6247a694
4
- data.tar.gz: 60c6b240668df642d9bba41bc67011a02f7602e143aaabc2e4a25d2f9aa5d5dc
3
+ metadata.gz: 48e3cb15eee9eccde5ed9781dbff0ebcf811d26b1a7f23f503e3de733b60c19b
4
+ data.tar.gz: b4a84a5c1b4496706292044964256d80728f7dadabc975937306fa2f08ae29d8
5
5
  SHA512:
6
- metadata.gz: 70393a40919bf80751385734885c88914a80acc47a80d5a068be431b4abd2e9677d8e1707dbeaf8510de49dc519d00441df3ffe2bed4ee8f50663895caf2e778
7
- data.tar.gz: 44cc94d912bdcee5ec8140ce8d78a0b2a10feb8c609944147446e4337641ca53394ee3e798b17d970cae887b07313ed511a4840e47af7fa903595311a5923eba
6
+ metadata.gz: bd7335d81867d2d954a692e071ed3ca42b9c1510d8ef166a3eff0ec317e9254d4bf42a319dadb0a894c8689808ac55769dcdb6687124457e575c38c134fc70ba
7
+ data.tar.gz: 4364f5451f67f91228e27ad40daf10af8c2db1b99d907be9cdb84b983bb5e9f274dfddc13be174a1bed2ca4dd7c8ee42b4ffec23eaeba3ae05bae761ed5fe223
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.29] - 2025-03-xx
5
+ ## [3.0.30] - 2025-03-xx
6
6
 
7
7
  ### Added
8
8
 
@@ -10,6 +10,19 @@ All notable changes to this project will be documented in this file.
10
10
 
11
11
  ### Fixed
12
12
 
13
+ ## [3.0.29] - 2025-03-31
14
+
15
+ ### Added
16
+
17
+ - `API::UseCases::Service::Sftp` **basic wrapper** to make this easier on Sftp functions.
18
+ - `Language::Delegation::DelegatingBlank`
19
+
20
+ ### Fixed
21
+
22
+ - `Eco::API::UseCases::Lib::Files::Sftp`
23
+ - **Rectified** named argument `only_latest` to fetch only latest file (**newest**).
24
+ - Wrong target object to call `#upload` on.
25
+
13
26
  ## [3.0.28] - 2025-03-31
14
27
 
15
28
  ### Added
@@ -5,7 +5,7 @@ module Eco
5
5
  module Helpers
6
6
  module PromptUser
7
7
  # Prompts user for input with option for default on timeout.
8
- def prompt_user(question, default:, explanation: "", timeout: nil)
8
+ def prompt_user(question, default:, explanation: '', timeout: nil)
9
9
  require 'timeout'
10
10
  response =
11
11
  if config.run_mode_remote?
@@ -18,6 +18,8 @@ module Eco
18
18
  begin
19
19
  Timeout::timeout(timeout) { STDIN.gets.chop }
20
20
  rescue Timeout::Error
21
+ print default
22
+ puts "\n"
21
23
  default
22
24
  end
23
25
  else
@@ -10,7 +10,7 @@ module Eco::API::UseCases::Lib::Files
10
10
 
11
11
  # @return [String, FalseClass] the path of the remote file or `false` if failed.
12
12
  def upload(local_file, subfolder: remote_subfolder, gid: sftp_group_id)
13
- sftp_session.upload(
13
+ sftp.upload(
14
14
  local_file,
15
15
  remote_folder: remote_folder(subfolder),
16
16
  gid: gid
@@ -40,8 +40,8 @@ module Eco::API::UseCases::Lib::Files
40
40
  )
41
41
  remote_files = with_remote_files(subfolder: subfolder, pattern: pattern)
42
42
 
43
- return [] if remote_files.empty?
44
- remote_files = [remote_files.first] if only_latest
43
+ return [] if remote_files.empty?
44
+ remote_files = [remote_files.last] if only_latest
45
45
 
46
46
  file_names = remote_files.map {|file| to_remote_path(file.name, subfolder: subfolder)}
47
47
 
@@ -92,7 +92,7 @@ module Eco::API::UseCases::Lib::Files
92
92
  files = with_remote_files(subfolder: subfolder, pattern: pattern)
93
93
  return if files.empty?
94
94
 
95
- msg = "There are still files in the remote folder that will be deleted: '#{subfolder}':\n"
95
+ msg = "There are files in the remote folder that will be deleted: '#{subfolder}':\n"
96
96
  msg << ' * '
97
97
  str = files.map(&:longname).join("\n * ")
98
98
  str << "\n"
@@ -0,0 +1,36 @@
1
+ module Eco::API::UseCases::Service
2
+ # Class that pulls configuration from the subject (i.e. `remote_folder`)
3
+ class Sftp
4
+ include Eco::API::UseCases::Lib::Files::Sftp
5
+ # include Eco::Language::Delegation::DelegatingMissing
6
+ include Eco::Language::Delegation::DelegatingMissingConst
7
+ include Eco::Language::Delegation::DelegatingBlank
8
+
9
+ DELEGATED_BLANK_PROPERTIES = %i[
10
+ remote_subfolder
11
+ local_folder
12
+ sftp_group_id
13
+ ].freeze
14
+
15
+ delegating_missing_to :subject
16
+ delegating_blank(*DELEGATED_BLANK_PROPERTIES, to: :subject, safe: true)
17
+
18
+ def initialize(subject)
19
+ @subject = subject
20
+ end
21
+
22
+ # @note overriding Sftp `attr_reader`
23
+ def session
24
+ subject.send(:session)
25
+ end
26
+
27
+ # @note overriding Sftp `attr_reader`
28
+ def options
29
+ subject.send(:options)
30
+ end
31
+
32
+ private
33
+
34
+ attr_reader :subject
35
+ end
36
+ end
@@ -0,0 +1,15 @@
1
+ module Eco
2
+ module API
3
+ class UseCases
4
+ # Service classes tied to `UseCases`
5
+ # @note its purpose to keep `UseCase` classes as dry as possible.
6
+ # Rather than including methods into the use case, a service class
7
+ # approach can prevent undesirable clashes, that in turn are very
8
+ # difficult to track down.
9
+ module Service
10
+ end
11
+ end
12
+ end
13
+ end
14
+
15
+ require_relative 'service/sftp'
@@ -177,6 +177,7 @@ require_relative 'usecases/base_io'
177
177
  require_relative 'usecases/use_case_io'
178
178
  require_relative 'usecases/cli'
179
179
  require_relative 'usecases/lib'
180
+ require_relative 'usecases/service'
180
181
  require_relative 'usecases/graphql'
181
182
  require_relative 'usecases/default'
182
183
  require_relative 'usecases/samples'
@@ -0,0 +1,162 @@
1
+ # rubocop:disable Naming/MethodParameterName
2
+
3
+ module Eco::Language::Delegation
4
+ # Installs a middleware for each delegated entity
5
+ # @note It adds an implicit delegate missing to the target,
6
+ # unless it has already been defined.
7
+ module DelegatingBlank
8
+ class << self
9
+ def included(base)
10
+ super
11
+
12
+ base.include DelegatingMissing
13
+ base.extend ClassMethods
14
+ base.inheritable_class_vars :_delegating_blank
15
+ end
16
+ end
17
+
18
+ module ClassMethods
19
+ include Eco::Language::Strings::Underscore
20
+
21
+ def delegating_blank(*these, to:, safe: false)
22
+ msg = "Delegating to: should be String or Symbol. Given: #{to.class}"
23
+ raise ArgumentError, msg unless sym_or_string?(to)
24
+
25
+ these.map do |this|
26
+ msg = "Expecting String or Symbol. Given: #{this}."
27
+ raise ArgumentError, msg unless sym_or_string?(this)
28
+
29
+ this.to_sym
30
+ end.each do |this|
31
+ delegating_missing(this, to: to) unless delegating_missing?(this)
32
+ install_blank_delegator(at: this, safe: safe)
33
+
34
+ _delegating_blank[this] = to
35
+ _safe_blank_delegation[this] = safe
36
+ end
37
+
38
+ self
39
+ end
40
+
41
+ def delegating_blank?(sym)
42
+ return false unless sym_or_string?(sym)
43
+ return true if _delegating_blank.key?(sym.to_sym)
44
+
45
+ false
46
+ end
47
+
48
+ def safe_blank_delegation?(sym)
49
+ return false unless sym_or_string?(sym)
50
+ return false unless _safe_blank_delegation.key?(sym.to_sym)
51
+
52
+ _safe_blank_delegation[sym.to_sym]
53
+ end
54
+
55
+ def delegating_blank_target(instance, at: nil)
56
+ return unless delegating_blank?(at)
57
+ return unless (subject_ref = _delegating_blank[at])
58
+
59
+ instance_has_method =
60
+ instance.methods.include?(subject_ref) ||
61
+ instance.private_methods.include?(subject_ref)
62
+
63
+ return instance.method(subject_ref).call if instance_has_method
64
+ return unless at.to_s.start_with?('@')
65
+ return unless instance.instance_variable_defined?(at)
66
+
67
+ instance.instance_variable_get(at)
68
+ end
69
+
70
+ private
71
+
72
+ def method_added(method_name)
73
+ return super if (@installing ||= false)
74
+
75
+ method_name = method_name.to_sym
76
+ return super unless delegating_blank?(method_name)
77
+
78
+ @installing = true
79
+ install_blank_delegator(at: method_name)
80
+ @installing = false
81
+ super
82
+ end
83
+
84
+ def _delegating_blank
85
+ @_delegating_blank ||= {}
86
+ end
87
+
88
+ def _safe_blank_delegation
89
+ @_safe_blank_delegation ||= {}
90
+ end
91
+
92
+ # If `base` does NOT have the method, don't install the middleware.
93
+ def install_blank_delegator(base = self, at:, safe: safe_blank_delegation?(at))
94
+ method_name = underscore(at).gsub('@', '').to_sym
95
+ install_safe = safe
96
+
97
+ return unless instance_method?(base, name: method_name, include_private: true)
98
+
99
+ method_was_inherited = inherited_method?(base, name: method_name)
100
+ original_method = :"delegated_blank_original_#{method_name}"
101
+
102
+ return if instance_method?(base, name: original_method, include_private: true, inherited: false)
103
+
104
+ base.alias_method(original_method, method_name) unless method_was_inherited
105
+
106
+ method_def = proc do |*args, **kargs, &block|
107
+ if method_was_inherited
108
+ super(*args, **kargs, &block)
109
+ else
110
+ send(original_method, *args, **kargs, &block)
111
+ end.then do |value|
112
+ next value unless blank?(value)
113
+
114
+ target = self.class.delegating_blank_target(self, at: at)
115
+
116
+ if at.to_s.start_with?('@')
117
+ target.instance_variable_get(at)
118
+ elsif !install_safe || target.respond_to?(method_name, true)
119
+ target.send(method_name, *args, **kargs, &block)
120
+ end
121
+ end
122
+ end
123
+
124
+ base.define_method(method_name, &method_def)
125
+ end
126
+
127
+ def instance_method?(base = self, name:, include_private: false, inherited: true)
128
+ return true if base.method_defined?(name, inherited)
129
+ return false unless include_private
130
+
131
+ base.private_instance_methods(inherited).include?(name.to_sym)
132
+ end
133
+
134
+ def inherited_method?(base = self, name:)
135
+ return false if base.public_instance_methods(false).include?(name.to_sym)
136
+ return false if base.private_instance_methods(false).include?(name.to_sym)
137
+
138
+ true
139
+ end
140
+
141
+ def sym_or_string?(value)
142
+ return false unless value.is_a?(Symbol) || value.is_a?(String)
143
+ return false if value.to_s.strip.empty?
144
+
145
+ true
146
+ end
147
+ end
148
+
149
+ # INSTANCE Methods
150
+
151
+ def blank?(value)
152
+ return super if defined?(super)
153
+ return true if value.nil?
154
+ return true if value.to_s.strip.empty?
155
+ return true if value.respond_to?(:empty?) && value.empty?
156
+
157
+ false
158
+ end
159
+ end
160
+ end
161
+
162
+ # rubocop:enable Naming/MethodParameterName
@@ -88,11 +88,11 @@ module Eco::Language::Delegation::ForDelegator
88
88
  base.define_method(meth_name, &method_def)
89
89
  end
90
90
 
91
- def instance_method?(base = self, name:, include_private: false)
92
- return true if base.method_defined?(name)
91
+ def instance_method?(base = self, name:, include_private: false, inherited: true)
92
+ return true if base.method_defined?(name, inherited)
93
93
  return false unless include_private
94
94
 
95
- base.private_instance_methods.include?(name.to_sym)
95
+ base.private_instance_methods(inherited).include?(name.to_sym)
96
96
  end
97
97
  end
98
98
  end
@@ -8,3 +8,4 @@ require_relative 'delegation/chainable_delegator'
8
8
  require_relative 'delegation/delegating_missing_on_class'
9
9
  require_relative 'delegation/delegating_missing'
10
10
  require_relative 'delegation/delegating_missing_const'
11
+ require_relative 'delegation/delegating_blank'
data/lib/eco/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Eco
2
- VERSION = '3.0.28'.freeze
2
+ VERSION = '3.0.29'.freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eco-helpers
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.28
4
+ version: 3.0.29
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oscar Segura
@@ -912,6 +912,8 @@ files:
912
912
  - lib/eco/api/usecases/samples/drivers/cli/url_pull_cli.rb
913
913
  - lib/eco/api/usecases/samples/drivers/sftp_sample.rb
914
914
  - lib/eco/api/usecases/samples/drivers/url_pull_sample.rb
915
+ - lib/eco/api/usecases/service.rb
916
+ - lib/eco/api/usecases/service/sftp.rb
915
917
  - lib/eco/api/usecases/use_case.rb
916
918
  - lib/eco/api/usecases/use_case/chainer.rb
917
919
  - lib/eco/api/usecases/use_case_chain.rb
@@ -1002,6 +1004,7 @@ files:
1002
1004
  - lib/eco/language/curry.rb
1003
1005
  - lib/eco/language/delegation.rb
1004
1006
  - lib/eco/language/delegation/chainable_delegator.rb
1007
+ - lib/eco/language/delegation/delegating_blank.rb
1005
1008
  - lib/eco/language/delegation/delegating_missing.rb
1006
1009
  - lib/eco/language/delegation/delegating_missing_const.rb
1007
1010
  - lib/eco/language/delegation/delegating_missing_on_class.rb