konfa 0.3.1 → 0.5.1

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: '019c8e91eccb651e1797bd4f14936e7e993d90cf41da39315c0756a6f9edc337'
4
+ data.tar.gz: b9cd987595b57b4747dc147f565f91fa435669ca0b84db275f2f69ff5c6b9f41
5
+ SHA512:
6
+ metadata.gz: 28ec3dd4747fd0f64f2ea7cca123b014a31701d2667ada2240f2a5dbc319ba21321bf2e25d2dc92a85f2bc5246ca2fd5d9d9e1453daa26decc4e4a1d3099e713
7
+ data.tar.gz: 4d94c094df739eea1c0f90b82f0329f95cba20f2048500216a5eaafd6878c5841f575697c84f80196e15548b780f4861b92d43c5dc6a3398def760b0c5fae66a
@@ -1,29 +1,48 @@
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
40
+ @configuration ||= default_values
23
41
  end
24
42
 
25
- def deferred
26
- @deferred ||= nil
43
+ # [DEPRECATED] This attribute will be removed in Konfa 1.0
44
+ def initializer
45
+ @initializer ||= nil
27
46
  end
28
47
 
29
48
  def truthy?(value)
@@ -39,11 +58,6 @@ module Konfa
39
58
  end
40
59
  end
41
60
 
42
- def do_deferred_initialization
43
- self.send(self.deferred.first, *self.deferred[1..-1])
44
- self.initialized_deferred = true
45
- end
46
-
47
61
  public
48
62
 
49
63
  #
@@ -63,20 +77,20 @@ module Konfa
63
77
  raise UnsupportedVariableError.new(key)
64
78
  end
65
79
 
66
- def do_deferred_initialization?
67
- !self.initialized_deferred && !self.deferred.nil?
68
- end
69
-
70
80
  #
71
81
  # The following methods provides the interface to this class
72
82
  #
73
83
 
74
84
  def get(variable)
75
- self.do_deferred_initialization if self.do_deferred_initialization?
76
85
  raise UnsupportedVariableError.new(variable) unless self.configuration.has_key? variable
77
86
  self.configuration[variable]
78
87
  end
79
88
 
89
+ def get!(variable)
90
+ raise NilVariableError.new(variable) if self.get(variable).nil?
91
+ self.get(variable)
92
+ end
93
+
80
94
  def true?(variable)
81
95
  self.truthy?(self.get(variable))
82
96
  end
@@ -93,8 +107,51 @@ module Konfa
93
107
  self.configuration.dup
94
108
  end
95
109
 
96
- def initialize_deferred(method, *args)
97
- self.deferred = [method, *args]
110
+ def init?
111
+ deprecated "[DEPRECATION] init? will be removed in Konfa 1.0, use initialized? instead"
112
+ !self.initialized && !self.initializer.nil?
113
+ end
114
+
115
+ def init
116
+ deprecated "[DEPRECATION] This style of initialization will no longer be supported in Konfa 1.0 and init "\
117
+ "will be removed. Use initialize! or read_from/initialized! instead"
118
+ return unless self.init?
119
+ # Set to true before calling to prevent recursion if
120
+ # an initializer is accessing the configuration
121
+ self.initialized = true
122
+ self.send(self.initializer.first, *self.initializer[1..-1])
123
+ self.after_initialize
124
+ end
125
+
126
+ def init_with(suffix, *args)
127
+ deprecated "[DEPRECATION] init will be removed in Konfa 1.0. Use read_from instead"
128
+ self.initializer = [:"init_with_#{suffix}", *args]
129
+ self
130
+ end
131
+
132
+ def reinit
133
+ deprecated "[DEPRECATION] reinit will be removed in Konfa 1.0. Use read_from to load multiple config files"
134
+ self.initialized = false
135
+ end
136
+
137
+ def read_from(initializer, *args)
138
+ raise AlreadyInitializedError if self.initialized?
139
+ raise UnsupportedInitializerError unless self.respond_to?(:"init_with_#{initializer}")
140
+
141
+ self.send(:"init_with_#{initializer}", *args)
142
+ self
143
+ end
144
+
145
+ def initialize!
146
+ raise AlreadyInitializedError if self.initialized?
147
+
148
+ @initialized = true
149
+ self.after_initialize
150
+ self
151
+ end
152
+
153
+ def initialized?
154
+ @initialized == true
98
155
  end
99
156
 
100
157
  def after_initialize
@@ -113,46 +170,11 @@ module Konfa
113
170
  result
114
171
  end
115
172
 
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
173
  end
151
174
  end
152
175
 
153
- class InitializationError < StandardError
154
- end
155
-
156
- class UnsupportedVariableError < StandardError
157
- end
176
+ class UnsupportedInitializerError < StandardError; end
177
+ class AlreadyInitializedError < StandardError; end
178
+ class UnsupportedVariableError < StandardError; end
179
+ class NilVariableError < StandardError; end
158
180
  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.1
5
- prerelease:
4
+ version: 0.5.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Gunnar Hansson
@@ -10,8 +9,64 @@ 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
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '0.8'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rake
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '12.0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '12.0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rspec
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '3.6'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '3.6'
56
+ - !ruby/object:Gem::Dependency
57
+ name: ruby_dep
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: 1.3.1
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: 1.3.1
15
70
  description: Helps you avoid common pitfalls when dealing with app config
16
71
  email: code@avidiy.se
17
72
  executables: []
@@ -19,29 +74,35 @@ extensions: []
19
74
  extra_rdoc_files: []
20
75
  files:
21
76
  - lib/konfa.rb
22
- homepage: http://github.com/avidity/konfa
77
+ - lib/konfa/autodoc.rb
78
+ - lib/konfa/autodoc/formatter.rb
79
+ - lib/konfa/autodoc/markdown.rb
80
+ - lib/konfa/autodoc/parser.rb
81
+ - lib/konfa/autodoc/rspec.rb
82
+ - lib/konfa/deprecation.rb
83
+ - lib/konfa/initializer.rb
84
+ - lib/konfa/rspec.rb
85
+ homepage: http://github.com/promoteinternational/konfa
23
86
  licenses:
24
87
  - MIT
88
+ metadata: {}
25
89
  post_install_message:
26
90
  rdoc_options: []
27
91
  require_paths:
28
92
  - lib
29
93
  required_ruby_version: !ruby/object:Gem::Requirement
30
- none: false
31
94
  requirements:
32
- - - ! '>='
95
+ - - ">="
33
96
  - !ruby/object:Gem::Version
34
97
  version: 1.9.3
35
98
  required_rubygems_version: !ruby/object:Gem::Requirement
36
- none: false
37
99
  requirements:
38
- - - ! '>='
100
+ - - ">="
39
101
  - !ruby/object:Gem::Version
40
102
  version: '0'
41
103
  requirements: []
42
- rubyforge_project:
43
- rubygems_version: 1.8.23
104
+ rubygems_version: 3.0.3
44
105
  signing_key:
45
- specification_version: 3
106
+ specification_version: 4
46
107
  summary: Application configuration
47
108
  test_files: []