From cf20812a994263d538c98e171474b472832a7554 Mon Sep 17 00:00:00 2001 From: Patrick Tulskie Date: Tue, 11 Sep 2012 16:50:24 -0400 Subject: [PATCH] Initial commit. --- .gitignore | 17 +++++ Gemfile | 4 ++ LICENSE.txt | 22 ++++++ README.md | 82 ++++++++++++++++++++++ Rakefile | 1 + configster.gemspec | 22 ++++++ lib/configster.rb | 5 ++ lib/configster/configster.rb | 52 ++++++++++++++ lib/configster/version.rb | 3 + spec/configster_spec.rb | 12 ++++ spec/configurations/test_configuration.yml | 8 +++ spec/konfigured_klass_spec.rb | 31 ++++++++ spec/spec_helper.rb | 37 ++++++++++ 13 files changed, 296 insertions(+) create mode 100644 .gitignore create mode 100644 Gemfile create mode 100644 LICENSE.txt create mode 100644 README.md create mode 100644 Rakefile create mode 100644 configster.gemspec create mode 100644 lib/configster.rb create mode 100644 lib/configster/configster.rb create mode 100644 lib/configster/version.rb create mode 100644 spec/configster_spec.rb create mode 100644 spec/configurations/test_configuration.yml create mode 100644 spec/konfigured_klass_spec.rb create mode 100644 spec/spec_helper.rb diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d87d4be --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +*.gem +*.rbc +.bundle +.config +.yardoc +Gemfile.lock +InstalledFiles +_yardoc +coverage +doc/ +lib/bundler/man +pkg +rdoc +spec/reports +test/tmp +test/version_tmp +tmp diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..520a8e1 --- /dev/null +++ b/Gemfile @@ -0,0 +1,4 @@ +source 'https://rubygems.org' + +# Specify your gem's dependencies in configster.gemspec +gemspec diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..623acb6 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,22 @@ +Copyright (c) 2012 Patrick Tulskie + +MIT License + +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. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..8e07425 --- /dev/null +++ b/README.md @@ -0,0 +1,82 @@ +# Configster + +Configster is a tidy little configuration management utility for your application. + +You probably haven't heard of it. + +## Installation + +Add this line to your application's Gemfile: + + gem 'configster' + +And then execute: + + $ bundle + +Or install it yourself as: + + $ gem install configster + +## Usage + +For most applications, you'll want to load Configster before you start loading the rest of your application. For example: + + require 'configster' + Configster.load_configster!(File.join('path', 'to', 'my_config.yml')) + +You can also pass a raw hash of stuff into `load_configster!` as long as it's in the format of `"ClassName" => { 'variable' => 'whatever' }` + +Then, just include Configster in any classes you want: + + class KonfiguredKlass + include Configster + end + +Your class now has access to a `configster` and `raw_configster` function where you can query bits and pieces of your configuration. + +## Example + +Say you're writing a sweet application that uses [HTTParty](https://github.com/jnunemaker/httparty) to fetch data from Twitter. You want to share this application with the world, but you don't want to hard code your credentials. Here's how you might handle that: + +First, make yourself a nice little configuration file and save it to `~/my_sweet_app_credentials.yml`: + + MySweetApp: + username: SweetUsername + password: SweetPassword123 + +Then, you'll write your application like this: + + require 'configster' + Configster.load_configster!('~/my_sweet_app_credentials.yml') + + class MySweetApp + + include Configster + include HTTParty + + def initialize + @auth = { + :username => configster.username, + :password => configster.password + } + end + + def timeline(which = :friends, options = { }) + options.merge!(:basic_auth => @auth) + self.class.get("/statuses/#{which}_timeline.json", options) + end + + end + +Now you can share your application without hard coding and/or sharing your credentials. + + +## Contributing + +1. Fork it +2. Create your feature branch (`git checkout -b my-new-feature`) +3. Write specs for your changes to make sure I don't break your features in the future. +4. Commit your changes (`git commit -am 'Add some feature'`) +5. Push to the branch (`git push origin my-new-feature`) +6. Create new Pull Request diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..2995527 --- /dev/null +++ b/Rakefile @@ -0,0 +1 @@ +require "bundler/gem_tasks" diff --git a/configster.gemspec b/configster.gemspec new file mode 100644 index 0000000..6f49a7e --- /dev/null +++ b/configster.gemspec @@ -0,0 +1,22 @@ +# -*- encoding: utf-8 -*- +lib = File.expand_path('../lib', __FILE__) +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) +require 'configster/version' + +Gem::Specification.new do |gem| + gem.name = "configster" + gem.version = Configster::VERSION + gem.authors = ["Patrick Tulskie"] + gem.email = ["patricktulskie@gmail.com"] + gem.description = %q{TODO: Write a gem description} + gem.summary = %q{TODO: Write a gem summary} + gem.homepage = "" + + gem.files = `git ls-files`.split($/) + gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) } + gem.test_files = gem.files.grep(%r{^(test|spec|features)/}) + gem.require_paths = ["lib"] + + gem.add_development_dependency('rspec') + +end diff --git a/lib/configster.rb b/lib/configster.rb new file mode 100644 index 0000000..58ff1af --- /dev/null +++ b/lib/configster.rb @@ -0,0 +1,5 @@ +require 'yaml' +require 'ostruct' + +require "configster/version" +require "configster/configster" \ No newline at end of file diff --git a/lib/configster/configster.rb b/lib/configster/configster.rb new file mode 100644 index 0000000..d6e3a1a --- /dev/null +++ b/lib/configster/configster.rb @@ -0,0 +1,52 @@ +module Configster + + # ========================================= + # = Class Methods for the Receiving Class = + # ========================================= + module ClassMethods + def configster + @configster ||= Configster.configuration_for(self) + end + + def raw_configster + Configster.raw_configuration_for(self) + end + end + + def self.included(base) + base.extend(ClassMethods) + end + + # ============================================ + # = Instance Methods for the Receiving Class = + # ============================================ + def configster + self.class.configster + end + + def raw_configster + self.class.raw_configster + end + + # =========================== + # = Core Configster Methods = + # =========================== + def self.load_configster!(configster_config) + @configster_config = case configster_config + when Hash + configster_config + when String + YAML.load_file(configster_config) + end + end + + def self.configuration_for(klass) + klass_config = @configster_config[klass.to_s] + klass_config ? OpenStruct.new(klass_config).freeze : nil + end + + def self.raw_configuration_for(klass) + @configster_config[klass.to_s] + end + +end \ No newline at end of file diff --git a/lib/configster/version.rb b/lib/configster/version.rb new file mode 100644 index 0000000..b40608b --- /dev/null +++ b/lib/configster/version.rb @@ -0,0 +1,3 @@ +module Configster + VERSION = "0.0.1" +end diff --git a/spec/configster_spec.rb b/spec/configster_spec.rb new file mode 100644 index 0000000..50e0ab6 --- /dev/null +++ b/spec/configster_spec.rb @@ -0,0 +1,12 @@ +require "spec_helper" + +describe Configster do + + subject { Configster } + it { should respond_to(:configuration_for) } + + it "should be able to load the configuration for a specific class" do + Configster.configuration_for(KonfiguredKlass).should_not be_nil + end + +end \ No newline at end of file diff --git a/spec/configurations/test_configuration.yml b/spec/configurations/test_configuration.yml new file mode 100644 index 0000000..4157103 --- /dev/null +++ b/spec/configurations/test_configuration.yml @@ -0,0 +1,8 @@ +KonfiguredKlass: + user_name: configster + password: c0nfigster! + tag_line: "You've probably never heard of it." +AnotherKlass: + user_name: another + password: weakpassword + tag_line: "Whatever, bro." \ No newline at end of file diff --git a/spec/konfigured_klass_spec.rb b/spec/konfigured_klass_spec.rb new file mode 100644 index 0000000..3558890 --- /dev/null +++ b/spec/konfigured_klass_spec.rb @@ -0,0 +1,31 @@ +require "spec_helper" + +describe KonfiguredKlass do + + before(:all) do + @test_klass = KonfiguredKlass.new + end + + subject { @test_klass } + it { should respond_to(:configster) } + + it "should be able to fetch attributes from the configuration" do + @test_klass.configster.should respond_to(:user_name) + @test_klass.configster.should respond_to(:password) + @test_klass.configster.should respond_to(:tag_line) + end + + it "should be frozen" do + @test_klass.configster.should be_frozen + end + + it "should not pollute other configurations" do + another_klass = AnotherKlass.new + @test_klass.configster.user_name.should_not == another_klass.configster.user_name + end + + it "should be able to load a raw configuration" do + @test_klass.raw_configster.should be_a(Hash) + end + +end \ No newline at end of file diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..5631b3c --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,37 @@ +# This file is copied to ~/spec when you run 'ruby script/generate rspec' +# from the project root directory. + +require 'rubygems' +require 'rspec' +require 'configster' + +$spec_root = File.dirname(__FILE__) + +RSpec.configure do |config| + old_verbose, $VERBOSE = $VERBOSE, nil + + def puts(s) + file = File.basename(caller.first) + super("puts() from #{file}: #{s}") + end + + def print(s) + file = File.basename(caller.first) + super("print() from #{file}: #{s}") + end + + def p(s) + file = File.basename(caller.first) + super("p() from #{file}: #{s}") + end +end + +Configster.load_configster!(File.join($spec_root, 'configurations', 'test_configuration.yml')) + +class KonfiguredKlass + include Configster +end + +class AnotherKlass + include Configster +end