eac_ruby_utils 0.8.0 → 0.9.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: '0119c50e5869164d29e5dc579df784a5e3576a613a4ea5c597a2ee6dcda212fe'
4
- data.tar.gz: c69eea7c7587d93d44e82da0b37a110e2ec5fb77dfac4e83ecf2d028fd10657f
3
+ metadata.gz: 9290fda1cce697dcfd049b6a8085af55f0ca059d64d183b7571a0f5cbfa9a820
4
+ data.tar.gz: 54679bb172f9c3a2dcac08d642fc0a23dec10142384dff4b6e7f4c72db21622b
5
5
  SHA512:
6
- metadata.gz: d7890f0ffebd4a457ba27eb4cd5ca5df500d19e74103039c441d4ff5c3a26685c6c5a239652e69b99a7007e4688e2a79c275c78b1b019f1ebbedf8f49a9e0f9a
7
- data.tar.gz: 4ed10a42a2b890e6995f67931648029e5f94c6de8b7cc9bf5de57f028169a0e7e122289c53f6b115a37879d2f742acb5b38edd686f93aae62614ffefddcd0102
6
+ metadata.gz: e0611daf87bdb28ca44827934496a9d546b5f9220a0807d80416b61a9b30b282333cbdd9d6699644c47924704d428f9e2a9f18eba4f1c3eab74dc0c432e6efc8
7
+ data.tar.gz: 4402ebebc43b4b862951a39c6213c5c13f2f86fc0784deadbf49a78408e36c3827e40c73e66552bb7313c6603421cb65c8cd3c24fbec8f391ee27048496d3692
@@ -2,12 +2,14 @@
2
2
 
3
3
  module EacRubyUtils
4
4
  require 'eac_ruby_utils/arguments_consumer'
5
+ require 'eac_ruby_utils/configs'
5
6
  require 'eac_ruby_utils/console'
6
7
  require 'eac_ruby_utils/contextualizable'
7
8
  require 'eac_ruby_utils/envs'
8
9
  require 'eac_ruby_utils/listable'
9
10
  require 'eac_ruby_utils/options_consumer'
10
11
  require 'eac_ruby_utils/patches'
12
+ require 'eac_ruby_utils/paths_hash'
11
13
  require 'eac_ruby_utils/simple_cache'
12
14
  require 'eac_ruby_utils/yaml'
13
15
  end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/string'
4
+ require 'yaml'
5
+ require 'eac_ruby_utils/patches/hash/sym_keys_hash'
6
+ require 'eac_ruby_utils/paths_hash'
7
+ require 'eac_ruby_utils/simple_cache'
8
+
9
+ module EacRubyUtils
10
+ class Configs
11
+ include ::EacRubyUtils::SimpleCache
12
+
13
+ attr_reader :configs_key, :options
14
+
15
+ # Valid options: [:storage_path]
16
+ def initialize(configs_key, options = {})
17
+ @configs_key = configs_key
18
+ @options = options.to_sym_keys_hash.freeze
19
+ load
20
+ end
21
+
22
+ def save
23
+ ::File.write(storage_path, data.to_h.to_yaml)
24
+ end
25
+
26
+ def load
27
+ self.data = ::EacRubyUtils::PathsHash.new(YAML.load_file(storage_path))
28
+ end
29
+
30
+ def []=(entry_key, entry_value)
31
+ write_entry(entry_key, entry_value)
32
+ end
33
+
34
+ def write_entry(entry_key, entry_value)
35
+ data[entry_key] = entry_value
36
+ save if autosave?
37
+ end
38
+
39
+ def [](entry_key)
40
+ read_entry(entry_key)
41
+ end
42
+
43
+ def read_entry(entry_key)
44
+ data[entry_key]
45
+ end
46
+
47
+ def autosave?
48
+ options[:autosave] ? true : false
49
+ end
50
+
51
+ private
52
+
53
+ attr_accessor :data
54
+
55
+ def storage_path_uncached
56
+ path = options[:storage_path] || default_storage_path
57
+ return path if ::File.exist?(path)
58
+ ::FileUtils.mkdir_p(::File.dirname(path))
59
+ ::File.write(path, {}.to_yaml)
60
+ path
61
+ end
62
+
63
+ def options_storage_path
64
+ options[:storage_path]
65
+ end
66
+
67
+ def default_storage_path
68
+ ::File.join(ENV['HOME'], '.config', configs_key, 'settings.yml')
69
+ end
70
+ end
71
+ end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'eac_ruby_utils/console/configs'
3
4
  require 'eac_ruby_utils/console/docopt_runner'
4
5
  require 'eac_ruby_utils/console/speaker'
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/configs'
4
+ require 'eac_ruby_utils/console/speaker'
5
+
6
+ module EacRubyUtils
7
+ module Console
8
+ class Configs
9
+ include ::EacRubyUtils::Console::Speaker
10
+
11
+ STORE_PASSWORDS_KEY = 'core.store_passwords'
12
+
13
+ attr_reader :configs
14
+
15
+ def initialize(configs_key)
16
+ @configs = ::EacRubyUtils::Configs.new(configs_key, autosave: true)
17
+ end
18
+
19
+ def request_password(entry_key, options = {})
20
+ options = options.merge(noecho: true)
21
+ if store_passwords?
22
+ read_entry(entry_key, options)
23
+ else
24
+ looped_entry_value_from_input(entry_key, options)
25
+ end
26
+ end
27
+
28
+ def read_entry(entry_key, options = {})
29
+ stored_value = configs.read_entry(entry_key)
30
+ return stored_value if stored_value
31
+ options[:before_input].call if options[:before_input].present?
32
+ entry_value = looped_entry_value_from_input(entry_key, options)
33
+ configs.write_entry(entry_key, entry_value)
34
+ entry_value
35
+ end
36
+
37
+ def store_passwords?
38
+ 'yes' == read_entry(
39
+ STORE_PASSWORDS_KEY,
40
+ before_input: -> { store_password_banner },
41
+ validator: ->(entry_value) { %w[yes no].include?(entry_value) }
42
+ )
43
+ end
44
+
45
+ protected
46
+
47
+ def store_password_banner
48
+ infom 'Do you wanna to store passwords?'
49
+ infom "Warning: the passwords will be store in clear text in \"#{configs.storage_path}\""
50
+ infom 'Enter "yes" or "no"'
51
+ end
52
+
53
+ def looped_entry_value_from_input(entry_key, options)
54
+ loop do
55
+ entry_value = entry_value_from_input(entry_key, options)
56
+ next unless entry_value.present?
57
+ next if options[:validator] && !options[:validator].call(entry_value)
58
+ return entry_value
59
+ end
60
+ end
61
+
62
+ def entry_value_from_input(entry_key, options)
63
+ entry_value = request_input("Value for entry \"#{entry_key}\"", options)
64
+ warn('Entered value is blank') if entry_value.blank?
65
+ entry_value
66
+ end
67
+ end
68
+ end
69
+ end
@@ -39,6 +39,17 @@ module EacRubyUtils
39
39
  puts string.to_s.yellow
40
40
  end
41
41
 
42
+ def request_input(question, options = {})
43
+ STDERR.write "#{question}: ".to_s.yellow
44
+ if options[:noecho]
45
+ r = STDIN.noecho(&:gets).chomp.strip
46
+ STDERR.write("\n")
47
+ r
48
+ else
49
+ gets.chomp.strip
50
+ end
51
+ end
52
+
42
53
  def infov(*args)
43
54
  r = []
44
55
  args.each_with_index do |v, i|
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ Dir["#{File.dirname(__FILE__)}/#{::File.basename(__FILE__, '.*')}/*.rb"].each do |path|
4
+ require path
5
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Object
4
+ def assert_argument(klass, argument_name)
5
+ return if is_a?(klass)
6
+ raise ::ArgumentError,
7
+ "Argument \"#{argument_name}\" is not a #{klass}" \
8
+ "(Actual class: #{self.class}, actual value: #{self})"
9
+ end
10
+ end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/object'
4
+ require 'eac_ruby_utils/patches/object/asserts'
5
+
6
+ module EacRubyUtils
7
+ class PathsHash
8
+ class << self
9
+ def parse_entry_key(entry_key)
10
+ r = entry_key.to_s.strip
11
+ raise EntryKeyError, 'Entry key cannot start or end with dot' if
12
+ r.start_with?('.') || r.end_with?('.')
13
+ r = r.split('.').map(&:strip)
14
+ raise EntryKeyError, "Entry key \"#{entry_key}\" is empty" if r.empty?
15
+ return r.map(&:to_sym) unless r.any?(&:blank?)
16
+ raise EntryKeyError, "Entry key \"#{entry_key}\" has at least one blank part"
17
+ end
18
+ end
19
+
20
+ attr_reader :root
21
+
22
+ def initialize(source_hash = {})
23
+ @root = Node.new(source_hash)
24
+ end
25
+
26
+ def [](entry_key)
27
+ root.read_entry(self.class.parse_entry_key(entry_key), [])
28
+ end
29
+
30
+ def []=(entry_key, entry_value)
31
+ root.write_entry(self.class.parse_entry_key(entry_key), entry_value, [])
32
+ end
33
+
34
+ def to_h
35
+ root.to_h
36
+ end
37
+
38
+ private
39
+
40
+ attr_reader :data
41
+
42
+ class EntryKeyError < StandardError
43
+ end
44
+
45
+ class Node
46
+ def initialize(source_hash)
47
+ source_hash.assert_argument(Hash, 'source_hash')
48
+ @data = source_hash.map { |k, v| [k.to_sym, v.is_a?(Hash) ? Node.new(v) : v] }.to_h
49
+ end
50
+
51
+ def to_h
52
+ data.map { |k, v| [k, v.is_a?(Node) ? v.to_h : v] }.to_h
53
+ end
54
+
55
+ def read_entry(path, current)
56
+ validate_path(path, current)
57
+ node_key = path.shift
58
+ node = data[node_key]
59
+ return (node.is_a?(Node) ? node.to_h : node) if path.empty?
60
+ return nil if node.blank?
61
+ return node.read_entry(path, current + [node_key]) if node.is_a?(Node)
62
+ raise(EntryKeyError,
63
+ "Path #{current.join(',')} is not a Node and path continues (#{current + path})")
64
+ end
65
+
66
+ def write_entry(path, value, current)
67
+ validate_path(path, current)
68
+ node_key = path.shift
69
+ write_entry_value(path, node_key, value, current)
70
+ end
71
+
72
+ private
73
+
74
+ def write_entry_value(path, node_key, value, current)
75
+ if path.empty?
76
+ data[node_key] = value.is_a?(Hash) ? Node.new(value) : value
77
+ else
78
+ data[node_key] = Node.new({}) unless data[node_key].is_a?(Node)
79
+ data[node_key].write_entry(path, value, current + [node_key])
80
+ end
81
+ end
82
+
83
+ def validate_path(path, current)
84
+ path.assert_argument(Array, 'path')
85
+ current.assert_argument(Array, 'current')
86
+ raise EntryKeyError, 'Path is empty' if path.empty?
87
+ end
88
+
89
+ attr_reader :data
90
+ end
91
+ end
92
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module EacRubyUtils
4
- VERSION = '0.8.0'
4
+ VERSION = '0.9.0'
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.8.0
4
+ version: 0.9.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: 2019-07-29 00:00:00.000000000 Z
11
+ date: 2019-07-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -103,7 +103,9 @@ files:
103
103
  - README.rdoc
104
104
  - lib/eac_ruby_utils.rb
105
105
  - lib/eac_ruby_utils/arguments_consumer.rb
106
+ - lib/eac_ruby_utils/configs.rb
106
107
  - lib/eac_ruby_utils/console.rb
108
+ - lib/eac_ruby_utils/console/configs.rb
107
109
  - lib/eac_ruby_utils/console/docopt_runner.rb
108
110
  - lib/eac_ruby_utils/console/docopt_runner/_class_methods.rb
109
111
  - lib/eac_ruby_utils/console/docopt_runner/_doc.rb
@@ -131,6 +133,9 @@ files:
131
133
  - lib/eac_ruby_utils/patches/hash.rb
132
134
  - lib/eac_ruby_utils/patches/hash/options_consumer.rb
133
135
  - lib/eac_ruby_utils/patches/hash/sym_keys_hash.rb
136
+ - lib/eac_ruby_utils/patches/object.rb
137
+ - lib/eac_ruby_utils/patches/object/asserts.rb
138
+ - lib/eac_ruby_utils/paths_hash.rb
134
139
  - lib/eac_ruby_utils/simple_cache.rb
135
140
  - lib/eac_ruby_utils/version.rb
136
141
  - lib/eac_ruby_utils/yaml.rb