eac_ruby_utils 0.8.0 → 0.9.0

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: '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