comfy_conf 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9e0e373dda41050a755c862f826b3f0a681ffa8f
4
+ data.tar.gz: 52d592f2888035caae394a6cdc7b41b52de02096
5
+ SHA512:
6
+ metadata.gz: f01dedb534b517c230942ca21d31ed683e5642f179c5858b1bc305bd6eba840a54f508ee8aceb7b0ce84964705819970851278121bb2ba14a1030205de3d19f6
7
+ data.tar.gz: 3e3821acda836b701e97a5a133248c7f9fe0c0a45c84ee4d38c364b17418f3042eb6903cfe7dbd79ada4dd299a9d72090e8f259c495c7dbefa3715fb43eb2e01
@@ -0,0 +1,59 @@
1
+ module ComfyConf
2
+ class Checker
3
+ def initialize(definition, given_prefix, data)
4
+ @definition, @given_prefix, @data = definition, given_prefix, data
5
+ end
6
+ attr_reader :definition, :data
7
+
8
+ def check
9
+ definition.props.each {|p| check_prop(p) }
10
+ definition.configs.each {|c| check_config(c) }
11
+ end
12
+
13
+ def prefix
14
+ given_prefix
15
+ end
16
+
17
+ private
18
+ attr_reader :given_prefix
19
+
20
+ def check_config(config)
21
+ if config.required and not valid_section(config)
22
+ raise MissingSection, "Expected configuration #{prefix} to contain "\
23
+ "section #{config.name} but it does not" \
24
+ end
25
+ end
26
+
27
+ def valid_section(config)
28
+ data[config.name] and data[config.name].kind_of?(Hash)
29
+ end
30
+
31
+ def check_prop(prop)
32
+ ensure_present(prop) if prop.required
33
+ ensure_type(prop) if data[prop]
34
+ end
35
+
36
+ def ensure_type(prop)
37
+ if not data[prop.name].kind_of?(prop.type)
38
+ raise InvalidOption, "Expect type #{prop.type} for "\
39
+ "configuration property #{prefixed_name(prop)}, "\
40
+ "got #{data[prop.name].class}"
41
+ end
42
+ end
43
+
44
+ def ensure_present(prop)
45
+ if not data[prop.name]
46
+ raise MissingOption,
47
+ "Configuration property #{prefixed_name(prop)} is required!"
48
+ end
49
+ end
50
+
51
+ def prefixed_name(prop)
52
+ if prefix
53
+ "#{prefix}[#{prop.name}]"
54
+ else
55
+ prop.name
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,44 @@
1
+ module ComfyConf
2
+ class Data
3
+ def initialize(prefix, definition, data)
4
+ @prefix, @definition, @data = prefix, definition, data
5
+ load
6
+ end
7
+ attr_reader :data, :definition, :prefix
8
+
9
+ def name
10
+ definition.name
11
+ end
12
+
13
+ private
14
+
15
+ def load
16
+ definition.check_data(full_name, data)
17
+ define_accessors
18
+ end
19
+
20
+ def full_name
21
+ if prefix
22
+ "#{prefix}[#{definition.name}]"
23
+ else
24
+ definition.name
25
+ end
26
+ end
27
+
28
+ def child_configs
29
+ @child_configs ||= definition.configs.map do |config|
30
+ Data.new full_name, config, @data[config.name]
31
+ end
32
+ end
33
+
34
+ def define_accessors
35
+ definition.props.each do |prop|
36
+ define_singleton_method(prop.name) { data[prop.name] }
37
+ end
38
+
39
+ child_configs.each do |config|
40
+ define_singleton_method(config.name) { config }
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,28 @@
1
+ require 'comfy_conf/checker'
2
+
3
+ module ComfyConf
4
+ class Definition
5
+ Prop = Struct.new(:name, :type, :required)
6
+
7
+ def initialize(name, required: false, &block)
8
+ @name = name.to_s
9
+ @required = required
10
+ @props = Array.new
11
+ @configs = Array.new
12
+ instance_eval(&block) if block
13
+ end
14
+ attr_reader :props, :configs, :name, :required
15
+
16
+ def prop(name, type:, required: false)
17
+ props.push Prop.new(name.to_s, type, required)
18
+ end
19
+
20
+ def config(name, required: false, &block)
21
+ configs.push Definition.new(name, required: required, &block)
22
+ end
23
+
24
+ def check_data(prefix, data)
25
+ Checker.new(self, prefix, data).check
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,34 @@
1
+ require 'pathname'
2
+ require 'yaml'
3
+ require 'comfy_conf/definition'
4
+ require 'comfy_conf/data'
5
+
6
+ module ComfyConf
7
+ class Parser
8
+ def initialize(pathname, &block)
9
+ @pathname = Pathname.new(pathname)
10
+ @definition = Definition.new('root', &block)
11
+ end
12
+ attr_reader :pathname, :definition
13
+
14
+ def data
15
+ @data ||= Data.new(nil, definition, type_checked_config_data)
16
+ end
17
+
18
+ private
19
+
20
+ def type_checked_config_data
21
+ unless config_data.kind_of?(Hash)
22
+ raise ParseError, "YAML config data must be a hash. File: #{pathname}"
23
+ end
24
+ config_data
25
+ end
26
+
27
+ def config_data
28
+ @config_data ||= YAML.load(pathname.read)
29
+ rescue Psych::SyntaxError => e
30
+ raise ParseError,
31
+ "YAML parse error in config file #{pathname}: #{e.message}"
32
+ end
33
+ end
34
+ end
data/lib/comfy_conf.rb ADDED
@@ -0,0 +1,9 @@
1
+ module ComfyConf
2
+ Error = Class.new(StandardError)
3
+ InvalidOption = Class.new(Error)
4
+ MissingOption = Class.new(Error)
5
+ MissingSection = Class.new(Error)
6
+ ParseError = Class.new(Error)
7
+ end
8
+
9
+ require 'comfy_conf/parser'
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: comfy_conf
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.0
5
+ platform: ruby
6
+ authors:
7
+ - Jack Forrest
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-01-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.0'
27
+ description: 'ComfyConf provides a minimal DSL for parsing YAML config files into
28
+ a structured and type-checked configuration '
29
+ email: jack@jrforrest.net
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - "./lib/comfy_conf.rb"
35
+ - "./lib/comfy_conf/checker.rb"
36
+ - "./lib/comfy_conf/data.rb"
37
+ - "./lib/comfy_conf/definition.rb"
38
+ - "./lib/comfy_conf/parser.rb"
39
+ homepage: http://github.com/jrforrest/comfy_conf
40
+ licenses:
41
+ - MIT
42
+ metadata: {}
43
+ post_install_message:
44
+ rdoc_options: []
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ requirements: []
58
+ rubyforge_project:
59
+ rubygems_version: 2.5.1
60
+ signing_key:
61
+ specification_version: 4
62
+ summary: A YAML configuration parser
63
+ test_files: []