simple-configurator 0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 12c6da130c9b8f8d3675e08fbc53ea1af2eb190e7e6d1012b69a7cb822a7af68
4
+ data.tar.gz: 697c77cb03524ea5bb760813d25b792298d6985a89e5c34c7dc8913fb048d6eb
5
+ SHA512:
6
+ metadata.gz: 86f195b7e0148f07aa7011bbf6ea778db92818330afc88d30c2c028646bbf474fffc0f31d9fcc4b6ce25fc4b9022d98ea28c06e920bdb5023fa20961b5ab00d4
7
+ data.tar.gz: 84a5022d547b2cfb1ea5c1c9a447e79307846b4f3c51816dd36acfa88fc1007a285b65b7b9125aeadb5b5960762d9f998ce657b630c6664262139744b767e3e7
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ .DS_Store
2
+ Gemfile.lock
3
+ *.gem
4
+ test/tmp
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 jslabovitz
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
data/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # Simple::Config
2
+
3
+ FIXME
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require 'simple-rake-tasks'
data/TODO.md ADDED
@@ -0,0 +1,2 @@
1
+ # TODO
2
+
@@ -0,0 +1,131 @@
1
+ require 'json'
2
+ require 'yaml'
3
+ require 'path'
4
+ require 'uri'
5
+
6
+ module Simple
7
+
8
+ class Configurator
9
+
10
+ class Error < StandardError; end
11
+
12
+ attr_accessor :parent
13
+ attr_accessor :fields
14
+ attr_accessor :data
15
+
16
+ def self.define(definitions)
17
+ fields = {}
18
+ data = definitions.map do |key, field|
19
+ field = Field.make(field)
20
+ fields[key] = field
21
+ [key, field.convert(field.default)]
22
+ end.to_h
23
+ new(fields: fields, data: data)
24
+ end
25
+
26
+ def initialize(parent: nil, fields:, data:)
27
+ @parent = parent
28
+ @fields = fields
29
+ @data = data.map do |key, value|
30
+ key = key.to_sym
31
+ field = @fields[key] or raise Error, "Unknown config key: #{key.inspect}"
32
+ [key, field.convert(value)]
33
+ end.to_h
34
+ end
35
+
36
+ def load(file)
37
+ data = File.read(file)
38
+ json = JSON.parse(data, symbolize_names: true)
39
+ make(**json)
40
+ end
41
+
42
+ def load_yaml(file)
43
+ yaml = YAML.load_file(file, permitted_classes: [Date, Symbol])
44
+ make(**yaml)
45
+ end
46
+
47
+ def make(**data)
48
+ self.class.new(parent: self, fields: @fields, data: data)
49
+ end
50
+
51
+ def as_json(*opts)
52
+ @data.compact
53
+ end
54
+
55
+ def to_json(*opts)
56
+ as_json.to_json(*opts)
57
+ end
58
+
59
+ def to_h
60
+ (@parent&.to_h || {}).merge(@data)
61
+ end
62
+
63
+ def save(file)
64
+ File.write(file, JSON.pretty_generate(self))
65
+ end
66
+
67
+ def method_missing(id, *args)
68
+ key = id.to_s.sub(/=$/, '').to_sym
69
+ field = @fields[key] or return super
70
+ if $&
71
+ @data[key] = args.first
72
+ elsif @data.has_key?(key)
73
+ @data[key]
74
+ elsif @parent
75
+ @parent.send(key)
76
+ else
77
+ super
78
+ end
79
+ end
80
+
81
+ class Field
82
+
83
+ attr_accessor :default
84
+ attr_accessor :converter
85
+
86
+ def self.make(obj)
87
+ case obj
88
+ when nil
89
+ new
90
+ when Proc
91
+ new(converter: obj)
92
+ when Hash
93
+ new(**obj)
94
+ when Field
95
+ obj
96
+ else
97
+ new(default: obj)
98
+ end
99
+ end
100
+
101
+ def initialize(default: nil, converter: nil)
102
+ @default = default
103
+ @converter = converter
104
+ end
105
+
106
+ def convert(value)
107
+ if value.nil?
108
+ nil
109
+ else
110
+ case @converter
111
+ when :path
112
+ Path.new(value)
113
+ when :date
114
+ value.kind_of?(Date) ? value : Date.parse(value)
115
+ when :uri
116
+ value.kind_of?(URI) ? value : URI.parse(value)
117
+ when :symbol
118
+ value.to_sym
119
+ when Proc
120
+ @converter.call(value)
121
+ else
122
+ value
123
+ end
124
+ end
125
+ end
126
+
127
+ end
128
+
129
+ end
130
+
131
+ end
@@ -0,0 +1,23 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'simple-configurator'
3
+ s.version = '0.2'
4
+ s.summary = 'simple hierarchical configuration object'
5
+ s.author = 'John Labovitz'
6
+ s.email = 'johnl@johnlabovitz.com'
7
+ s.description = %q{
8
+ A simple hierarchical configuration object.
9
+ }
10
+ s.homepage = 'http://github.com/jslabovitz/simple-configurator'
11
+ s.license = 'MIT'
12
+ s.files = `git ls-files`.split("\n")
13
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
15
+ s.require_path = 'lib'
16
+
17
+ s.add_dependency 'path', '~> 2.1'
18
+
19
+ s.add_development_dependency 'minitest', '~> 5.26'
20
+ s.add_development_dependency 'minitest-power_assert', '~> 0.3'
21
+ s.add_development_dependency 'rake', '~> 13.3'
22
+ s.add_development_dependency 'simple-rake-tasks', '~> 0.1'
23
+ end
data/test/config.json ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ "a": 11,
3
+ "b": 22
4
+ }
@@ -0,0 +1,73 @@
1
+ $VERBOSE = false
2
+
3
+ require 'minitest/autorun'
4
+ require 'minitest/power_assert'
5
+
6
+ $LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
7
+ require 'simple-configurator'
8
+
9
+ class SimpleConfiguratorTest < Minitest::Test
10
+
11
+ def setup
12
+ @base_config = Simple::Configurator.define(
13
+ a: { default: 1 },
14
+ b: { default: 2, converter: proc { |o| Integer(o) } },
15
+ c: nil,
16
+ d: nil,
17
+ )
18
+ @config1 = @base_config.make
19
+ @config2 = @config1.make(b: '22', c: 3)
20
+ @config3 = @config2.make(d: 4)
21
+ end
22
+
23
+ def test_config
24
+ assert { @config1.a == 1 }
25
+ assert { @config1.b == 2 }
26
+ assert { @config1.c == nil }
27
+ assert { @config1.d == nil }
28
+
29
+ assert { @config2.a == 1 }
30
+ assert { @config2.b == 22 }
31
+ assert { @config2.c == 3 }
32
+ assert { @config2.d == nil }
33
+
34
+ assert { @config3.a == 1 }
35
+ assert { @config3.b == 22 }
36
+ assert { @config3.c == 3 }
37
+ assert { @config3.d == 4 }
38
+ end
39
+
40
+ def test_load
41
+ file = 'test/config.json'
42
+ config = @base_config.load(file)
43
+ assert { config.a == 11 }
44
+ assert { config.b == 22 }
45
+ end
46
+
47
+ def test_save
48
+ file = 'test/tmp/config.json'
49
+ FileUtils.mkpath(File.dirname(file))
50
+ File.unlink(file) if File.exist?(file)
51
+ @base_config.save(file)
52
+ config = @base_config.load(file)
53
+ assert { config.a == 1 }
54
+ assert { config.b == 2 }
55
+ end
56
+
57
+ def test_set
58
+ @base_config.d = 4
59
+ assert { @base_config.d == 4 }
60
+ end
61
+
62
+ def test_types
63
+ config = Simple::Configurator.define(
64
+ uri: { default: 'http://localhost', converter: :uri },
65
+ sym: { default: 'a', converter: :symbol },
66
+ path: { default: 'a/b/c', converter: :path },
67
+ )
68
+ assert { config.uri.kind_of?(URI) }
69
+ assert { config.sym == :a }
70
+ assert { config.path == Path.new('a/b/c') }
71
+ end
72
+
73
+ end
metadata ADDED
@@ -0,0 +1,120 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: simple-configurator
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.2'
5
+ platform: ruby
6
+ authors:
7
+ - John Labovitz
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: path
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '2.1'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '2.1'
26
+ - !ruby/object:Gem::Dependency
27
+ name: minitest
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '5.26'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '5.26'
40
+ - !ruby/object:Gem::Dependency
41
+ name: minitest-power_assert
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '0.3'
47
+ type: :development
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '0.3'
54
+ - !ruby/object:Gem::Dependency
55
+ name: rake
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '13.3'
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '13.3'
68
+ - !ruby/object:Gem::Dependency
69
+ name: simple-rake-tasks
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '0.1'
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '0.1'
82
+ description: "\n A simple hierarchical configuration object.\n "
83
+ email: johnl@johnlabovitz.com
84
+ executables: []
85
+ extensions: []
86
+ extra_rdoc_files: []
87
+ files:
88
+ - ".gitignore"
89
+ - LICENSE
90
+ - README.md
91
+ - Rakefile
92
+ - TODO.md
93
+ - lib/simple-configurator.rb
94
+ - simple-configurator.gemspec
95
+ - test/config.json
96
+ - test/config_test.rb
97
+ homepage: http://github.com/jslabovitz/simple-configurator
98
+ licenses:
99
+ - MIT
100
+ metadata: {}
101
+ rdoc_options: []
102
+ require_paths:
103
+ - lib
104
+ required_ruby_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ requirements: []
115
+ rubygems_version: 3.7.2
116
+ specification_version: 4
117
+ summary: simple hierarchical configuration object
118
+ test_files:
119
+ - test/config.json
120
+ - test/config_test.rb