konfa 0.3.2 → 0.5.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 6fc9b3c14daca0a85ab0153ca8f0bc08f29b3b37ca2f525032fabf4b9b55d40b
4
+ data.tar.gz: c5825cb8c07354459a40d8e864b442a174c6ab9e45ec4d7c0d79f43ca5e6bce1
5
+ SHA512:
6
+ metadata.gz: 4b1cd2caf59b7cc337333226806bdca2160f6e195815b6e5b6d1ec7ae2c0e02c34126709ec54465d6e08be7e5f6aaada2ecbbe4147fa2ea61d03970dfa0bf24e
7
+ data.tar.gz: c3a89e3e6efad0221412e9d5a1a7cc5ccdd3c8479477caeb0e72639e80974a2860f9fa0db2326602d740da01749b662b0515f1207ebf7a9e0ef3eae0363c5caa
@@ -1,29 +1,49 @@
1
- # -*- coding: utf-8 -*-
2
- require 'yaml'
1
+ require_relative File.join(File.dirname(__FILE__), 'konfa', 'initializer')
2
+ require_relative File.join(File.dirname(__FILE__), 'konfa', 'deprecation')
3
3
 
4
4
  module Konfa
5
5
  class Base
6
+ include Konfa::Initializer
7
+ include Konfa::Deprecation
8
+
6
9
  class << self
10
+
11
+ private
12
+
13
+ def default_values
14
+ self.allowed_variables.each do |key, value|
15
+ if !value.nil? && !value.kind_of?(String)
16
+ deprecated "[DEPRECATION] default value for #{key} will be automatically stringified in future versions"
17
+ end
18
+ end
19
+
20
+ self.allowed_variables
21
+ end
22
+
7
23
  protected
8
24
 
9
25
  #
10
- # The following methods are not a part of the public API. You may sublcass
26
+ # The following methods are not a part of the public API. You may subclass
11
27
  # them, but remember that unless you scope them as protected or private,
12
28
  # they will then be public
13
29
  #
14
30
 
15
- attr_writer :configuration, :deferred, :initialized_deferred
31
+ attr_writer :configuration, :initializer, :initialized
16
32
 
17
- def initialized_deferred
18
- @initialized_deferred ||= false
33
+ # [DEPRECATED] This method will be removed in favor of initialized? in Konfa 1.0
34
+ def initialized
35
+ @initialized ||= false
19
36
  end
20
37
 
21
38
  def configuration
22
- @configuration ||= self.allowed_variables
39
+ self.init if self.initializer
40
+
41
+ @configuration ||= default_values
23
42
  end
24
43
 
25
- def deferred
26
- @deferred ||= nil
44
+ # [DEPRECATED] This attribute will be removed in Konfa 1.0
45
+ def initializer
46
+ @initializer ||= nil
27
47
  end
28
48
 
29
49
  def truthy?(value)
@@ -39,11 +59,6 @@ module Konfa
39
59
  end
40
60
  end
41
61
 
42
- def do_deferred_initialization
43
- self.send(self.deferred.first, *self.deferred[1..-1])
44
- self.initialized_deferred = true
45
- end
46
-
47
62
  public
48
63
 
49
64
  #
@@ -63,20 +78,20 @@ module Konfa
63
78
  raise UnsupportedVariableError.new(key)
64
79
  end
65
80
 
66
- def do_deferred_initialization?
67
- !self.initialized_deferred && !self.deferred.nil?
68
- end
69
-
70
81
  #
71
82
  # The following methods provides the interface to this class
72
83
  #
73
84
 
74
85
  def get(variable)
75
- self.do_deferred_initialization if self.do_deferred_initialization?
76
86
  raise UnsupportedVariableError.new(variable) unless self.configuration.has_key? variable
77
87
  self.configuration[variable]
78
88
  end
79
89
 
90
+ def get!(variable)
91
+ raise NilVariableError.new(variable) if self.get(variable).nil?
92
+ self.get(variable)
93
+ end
94
+
80
95
  def true?(variable)
81
96
  self.truthy?(self.get(variable))
82
97
  end
@@ -93,8 +108,51 @@ module Konfa
93
108
  self.configuration.dup
94
109
  end
95
110
 
96
- def initialize_deferred(method, *args)
97
- self.deferred = [method, *args]
111
+ def init?
112
+ deprecated "[DEPRECATION] init? will be removed in Konfa 1.0, use initialized? instead"
113
+ !self.initialized && !self.initializer.nil?
114
+ end
115
+
116
+ def init
117
+ deprecated "[DEPRECATION] This style of initialization will no longer be supported in Konfa 1.0 and init "\
118
+ "will be removed. Use initialize! or read_from/initialized! instead"
119
+ return unless self.init?
120
+ # Set to true before calling to prevent recursion if
121
+ # an initializer is accessing the configuration
122
+ self.initialized = true
123
+ self.send(self.initializer.first, *self.initializer[1..-1])
124
+ self.after_initialize
125
+ end
126
+
127
+ def init_with(suffix, *args)
128
+ deprecated "[DEPRECATION] init will be removed in Konfa 1.0. Use read_from instead"
129
+ self.initializer = [:"init_with_#{suffix}", *args]
130
+ self
131
+ end
132
+
133
+ def reinit
134
+ deprecated "[DEPRECATION] reinit will be removed in Konfa 1.0. Use read_from to load multiple config files"
135
+ self.initialized = false
136
+ end
137
+
138
+ def read_from(initializer, *args)
139
+ raise AlreadyInitializedError if self.initialized?
140
+ raise UnsupportedInitializerError unless self.respond_to?(:"init_with_#{initializer}")
141
+
142
+ self.send(:"init_with_#{initializer}", *args)
143
+ self
144
+ end
145
+
146
+ def initialize!
147
+ raise AlreadyInitializedError if self.initialized?
148
+
149
+ @initialized = true
150
+ self.after_initialize
151
+ self
152
+ end
153
+
154
+ def initialized?
155
+ @initialized == true
98
156
  end
99
157
 
100
158
  def after_initialize
@@ -113,46 +171,11 @@ module Konfa
113
171
  result
114
172
  end
115
173
 
116
- # FIXME: Move out to external package
117
- def initialize_from_yaml(path)
118
- # FIXME: It would be a lot cleaner if the YAML library would raise an
119
- # exception if it fails to read the file. We'll handle it like this for now
120
- # load_file just returns "false" if it fails
121
- yaml_data = YAML.load_file(path)
122
-
123
- unless yaml_data.nil?
124
- raise InitializationError.new("Bad YAML format, key/value pairs expected") unless yaml_data.kind_of?(Hash)
125
-
126
- yaml_data.each do |variable, value|
127
- self.store(variable, value)
128
- end
129
- end
130
-
131
- after_initialize
132
- dump
133
- end
134
-
135
- # FIXME: Move out to external package
136
- def initialize_from_env
137
- conf_prefix = self.env_variable_prefix.upcase
138
-
139
- ENV.keys.reject { |key|
140
- key !~ /^#{conf_prefix}/ # Ignore everything that doesn't match the prefix
141
- }.each { |key|
142
- variable = key[conf_prefix.size..-1].downcase
143
-
144
- self.store(variable, ENV[key])
145
- }
146
-
147
- after_initialize
148
- dump
149
- end
150
174
  end
151
175
  end
152
176
 
153
- class InitializationError < StandardError
154
- end
155
-
156
- class UnsupportedVariableError < StandardError
157
- end
177
+ class UnsupportedInitializerError < StandardError; end
178
+ class AlreadyInitializedError < StandardError; end
179
+ class UnsupportedVariableError < StandardError; end
180
+ class NilVariableError < StandardError; end
158
181
  end
@@ -0,0 +1,8 @@
1
+ require 'konfa/autodoc/parser'
2
+ require 'konfa/autodoc/formatter'
3
+ require 'konfa/autodoc/markdown'
4
+
5
+ module Konfa
6
+ module AutoDoc
7
+ end
8
+ end
@@ -0,0 +1,24 @@
1
+ module Konfa
2
+ module AutoDoc
3
+ class Formatter
4
+ attr_reader :konfa_class
5
+ attr_accessor :version
6
+
7
+ def initialize(const, version=nil)
8
+ @konfa_class = const
9
+ @version = version
10
+ end
11
+
12
+ def generate
13
+ autodoc = Konfa::AutoDoc::Parser.new(@konfa_class)
14
+ format(autodoc.parse)
15
+ end
16
+
17
+ def format(variables)
18
+ raise ImplementationMissing.new
19
+ end
20
+
21
+ class ImplementationMissing < StandardError; end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ module Konfa
2
+ module AutoDoc
3
+ class Markdown < Formatter
4
+ def format(variables)
5
+ md_lines = [header(konfa_class.name)]
6
+ md_lines << "*Version: #{version}*" unless version.nil?
7
+
8
+ variables.each do |variable|
9
+ md_lines << header(variable.name, 2)
10
+ md_lines << "Default: *#{variable.default}*"
11
+ md_lines << variable.comment unless variable.comment.nil?
12
+ end
13
+
14
+ md_lines.join("\n\n")
15
+ end
16
+
17
+ private
18
+
19
+ def header(text, level=1)
20
+ "#{'#' * level} #{text}"
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,66 @@
1
+ require "method_source"
2
+
3
+ module Konfa
4
+ module AutoDoc
5
+
6
+ Variable = Struct.new(:name, :default, :comment)
7
+
8
+ class Parser
9
+ attr_reader :variables, :konfa_class
10
+
11
+ def initialize(const)
12
+ @variables = []
13
+ @konfa_class = const
14
+ end
15
+
16
+ RE_VAR = /
17
+ (?:
18
+ :(\w+)\s*=> # 0: Old style hash key declaration - :key => 'value'
19
+ | # - or -
20
+ (\w+): # 1: New style hash key declaration - key: 'value'
21
+ )
22
+ \s*
23
+ (?:
24
+ (?:'|")(.+?)(?:'|") # 2: A string constant (FIXME: unless Backrefs to match leading and tailing quote)
25
+ | # - or -
26
+ ([\w\@\:\.]+) # 3: Bareword
27
+ )
28
+ \s*
29
+ ,? # - an optional comma -
30
+ \s*
31
+ (?:
32
+ \#\s*(.+?) # 4: An optional comment
33
+ (?=\n\s*(?: # Match all lines to next entry,
34
+ :\w+\s*=> # or end of hash declaraion. The lookahead
35
+ |\} # ensures we do not gobble up string for next match
36
+ |\w+:
37
+ ))
38
+ )?
39
+ /xm
40
+
41
+ def parse
42
+ @variables = []
43
+ code = @konfa_class.method(:allowed_variables).source
44
+ code.scan(RE_VAR).each do |tokens|
45
+ @variables << Variable.new(
46
+ tokens[0] || tokens[1],
47
+ tokens[2] || tokens[3],
48
+ trim_comment(tokens[4])
49
+ )
50
+ end
51
+
52
+ variables
53
+ end
54
+
55
+ private
56
+
57
+ def trim_comment(comment)
58
+ unless comment.nil?
59
+ comment.gsub!(/^\s*|\s*$/x, "") # The ^ and $ rather than \A and \Z anchors are intentional
60
+ comment.gsub!(/\n\#\s*/x, " ") # Not sure if we should perserve line breaks. We currenty do not. Can be fixed by using a zero width look-behind
61
+ end
62
+ comment
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,45 @@
1
+ module Konfa
2
+ module AutoDoc
3
+ module RSpec
4
+ shared_examples 'an Konfa::AutoDoc::Formatter subclass' do
5
+ let(:konfa_class) { double("KonfaClass") }
6
+
7
+ subject { described_class.new(konfa_class) }
8
+
9
+ it { is_expected.to be_kind_of Konfa::AutoDoc::Formatter }
10
+ it { is_expected.to respond_to :konfa_class }
11
+ it { is_expected.to respond_to :version }
12
+
13
+ it 'sets class as r/o accessor' do
14
+ expect(subject.konfa_class).to be konfa_class
15
+ end
16
+
17
+ it 'sets version as r/w accessor' do
18
+ expect(subject).to respond_to :version=
19
+ end
20
+
21
+ context '#generate' do
22
+ let(:autodoc_instance) { double }
23
+
24
+ before(:each) do
25
+ allow(Konfa::AutoDoc::Parser).to receive(:new).with(subject.konfa_class).and_return autodoc_instance
26
+ allow(subject).to receive(:format).and_return "something formatted"
27
+ allow(autodoc_instance).to receive(:parse).and_return "something parsed"
28
+ end
29
+
30
+ after(:each) do
31
+ subject.generate
32
+ end
33
+
34
+ it 'constructs a parser with konfa_class' do
35
+ expect(Konfa::AutoDoc::Parser).to receive(:new).with(subject.konfa_class).and_return autodoc_instance
36
+ end
37
+
38
+ it 'passes the parsed value to #format' do
39
+ expect(subject).to receive(:format).with("something parsed")
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,23 @@
1
+ module Konfa
2
+ module Deprecation
3
+ def self.included(base)
4
+ base.extend ClassMethods
5
+ end
6
+
7
+ module ClassMethods
8
+ @@deprecation_warnings = true
9
+
10
+ def deprecation_warnings=(val)
11
+ @@deprecation_warnings = val
12
+ end
13
+
14
+ def deprecation_warnings
15
+ @@deprecation_warnings
16
+ end
17
+
18
+ def deprecated(*args)
19
+ warn(*args) if @@deprecation_warnings
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,48 @@
1
+ require 'yaml'
2
+
3
+ module Konfa
4
+ module Initializer
5
+ def self.included(base)
6
+ base.extend ClassMethods
7
+ end
8
+
9
+ module ClassMethods
10
+ def init_with_yaml(*paths)
11
+ paths.each do |path|
12
+ # FIXME: It would be a lot cleaner if the YAML library would raise an
13
+ # exception if it fails to read the file. We'll handle it like this for now
14
+ # load_file just returns "false" if it fails
15
+ yaml_data = YAML.load_file(path)
16
+
17
+ unless yaml_data.nil?
18
+ raise Konfa::InitializationError.new("Bad YAML format, key/value pairs expected") unless yaml_data.kind_of?(Hash)
19
+
20
+ yaml_data.each do |variable, value|
21
+ self.store(variable, value)
22
+ end
23
+ end
24
+ end
25
+
26
+ dump
27
+ end
28
+
29
+ def init_with_env
30
+ conf_prefix = self.env_variable_prefix.upcase
31
+
32
+ ENV.keys.reject { |key|
33
+ key !~ /^#{conf_prefix}/ # Ignore everything that doesn't match the prefix
34
+ }.each { |key|
35
+ variable = key[conf_prefix.size..-1].downcase
36
+
37
+ self.store(variable, ENV[key])
38
+ }
39
+
40
+ dump
41
+ end
42
+ end
43
+
44
+ end
45
+
46
+ class InitializationError < StandardError
47
+ end
48
+ end
@@ -0,0 +1,38 @@
1
+ module Konfa
2
+ module RSpec
3
+ shared_context 'with konfa' do |klass|
4
+ before {
5
+ @konfa_klass = klass
6
+ @konfa_stubbed_klasses = []
7
+ }
8
+
9
+ def let_config(variable, value, use_klass=@konfa_klass)
10
+ raise Konfa::UnsupportedVariableError.new(variable) unless use_klass.allowed_variables.has_key?(variable)
11
+ raise Konfa::RSpec::BadValueError.new(value) unless value.kind_of?(String) || value.kind_of?(NilClass)
12
+
13
+ unless @konfa_stubbed_klasses.include?(use_klass)
14
+ allow(use_klass).to receive(:get).and_call_original
15
+ @konfa_stubbed_klasses << use_klass
16
+ end
17
+
18
+ allow(use_klass).to receive(:get).with(variable).and_return(value)
19
+ end
20
+
21
+ def with_config(variables, use_klass=@konfa_klass)
22
+ variables.each_pair do |var, val|
23
+ let_config(var, val, use_klass)
24
+ end
25
+ end
26
+ end
27
+
28
+ class BadValueError < StandardError
29
+ def initialize(msg)
30
+ @type = msg.class.name
31
+ end
32
+
33
+ def to_s
34
+ "Konfa requires values to be of type String (or NilClass), you passed #{@type}"
35
+ end
36
+ end
37
+ end
38
+ end
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: konfa
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
5
- prerelease:
4
+ version: 0.5.2
6
5
  platform: ruby
7
6
  authors:
8
7
  - Gunnar Hansson
@@ -10,8 +9,70 @@ authors:
10
9
  autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2014-11-06 00:00:00.000000000 Z
14
- dependencies: []
12
+ date: 2017-06-15 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: method_source
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '0.8'
21
+ - - "<="
22
+ - !ruby/object:Gem::Version
23
+ version: '1.0'
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: !ruby/object:Gem::Requirement
27
+ requirements:
28
+ - - ">="
29
+ - !ruby/object:Gem::Version
30
+ version: '0.8'
31
+ - - "<="
32
+ - !ruby/object:Gem::Version
33
+ version: '1.0'
34
+ - !ruby/object:Gem::Dependency
35
+ name: rake
36
+ requirement: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '12.0'
41
+ type: :development
42
+ prerelease: false
43
+ version_requirements: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '12.0'
48
+ - !ruby/object:Gem::Dependency
49
+ name: rspec
50
+ requirement: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.6'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.6'
62
+ - !ruby/object:Gem::Dependency
63
+ name: ruby_dep
64
+ requirement: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.3.1
69
+ type: :development
70
+ prerelease: false
71
+ version_requirements: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 1.3.1
15
76
  description: Helps you avoid common pitfalls when dealing with app config
16
77
  email: code@avidiy.se
17
78
  executables: []
@@ -19,29 +80,35 @@ extensions: []
19
80
  extra_rdoc_files: []
20
81
  files:
21
82
  - lib/konfa.rb
22
- homepage: http://github.com/avidity/konfa
83
+ - lib/konfa/autodoc.rb
84
+ - lib/konfa/autodoc/formatter.rb
85
+ - lib/konfa/autodoc/markdown.rb
86
+ - lib/konfa/autodoc/parser.rb
87
+ - lib/konfa/autodoc/rspec.rb
88
+ - lib/konfa/deprecation.rb
89
+ - lib/konfa/initializer.rb
90
+ - lib/konfa/rspec.rb
91
+ homepage: http://github.com/promoteinternational/konfa
23
92
  licenses:
24
93
  - MIT
94
+ metadata: {}
25
95
  post_install_message:
26
96
  rdoc_options: []
27
97
  require_paths:
28
98
  - lib
29
99
  required_ruby_version: !ruby/object:Gem::Requirement
30
- none: false
31
100
  requirements:
32
- - - ! '>='
101
+ - - ">="
33
102
  - !ruby/object:Gem::Version
34
103
  version: 1.9.3
35
104
  required_rubygems_version: !ruby/object:Gem::Requirement
36
- none: false
37
105
  requirements:
38
- - - ! '>='
106
+ - - ">="
39
107
  - !ruby/object:Gem::Version
40
108
  version: '0'
41
109
  requirements: []
42
- rubyforge_project:
43
- rubygems_version: 1.8.23
110
+ rubygems_version: 3.0.3
44
111
  signing_key:
45
- specification_version: 3
112
+ specification_version: 4
46
113
  summary: Application configuration
47
114
  test_files: []