eac_ruby_utils 0.32.1 → 0.36.0

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: c3b4252e76ab06f5b59322d5fda1ef5449a96902fc2fd1dd0d8351b9b158d82e
4
- data.tar.gz: 9d75843b64980304d25951adda38219e9b0ef7d8053af3cbd5b2d36bc4fefa86
3
+ metadata.gz: 5ba02fdc9d6fb66a14fbaf450133ad2ff83c8e0950ffa48bd8a26dcd217162be
4
+ data.tar.gz: 8720f2d7da61a357a578c8005079739c127a3afb464e7a83b32516f2c81f34db
5
5
  SHA512:
6
- metadata.gz: 23b52276403c3eef53b6239b1095e1e58eec87fb9d00c3c8fa8b0ea06b12e1292951dab3b58ad4068922c7f6020309c73ec8b9f00d2ae678847f37b8fc959669
7
- data.tar.gz: 8e352a0818a7c7aa7392e8b8333db4dfabcd7d31f9a4a06e19177c3d44405f6cdc4e4ccda099d28407942cd1f0c18f033c07163e99bfc5492eb392ad885c1041
6
+ metadata.gz: 6fa38e552ff8a9f8808614aa67e55eb5a50b837891f0bcd3d6e909bea3ba739307c661a7754f91b048bb600be23fa6ce049d487d6d098931073a54fb70128f00
7
+ data.tar.gz: 68156f1fc6a1bab01b5524d4568aed52e3361cb46d3306aec17f82da80400c8802b2f8e65f78252de5271160b4fcf5b1eb689d73d21e9f82b95bcdf93ac4b7a4
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/concern'
4
+ require 'eac_ruby_utils/simple_cache'
5
+ require 'eac_ruby_utils/patches/object/if_present'
6
+
7
+ module EacRubyUtils
8
+ class CommonConcern
9
+ CLASS_METHODS_MODULE_NAME = 'ClassMethods'
10
+ INSTANCE_METHODS_MODULE_NAME = 'InstanceMethods'
11
+
12
+ attr_reader :after_callback
13
+
14
+ def initialize(&after_callback)
15
+ @after_callback = after_callback
16
+ end
17
+
18
+ def setup(a_module)
19
+ Setup.new(self, a_module).run
20
+ end
21
+
22
+ class Setup
23
+ include ::EacRubyUtils::SimpleCache
24
+ attr_reader :a_module, :common_constructor
25
+
26
+ def initialize(common_constructor, a_module)
27
+ @common_constructor = common_constructor
28
+ @a_module = a_module
29
+ end
30
+
31
+ def run
32
+ setup = self
33
+ a_module.extend(::ActiveSupport::Concern)
34
+ a_module.included do
35
+ %w[class_methods instance_methods after_callback].each do |suffix|
36
+ setup.send("setup_#{suffix}", self)
37
+ end
38
+ end
39
+ end
40
+
41
+ def setup_class_methods(base)
42
+ class_methods_module.if_present { |v| base.extend v }
43
+ end
44
+
45
+ def setup_instance_methods(base)
46
+ instance_methods_module.if_present { |v| base.include v }
47
+ end
48
+
49
+ def setup_after_callback(base)
50
+ common_constructor.after_callback.if_present do |v|
51
+ base.instance_eval(&v)
52
+ end
53
+ end
54
+
55
+ def class_methods_module_uncached
56
+ a_module.const_get(CLASS_METHODS_MODULE_NAME)
57
+ rescue NameError
58
+ nil
59
+ end
60
+
61
+ def instance_methods_module_uncached
62
+ a_module.const_get(INSTANCE_METHODS_MODULE_NAME)
63
+ rescue NameError
64
+ nil
65
+ end
66
+ end
67
+ end
68
+ end
@@ -20,17 +20,11 @@ module EacRubyUtils
20
20
  load
21
21
  end
22
22
 
23
- def clear
24
- file.clear
25
- end
23
+ delegate :clear, to: :file
26
24
 
27
- def save
28
- file.save
29
- end
25
+ delegate :save, to: :file
30
26
 
31
- def load
32
- file.load
33
- end
27
+ delegate :load, to: :file
34
28
 
35
29
  def []=(entry_key, entry_value)
36
30
  write_entry(entry_key, entry_value)
@@ -48,9 +42,7 @@ module EacRubyUtils
48
42
  file.read(entry_key)
49
43
  end
50
44
 
51
- def autosave?
52
- file.autosave?
53
- end
45
+ delegate :autosave?, to: :file
54
46
 
55
47
  private
56
48
 
@@ -85,7 +85,7 @@ module EacRubyUtils
85
85
  def looped_entry_value_from_input(entry_key, options)
86
86
  loop do
87
87
  entry_value = entry_value_from_input(entry_key, options)
88
- next unless entry_value.present?
88
+ next if entry_value.blank?
89
89
  next if options[:validator] && !options[:validator].call(entry_value)
90
90
 
91
91
  return entry_value
@@ -10,7 +10,7 @@ module EacRubyUtils
10
10
  new(options).send(:run)
11
11
  rescue Docopt::Exit => e
12
12
  STDERR.write(e.message + "\n")
13
- ::Kernel.exit(DOCOPT_ERROR_EXIT_CODE)
13
+ ::Kernel.exit(DOCOPT_ERROR_EXIT_CODE) # rubocop:disable Rails/Exit
14
14
  end
15
15
  end
16
16
  end
@@ -26,7 +26,7 @@ module EacRubyUtils
26
26
 
27
27
  def fatal_error(string)
28
28
  puts "ERROR: #{string}".white.on_red
29
- Kernel.exit 1
29
+ Kernel.exit 1 # rubocop:disable Rails/Exit
30
30
  end
31
31
 
32
32
  def title(string)
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacRubyUtils
4
+ module Fs
5
+ class << self
6
+ # A [File.extname] which find multiple extensions (Ex.: .tar.gz).
7
+ def extname(path, limit = -1)
8
+ recursive_extension(::File.basename(path), limit)
9
+ end
10
+
11
+ # Shortcut to +extname(2)+.
12
+ def extname2(path)
13
+ extname(path, 2)
14
+ end
15
+
16
+ private
17
+
18
+ def recursive_extension(basename, limit)
19
+ return '' if limit.zero?
20
+
21
+ m = /\A(.+)(\.[a-z][a-z0-9]*)\z/i.match(basename)
22
+ if m
23
+ "#{recursive_extension(m[1], limit - 1)}#{m[2]}"
24
+ else
25
+ ''
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -12,6 +12,10 @@ module EacRubyUtils
12
12
  apply_constants
13
13
  end
14
14
 
15
+ def each_value(&block)
16
+ values.each(&block)
17
+ end
18
+
15
19
  def values
16
20
  @values.values.map(&:value)
17
21
  end
@@ -4,6 +4,7 @@ require 'active_support/hash_with_indifferent_access'
4
4
  require 'active_support/core_ext/string/inflections'
5
5
  require_relative 'integer_list'
6
6
  require_relative 'string_list'
7
+ require_relative 'symbol_list'
7
8
 
8
9
  module EacRubyUtils
9
10
  module Listable
@@ -14,18 +15,10 @@ module EacRubyUtils
14
15
  @source = source
15
16
  end
16
17
 
17
- def add_integer(item, *labels)
18
- check_acts_as_listable_new_item(item)
19
- acts_as_listable_items[item] = ::EacRubyUtils::Listable::IntegerList.new(
20
- self, item, labels
21
- )
22
- end
23
-
24
- def add_string(item, *labels)
25
- check_acts_as_listable_new_item(item)
26
- acts_as_listable_items[item] = ::EacRubyUtils::Listable::StringList.new(
27
- self, item, labels
28
- )
18
+ %w[integer string symbol].each do |list_type|
19
+ define_method "add_#{list_type}" do |item, *labels|
20
+ add(::EacRubyUtils::Listable.const_get("#{list_type}_list".camelize), item, labels)
21
+ end
29
22
  end
30
23
 
31
24
  def method_missing(name, *args, &block)
@@ -43,6 +36,11 @@ module EacRubyUtils
43
36
 
44
37
  private
45
38
 
39
+ def add(list_class, item, labels)
40
+ check_acts_as_listable_new_item(item)
41
+ acts_as_listable_items[item] = list_class.new(self, item, labels)
42
+ end
43
+
46
44
  def check_acts_as_listable_new_item(item)
47
45
  return unless acts_as_listable_items.key?(item)
48
46
 
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'list'
4
+
5
+ module EacRubyUtils
6
+ module Listable
7
+ class SymbolList < ::EacRubyUtils::Listable::List
8
+ protected
9
+
10
+ def parse_labels(labels)
11
+ if labels.first.is_a?(Hash)
12
+ Hash[labels.first.map { |k, v| [k.to_sym, v.to_sym] }]
13
+ else
14
+ Hash[labels.map { |v| [v.to_sym, v.to_sym] }]
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/common_concern'
4
+ require 'eac_ruby_utils/console/speaker'
5
+
6
+ class Module
7
+ def common_concern(&after_callback)
8
+ ::EacRubyUtils::CommonConcern.new(&after_callback).setup(self)
9
+ end
10
+ end
@@ -4,6 +4,6 @@ require 'eac_ruby_utils/patch'
4
4
 
5
5
  class Module
6
6
  def patch(patch_module)
7
- ::Eac::Ruby::Utils.patch(self, patch_module)
7
+ ::EacRubyUtils.patch(self, patch_module)
8
8
  end
9
9
  end
@@ -3,7 +3,7 @@
3
3
  require 'eac_ruby_utils/require_sub'
4
4
 
5
5
  class Module
6
- def require_sub(file_path)
7
- ::EacRubyUtils.require_sub(file_path)
6
+ def require_sub(file_path, options = {})
7
+ ::EacRubyUtils.require_sub(file_path, { base: self }.merge(options))
8
8
  end
9
9
  end
@@ -5,7 +5,7 @@ require 'active_support/core_ext/object/blank'
5
5
  class Object
6
6
  # @return +block.call(self)+ if +self+ is present, +default_value+ otherwise.
7
7
  def if_present(default_value = nil)
8
- return default_value unless present?
8
+ return default_value if blank?
9
9
 
10
10
  block_given? ? yield(self) : self
11
11
  end
@@ -33,9 +33,7 @@ module EacRubyUtils
33
33
  root.write_entry(self.class.parse_entry_key(entry_key), entry_value, [])
34
34
  end
35
35
 
36
- def to_h
37
- root.to_h
38
- end
36
+ delegate :to_h, to: :root
39
37
 
40
38
  private
41
39
 
@@ -2,9 +2,52 @@
2
2
 
3
3
  module EacRubyUtils
4
4
  class << self
5
- def require_sub(file)
5
+ def require_sub(file, options = {})
6
+ ::EacRubyUtils::RequireSub.new(file, options).apply
7
+ end
8
+ end
9
+
10
+ class RequireSub
11
+ BASE_OPTION_KEY = :base
12
+ INCLUDE_MODULES_OPTION_KEY = :include_modules
13
+ REQUIRE_DEPENDENCY_OPTION_KEY = :require_dependency
14
+
15
+ attr_reader :file, :options
16
+
17
+ def initialize(file, options = {})
18
+ @file = file
19
+ @options = options
20
+ end
21
+
22
+ def apply
23
+ require_sub_files
24
+ include_modules
25
+ end
26
+
27
+ private
28
+
29
+ def include_modules
30
+ return unless options[INCLUDE_MODULES_OPTION_KEY]
31
+
32
+ base.constants.each do |constant_name|
33
+ constant = base.const_get(constant_name)
34
+ next unless constant.is_a?(::Module) && !constant.is_a?(::Class)
35
+
36
+ base.include(constant)
37
+ end
38
+ end
39
+
40
+ def base
41
+ options[BASE_OPTION_KEY] || raise('Option :base not setted')
42
+ end
43
+
44
+ def require_sub_files
6
45
  Dir["#{File.dirname(file)}/#{::File.basename(file, '.*')}/*.rb"].sort.each do |path|
7
- require path
46
+ if options[REQUIRE_DEPENDENCY_OPTION_KEY]
47
+ require_dependency path
48
+ else
49
+ require path
50
+ end
8
51
  end
9
52
  end
10
53
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module EacRubyUtils
4
- VERSION = '0.32.1'
4
+ VERSION = '0.36.0'
5
5
  end
@@ -3,10 +3,93 @@
3
3
  require 'yaml'
4
4
 
5
5
  module EacRubyUtils
6
+ # A safe YAML loader/dumper with common types included.
6
7
  class Yaml
7
8
  class << self
8
- def load_common(string)
9
- ::YAML.safe_load(string, [::Symbol, ::Date])
9
+ DEFAULT_PERMITTED_CLASSES = [::Array, ::Date, ::FalseClass, ::Hash, ::NilClass, ::Numeric,
10
+ ::String, ::Symbol, ::Time, ::TrueClass].freeze
11
+
12
+ def dump(object)
13
+ ::YAML.dump(sanitize(object))
14
+ end
15
+
16
+ def load(string)
17
+ ::YAML.safe_load(string, permitted_classes)
18
+ end
19
+
20
+ def permitted_classes
21
+ DEFAULT_PERMITTED_CLASSES
22
+ end
23
+
24
+ def sanitize(object)
25
+ Sanitizer.new(object).result
26
+ end
27
+
28
+ def yaml?(object)
29
+ return false unless object.is_a?(::String)
30
+ return false unless object.start_with?('---')
31
+
32
+ load(object)
33
+ true
34
+ rescue ::Psych::SyntaxError
35
+ false
36
+ end
37
+
38
+ class Sanitizer
39
+ attr_reader :source
40
+
41
+ RESULT_TYPES = %w[permitted enumerableable hashable].freeze
42
+
43
+ def initialize(source)
44
+ @source = source
45
+ end
46
+
47
+ def result
48
+ RESULT_TYPES.each do |type|
49
+ return send("result_#{type}") if send("result_#{type}?")
50
+ end
51
+
52
+ source.to_s
53
+ end
54
+
55
+ private
56
+
57
+ def result_enumerableable?
58
+ source.respond_to?(:to_a) && !source.is_a?(::Hash)
59
+ end
60
+
61
+ def result_enumerableable
62
+ source.to_a.map { |child| sanitize_value(child) }
63
+ end
64
+
65
+ def result_hashable?
66
+ source.respond_to?(:to_h)
67
+ end
68
+
69
+ def result_hashable
70
+ source.to_h.map { |k, v| [k.to_sym, sanitize_value(v)] }.to_h
71
+ end
72
+
73
+ def result_nil?
74
+ source.nil?
75
+ end
76
+
77
+ def result_nil
78
+ nil
79
+ end
80
+
81
+ def result_permitted?
82
+ (::EacRubyUtils::Yaml.permitted_classes - [::Array, ::Hash])
83
+ .any? { |klass| source.is_a?(klass) }
84
+ end
85
+
86
+ def result_permitted
87
+ source
88
+ end
89
+
90
+ def sanitize_value(value)
91
+ self.class.new(value).result
92
+ end
10
93
  end
11
94
  end
12
95
  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.32.1
4
+ version: 0.36.0
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: 2020-05-12 00:00:00.000000000 Z
11
+ date: 2020-06-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -110,6 +110,7 @@ files:
110
110
  - lib/eac_ruby_utils.rb
111
111
  - lib/eac_ruby_utils/arguments_consumer.rb
112
112
  - lib/eac_ruby_utils/by_reference.rb
113
+ - lib/eac_ruby_utils/common_concern.rb
113
114
  - lib/eac_ruby_utils/common_constructor.rb
114
115
  - lib/eac_ruby_utils/configs.rb
115
116
  - lib/eac_ruby_utils/configs/file.rb
@@ -140,6 +141,7 @@ files:
140
141
  - lib/eac_ruby_utils/envs/ssh_env.rb
141
142
  - lib/eac_ruby_utils/filesystem_cache.rb
142
143
  - lib/eac_ruby_utils/fs.rb
144
+ - lib/eac_ruby_utils/fs/extname.rb
143
145
  - lib/eac_ruby_utils/fs/temp.rb
144
146
  - lib/eac_ruby_utils/fs/temp/directory.rb
145
147
  - lib/eac_ruby_utils/fs/temp/file.rb
@@ -153,6 +155,7 @@ files:
153
155
  - lib/eac_ruby_utils/listable/list.rb
154
156
  - lib/eac_ruby_utils/listable/lists.rb
155
157
  - lib/eac_ruby_utils/listable/string_list.rb
158
+ - lib/eac_ruby_utils/listable/symbol_list.rb
156
159
  - lib/eac_ruby_utils/listable/value.rb
157
160
  - lib/eac_ruby_utils/on_clean_ruby_environment.rb
158
161
  - lib/eac_ruby_utils/options_consumer.rb
@@ -166,6 +169,7 @@ files:
166
169
  - lib/eac_ruby_utils/patches/hash/options_consumer.rb
167
170
  - lib/eac_ruby_utils/patches/hash/sym_keys_hash.rb
168
171
  - lib/eac_ruby_utils/patches/module.rb
172
+ - lib/eac_ruby_utils/patches/module/common_concern.rb
169
173
  - lib/eac_ruby_utils/patches/module/console_speaker.rb
170
174
  - lib/eac_ruby_utils/patches/module/listable.rb
171
175
  - lib/eac_ruby_utils/patches/module/patch.rb