Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add ability change settings #4

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ source "http://rubygems.org"
# Add dependencies to develop your gem here.
# Include everything needed to run rake, tests, features, etc.
group :development do
gem "rspec", "~> 2.1.0"
gem "bundler", "~> 1.0.0"
gem "jeweler", "~> 1.5.1"
gem "rspec", ">= 2.1.0"
gem "bundler", ">= 1.0.0"
gem "jeweler", ">= 1.5.1"
gem "simplecov", ">= 0"
end
26 changes: 13 additions & 13 deletions README.rdoc
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
= yettings

YAML settings for your Rails 3 app.
YAML settings for your Rails 3 app.

== What does it do?

Yettings allows you to add a yml file to your "config" directory and you can access the values defined in the YAML in your Rails app. You can
use this to store API keys, constants, and other key/value pairs. This plugin was heavily inspired by settingslogic, with a few differences... You don't
have to add a class and point to the YML file. The Yetting class will be created dynamically and will be available to your Rails app. This plugin is also
Yettings allows you to add a yml file to your "config" directory and you can access the values defined in the YAML in your Rails app. You can
use this to store API keys, constants, and other key/value pairs. This plugin was heavily inspired by settingslogic, with a few differences... You don't
have to add a class and point to the YML file. The Yetting class will be created dynamically and will be available to your Rails app. This plugin is also
more basic than settingslogic. It does not have support for dynamic setting creation... only the values in the yetting.yml will be available.

== This project only supports Rails 3 and Ruby 1.9.2

There is a branch for 1.8.7, but it has not been merged into master. If you want to use it, you can reference the github location and branch in your Gemfile. See the issue tracker for more details

== Known bug in YAML psych parser
This bug can cause issues loading the YAML keys when using Yettings. The workaround is to set your YAML parser to sych if your environment is currently using psych:
This bug can cause issues loading the YAML keys when using Yettings. The workaround is to set your YAML parser to sych if your environment is currently using psych:

YAML::ENGINE.yamler = "syck"
YAML::ENGINE.yamler = "syck"

More info here: http://pivotallabs.com/users/mkocher/blog/articles/1692-yaml-psych-and-ruby-1-9-2-p180-here-there-be-dragons

Expand All @@ -35,10 +35,10 @@ Install with Bundler
===Adding the YAML file with your key/value pairs

1. Create a YAML file inside /your_rails_app/config called yetting.yml
2. If you want to namespace your Yettings, create a YAML file inside /your_rails_app/config/yettings/ and call it whatever you want.
2. If you want to namespace your Yettings, create a YAML file inside /your_rails_app/config/yettings/ and call it whatever you want.

===YAML file content
You can define key/value pairs in the YAML file and these will be available in your app. You can set the defaults and any environment specific values.
You can define key/value pairs in the YAML file and these will be available in your app. You can set the defaults and any environment specific values.
The file must contain each environment that you will use in your Rails app. Here is a sample:

defaults: &defaults
Expand All @@ -58,14 +58,14 @@ The file must contain each environment that you will use in your Rails app. Her

production:
<<: *defaults
In the above example, you can define the key/value pair using strings, numbers, erb code, or arrays. Notice that the "api_key" in the development

In the above example, you can define the key/value pair using strings, numbers, erb code, or arrays. Notice that the "api_key" in the development
environment will override the "api_key" from defaults.

===Accessing the values in your Rails app

You simply call the Yetting class or the namespaced class and the key as a class method. For namespaced yml files, Yettings will convert the filename in
/your_rails_app/config/yettings/ to a class name and append Yetting. So if you have main.yml, then it will use MainYetting as the class name.
You simply call the Yetting class or the namespaced class and the key as a class method. For namespaced yml files, Yettings will convert the filename in
/your_rails_app/config/yettings/ to a class name and append Yetting. So if you have main.yml, then it will use MainYetting as the class name.
Then you can call the key that you put in the YAML as a class method. Here are 2 examples:

#/your_rails_app/config/yetting.yml in production
Expand All @@ -78,7 +78,7 @@ Then you can call the key that you put in the YAML as a class method. Here are


== Contributing to yettings

* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
* Fork the project
Expand Down
4 changes: 2 additions & 2 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Jeweler::Tasks.new do |gem|
gem.email = "[email protected]"
gem.authors = ["johnmcaliley"]
gem.files.exclude 'test_app/**/*'
gem.files.exclude 'test_app/**/.*'
gem.files.exclude 'test_app/**/.*'
end
Jeweler::RubygemsDotOrgTasks.new

Expand All @@ -37,7 +37,7 @@ end

task :default => :spec

require 'rake/rdoctask'
require 'rdoc/task'
Rake::RDocTask.new do |rdoc|
version = File.exist?('VERSION') ? File.read('VERSION') : ""

Expand Down
19 changes: 13 additions & 6 deletions lib/yettings.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,45 @@

module Yettings
class UndefinedYetting < StandardError; end

class << self
def setup!
find_ymls.each do |yml|
create_yetting_class(yml)
end
end

def find_ymls
main_file = "#{Rails.root.to_s}/config/yetting.yml"
yettings_main_file = File.exists?(main_file) ? [main_file] : []
yettings_namespaced_files = Dir.glob("#{Rails.root.to_s}/config/yettings/**/*.yml")
yettings_main_file.concat(yettings_namespaced_files)
end

def create_yetting_class(yml_file)
hash = load_yml(yml_file)
klass_name = File.basename(yml_file).gsub(".yml","").camelize
klass_name = "#{klass_name}Yetting" unless klass_name=="Yetting"
klass = Object.const_set(klass_name,Class.new)
hash.each do |key,value|
klass.define_singleton_method(key){ value }
end
@@key = key
klass.class_eval do
class << self
attr_accessor @@key.to_sym
end
end
klass.instance_variable_set("@#{key}",value)
end unless hash.nil?
klass.class_eval do
def self.method_missing(method_id,*args)
raise UndefinedYetting, "#{method_id} is not defined in #{self.to_s}"
end
end
end

def load_yml(yml_file)
erb = ERB.new(File.read(yml_file)).result
erb.present? ? YAML.load(erb).to_hash[Rails.env] : {}
end
end # class << self
end
end
15 changes: 15 additions & 0 deletions test_app/db/schema.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
#
# Note that this schema.rb definition is the authoritative source for your
# database schema. If you need to create the application database on another
# system, you should be using db:schema:load, not running all the migrations
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
# you'll amass, the slower it'll run and the greater likelihood for issues).
#
# It's strongly recommended to check this file into your version control system.

ActiveRecord::Schema.define(:version => 0) do

end
32 changes: 18 additions & 14 deletions test_app/spec/yettings_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,54 +4,58 @@
YETTINGS_DIR = "#{Rails.root}/config/yettings"
YETTING_FILE = "#{Rails.root}/config/yetting.yml"
BLANK_YETTING_FILE = "#{Rails.root}/config/yettings/blank.yml"

it "should load yettings in the rails app" do
assert defined?(Yettings)
end

it "should find only default yml file if no others exist" do
FileUtils.mv(YETTINGS_DIR,"#{YETTINGS_DIR}_tmp") if File.directory?(YETTINGS_DIR)
Yettings.find_ymls.should eq ["#{Rails.root}/config/yetting.yml"]
FileUtils.mv("#{YETTINGS_DIR}_tmp",YETTINGS_DIR) if File.directory?("#{YETTINGS_DIR}_tmp")
end

it "should find main and 3 yettings dir files" do
Yettings.find_ymls.should eq ["#{Rails.root}/config/yetting.yml",
"#{Rails.root}/config/yettings/blank.yml",
"#{Rails.root}/config/yettings/hendrix.yml",
"#{Rails.root}/config/yettings/jimi.yml"]
"#{Rails.root}/config/yettings/jimi.yml"].sort
end

it "should find 3 yettings dir files if there is no main file" do
FileUtils.mv("#{YETTING_FILE}","#{YETTING_FILE}_tmp") if File.exists?("#{YETTING_FILE}")
Yettings.find_ymls.should eq ["#{Rails.root}/config/yettings/blank.yml",
"#{Rails.root}/config/yettings/hendrix.yml",
"#{Rails.root}/config/yettings/jimi.yml"]
"#{Rails.root}/config/yettings/jimi.yml"]
FileUtils.mv("#{YETTING_FILE}_tmp","#{YETTING_FILE}") if File.exists?("#{YETTING_FILE}_tmp")
end

it "should load the yml and return hash" do
Yettings.load_yml("#{YETTING_FILE}").should eq "yetting1"=>"what", "yetting2"=>999, "yetting3"=>"this is erb", "yetting4"=>["element1", "element2"]
end

it "should continue gracefully given blank yettings file" do
Yettings.load_yml("#{BLANK_YETTING_FILE}").should == {}
end

it "should create the classes and class methods" do
Yettings.create_yetting_class("#{YETTING_FILE}")
Yetting.yetting1.should eq "what"
Yetting.yetting2.should eq 999
Yetting.yetting3.should eq "this is erb"
Yetting.yetting4.should eq ["element1", "element2"]
# ability change configurations(using for test)
Yetting.yetting2 = 'hello123'
Yetting.yetting2.should eq 'hello123'
end



it "should pass the integration test, since rails will run the initializer" do
Yetting.yetting1.should eq "what"
JimiYetting.yetting1.should eq "hendrix"
HendrixYetting.yetting1.should eq "jimi"
end

it "should issue a warning for method_missing" do
begin
Yetting.whatwhat
Expand All @@ -60,10 +64,10 @@
e.message.should =~ /whatwhat is not defined in Yetting/
end
end

it "should print the performance of setup method" do
start = Time.now
Yettings.setup!
Yettings.setup!
puts "Load time for Yettings.setup! = #{Time.now - start} seconds"
end
end
end