king_konf 0.1.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: 6744213f0b37e03068723d66aed90974aaa0674d
4
+ data.tar.gz: 8e425438c7a1d649754dbaf913888032adfbd7c3
5
+ SHA512:
6
+ metadata.gz: 1934dbad4faea5353f43a376f11e58ebbef4347298615210888508d16ead83e3473bb757efdc3ff56ffcacfb5a93f04c8eb5fa63224d36d5dfc434b55740794f
7
+ data.tar.gz: ad7c4aa1ac20152f3afc4399402f9774a75ac2bdbb89c41cbdc9e5a1efb97ade303d83d7cb764a7e4673275566d038db044da55f96ec623bb79ad0579367ed1b
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+
11
+ # rspec failure tracking
12
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in king_konf.gemspec
6
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Daniel Schierbeck
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
13
+ all 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
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,88 @@
1
+ # KingKonf
2
+
3
+ KingKonf gives you a way of declaratively specifying configuration variables for your application or library. It is focused on simplicity and being able to work well with environment variables, meaning that there is no nesting or fancy structures: all configuration can be passed as strings.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'king_konf'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install king_konf
20
+
21
+ ## Usage
22
+
23
+ In order to specify a set configuration variables, simply subclass `KingKonf::Config` and use the DSL:
24
+
25
+ ```ruby
26
+ require "king_konf"
27
+
28
+ class MyApplication::Config < KingKonf::Config
29
+ # The prefix is used to identify environment variables. Here, we require
30
+ # that all environment variables used for config start with `MY_APP_`,
31
+ # followed by the all caps name of the variable.
32
+ prefix :my_app
33
+
34
+ # Strings are the simplest:
35
+ string :title
36
+
37
+ # Integer variables require the value to be a valid integer:
38
+ integer :score
39
+
40
+ # Booleans by default use "true", "false", "1", and "0" as valid values:
41
+ boolean :promoted
42
+
43
+ # These can be configured:
44
+ boolean :allow_comments, true_values: ["yes"], false_values: ["no"]
45
+
46
+ # Lists are by default comma-separated arrays of strings:
47
+ list :tags
48
+
49
+ # You can separate with other characters, and decode each value as another type:
50
+ list :codes, sep: ";", items: :integer
51
+
52
+ # You can also provide a default value to any variable:
53
+ string :body, default: "N/A"
54
+ end
55
+ ```
56
+
57
+ Now that we've defined a configuration class, we can initialize it. KingKonf will read the ENV and detect any variables that match the prefix:
58
+
59
+ ```ruby
60
+ # These would normally be passed by the system running your app:
61
+ ENV["MY_APP_TITLE"] = "Hello, World!"
62
+ ENV["MY_APP_SCORE"] = "85"
63
+ ENV["MY_APP_PROMOTED"] = "true"
64
+ ENV["MY_APP_ALLOW_COMMENTS"] = "no"
65
+ ENV["MY_APP_TAGS"] = "greetings,introductions,articles"
66
+ ENV["MY_APP_CODES"] = "435;2342;8678"
67
+
68
+ config = MyApplication::Config.new
69
+
70
+ config.title #=> "Hello, World!"
71
+ config.score #=> 85
72
+ config.promoted #=> true
73
+ config.allow_comments #=> false
74
+ config.tags #=> ["greetings", "introductions", "articles"]
75
+ config.codes #=> [435, 2342, 8678]
76
+ ```
77
+
78
+ ## Development
79
+
80
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
81
+
82
+ ## Contributing
83
+
84
+ Bug reports and pull requests are welcome on GitHub at https://github.com/dasch/king_konf.
85
+
86
+ ## License
87
+
88
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "king_konf"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/king_konf.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "king_konf/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "king_konf"
8
+ spec.version = KingKonf::VERSION
9
+ spec.authors = ["Daniel Schierbeck"]
10
+ spec.email = ["daniel.schierbeck@gmail.com"]
11
+
12
+ spec.summary = "A simple configuration library"
13
+ spec.description = "A simple configuration library"
14
+ spec.homepage = "https://github.com/dasch/king_konf"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(test|spec|features)/})
19
+ end
20
+
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.15"
24
+ spec.add_development_dependency "rake", "~> 10.0"
25
+ spec.add_development_dependency "rspec", "~> 3.0"
26
+ end
@@ -0,0 +1,154 @@
1
+ require "king_konf/config_file_loader"
2
+
3
+ module KingKonf
4
+ class Decoder
5
+ def self.boolean(value, true_values: ["true", "1"], false_values: ["false", "0"])
6
+ if true_values.include?(value)
7
+ true
8
+ elsif false_values.include?(value)
9
+ false
10
+ else
11
+ values = true_values + false_values
12
+ raise ConfigError, "#{value.inspect} is not a boolean: must be one of #{values.join(', ')}"
13
+ end
14
+ end
15
+
16
+ def self.string(value, **)
17
+ value
18
+ end
19
+
20
+ def self.list(value, sep: ",", items: :string)
21
+ value.split(sep).map {|s| public_send(items, s) }
22
+ end
23
+
24
+ def self.integer(value, **)
25
+ Integer(value)
26
+ rescue ArgumentError
27
+ raise ConfigError, "#{value.inspect} is not an integer"
28
+ end
29
+ end
30
+
31
+ class Variable
32
+ attr_reader :name, :type, :default, :options
33
+
34
+ def initialize(name, type, default, options)
35
+ @name, @type, @default = name, type, default
36
+ @options = options
37
+ end
38
+
39
+ def valid?(value)
40
+ case @type
41
+ when :string then value.is_a?(String)
42
+ when :list then value.is_a?(Array)
43
+ when :integer then value.is_a?(Integer)
44
+ when :boolean then value == true || value == false
45
+ else raise "invalid type #{@type}"
46
+ end
47
+ end
48
+
49
+ def decode(value)
50
+ Decoder.public_send(@type, value, **options)
51
+ end
52
+ end
53
+
54
+ class Config
55
+ @variables = {}
56
+
57
+ class << self
58
+ def prefix(prefix = nil)
59
+ @prefix = prefix if prefix
60
+ @prefix
61
+ end
62
+
63
+ def variable(name)
64
+ @variables.fetch(name.to_s)
65
+ end
66
+
67
+ def variable?(name)
68
+ @variables.key?(name.to_s)
69
+ end
70
+
71
+ def variables
72
+ @variables.values
73
+ end
74
+
75
+ %i(boolean integer string list).each do |type|
76
+ define_method(type) do |name, default: nil, **options|
77
+ variable = Variable.new(name, type, default, options)
78
+
79
+ @variables ||= {}
80
+ @variables[name.to_s] = variable
81
+
82
+ define_method(name) do
83
+ get(name)
84
+ end
85
+
86
+ define_method("#{name}=") do |value|
87
+ set(name, value)
88
+ end
89
+ end
90
+ end
91
+ end
92
+
93
+ def initialize(env: ENV)
94
+ load_env(env)
95
+ end
96
+
97
+ def load_file(path, environment)
98
+ loader = ConfigFileLoader.new(self)
99
+ loader.load_file(path, environment)
100
+ end
101
+
102
+ def get(name)
103
+ if value = instance_variable_get("@#{name}")
104
+ value
105
+ else
106
+ variable = self.class.variable(name)
107
+ variable.default
108
+ end
109
+ end
110
+
111
+ def set(name, value)
112
+ unless self.class.variable?(name)
113
+ raise ConfigError, "unknown configuration variable #{name}"
114
+ end
115
+
116
+ variable = self.class.variable(name)
117
+
118
+ if variable.valid?(value)
119
+ instance_variable_set("@#{name}", value)
120
+ else
121
+ raise ConfigError, "invalid value #{value.inspect}, expected #{variable.type}"
122
+ end
123
+ end
124
+
125
+ private
126
+
127
+ def load_config(config)
128
+ config.each do |variable, value|
129
+ set(variable, value)
130
+ end
131
+ end
132
+
133
+ def load_env(env)
134
+ loaded_keys = []
135
+ prefix = self.class.prefix || ""
136
+
137
+ self.class.variables.each do |variable|
138
+ key = "#{prefix.upcase}_#{variable.name.upcase}"
139
+
140
+ if string = env[key]
141
+ value = variable.decode(string)
142
+ set(variable.name, value)
143
+ loaded_keys << key
144
+ end
145
+ end
146
+
147
+ env.keys.grep(/^#{prefix.upcase}_/).each do |key|
148
+ unless loaded_keys.include?(key)
149
+ raise ConfigError, "unknown env variable #{key}"
150
+ end
151
+ end
152
+ end
153
+ end
154
+ end
@@ -0,0 +1,23 @@
1
+ require "erb"
2
+ require "yaml"
3
+
4
+ module KingKonf
5
+ class ConfigFileLoader
6
+ def initialize(config)
7
+ @config = config
8
+ end
9
+
10
+ def load_file(path, environment)
11
+ # First, load the ERB template from disk.
12
+ template = ERB.new(File.new(path).read)
13
+
14
+ # The last argument to `safe_load` allows us to use aliasing to share
15
+ # configuration between environments.
16
+ processed = YAML.safe_load(template.result(binding), [], [], true)
17
+
18
+ processed.fetch(environment).each do |variable, value|
19
+ @config.set(variable, value)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,3 @@
1
+ module KingKonf
2
+ VERSION = "0.1.0"
3
+ end
data/lib/king_konf.rb ADDED
@@ -0,0 +1,6 @@
1
+ require "king_konf/version"
2
+ require "king_konf/config"
3
+
4
+ module KingKonf
5
+ ConfigError = Class.new(StandardError)
6
+ end
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: king_konf
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Daniel Schierbeck
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-09-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.15'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.15'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ description: A simple configuration library
56
+ email:
57
+ - daniel.schierbeck@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".rspec"
64
+ - Gemfile
65
+ - LICENSE.txt
66
+ - README.md
67
+ - Rakefile
68
+ - bin/console
69
+ - bin/setup
70
+ - king_konf.gemspec
71
+ - lib/king_konf.rb
72
+ - lib/king_konf/config.rb
73
+ - lib/king_konf/config_file_loader.rb
74
+ - lib/king_konf/version.rb
75
+ homepage: https://github.com/dasch/king_konf
76
+ licenses:
77
+ - MIT
78
+ metadata: {}
79
+ post_install_message:
80
+ rdoc_options: []
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ requirements: []
94
+ rubyforge_project:
95
+ rubygems_version: 2.4.5.1
96
+ signing_key:
97
+ specification_version: 4
98
+ summary: A simple configuration library
99
+ test_files: []