bogo-config 0.1.0 → 0.1.2

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
  SHA1:
3
- metadata.gz: 1a46c891352700a77e9ef059c11ddab4982b5ad4
4
- data.tar.gz: a55a4a18e70c690a51d78f5cd71a4fbf6ac0dcb7
3
+ metadata.gz: 1f49c05d8c2034aa1970d1698e22da05f9087cf6
4
+ data.tar.gz: 31165aaac2b92557f540d524ad9d4ea947662394
5
5
  SHA512:
6
- metadata.gz: a03fd7ceed2ffbb0a75a8a49c99ec931ce1dcc1cc960142953c6c47d811810e914464efa4392921acd8e21f8ad851a68e394d324d150ef2870cb720cdeb67628
7
- data.tar.gz: e5ae238374429a9c21c74b5ff6c6ad5670bf637ffea2c3a822d54efb6e326a828ce6d741299d019149e507e3474e729638e30b4ae751ca2a267f89fcceba30a8
6
+ metadata.gz: 0d213e98b6b0fc79bff17f96c218f7d9dce072b2e6c7c4f1d19326ca72fc95bd3ec97bdeb7a58e43a8b931af1c36c5e8bafa8d05971a18a03bc53837463c0089
7
+ data.tar.gz: 4e2763f923be989f93803396b31dbe860a92f99f2f284bf951a3636efb5d23dd2df9a35c964bbf787116e36683be38884b01e7e5930bc52e9dbc8ebacf3d5b6b
data/CHANGELOG.md CHANGED
@@ -1,2 +1,8 @@
1
+ ## v0.1.2
2
+ * Update `Bogo::Config` to behave more like `Smash`
3
+ * Make XML usage more consistent and apply type formats
4
+ * Add `Configuration` class for cleaner struct usage
5
+ * Add test coverage
6
+
1
7
  ## v0.1.0
2
8
  * Initial release
data/README.md CHANGED
@@ -1,6 +1,127 @@
1
1
  # Bogo Config
2
2
 
3
- A configuration helper library.
3
+ Hash based application configuration helpers, because
4
+ snowflake configurations are evil.
5
+
6
+ ## Usage
7
+
8
+ ### Direct
9
+
10
+ Use the `Bogo::Config` directly to store configuration values:
11
+
12
+ ```ruby
13
+ require 'bogo-config'
14
+
15
+ config = Bogo::Config.new(
16
+ :bind => {
17
+ :address => '0.0.0.0',
18
+ :port => 8080
19
+ },
20
+ :run_as => 'www-data'
21
+ )
22
+
23
+ puts config.get(:bind, :address)
24
+ puts config[:run_as]
25
+ ```
26
+
27
+ ### Configuration files
28
+
29
+ A path to a configuration file can also be provided. Lets
30
+ define the file:
31
+
32
+ ```json
33
+ # /tmp/bogo-config.json
34
+ {
35
+ "bind": {
36
+ "address": "0.0.0.0",
37
+ "port": 8080
38
+ },
39
+ "run_as": "www-data"
40
+ }
41
+ ```
42
+
43
+ and now we can load it:
44
+
45
+ ```ruby
46
+ require 'bogo-config'
47
+
48
+ config = Bogo::Config.new('/tmp/bogo-config.json')
49
+
50
+ puts config.get(:bind, :address)
51
+ puts config[:run_as]
52
+ ```
53
+
54
+ ### Subclassing
55
+
56
+ Subclassing `Bogo::Config` allows adding some structure
57
+ to the configuration file. The `Bogo::Lazy` module is
58
+ used to provide the `#attribute` method to describe
59
+ the configuration:
60
+
61
+ ```ruby
62
+ require 'bogo-config'
63
+
64
+ class MyConfig < Bogo::Config
65
+ attribute :bind, Smash, :coerce => proc{|v| v.to_smash}
66
+ attribute :run_as, String, :default => 'www-data'
67
+ end
68
+
69
+ config = MyConfig.new('/tmp/bogo-config.json')
70
+ puts config.get(:bind, :address)
71
+ puts config[:run_as]
72
+ ```
73
+
74
+ ### `Configuration` file
75
+
76
+ Support for `AttributeStruct` configuration files is builtin.
77
+ A helper class is provided as a visual nicety. The above
78
+ JSON example could also be written as:
79
+
80
+ ```ruby
81
+ # /tmp/bogo-config.rb
82
+ Configuration do
83
+ bind do
84
+ address '0.0.0.0'
85
+ port 8080
86
+ end
87
+ run_as 'www-data'
88
+ end
89
+ ```
90
+
91
+ ### Configuration file support
92
+
93
+ Currently the following serialization types are supported:
94
+
95
+ * JSON
96
+ * YAML
97
+ * XML
98
+ * AttributeStruct
99
+
100
+ Note on XML configuration files: The configuration must
101
+ be contained within a `<configuration>` tag. The above
102
+ example would then look like this:
103
+
104
+ ```xml
105
+ <configuration>
106
+ <bind>
107
+ <address>
108
+ 0.0.0.0
109
+ </address>
110
+ <port>
111
+ 8080
112
+ </port>
113
+ </bind>
114
+ <run_as>
115
+ www-data
116
+ </run_as>
117
+ </configuration>
118
+ ```
119
+
120
+ ### Configuration directory
121
+
122
+ The path provided on initialization can also be a directory.
123
+ The contents of the directory will be read in string sorted
124
+ order and deep merged. Files can be a mix of supported types.
4
125
 
5
126
  ## Info
6
127
  * Repository: https://github.com/spox/bogo-config
@@ -2,6 +2,7 @@ require 'yaml'
2
2
  require 'multi_xml'
3
3
  require 'multi_json'
4
4
  require 'attribute_struct'
5
+ require 'forwardable'
5
6
 
6
7
  require 'bogo-config'
7
8
 
@@ -10,9 +11,10 @@ module Bogo
10
11
  class Config
11
12
 
12
13
  include Bogo::Lazy
14
+ extend Forwardable
13
15
 
14
16
  # @return [String] configuration path
15
- attr_reader :path
17
+ attr_accessor :path
16
18
 
17
19
  # Create new instance
18
20
  #
@@ -20,20 +22,27 @@ module Bogo
20
22
  # @return [self]
21
23
  def initialize(path_or_hash=nil)
22
24
  if(path_or_hash.is_a?(String))
23
- super
25
+ @path = path_or_hash
26
+ hash = load!
24
27
  else
25
- @path = path
26
- load! if path
28
+ hash = path_or_hash
29
+ end
30
+ if(hash)
31
+ load_data(hash)
32
+ data.replace(hash.to_smash.deep_merge(data))
27
33
  end
28
34
  end
29
35
 
36
+ # Allow Smash like behavior
37
+ def_delegators *([:data, :[]] + Smash.public_instance_methods(false))
38
+
30
39
  # Load configuration from file(s)
31
40
  #
32
41
  # @return [self]
33
42
  def load!
34
43
  if(path)
35
44
  if(File.directory?(path))
36
- conf = Dir.glob(File.join(path, '*')).inject(Smash.new) do |memo, file_path|
45
+ conf = Dir.glob(File.join(path, '*')).sort.inject(Smash.new) do |memo, file_path|
37
46
  memo.deep_merge(load_file(file_path))
38
47
  end
39
48
  elsif(File.file?(path))
@@ -41,13 +50,8 @@ module Bogo
41
50
  else
42
51
  raise Errno::ENOENT.new path
43
52
  end
44
- data.replace(
45
- self.class.new(
46
- conf
47
- ).data
48
- )
53
+ conf
49
54
  end
50
- self
51
55
  end
52
56
 
53
57
  # Load configuration file
@@ -62,14 +66,19 @@ module Bogo
62
66
  json_load(file_path)
63
67
  when '.xml'
64
68
  xml_load(file_path)
69
+ when '.rb'
70
+ struct_load(file_path)
65
71
  else
66
- result = [:struct_load, :json_load, :yaml_load, :xml_load].detect do |loader|
72
+ result = [:struct_load, :json_load, :yaml_load, :xml_load].map do |loader|
67
73
  begin
68
74
  send(loader, file_path)
69
75
  rescue => e
76
+ if(ENV['DEBUG'])
77
+ $stderr.puts "#{e.class}: #{e}\n#{e.backtrace.join("\n")}"
78
+ end
70
79
  nil
71
80
  end
72
- end
81
+ end.compact.first
73
82
  unless(result)
74
83
  raise "Failed to load configuration from file (#{file_path})"
75
84
  end
@@ -99,7 +108,42 @@ module Bogo
99
108
  # @return [Smash]
100
109
  # @note supar ENTERPRISE
101
110
  def xml_load(file_path)
102
- MultiXml.parse(File.read(file_path)).to_smash
111
+ result = MultiXml.parse(File.read(file_path)).to_smash[:configuration]
112
+ xml_format(result)
113
+ end
114
+
115
+ # Format XML types
116
+ #
117
+ # @param result [Smash]
118
+ # @return [Smash]
119
+ def xml_format(result)
120
+ Smash[result.map{|k,v| [k, xml_format_value(v)]}]
121
+ end
122
+
123
+ # Format XML value types
124
+ #
125
+ # @param value [Object]
126
+ # @return [Object]
127
+ def xml_format_value(value)
128
+ case value
129
+ when Hash
130
+ xml_format(value)
131
+ when Array
132
+ value.map{|v| xml_format_value(v)}
133
+ else
134
+ value.strip!
135
+ if(value == 'true')
136
+ true
137
+ elsif(value == 'false')
138
+ false
139
+ elsif(value.to_i.to_s == value)
140
+ value.to_i
141
+ elsif(value.to_f.to_s == value)
142
+ value.to_f
143
+ else
144
+ value
145
+ end
146
+ end
103
147
  end
104
148
 
105
149
  # Read and parse AttributeStruct file
@@ -107,7 +151,7 @@ module Bogo
107
151
  # @param file_path
108
152
  # @return [Smash]
109
153
  def struct_load(file_path)
110
- result = BasicObject.new.instance_eval(
154
+ result = Module.new.instance_eval(
111
155
  IO.read(file_path), file_path, 1
112
156
  )
113
157
  result._dump.to_smash
@@ -0,0 +1,5 @@
1
+ require 'bogo-config'
2
+ require 'attribute_struct'
3
+
4
+ class Configuration < AttributeStruct
5
+ end
@@ -1,6 +1,6 @@
1
1
  module Bogo
2
2
  class Config
3
3
  # Current library version
4
- VERSION = Gem::Version.new('0.1.0')
4
+ VERSION = Gem::Version.new('0.1.2')
5
5
  end
6
6
  end
data/lib/bogo-config.rb CHANGED
@@ -1,6 +1,5 @@
1
- require 'bogo-config/version'
2
1
  require 'bogo'
2
+ require 'bogo-config/config'
3
+ require 'bogo-config/version'
3
4
 
4
- module Bogo
5
- autoload :Config, 'bogo-config/config'
6
- end
5
+ autoload :Configuration, 'bogo-config/configuration'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bogo-config
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Roberts
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-29 00:00:00.000000000 Z
11
+ date: 2014-12-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bogo
@@ -79,6 +79,7 @@ files:
79
79
  - bogo-config.gemspec
80
80
  - lib/bogo-config.rb
81
81
  - lib/bogo-config/config.rb
82
+ - lib/bogo-config/configuration.rb
82
83
  - lib/bogo-config/version.rb
83
84
  homepage: https://github.com/spox/bogo-config
84
85
  licenses: