konfa 0.3.2 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []