konfig 0.1.0

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,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,22 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
22
+ .yardoc
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Starr Horne
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,43 @@
1
+ = konfig: Config file management for rails apps
2
+
3
+ Every app needs to store seldom-changing data like facebook access keys, or
4
+ SMTP settings, or Authorize.net credentials.
5
+
6
+ Usually, you just stick it in an intializer. Or if you're feeling really
7
+ sassy, you might make a yml file and create an initializer to load it.
8
+ It's kind of a pain, and it's kind of messy.
9
+
10
+ Konfig gives you a better, easier way to manage these config files.
11
+
12
+ == Overview
13
+
14
+ It works like this:
15
+
16
+ > mkidr ./config/settings
17
+ > cat "bar: baz" > ./config/settings/foo.yml
18
+ > rails console
19
+
20
+ irb(main):001:0> Konfig[:foo][:bar]
21
+
22
+ => "baz"
23
+
24
+
25
+ Konfig automagically loads all .yml files in the
26
+ RAILS_ROOT/config/settings directory. It makes them
27
+ accessible via the Konfig module. ie. Konfig[:filename][:key]
28
+
29
+ Note: Konfig only works with Rails 3
30
+
31
+ == Note on Patches/Pull Requests
32
+
33
+ * Fork the project.
34
+ * Make your feature addition or bug fix.
35
+ * Add tests for it. This is important so I don't break it in a
36
+ future version unintentionally.
37
+ * Commit, do not mess with rakefile, version, or history.
38
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
39
+ * Send me a pull request. Bonus points for topic branches.
40
+
41
+ == Copyright
42
+
43
+ Copyright (c) 2010 Starr Horne. See LICENSE for details.
@@ -0,0 +1,53 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "konfig"
8
+ gem.summary = %Q{Configuration manager for rails apps}
9
+ gem.description = %Q{So you need to store some static config values in your app? Konfig does that.}
10
+ gem.email = "starr@chromahq.com"
11
+ gem.homepage = "http://github.com/starrhorne/konfig"
12
+ gem.authors = ["Starr Horne"]
13
+ gem.add_development_dependency "shoulda", ">= 0"
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
19
+ end
20
+
21
+ require 'rake/testtask'
22
+ Rake::TestTask.new(:test) do |test|
23
+ test.libs << 'lib' << 'test'
24
+ test.pattern = 'test/**/test_*.rb'
25
+ test.verbose = true
26
+ end
27
+
28
+ begin
29
+ require 'rcov/rcovtask'
30
+ Rcov::RcovTask.new do |test|
31
+ test.libs << 'test'
32
+ test.pattern = 'test/**/test_*.rb'
33
+ test.verbose = true
34
+ end
35
+ rescue LoadError
36
+ task :rcov do
37
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
38
+ end
39
+ end
40
+
41
+ task :test => :check_dependencies
42
+
43
+ task :default => :test
44
+
45
+ require 'rake/rdoctask'
46
+ Rake::RDocTask.new do |rdoc|
47
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
48
+
49
+ rdoc.rdoc_dir = 'rdoc'
50
+ rdoc.title = "konfig #{version}"
51
+ rdoc.rdoc_files.include('README*')
52
+ rdoc.rdoc_files.include('lib/**/*.rb')
53
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,64 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{konfig}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Starr Horne"]
12
+ s.date = %q{2010-05-27}
13
+ s.description = %q{So you need to store some static config values in your app? Konfig does that.}
14
+ s.email = %q{starr@chromahq.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "konfig.gemspec",
27
+ "lib/konfig.rb",
28
+ "lib/konfig/evaluator.rb",
29
+ "lib/konfig/helpers.rb",
30
+ "lib/konfig/railtie.rb",
31
+ "lib/konfig/store.rb",
32
+ "test/fixtures/dynamic.yml",
33
+ "test/fixtures/static.yml",
34
+ "test/helper.rb",
35
+ "test/test_evaluator.rb",
36
+ "test/test_konfig.rb",
37
+ "test/test_store.rb"
38
+ ]
39
+ s.homepage = %q{http://github.com/starrhorne/konfig}
40
+ s.rdoc_options = ["--charset=UTF-8"]
41
+ s.require_paths = ["lib"]
42
+ s.rubygems_version = %q{1.3.6}
43
+ s.summary = %q{Configuration manager for rails apps}
44
+ s.test_files = [
45
+ "test/helper.rb",
46
+ "test/test_evaluator.rb",
47
+ "test/test_konfig.rb",
48
+ "test/test_store.rb"
49
+ ]
50
+
51
+ if s.respond_to? :specification_version then
52
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
53
+ s.specification_version = 3
54
+
55
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
56
+ s.add_development_dependency(%q<shoulda>, [">= 0"])
57
+ else
58
+ s.add_dependency(%q<shoulda>, [">= 0"])
59
+ end
60
+ else
61
+ s.add_dependency(%q<shoulda>, [">= 0"])
62
+ end
63
+ end
64
+
@@ -0,0 +1,32 @@
1
+ require 'konfig/evaluator'
2
+ require 'konfig/store'
3
+
4
+ if defined?(::Rails::Railtie)
5
+ require 'konfig/railtie'
6
+ end
7
+
8
+ # Provides a global accessor for configuration.
9
+ # ie. Konfig[:some_key]
10
+ module Konfig
11
+
12
+ # Creates a default store and loads a directory into it
13
+ # @param [String] path path to a directory with yml files
14
+ def self.load_directory(path)
15
+ @default_store ||= Konfig::Store.new
16
+ @default_store.load_directory(path)
17
+ end
18
+
19
+ # Hash-style access to data
20
+ # @param [String, Symbol] key
21
+ def self.[](key)
22
+ if !@default_store
23
+ raise "Konfig default store not set. Call Konfig.load(path) to set one."
24
+ end
25
+ @default_store[key]
26
+ end
27
+
28
+ def self.inspect
29
+ (@default_store || self).inspect
30
+ end
31
+
32
+ end
@@ -0,0 +1,32 @@
1
+ module Konfig
2
+
3
+ # Used by Konfig::Store to evaluate inline code pulled from
4
+ # configuration files.
5
+ class Evaluator
6
+
7
+ attr_accessor :data
8
+
9
+ # Set up the evaluator
10
+ # @param [Hash] data data to be available inline code
11
+ def initialize(data)
12
+ @data = data
13
+ end
14
+
15
+ # Runs a code fragment
16
+ # @param [String] code some valid ruby code
17
+ # @return the results of the eval
18
+ def run(code)
19
+ eval(code, binding)
20
+ end
21
+
22
+ # Converts an options-style nested array into a hash
23
+ # for easy name lookup
24
+ # @param [Array] a an array like [['name', 'val']]
25
+ # @return [Hash] a hash like { val => name }
26
+ def names_by_value(a)
27
+ a = @data[a] if a.is_a?(String) || a.is_a?(Symbol)
28
+ Hash[ a.map { |i| i.reverse } ]
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,8 @@
1
+ module Konfig
2
+ module Helpers
3
+ def names_for(a)
4
+ p "!!!!!"
5
+ a.reverse_hash
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,19 @@
1
+ require 'konfig'
2
+ require 'rails'
3
+
4
+ module Konfig
5
+ class InitializeKonfig < Rails::Railtie
6
+ initializer "initialize_konfig.configure_rails_initialization" do
7
+
8
+ path = File.join(Rails.root, "config", "settings")
9
+ Konfig.load_directory(path)
10
+
11
+ begin
12
+ c = Konfig[:email][:smtp][Rails.env]
13
+ ActionMailer::Base.smtp_settings = c.symbolize_keys
14
+ rescue
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,65 @@
1
+ require 'active_support/hash_with_indifferent_access'
2
+ require 'active_support/core_ext/hash/indifferent_access'
3
+ require 'yaml'
4
+
5
+ module Konfig
6
+
7
+ class Store
8
+
9
+ def initialize
10
+ @data = HashWithIndifferentAccess.new
11
+ end
12
+
13
+ # Loads all yml files in a directory into this store
14
+ # Will not recurse into subdirectories.
15
+ # @param [String] path to directory
16
+ def load_directory(path)
17
+
18
+ unless File.directory?(path)
19
+ raise "Konfig couldn't load because it was unable to access #{ path }. Please make sure the directory exists and has the correct permissions."
20
+ end
21
+
22
+ Dir[File.join(path, "*.yml")].each { |f| load_file(f) }
23
+ end
24
+
25
+ # Loads a single yml file into the store
26
+ # @param [String] path to file
27
+ def load_file(path)
28
+ d = YAML.load_file(path)
29
+
30
+ if d.is_a?(Hash)
31
+ d = HashWithIndifferentAccess.new(d)
32
+ e = Evaluator.new(d)
33
+ d = process(d, e)
34
+ end
35
+
36
+ @data[File.basename(path, ".yml").downcase] = d
37
+ end
38
+
39
+ # Hash-style access to data
40
+ # @param [String, Symbol] key
41
+ def [](key)
42
+ @data[key]
43
+ end
44
+
45
+ def inspect
46
+ @data.inspect
47
+ end
48
+
49
+ protected
50
+
51
+ def process(piece, evaluator)
52
+ piece.each do |k, v|
53
+ if v.is_a?(Hash)
54
+ piece[k] = process(v, evaluator)
55
+ elsif v.is_a?(String) && v.strip =~ /\A<<(.*)\z/
56
+ piece[k] = evaluator.run($1)
57
+ end
58
+ end
59
+ piece
60
+ end
61
+
62
+
63
+ end
64
+
65
+ end
@@ -0,0 +1,8 @@
1
+ one_plus_one: << 1 + 1
2
+ five: 5
3
+ six: 6
4
+ five_times_six: << data[:five] * data['six']
5
+
6
+ parent:
7
+ child: 5
8
+ child_plus_one: << data[:parent][:child] + 1
@@ -0,0 +1,6 @@
1
+ one: 1
2
+ two: 2
3
+ three:
4
+ - a
5
+ - b
6
+ - c
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'konfig'
8
+
9
+ class Test::Unit::TestCase
10
+ end
@@ -0,0 +1,37 @@
1
+ require 'helper'
2
+
3
+ class TestEvaluator < Test::Unit::TestCase
4
+
5
+ context "an evaluator with simple data" do
6
+ setup do
7
+ @data = { :a => 1, :b => 2 }
8
+ @evaluator = Konfig::Evaluator.new(@data)
9
+ end
10
+
11
+ should "evaluate" do
12
+ assert_equal 4, @evaluator.run("2+2")
13
+ end
14
+
15
+ should "have access to data" do
16
+ assert_equal @data[:a], @evaluator.run("data[:a]")
17
+ end
18
+
19
+ end
20
+
21
+ context "names_by_value helper" do
22
+ setup do
23
+ @data = { :options => [["name", "val"], ["name2", "val2"]] }
24
+ @evaluator = Konfig::Evaluator.new(@data)
25
+ end
26
+
27
+ should "work when given key" do
28
+ assert_equal({"val" => "name", "val2" => "name2"}, @evaluator.run("names_by_value(:options)"))
29
+ end
30
+
31
+ should "work when given an array" do
32
+ assert_equal({"val" => "name", "val2" => "name2"}, @evaluator.run("names_by_value(data[:options])"))
33
+ end
34
+
35
+ end
36
+
37
+ end
@@ -0,0 +1,27 @@
1
+ require 'helper'
2
+ require 'yaml'
3
+
4
+ class TestKonfig < Test::Unit::TestCase
5
+
6
+ context "no store loaded" do
7
+
8
+ should "raise an exception on access" do
9
+ assert_raises(RuntimeError) { Konfig[:some_key] }
10
+ end
11
+
12
+ end
13
+
14
+ context "store loaded" do
15
+
16
+ setup do
17
+ Konfig.load_directory("./test/fixtures")
18
+ end
19
+
20
+ should "load all files" do
21
+ assert Konfig[:static]
22
+ assert Konfig[:dynamic]
23
+ end
24
+
25
+ end
26
+
27
+ end
@@ -0,0 +1,75 @@
1
+ require 'helper'
2
+ require 'yaml'
3
+
4
+ class TestStore < Test::Unit::TestCase
5
+
6
+ context "an empty store" do
7
+
8
+ setup do
9
+ @store = Konfig::Store.new
10
+ end
11
+
12
+ should "return nil from store[key]" do
13
+ assert_nil @store[:some_key]
14
+ end
15
+
16
+ should "return an empty string on inspect" do
17
+ assert_equal "{}", @store.inspect
18
+ end
19
+
20
+ context "with static.yml file loaded" do
21
+
22
+ setup do
23
+ @store.load_file("./test/fixtures/static.yml")
24
+ @static = YAML.load_file("./test/fixtures/static.yml")
25
+ end
26
+
27
+ should "have key named static" do
28
+ assert @store[:static]
29
+ end
30
+
31
+ should "have correct_values" do
32
+ assert_equal @static, @store[:static]
33
+ end
34
+
35
+ end
36
+
37
+ context "with dynamic.yml file loaded" do
38
+
39
+ setup do
40
+ @store.load_file("./test/fixtures/dynamic.yml")
41
+ end
42
+
43
+ should "evaluate code" do
44
+ assert_equal 2, @store[:dynamic][:one_plus_one]
45
+ end
46
+
47
+ should "be able to reference itself" do
48
+ assert_equal 5, @store[:dynamic][:five]
49
+ assert_equal 6, @store[:dynamic][:six]
50
+ assert_equal 5*6, @store[:dynamic][:five_times_six]
51
+ end
52
+
53
+ should "be able to reference nested attributes" do
54
+ assert_equal 5, @store[:dynamic][:parent][:child]
55
+ assert_equal 5+1, @store[:dynamic][:parent][:child_plus_one]
56
+ end
57
+
58
+ end
59
+
60
+ context "with directory loaded" do
61
+ setup do
62
+ @store.load_directory("./test/fixtures")
63
+ end
64
+
65
+ should "load all files" do
66
+ assert @store[:static]
67
+ assert @store[:dynamic]
68
+ end
69
+
70
+ end
71
+
72
+ end
73
+
74
+
75
+ end
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: konfig
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Starr Horne
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-05-27 00:00:00 -05:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: shoulda
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :development
31
+ version_requirements: *id001
32
+ description: So you need to store some static config values in your app? Konfig does that.
33
+ email: starr@chromahq.com
34
+ executables: []
35
+
36
+ extensions: []
37
+
38
+ extra_rdoc_files:
39
+ - LICENSE
40
+ - README.rdoc
41
+ files:
42
+ - .document
43
+ - .gitignore
44
+ - LICENSE
45
+ - README.rdoc
46
+ - Rakefile
47
+ - VERSION
48
+ - konfig.gemspec
49
+ - lib/konfig.rb
50
+ - lib/konfig/evaluator.rb
51
+ - lib/konfig/helpers.rb
52
+ - lib/konfig/railtie.rb
53
+ - lib/konfig/store.rb
54
+ - test/fixtures/dynamic.yml
55
+ - test/fixtures/static.yml
56
+ - test/helper.rb
57
+ - test/test_evaluator.rb
58
+ - test/test_konfig.rb
59
+ - test/test_store.rb
60
+ has_rdoc: true
61
+ homepage: http://github.com/starrhorne/konfig
62
+ licenses: []
63
+
64
+ post_install_message:
65
+ rdoc_options:
66
+ - --charset=UTF-8
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ segments:
74
+ - 0
75
+ version: "0"
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ segments:
81
+ - 0
82
+ version: "0"
83
+ requirements: []
84
+
85
+ rubyforge_project:
86
+ rubygems_version: 1.3.6
87
+ signing_key:
88
+ specification_version: 3
89
+ summary: Configuration manager for rails apps
90
+ test_files:
91
+ - test/helper.rb
92
+ - test/test_evaluator.rb
93
+ - test/test_konfig.rb
94
+ - test/test_store.rb