eac_ruby_utils 0.58.1 → 0.62.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '059525385419a316a364ba62f82e064c2eff52467f92e2a16adc0f60a0f04008'
4
- data.tar.gz: 689cedcecce832ce4473697dd439c12c08c0fca1b5cef5464d5d8ed3c5b99e5f
3
+ metadata.gz: 76b0e92df72f0b6b552d62eda2aad5f2701409e7d8093aee4d30c5df70ee30a1
4
+ data.tar.gz: b6450dc7143e3a1669df002394357c2209d51983111cefc2d8f25efbd8e5344a
5
5
  SHA512:
6
- metadata.gz: 26f4c05be42c42e86eade057a841dd0d6277479601b050a770bca40c36ff9300dd2f9d74c0ddf5f7f050ed37047cbfa3e6313f61cfe3a86c70a414bd367ed570
7
- data.tar.gz: 9a981083c0ef681f5e20c77e965d05cbdd252035b2c1d6400c982da0258ab7b3f99f5225e58876d6ccaf40c8750a0ce60e957d50d1e107f28f0d2b2435635af9
6
+ metadata.gz: 7839203f7f9e9a8baa17167e4a5e0d9d812ff9028de3fb3c8298ce6bb584f6b77256b8afdfd49ff79f23d0614afcef74aa5f003ab00a0d3fc14d58816e695fce
7
+ data.tar.gz: 9392bdfc10d5a2ba53de62a816c307e0d2f3e21b6731888cc0fe63a46853ed5c074d91fafc5f91194256fa33c6ddb39a930c75564db7aac3ff3967c9e4329eee
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/string/filters'
4
+ require 'eac_ruby_utils/fs/temp'
5
+ require 'filesize'
6
+
7
+ module EacRubyUtils
8
+ module Fs
9
+ class Logs
10
+ TRUNCATE_DEFAULT_LENGTH = 1000
11
+ TRUNCATE_APPEND_TEXT = '(...) '
12
+
13
+ def [](label)
14
+ log_set.fetch(sanitize_label(label))
15
+ end
16
+
17
+ def add(label)
18
+ log_set[sanitize_label(label)] = ::EacRubyUtils::Fs::Temp.file
19
+
20
+ self
21
+ end
22
+
23
+ def remove_all
24
+ log_set.each_key { |label| remove(label) }
25
+
26
+ self
27
+ end
28
+
29
+ def remove(label)
30
+ log_set.fetch(sanitize_label(label)).remove
31
+ log_set.delete(sanitize_label(label))
32
+ end
33
+
34
+ def truncate(label, length = TRUNCATE_DEFAULT_LENGTH)
35
+ content = self[label].read.strip
36
+ return content if content.length <= TRUNCATE_DEFAULT_LENGTH
37
+
38
+ TRUNCATE_APPEND_TEXT + content[content.length - length + TRUNCATE_APPEND_TEXT.length,
39
+ length - TRUNCATE_APPEND_TEXT.length]
40
+ end
41
+
42
+ def truncate_all(length = TRUNCATE_DEFAULT_LENGTH)
43
+ s = "Files: #{log_set.length}\n"
44
+ log_set.each do |label, path|
45
+ x = truncate(label, length)
46
+ y = [label, path, ::Filesize.from("#{path.size} B").pretty].join(' / ')
47
+ s += x.blank? ? ">>> #{y} (Blank) <<<" : ">>> #{y}\n#{x}\n<<< #{y}\n"
48
+ end
49
+ s
50
+ end
51
+
52
+ private
53
+
54
+ def sanitize_label(label)
55
+ label.to_sym
56
+ end
57
+
58
+ def log_set
59
+ @log_set ||= {}
60
+ end
61
+ end
62
+ end
63
+ end
@@ -7,11 +7,19 @@ module EacRubyUtils
7
7
  class << self
8
8
  VARIABLE_NAME_PATTERN = /[_a-z][_a-z0-9]*/i.freeze
9
9
 
10
- def variableize(string)
10
+ # Convert a string to a variable format: first character as a lowercase letter or underscore
11
+ # and other as a lowercase letter, underscore or numbers.
12
+ # @param string [String] The source string.
13
+ # @param validate [Boolean] Affect the outcome when the result builded is not in a valid
14
+ # variable format. If `true`, it raises a {ArgumentError}. If `false`, return `nil`.
15
+ # @return [String, nil]
16
+ # @raise [ArgumentError]
17
+ def variableize(string, validate = true)
11
18
  r = ::ActiveSupport::Inflector.transliterate(string).gsub(/[^_a-z0-9]/i, '_')
12
19
  .gsub(/_+/, '_').gsub(/_\z/, '').gsub(/\A_/, '').downcase
13
20
  m = VARIABLE_NAME_PATTERN.match(r)
14
21
  return r if m
22
+ return nil unless validate
15
23
 
16
24
  raise ::ArgumentError, "Invalid variable name \"#{r}\" was generated " \
17
25
  "from string \"#{string}\""
@@ -54,8 +54,9 @@ module EacRubyUtils
54
54
  end
55
55
 
56
56
  def value_validate!(value, error_class = ::StandardError)
57
- value_valid?(value) ||
58
- raise(error_class, "Invalid value: \"#{value}\" (Valid: #{values_to_s})")
57
+ return value if value_valid?(value)
58
+
59
+ raise(error_class, "Invalid value: \"#{value}\" (Valid: #{values_to_s})")
59
60
  end
60
61
 
61
62
  def values_to_s
@@ -10,6 +10,7 @@ module EacRubyUtils
10
10
  class << self
11
11
  TIMEDATECTL_TIMEZONE_LINE_PATTERN = %r{\s*Time zone:\s*(\S+/\S+)\s}.freeze
12
12
 
13
+ # @return [ActiveSupport::TimeZone]
13
14
  def auto
14
15
  %w[tz_env debian_config offset].lazy.map { |s| send("by_#{s}") }.find(&:present?)
15
16
  end
@@ -18,22 +19,27 @@ module EacRubyUtils
18
19
  ::Time.zone = auto
19
20
  end
20
21
 
22
+ # @return [ActiveSupport::TimeZone]
21
23
  def by_debian_config
22
24
  path = ::Pathname.new(DEBIAN_CONFIG_PATH)
23
- path.exist? ? path.read.strip.presence : nil
25
+ path.exist? ? path.read.strip.if_present { |v| ::ActiveSupport::TimeZone[v] } : nil
24
26
  end
25
27
 
28
+ # @return [ActiveSupport::TimeZone]
26
29
  def by_offset
27
- ::ActiveSupport::TimeZone[::Time.now.getlocal.gmt_offset].name
30
+ ::ActiveSupport::TimeZone[::Time.now.getlocal.gmt_offset]
28
31
  end
29
32
 
33
+ # @return [ActiveSupport::TimeZone]
30
34
  def by_timedatectl
31
35
  executable = ::EacRubyUtils::Envs.local.executable('timedatectl', '--version')
32
36
  return nil unless executable.exist?
33
37
 
34
38
  TIMEDATECTL_TIMEZONE_LINE_PATTERN.if_match(executable.command.execute!) { |m| m[1] }
39
+ .if_present { |v| ::ActiveSupport::TimeZone[v] }
35
40
  end
36
41
 
42
+ # @return [ActiveSupport::TimeZone]
37
43
  def by_tz_env
38
44
  ENV['TZ'].presence
39
45
  end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/patch'
4
+ require 'eac_ruby_utils/settings_provider'
5
+
6
+ class Class
7
+ def enable_settings_provider
8
+ ::EacRubyUtils.patch(self, ::EacRubyUtils::SettingsProvider)
9
+ end
10
+ end
@@ -2,7 +2,9 @@
2
2
 
3
3
  module Kernel
4
4
  # Raise exception with text "Not yet implemented".
5
- def nyi
6
- raise "Not yet implemented (Called in #{caller.first})"
5
+ def nyi(message = nil)
6
+ s = "Not yet implemented (Called in #{caller.first})"
7
+ s += ": #{message}" if message
8
+ raise s
7
9
  end
8
10
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Object
4
+ # @return +block.call(self)+ if +self+ is not nil, +default_value+ otherwise.
5
+ def if_not_nil(default_value = nil)
6
+ return default_value if nil?
7
+
8
+ block_given? ? yield(self) : self
9
+ end
10
+
11
+ # @return +yield+ if +self+ is nil, +self+ otherwise.
12
+ def if_nil
13
+ return yield if nil? && block_given?
14
+
15
+ self
16
+ end
17
+ end
@@ -3,7 +3,9 @@
3
3
  require 'eac_ruby_utils/inflector'
4
4
 
5
5
  class String
6
- def variableize
7
- ::EacRubyUtils::Inflector.variableize(self)
6
+ # Shortcut to `EacRubyUtils::Inflector.variableize(self, ...)`.
7
+ # @see EacRubyUtils::Inflector.variableize
8
+ def variableize(validate = true)
9
+ ::EacRubyUtils::Inflector.variableize(self, validate)
8
10
  end
9
11
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/local_time_zone'
4
+
5
+ class Time
6
+ class << self
7
+ def required_zone
8
+ zone || ::EacRubyUtils::LocalTimeZone.auto || raise('No zone set or discovered')
9
+ end
10
+ end
11
+ end
@@ -1,15 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'active_support/core_ext/string/inflections'
4
- require 'eac_ruby_utils/options_consumer'
3
+ require 'eac_ruby_utils/require_sub'
5
4
 
6
5
  module EacRubyUtils
7
6
  # Provide a option by constant, method or options object.
8
7
  module SettingsProvider
8
+ ::EacRubyUtils.require_sub __FILE__, base: self
9
+
9
10
  def setting_constant_name(key, fullname = false)
10
- name = key.to_s.underscore.upcase
11
- name = "#{self.class.name}::#{name}" if fullname
12
- name
11
+ setting_value_instance(key).constant_name(fullname)
13
12
  end
14
13
 
15
14
  def setting_search_order
@@ -25,41 +24,23 @@ module EacRubyUtils
25
24
  end
26
25
 
27
26
  def setting_value(key, options = {})
28
- options = parse_setting_value_options(options)
29
- options.order.each do |method|
30
- value = send("setting_value_by_#{method}", key)
31
- return value if value
32
- end
33
- return nil unless options.required
34
-
35
- raise "Setting \"#{key}\" not found. Supply in #{settings_object_name}, implement a " \
36
- "\"#{key}\" method or declare a #{setting_constant_name(key, true)} constant."
27
+ setting_value_instance(key, options).value
37
28
  end
38
29
 
39
30
  def setting_value_by_constant(key)
40
- constant_name = setting_constant_name(key)
41
- begin
42
- self.class.const_get(constant_name)
43
- rescue NameError
44
- nil
45
- end
31
+ setting_value_instance(key).value_by_constant
46
32
  end
47
33
 
48
34
  def setting_value_by_method(key)
49
- respond_to?(key) ? send(key) : nil
35
+ setting_value_instance(key).value_by_method
50
36
  end
51
37
 
52
38
  def setting_value_by_settings_object(key)
53
- settings_object[key.to_s] || settings_object[key.to_sym]
39
+ setting_value_instance(key).value_by_settings_object
54
40
  end
55
41
 
56
- private
57
-
58
- def parse_setting_value_options(options)
59
- r = ::EacRubyUtils::OptionsConsumer.new(options).consume_all(:required, :order, ostruct: true)
60
- r.required = true if r.required.nil?
61
- r.order = setting_search_order if r.order.nil?
62
- r
42
+ def setting_value_instance(key, options = {})
43
+ ::EacRubyUtils::SettingsProvider::SettingValue.new(self, key, options)
63
44
  end
64
45
  end
65
46
  end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/string/inflections'
4
+ require 'eac_ruby_utils/listable'
5
+ require 'eac_ruby_utils/simple_cache'
6
+ require 'eac_ruby_utils/struct'
7
+
8
+ module EacRubyUtils
9
+ module SettingsProvider
10
+ class SettingValue
11
+ include ::EacRubyUtils::Listable
12
+ include ::EacRubyUtils::SimpleCache
13
+
14
+ attr_reader :source, :key, :options
15
+ lists.add_symbol :option, :default, :order, :required
16
+
17
+ def initialize(source, key, options)
18
+ @source = source
19
+ @key = key
20
+ @options = options
21
+ end
22
+
23
+ def constant_name(fullname = false)
24
+ name = key.to_s.underscore.upcase
25
+ name = "#{source.class.name}::#{name}" if fullname
26
+ name
27
+ end
28
+
29
+ def value
30
+ parsed_options.order.each do |method|
31
+ value = send("value_by_#{method}")
32
+ return value if value
33
+ end
34
+ return parsed_options.default if parsed_options.respond_to?(OPTION_DEFAULT)
35
+ return nil unless parsed_options.required
36
+
37
+ raise_key_not_found
38
+ end
39
+
40
+ def value_by_constant
41
+ source.class.const_get(constant_name)
42
+ rescue NameError
43
+ nil
44
+ end
45
+
46
+ def value_by_method
47
+ source.respond_to?(key, true) ? source.send(key) : nil
48
+ end
49
+
50
+ def value_by_settings_object
51
+ source.settings_object[key.to_s] || source.settings_object[key.to_sym]
52
+ end
53
+
54
+ private
55
+
56
+ def parsed_options_uncached
57
+ r = self.class.lists.option.hash_keys_validate!(options.symbolize_keys)
58
+ r[:required] = true unless r.key?(OPTION_REQUIRED)
59
+ r[:order] = source.setting_search_order if r[OPTION_ORDER].nil?
60
+ ::EacRubyUtils::Struct.new(r)
61
+ end
62
+
63
+ def raise_key_not_found
64
+ raise "Setting \"#{key}\" not found. Supply in #{source.settings_object_name}, implement "\
65
+ "a \"#{key}\" method or declare a #{constant_name(true)} constant."
66
+ end
67
+ end
68
+ end
69
+ end
@@ -2,12 +2,18 @@
2
2
 
3
3
  module EacRubyUtils
4
4
  module SimpleCache
5
- UNCACHED_METHOD_PATTERN = /\A(\s+)_uncached\z/.freeze
5
+ UNCACHED_METHOD_NAME_SUFFIX = '_uncached'
6
+ UNCACHED_METHOD_PATTERN = /\A(\s+)_#{::Regexp.quote(UNCACHED_METHOD_NAME_SUFFIX)}\z/.freeze
7
+
8
+ class << self
9
+ def uncached_method_name(method_name)
10
+ "#{method_name}#{UNCACHED_METHOD_NAME_SUFFIX}"
11
+ end
12
+ end
6
13
 
7
14
  def method_missing(method, *args, &block)
8
- uncached_method = "#{method}_uncached"
9
- if respond_to?(uncached_method, true)
10
- call_method_with_cache(uncached_method, args, &block)
15
+ if respond_to?(::EacRubyUtils::SimpleCache.uncached_method_name(method), true)
16
+ call_method_with_cache(method, args, &block)
11
17
  else
12
18
  super
13
19
  end
@@ -35,10 +41,17 @@ module EacRubyUtils
35
41
  raise 'Não é possível realizar o cache de métodos com bloco' if block
36
42
 
37
43
  key = ([method] + args).join('@@@')
38
- cache_keys[key] = send(method, *args) unless cache_keys.key?(key)
44
+ unless cache_keys.key?(key)
45
+ uncached_value = call_uncached_method(method, args)
46
+ cache_keys[key] = uncached_value
47
+ end
39
48
  cache_keys[key]
40
49
  end
41
50
 
51
+ def call_uncached_method(method, args)
52
+ send(::EacRubyUtils::SimpleCache.uncached_method_name(method), *args)
53
+ end
54
+
42
55
  def cache_keys
43
56
  @cache_keys ||= {}
44
57
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module EacRubyUtils
4
- VERSION = '0.58.1'
4
+ VERSION = '0.62.1'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eac_ruby_utils
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.58.1
4
+ version: 0.62.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Esquilo Azul Company
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-09 00:00:00.000000000 Z
11
+ date: 2021-04-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: 0.6.1
69
+ - !ruby/object:Gem::Dependency
70
+ name: filesize
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: net-ssh
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -162,6 +176,7 @@ files:
162
176
  - lib/eac_ruby_utils/fs.rb
163
177
  - lib/eac_ruby_utils/fs/clearable_directory.rb
164
178
  - lib/eac_ruby_utils/fs/extname.rb
179
+ - lib/eac_ruby_utils/fs/logs.rb
165
180
  - lib/eac_ruby_utils/fs/temp.rb
166
181
  - lib/eac_ruby_utils/fs/temp/directory.rb
167
182
  - lib/eac_ruby_utils/fs/temp/file.rb
@@ -193,6 +208,7 @@ files:
193
208
  - lib/eac_ruby_utils/patches.rb
194
209
  - lib/eac_ruby_utils/patches/class.rb
195
210
  - lib/eac_ruby_utils/patches/class/common_constructor.rb
211
+ - lib/eac_ruby_utils/patches/class/settings_provider.rb
196
212
  - lib/eac_ruby_utils/patches/enumerable.rb
197
213
  - lib/eac_ruby_utils/patches/enumerable/boolean_combinations.rb
198
214
  - lib/eac_ruby_utils/patches/enumerator.rb
@@ -216,6 +232,7 @@ files:
216
232
  - lib/eac_ruby_utils/patches/object.rb
217
233
  - lib/eac_ruby_utils/patches/object/asserts.rb
218
234
  - lib/eac_ruby_utils/patches/object/debug.rb
235
+ - lib/eac_ruby_utils/patches/object/if_nil.rb
219
236
  - lib/eac_ruby_utils/patches/object/if_present.rb
220
237
  - lib/eac_ruby_utils/patches/object/if_respond.rb
221
238
  - lib/eac_ruby_utils/patches/object/template.rb
@@ -227,6 +244,7 @@ files:
227
244
  - lib/eac_ruby_utils/patches/string.rb
228
245
  - lib/eac_ruby_utils/patches/string/inflector.rb
229
246
  - lib/eac_ruby_utils/patches/time.rb
247
+ - lib/eac_ruby_utils/patches/time/required_zone.rb
230
248
  - lib/eac_ruby_utils/paths_hash.rb
231
249
  - lib/eac_ruby_utils/paths_hash/entry_key_error.rb
232
250
  - lib/eac_ruby_utils/paths_hash/node.rb
@@ -239,6 +257,7 @@ files:
239
257
  - lib/eac_ruby_utils/ruby/command.rb
240
258
  - lib/eac_ruby_utils/ruby/on_clean_environment.rb
241
259
  - lib/eac_ruby_utils/settings_provider.rb
260
+ - lib/eac_ruby_utils/settings_provider/setting_value.rb
242
261
  - lib/eac_ruby_utils/simple_cache.rb
243
262
  - lib/eac_ruby_utils/struct.rb
244
263
  - lib/eac_ruby_utils/templates.rb
@@ -272,7 +291,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
272
291
  - !ruby/object:Gem::Version
273
292
  version: '0'
274
293
  requirements: []
275
- rubygems_version: 3.0.8
294
+ rubygems_version: 3.0.9
276
295
  signing_key:
277
296
  specification_version: 4
278
297
  summary: Utilities for E.A.C.'s Ruby projects.