smart_config 0.0.1 → 0.0.2

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: 2916bd8a506f8c74af2f8b00729d7ba04241159b7ea993090b0010b82657b62e
4
- data.tar.gz: 55d1eadaf37c20f76de2ff01e21b23aba1448eedae035404c739d0a7b2d74cff
3
+ metadata.gz: 79021decd1e8da1ca164f03eb52d4e4291516844c5142ae38c11d1ba88f967f7
4
+ data.tar.gz: 728aaac6723424090f3c5b53cbb0289ac003fb40b1429b7ed5c7ebef71f3690b
5
5
  SHA512:
6
- metadata.gz: 04f2a8e1094f315d3afe3e47d0dc42fbd305d079abd11024b0f8b2762c4f0154f23a5deda724c6223b4b08cd784f0e4836777354595f401102cc59d573a0276e
7
- data.tar.gz: 59ee036cb4a4253af357017db22662e01c6765d589282939e2638e422e303f5e97213ee91395fe009e9b1a11f8e795c15f86adb11130a59d862f6c08a65e3917
6
+ metadata.gz: 3e4754d90251092a7ae9d31b8a16ab855ce4630f2e1595e23b0b532bec60c383e5d1a26c08319bf2f72683ff5147681eb4549ad880a1e2cf764be302965be0cc
7
+ data.tar.gz: ad94e8af908a5a4cd9da816552af14374187a6d18c643fad444a893b5a87319e845b993af1fbb4326f08b61f36b0434c399b7f062678e7b9a9179baaf2fd3971
data/README.md CHANGED
@@ -17,20 +17,22 @@ Add the `smart_gem` dependency to you Gemfile:
17
17
  gem 'smart_gem'
18
18
  ```
19
19
 
20
+ ### Usage
21
+
20
22
  Then, create a new config class that, and define the configuration you need:
21
23
 
22
- ```
24
+ ```ruby
23
25
  class Config
24
26
  extend SmartConfig::Config
25
27
 
26
28
  # Optional. Will default to `config/config.yml`
27
29
  config_path 'config/app_config.yml'
28
30
 
29
- value :app_name
31
+ value :app_name, default: 'My App'
30
32
 
31
33
  group :smtp do
32
34
  value :hostname
33
- value :port
35
+ value :port, format: :integer
34
36
  value :username
35
37
  value :password
36
38
  end
@@ -54,4 +56,31 @@ Then, within your application, you can call:
54
56
  Config.redis.connection.hostname
55
57
  ```
56
58
 
57
- To access the configuration value.
59
+ To access the configuration value, from the following YAML file for example:
60
+
61
+ ```yaml
62
+ redis:
63
+ connection:
64
+ hostname: 'localhost'
65
+ ```
66
+
67
+ For values that are not in the YAML config, the tool will try reading it from environment variables, such as (from the previous configuration):
68
+
69
+ ```
70
+ REDIS_CONNECTION_PASSWORD
71
+ ```
72
+
73
+ #### Value Options
74
+
75
+ Values can use options, which can be set after the value name. For example:
76
+
77
+ ```ruby
78
+ value :hostname, default: 'localhost'
79
+ ```
80
+
81
+ All available options are:
82
+
83
+ | name | description |
84
+ |-----------|----------------------------------------------------------------------------------------------------------------------------------------------------|
85
+ | default | Sets a default value for the field, if no configuration could be found. If this option is not set, getting an unset field will raise an exception. |
86
+ | format | Sets the format of the field. If this option is not set, the field will be formatted as string. |
@@ -22,11 +22,17 @@ module SmartConfig
22
22
  @config_path
23
23
  end
24
24
 
25
- def data
26
- @data ||= [
27
- YAML.load_file(config_file_path),
28
- ENV.to_h.transform_keys(&:downcase)
29
- ]
25
+ def walker
26
+ @walker ||= SmartConfig::Walker.new([
27
+ {
28
+ data: config_file_path,
29
+ strategy: :nested
30
+ },
31
+ {
32
+ data: ENV.to_h.transform_keys(&:downcase),
33
+ strategy: :flat
34
+ }
35
+ ])
30
36
  end
31
37
  end
32
38
  end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SmartConfig
4
+ module Formatters
5
+ #
6
+ # Boolean formats the value into a boolean
7
+ class Boolean
8
+ def self.format(value)
9
+ ['true', '1', 1, true].include?(value)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SmartConfig
4
+ module Formatters
5
+ #
6
+ # Float formats the value into a float
7
+ class Float
8
+ def self.format(value)
9
+ return nil if value.nil?
10
+
11
+ value.to_f
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SmartConfig
4
+ module Formatters
5
+ #
6
+ # Integer formats the value into an integer
7
+ class Integer
8
+ def self.format(value)
9
+ return nil if value.nil?
10
+
11
+ value.to_i
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SmartConfig
4
+ module Formatters
5
+ #
6
+ # String formats the value into a string
7
+ class String
8
+ def self.format(value)
9
+ value
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SmartConfig
4
+ #
5
+ # Formatters define behaviors to format values into another type
6
+ # This is especially useful for environment variables, which are always strings
7
+ #
8
+ module Formatters
9
+ def self.find(format)
10
+ SmartConfig::Formatters.const_get(camelize(format))
11
+ end
12
+
13
+ def self.camelize(format)
14
+ format.to_s.split('_').collect(&:capitalize).join
15
+ end
16
+ end
17
+ end
18
+
19
+ require 'smart_config/formatters/string'
20
+ require 'smart_config/formatters/integer'
21
+ require 'smart_config/formatters/float'
22
+ require 'smart_config/formatters/boolean'
@@ -9,16 +9,14 @@ module SmartConfig
9
9
  class Group
10
10
  include SmartConfig::Values
11
11
 
12
- def initialize(name, parent, &)
13
- @name = name
14
- @parent = parent
12
+ def initialize(namespace, walker, &)
13
+ @namespace = namespace
14
+ @walker = walker
15
15
  instance_exec(&)
16
16
  end
17
17
 
18
18
  private
19
19
 
20
- def data
21
- @data ||= @parent.get_path(@name)
22
- end
20
+ attr_reader :walker
23
21
  end
24
22
  end
@@ -7,14 +7,17 @@ module SmartConfig
7
7
  # Handles the retrieval of values, but with already provided data.
8
8
  #
9
9
  module Values
10
- def value(name)
10
+ attr_reader :namespace
11
+
12
+ def value(name, *opts)
11
13
  @config ||= {}
12
- @config[name.to_sym] = {}
14
+ @config[name.to_sym] = opts.reduce({}, :merge)
13
15
  end
14
16
 
15
17
  def group(name, &)
16
18
  @config ||= {}
17
- @config[name.to_sym] = SmartConfig::Group.new(name, self, &)
19
+ @config[name.to_sym] ||= {}
20
+ @config[name.to_sym][:group] = SmartConfig::Group.new([namespace, name].compact.flatten, walker, &)
18
21
  end
19
22
 
20
23
  def keys
@@ -22,7 +25,7 @@ module SmartConfig
22
25
  end
23
26
 
24
27
  def method_missing(name, *args, &)
25
- return get_value(name) if keys.include?(name)
28
+ return format_value(name, get_value(name)) if keys.include?(name)
26
29
 
27
30
  super
28
31
  end
@@ -34,26 +37,31 @@ module SmartConfig
34
37
  end
35
38
 
36
39
  def get_value(name)
37
- path = get_path(name)
40
+ return @config[name][:group] if @config[name].key?(:group)
41
+
42
+ path = walker.walk(full_name(name))
43
+ return path.first unless path.first.nil?
44
+ return @config[name][:default] if @config[name].key?(:default)
38
45
 
39
- case @config[name]
40
- when SmartConfig::Group
41
- @config[name]
42
- else
43
- path.first
44
- end
46
+ raise SmartConfig::MissingConfigValue, full_name(name)
45
47
  end
46
48
 
47
- def get_path(name)
48
- name = name.to_s
49
- data.map { |a| a[name] }.compact
49
+ def format_value(name, value)
50
+ @formatters ||= {}
51
+
52
+ @formatters[name] ||= SmartConfig::Formatters.find(@config[name].fetch(:format, :string))
53
+ @formatters[name].format(value)
50
54
  end
51
55
 
52
56
  private
53
57
 
54
- # Getting the data needs to be implemented by a lateral module
55
- def data
58
+ # Getting the data through a walker needs to be implemented by a lateral module
59
+ def walker
56
60
  raise NotImplementedError
57
61
  end
62
+
63
+ def full_name(name)
64
+ [namespace, name.to_s].compact.flatten.join('.')
65
+ end
58
66
  end
59
67
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SmartConfig
4
- VERSION = '0.0.1'
4
+ VERSION = '0.0.2'
5
5
  end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+
5
+ module SmartConfig
6
+ #
7
+ # Loads the data from any configured source and walks through it to find
8
+ # values
9
+ #
10
+ class Walker
11
+ def initialize(sources)
12
+ @sources = sources
13
+ end
14
+
15
+ def walk(path)
16
+ data.filter_map do |d|
17
+ next if d[:data].nil?
18
+
19
+ case d[:strategy]
20
+ when :nested
21
+ d[:data].dig(*path.split('.'))
22
+ when :flat
23
+ d[:data][path.tr('.', '_')]
24
+ end
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def data
31
+ @data ||= @sources.filter_map do |s|
32
+ {
33
+ data: load_source(s[:data]),
34
+ strategy: s[:strategy]
35
+ }
36
+ end
37
+ end
38
+
39
+ def load_source(name)
40
+ case name
41
+ when Hash
42
+ name
43
+ when /\.(yml|yaml)$/
44
+ YAML.load_file(name)
45
+ end
46
+ rescue Errno::ENOENT
47
+ nil
48
+ end
49
+ end
50
+ end
data/lib/smart_config.rb CHANGED
@@ -3,8 +3,12 @@
3
3
  #
4
4
  # The main SmartConfig module. See documentation for the sub modules.
5
5
  #
6
- module SmartConfig; end
6
+ module SmartConfig
7
+ class MissingConfigValue < StandardError; end
8
+ end
7
9
 
10
+ require 'smart_config/formatters'
11
+ require 'smart_config/walker'
8
12
  require 'smart_config/values'
9
13
  require 'smart_config/group'
10
14
  require 'smart_config/config'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smart_config
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Damien MATHIEU
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-02-28 00:00:00.000000000 Z
11
+ date: 2024-03-13 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Define and access static configuration, from a YAML config file, or environment
14
14
  variables
@@ -22,9 +22,15 @@ files:
22
22
  - README.md
23
23
  - lib/smart_config.rb
24
24
  - lib/smart_config/config.rb
25
+ - lib/smart_config/formatters.rb
26
+ - lib/smart_config/formatters/boolean.rb
27
+ - lib/smart_config/formatters/float.rb
28
+ - lib/smart_config/formatters/integer.rb
29
+ - lib/smart_config/formatters/string.rb
25
30
  - lib/smart_config/group.rb
26
31
  - lib/smart_config/values.rb
27
32
  - lib/smart_config/version.rb
33
+ - lib/smart_config/walker.rb
28
34
  homepage: https://github.com/dmathieu/smart_config
29
35
  licenses:
30
36
  - MIT