eac_ruby_utils 0.32.0 → 0.35.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: 05bbf308b269ce2c53f415b9c318dc362cffb70577ecdfb1490c18e60c9c5d48
4
- data.tar.gz: ae1ea3db1726a14019cefd212d8f5cca39a9b40888bc9e785813ed533c03c5aa
3
+ metadata.gz: 3edd773afcebdd9c7f6af74230428101cfd4afc0e18c2311ace07c45764db8ce
4
+ data.tar.gz: fee5141ecfb6aa6d457d842b0cbafe42abbcb2da5a88cdc873dce82f647459e7
5
5
  SHA512:
6
- metadata.gz: 6d5be7fa53fb4f4ee4dc5032f2600189814505508394a41f3b3302752ff360eb9d62b0be6d45cfcccf6857c03ac20d8e49c83db06f7b66ee0bb7add7172fd6af
7
- data.tar.gz: 5be5e79109cda664d2ac63aa1050f3e11dac629471618cfeb31d7f90183db024ba42caf7edc6b1f07bdc241043a2d8aa9eb73e426c57872b52f430c267619fc8
6
+ metadata.gz: 94629883aff72c800948b4de4f102434a642771a18603971b689311eae89fba38c5729601a1075c8bdb949fd0c85540be846a6b1745fa7247092432e244b111d
7
+ data.tar.gz: 91b1694cde13eaa0621f0ccc847267d3ad7e6656d927cdcdd5b4f21673a1398f99929ed06e368d4b1e49e6d4738ab86139d032436e6bd6a706fcc821cbf27526
@@ -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
@@ -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.0'
4
+ VERSION = '0.35.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.0
4
+ version: 0.35.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-08 00:00:00.000000000 Z
11
+ date: 2020-06-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -87,6 +87,9 @@ dependencies:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0.1'
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: 0.1.1
90
93
  type: :development
91
94
  prerelease: false
92
95
  version_requirements: !ruby/object:Gem::Requirement
@@ -94,6 +97,9 @@ dependencies:
94
97
  - - "~>"
95
98
  - !ruby/object:Gem::Version
96
99
  version: '0.1'
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: 0.1.1
97
103
  description:
98
104
  email:
99
105
  executables: []
@@ -104,6 +110,7 @@ files:
104
110
  - lib/eac_ruby_utils.rb
105
111
  - lib/eac_ruby_utils/arguments_consumer.rb
106
112
  - lib/eac_ruby_utils/by_reference.rb
113
+ - lib/eac_ruby_utils/common_concern.rb
107
114
  - lib/eac_ruby_utils/common_constructor.rb
108
115
  - lib/eac_ruby_utils/configs.rb
109
116
  - lib/eac_ruby_utils/configs/file.rb
@@ -134,6 +141,7 @@ files:
134
141
  - lib/eac_ruby_utils/envs/ssh_env.rb
135
142
  - lib/eac_ruby_utils/filesystem_cache.rb
136
143
  - lib/eac_ruby_utils/fs.rb
144
+ - lib/eac_ruby_utils/fs/extname.rb
137
145
  - lib/eac_ruby_utils/fs/temp.rb
138
146
  - lib/eac_ruby_utils/fs/temp/directory.rb
139
147
  - lib/eac_ruby_utils/fs/temp/file.rb
@@ -160,6 +168,7 @@ files:
160
168
  - lib/eac_ruby_utils/patches/hash/options_consumer.rb
161
169
  - lib/eac_ruby_utils/patches/hash/sym_keys_hash.rb
162
170
  - lib/eac_ruby_utils/patches/module.rb
171
+ - lib/eac_ruby_utils/patches/module/common_concern.rb
163
172
  - lib/eac_ruby_utils/patches/module/console_speaker.rb
164
173
  - lib/eac_ruby_utils/patches/module/listable.rb
165
174
  - lib/eac_ruby_utils/patches/module/patch.rb