Permalink
Browse files

initial commit

  • Loading branch information...
0 parents commit c0b36354dcac6c3b90929170df7e115f52ddc4ce chatgris committed Sep 28, 2011
3 Gemfile
@@ -0,0 +1,3 @@
+source :rubygems
+
+gemspec
24 Gemfile.lock
@@ -0,0 +1,24 @@
+PATH
+ remote: .
+ specs:
+ gaston (0.0.1)
+
+GEM
+ remote: http://rubygems.org/
+ specs:
+ diff-lcs (1.1.3)
+ rspec (2.6.0)
+ rspec-core (~> 2.6.0)
+ rspec-expectations (~> 2.6.0)
+ rspec-mocks (~> 2.6.0)
+ rspec-core (2.6.4)
+ rspec-expectations (2.6.0)
+ diff-lcs (~> 1.1.2)
+ rspec-mocks (2.6.0)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ gaston!
+ rspec (~> 2.6)
21 LICENSE
@@ -0,0 +1,21 @@
+MIT LICENSE
+
+Copyright (c) chatgris <jboyer@af83.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
59 README.md
@@ -0,0 +1,59 @@
+GASTON
+======
+
+Gaston is a dead simple Ruby config store. Write your config in yaml files, and retrieve it through one Gaston.
+
+Installation
+------------
+
+Install it with rubygems:
+
+ gem install gaston
+
+With bundler, add it to your `Gemfile`:
+
+``` ruby
+gem "gaston", "~>0.0.1"
+```
+
+Always specify environment in yaml :
+
+``` yaml
+:development:
+ api:
+ key: "api_key"
+:test:
+ api:
+ key: "prod_api_key"
+```
+
+Create an initializer. You can define an environment with the `env` method, and specify config files with the `files` method. Default `env` is `:development`.
+
+``` ruby
+Gaston.configure do |config|
+ config.env = Rails.env
+ config.files = Dir[Rails.root.join("config/gaston/**/*.yml"]
+end
+Config = Gaston.retrieve
+```
+
+Querying a config key :
+
+``` ruby
+Config.db.user
+```
+
+Note on Patches/Pull Requests
+-----------------------------
+
+* Fork the project.
+* Make your feature addition or bug fix.
+* Add tests for it. This is important so I don't break it in a future version unintentionally.
+* Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself in another branch so I can ignore when I pull)
+* Send me a pull request. Bonus points for topic branches.
+
+
+Copyright
+---------
+
+MIT. See LICENSE for further details.
18 gaston.gemspec
@@ -0,0 +1,18 @@
+# encoding: utf-8
+
+$:.unshift File.expand_path('../lib', __FILE__)
+require 'gaston/version'
+
+Gem::Specification.new do |s|
+ s.name = "gaston"
+ s.version = Gaston::VERSION
+ s.authors = ["chatgris"]
+ s.email = "jboyer@af83.com"
+ s.homepage = "https://github.com/chatgris/gaston"
+ s.summary = "[Dead simple Ruby config store.]"
+ s.description = "[Dead simple Ruby config store.]"
+ s.files = `git ls-files app lib`.split("\n")
+ s.platform = Gem::Platform::RUBY
+ s.require_path = 'lib'
+ s.add_development_dependency "rspec", "~>2.6"
+end
65 lib/gaston.rb
@@ -0,0 +1,65 @@
+# encoding: utf-8
+require 'yaml'
+require 'singleton'
+
+class Gaston
+ include Singleton
+ require 'gaston/configuration'
+ require 'gaston/store'
+
+ # Parse yml config files, merge them, and store into
+ # gaston::Store
+ #
+ # @since 0.0.1
+ #
+ def store
+ @store ||= Gaston::Store.new (files.inject({}) {|hash, config|
+ parse = YAML.load_file(config)[env]
+ hash.merge(parse) if parse
+ })
+ end
+
+ class << self
+
+ def retrieve
+ self.instance.store
+ end
+
+ # Define a configure block.
+ #
+ # Delegates to Gaston::Configuration
+ #
+ # @example Define the option.
+ # Gaston.configure do |config|
+ # config.env = :test
+ # config.files = Dir[Rails.root.join("config/libraries/**/*.rb"]
+ # end
+ #
+ # @param [ Proc ] block The block getting called.
+ #
+ # @since 0.0.1
+ #
+ def configure(&block)
+ Gaston::Configuration.configure(&block)
+ end
+ end # self
+
+ private
+
+ # List config files.
+ #
+ # @since 0.0.1
+ #
+ def files
+ Gaston::Configuration.files
+ end
+
+ # Current enironment.
+ #
+ # @since 0.0.1
+ #
+ def env
+ Gaston::Configuration.env.to_sym
+ end
+
+end # Gaston
39 lib/gaston/configuration.rb
@@ -0,0 +1,39 @@
+# encoding: utf-8
+class Gaston
+ class Configuration
+
+ class << self
+
+ attr_accessor :files, :env
+
+ # Define a configure block.
+ #
+ # @example
+ # Gaston.configure do |config|
+ # config.env = :test
+ # config.files = Dir[Rails.root.join("config/libraries/**/*.rb"]
+ # end
+ #
+ # @param [ Proc ] block The block getting called.
+ #
+ # @since 0.0.1
+ #
+ def configure(&block)
+ default_values!
+ yield self
+ end
+
+ private
+
+ # Set default values
+ #
+ # @since 0.0.1
+ #
+ def default_values!
+ @files = []
+ @env = :development
+ end
+
+ end # self
+ end # Configuration
+end #Gaston
39 lib/gaston/store.rb
@@ -0,0 +1,39 @@
+# encoding: utf-8
+class Gaston
+ class Store < Hash
+
+ # Initialize Store.
+ #
+ # @param [ Hash ] Hash config to be stored.
+ #
+ # @since 0.0.1
+ #
+ def initialize(hash)
+ hash ||= {}
+ hash.each do |key, value|
+ value.is_a?(Hash) ? self[key] = Gaston::Store.new(value) : self[key] = value
+ end
+ end
+
+ # Search into store for value.
+ #
+ # @param [ String || Symbol ] key store.
+ #
+ # @since 0.0.1
+ #
+ def method_missing(method, *args, &block)
+ return self[method.to_s] if has_key? method.to_s
+ return self[method.to_sym] if has_key? method.to_sym
+ super(method, *args, &block)
+ end
+
+ # Implement respond_to?
+ #
+ # @since 0.0.1
+ #
+ def respond_to?(method)
+ has_key?(method.to_s) || has_key?(method.to_sym) || super(method)
+ end
+
+ end # Store
+end #Gaston
4 lib/gaston/version.rb
@@ -0,0 +1,4 @@
+# encoding: utf-8
+class Gaston
+ VERSION = "0.0.1"
+end
8 spec/fixtures/c3po.yml
@@ -0,0 +1,8 @@
+:development:
+ api:
+ provider: :bing
+ bing: "api_key"
+:test:
+ api:
+ provider: :bing
+ bing: "prod_api_key"
21 spec/gaston/configuration_spec.rb
@@ -0,0 +1,21 @@
+# encoding: utf-8
+require 'spec_helper'
+
+describe Gaston::Configuration do
+
+ before do
+ Gaston.configure do |config|
+ config.files << "my/path"
+ config.env = :production
+ end
+ end
+
+ it 'should have a files method' do
+ Gaston::Configuration.files.should eq(["my/path"])
+ end
+
+ it 'should have a env method' do
+ Gaston::Configuration.env.should eq(:production)
+ end
+
+end
52 spec/gaston/store_spec.rb
@@ -0,0 +1,52 @@
+# encoding: utf-8
+require 'spec_helper'
+
+describe Gaston::Store do
+ let(:store) { Gaston::Store.new({:config => 'test'})}
+ let(:multi_store) do
+ Gaston::Store.new({:config => 'test',
+ :nested => {:one => :level, :nested => {:two => ['warp', :zone]}}
+ })
+ end
+
+ describe 'one level store' do
+
+ context 'existing method' do
+ it 'should return value through method' do
+ store.config.should eq('test')
+ end
+
+ it 'should respond to respond_to?' do
+ store.respond_to?(:config).should be_true
+ end
+
+ end
+
+ context 'no method' do
+
+ it 'should raise NoMethodError' do
+ lambda {
+ store.no_method
+ }.should raise_error(NoMethodError)
+ end
+
+ it 'should not respond to respond_to?' do
+ store.config.respond_to?(:no_method).should be_false
+ end
+
+ end
+
+ end
+
+ describe 'multi level store' do
+ it 'should be a Store' do
+ multi_store.nested.should be_a_kind_of Gaston::Store
+ end
+
+ it 'should be recursive' do
+ multi_store.nested.nested.two.should eq(["warp", :zone])
+ end
+
+ end
+
+end
21 spec/gaston_spec.rb
@@ -0,0 +1,21 @@
+# encoding: utf-8
+require 'spec_helper'
+
+describe Gaston do
+ let(:gaston) { Gaston.retrieve }
+
+ before do
+ Gaston.configure do |config|
+ config.env = :test
+ config.files = Dir[File.join(File.dirname(__FILE__), 'fixtures/**/*.yml')]
+ end
+ end
+
+ it 'should be a Gaston::Store' do
+ gaston.should be_a_kind_of Gaston::Store
+ end
+
+ it 'should return api_key from api config' do
+ gaston.api.provider.should eq(:bing)
+ end
+end
5 spec/spec_helper.rb
@@ -0,0 +1,5 @@
+# encoding: utf-8
+path = File.expand_path(File.dirname(__FILE__) + '/../lib/')
+$LOAD_PATH.unshift(path) unless $LOAD_PATH.include?(path)
+
+require 'gaston'

0 comments on commit c0b3635

Please sign in to comment.