brendan-simpleconfig 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/Manifest.txt ADDED
@@ -0,0 +1,16 @@
1
+ lib
2
+ lib/simpleconfig.rb
3
+ Rakefile
4
+ README
5
+ spec
6
+ spec/fixtures
7
+ spec/fixtures/folder1
8
+ spec/fixtures/folder1/data.yml
9
+ spec/fixtures/folder1/erbified.yml
10
+ spec/fixtures/folder1/other_data.yml
11
+ spec/fixtures/folder2
12
+ spec/fixtures/folder2/data.yml
13
+ spec/fixtures/folder2/only_in_folder2.yml
14
+ spec/fixtures/folder2/other_data.yml
15
+ spec/simpleconfig_spec.rb
16
+ spec/spec_helper.rb
data/README ADDED
File without changes
data/Rakefile ADDED
@@ -0,0 +1,126 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH << File.join(File.dirname(__FILE__), 'lib')
3
+ require 'rubygems'
4
+ require './lib/simpleconfig.rb'
5
+ require 'rake'
6
+ require 'spec/rake/spectask'
7
+
8
+ desc "Generates the gemspec, Manifest.txt and builds the gem."
9
+ task :gem => ["gem:gemspec","gem:manifest"]
10
+
11
+ namespace :gem do
12
+ desc "Generates the simpleconfig.gemspec file"
13
+ task :gemspec do
14
+ gemspec_code = <<-gemspec
15
+ Gem::Specification.new do |s|
16
+ s.name = %q{simpleconfig}
17
+ s.version = #{SimpleConfig::VERSION.inspect}
18
+
19
+ s.specification_version = 2 if s.respond_to? :specification_version=
20
+
21
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
22
+ s.authors = #{SimpleConfig::AUTHORS.inspect}
23
+ s.date = #{Time.now.strftime('%Y-%m-%d').inspect}
24
+ s.default_executable = nil
25
+ s.description = #{SimpleConfig::DESCRIPTION.inspect}
26
+ s.email = #{SimpleConfig::EMAIL.inspect}
27
+ s.executables = []
28
+ s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.txt"]
29
+ s.files = #{SimpleConfig::MANIFEST.inspect}
30
+ s.has_rdoc = true
31
+ s.homepage = #{SimpleConfig::HOMEPAGE.inspect}
32
+ s.rdoc_options = ["--main", "README.txt"]
33
+ s.require_paths = ["lib"]
34
+ s.rubygems_version = %q{1.1.1}
35
+ s.summary = #{SimpleConfig::DESCRIPTION.inspect}
36
+ end
37
+ gemspec
38
+ gemspec = File.open(File.join(File.dirname(__FILE__),'simpleconfig.gemspec'),'w')
39
+ gemspec.write(gemspec_code)
40
+ gemspec.close
41
+ end
42
+ desc "Generates the Manifest.txt file"
43
+ task :manifest do
44
+ manifest = File.open(File.join(File.dirname(__FILE__),'Manifest.txt'),'w')
45
+ manifest.write(SimpleConfig::MANIFEST.join("\n")<<"\n")
46
+ manifest.close
47
+ end
48
+ end
49
+
50
+ desc "Run all specs"
51
+ Spec::Rake::SpecTask.new do |t|
52
+ t.spec_files = FileList['spec/**/*_spec.rb']
53
+ end
54
+
55
+ namespace :spec do
56
+ desc "Run all specs and stake out all files/folders for changes, running rake spec upon change"
57
+ task :auto => 'spec' do
58
+
59
+ # This task assumes you are running on a Mac, with growl installed. Perhaps
60
+ # there will be a better way to abstract this, but it works for us now.
61
+ def growl(title, msg, img, pri=0, sticky="")
62
+ system "growlnotify -n autotest --image ~/.autotest_images/#{img} -p #{pri} -m #{msg.inspect} #{title} #{sticky}"
63
+ end
64
+ def self.growl_fail(output)
65
+ growl "FAIL", "#{output}", "fail.png", 2
66
+ end
67
+ def self.growl_pass(output)
68
+ growl "Pass", "#{output}", "pass.png"
69
+ end
70
+
71
+ command = 'rake spec'
72
+ files = {}
73
+
74
+ def files.reglob
75
+ Dir['**/*.rb'].each {|file| self[file] ||= File.mtime(file)}
76
+ end
77
+
78
+ files.reglob
79
+
80
+ puts "Watching #{files.keys.join(', ')}\n\nFiles: #{files.keys.length}"
81
+
82
+ trap('INT') do
83
+ puts "\nQuitting..."
84
+ exit
85
+ end
86
+
87
+ loop do
88
+
89
+ sleep 3
90
+
91
+ files.reglob
92
+
93
+ changed_file, last_changed = files.find do |file, last_changed|
94
+ begin
95
+ File.mtime(file) > last_changed
96
+ rescue
97
+ files.delete(file)
98
+ end
99
+ end
100
+
101
+ if changed_file
102
+ files[changed_file] = File.mtime(changed_file)
103
+ puts "=> #{changed_file} changed, running #{command}"
104
+ results = `#{command}`
105
+ puts results
106
+
107
+ if results.include? 'tests'
108
+ output = results.slice(/(\d+)\s+tests?,\s*(\d+)\s+assertions?,\s*(\d+)\s+failures?(,\s*(\d+)\s+errors)?/)
109
+ if output
110
+ $~[3].to_i + $~[5].to_i > 0 ? growl_fail(output) : growl_pass(output)
111
+ end
112
+ else
113
+ output = results.slice(/(\d+)\s+examples?,\s*(\d+)\s+failures?(,\s*(\d+)\s+not implemented)?/)
114
+ if output
115
+ $~[2].to_i > 0 ? growl_fail(output) : growl_pass(output)
116
+ end
117
+ end
118
+ # TODO Generic growl notification for other actions
119
+
120
+ puts "=> done"
121
+ end
122
+
123
+ end
124
+
125
+ end
126
+ end
@@ -0,0 +1,104 @@
1
+ require 'erb'
2
+ require 'yaml'
3
+
4
+ class SimpleConfig < Hash
5
+
6
+ VERSION='0.0.1'
7
+ AUTHORS=["Brendan Baldwin"]
8
+ EMAIL=["brendan@usergenic.com"]
9
+ DESCRIPTION=%q{This is a really simple system for getting configuration data into your app. See the wiki at http://github.com/brendan/simpleconfig/wikis for usage.}
10
+ FOLDER=File.expand_path(File.join(File.dirname(__FILE__),'..'))
11
+ MANIFEST=Dir.glob(File.join(FOLDER,'**','*')).map{|path|path[FOLDER.size+1..-1]}
12
+ HOMEPAGE="http://github.com/brendan/simpleconfig/wikis"
13
+
14
+ def [](key)
15
+ super key.to_s
16
+ end
17
+
18
+ def []=(key,value)
19
+ value = self.class.new.replace(value) if value.is_a?(Hash) and !value.is_a?(self.class)
20
+ super key.to_s, value
21
+ end
22
+
23
+ def fetch(key, default=nil, &block)
24
+ super(key.to_s, default, &block)
25
+ end
26
+
27
+ def freeze
28
+ values.each do |value|
29
+ value.freeze if value.respond_to?(:freeze)
30
+ end
31
+ super
32
+ end
33
+
34
+ def has_key?(key)
35
+ super key.to_s
36
+ end
37
+
38
+ def key?(key)
39
+ super key.to_s
40
+ end
41
+
42
+ def merge!(other)
43
+ other.each do |key, value|
44
+ if self[key].is_a?(Hash) and value.is_a?(Hash)
45
+ self[key].merge!(value)
46
+ else
47
+ self[key] = value
48
+ end
49
+ end
50
+ end
51
+
52
+ def replace(other)
53
+ clear
54
+ other.each do |key, value|
55
+ self[key] = value
56
+ end
57
+ self
58
+ end
59
+
60
+ protected
61
+
62
+ def methodize_keys_and_freeze
63
+ keys.each do |key|
64
+ value = send(key)
65
+ value.methodize_keys_and_freeze if value.is_a?(Hash)
66
+ end
67
+ freeze
68
+ self
69
+ end
70
+
71
+ private
72
+
73
+ def initialize(*folders)
74
+ @folders = folders unless folders.empty?
75
+ end
76
+
77
+ def load_and_merge(paths)
78
+ merged_data = nil
79
+ paths.each do |path|
80
+ if File.exists?(path)
81
+ data = YAML.load(ERB.new(File.read(path)).result)
82
+ data = self.class.new.replace(data) if data.is_a?(Hash)
83
+ if merged_data.is_a?(Hash)
84
+ merged_data.merge!(data)
85
+ else
86
+ merged_data = data
87
+ end
88
+ end
89
+ end
90
+ merged_data.methodize_keys_and_freeze if merged_data.is_a?(Hash)
91
+ merged_data
92
+ end
93
+
94
+ def method_missing(method_id, *arguments, &block)
95
+ if defined?(@folders)
96
+ data = load_and_merge(@folders.reverse.map {|f| File.join(f,"#{method_id}.yml")})
97
+ self[method_id] = data unless data == nil
98
+ end
99
+ return super unless key?(method_id)
100
+ class << self; self; end.send(:define_method, method_id) { self[method_id] }
101
+ send(method_id)
102
+ end
103
+
104
+ end
@@ -0,0 +1,4 @@
1
+ some_key : some_value
2
+ some_other_key : some_other_value
3
+ some_key_with_hash_value :
4
+ some_subkey : some_subvalue
@@ -0,0 +1 @@
1
+ <%= %w{a dynamic key}.join('_') %> : some_<%='dynamic'%>_content
@@ -0,0 +1 @@
1
+ definitely_not_a_hash
@@ -0,0 +1,4 @@
1
+ some_key : this_will_be_ignored
2
+ some_key_with_hash_value :
3
+ some_subkey : will_also_be_ignored
4
+ some_other_subkey : some_other_subvalue
@@ -0,0 +1 @@
1
+ i_am_so_uniq
@@ -0,0 +1 @@
1
+ not_a_hash
@@ -0,0 +1,64 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ describe "SimpleConfig" do
4
+
5
+ def fixture_folders
6
+ %w{folder1 folder2}.map{|f|File.join(File.dirname(__FILE__),'fixtures',f)}
7
+ end
8
+
9
+ describe ".new" do
10
+
11
+ it "creates a new SimpleConfig hash and sets the @folders instance_variable to the list of arguments provided." do
12
+ config = SimpleConfig.new('x','y','z')
13
+ config.instance_variable_get('@folders').should == ['x','y','z']
14
+ end
15
+
16
+ end
17
+
18
+ describe "#method_missing" do
19
+
20
+ it "when a key matching the method_id string is present, defines a singleton_method named for the key to return the value and calls it." do
21
+ config = SimpleConfig.new
22
+ config['some_key']=1
23
+ config.should be_key('some_key')
24
+ config.methods.should_not include('some_key')
25
+ config.some_key.should == 1
26
+ config.methods.should include('some_key')
27
+ config.some_key.should == 1
28
+ end
29
+
30
+ it "delegates to method_missing super if no matching key is found" do
31
+ config = SimpleConfig.new
32
+ config[:this_method_does_exist] = "good_for_you"
33
+ proc{config.this_method_does_not_exist}.should raise_error(NoMethodError)
34
+ proc{config.this_method_does_exist}.should_not raise_error(NoMethodError)
35
+ end
36
+
37
+ end
38
+
39
+ describe "when all is said and done" do
40
+
41
+ it "performs a load_and_merge for all files named data.yml in specified folders, giving preference to first" do
42
+ config = SimpleConfig.new(*fixture_folders)
43
+ config.data.some_key.should == 'some_value'
44
+ config.data.some_other_key.should == 'some_other_value'
45
+ config.data.some_key_with_hash_value.some_subkey.should == 'some_subvalue'
46
+ config.data.some_key_with_hash_value.some_other_subkey.should == 'some_other_subvalue'
47
+ config.should == {
48
+ 'data' => {
49
+ 'some_key' => 'some_value',
50
+ 'some_other_key' => 'some_other_value',
51
+ 'some_key_with_hash_value' => {
52
+ 'some_subkey' => 'some_subvalue',
53
+ 'some_other_subkey' => 'some_other_subvalue' }}}
54
+ end
55
+
56
+ it "runs file content through ERB before parsing with YAML" do
57
+ config = SimpleConfig.new(*fixture_folders)
58
+ config.erbified.a_dynamic_key.should == 'some_dynamic_content'
59
+ config.should == {'erbified' => {'a_dynamic_key' => 'some_dynamic_content'}}
60
+ end
61
+
62
+ end
63
+
64
+ end
@@ -0,0 +1,12 @@
1
+ ENV['LOG_NAME'] = 'spec'
2
+
3
+ $: << File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
4
+
5
+ begin
6
+ require 'spec'
7
+ rescue LoadError
8
+ require 'rubygems'
9
+ require 'spec'
10
+ end
11
+
12
+ require 'simpleconfig'
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: brendan-simpleconfig
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Brendan Baldwin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-07-02 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: This is a really simple system for getting configuration data into your app. See the wiki at http://github.com/brendan/simpleconfig/wikis for usage.
17
+ email:
18
+ - brendan@usergenic.com
19
+ executables: []
20
+
21
+ extensions: []
22
+
23
+ extra_rdoc_files:
24
+ - History.txt
25
+ - Manifest.txt
26
+ - README.txt
27
+ files:
28
+ - lib
29
+ - lib/simpleconfig.rb
30
+ - Rakefile
31
+ - README
32
+ - spec
33
+ - spec/fixtures
34
+ - spec/fixtures/folder1
35
+ - spec/fixtures/folder1/data.yml
36
+ - spec/fixtures/folder1/erbified.yml
37
+ - spec/fixtures/folder1/other_data.yml
38
+ - spec/fixtures/folder2
39
+ - spec/fixtures/folder2/data.yml
40
+ - spec/fixtures/folder2/only_in_folder2.yml
41
+ - spec/fixtures/folder2/other_data.yml
42
+ - spec/simpleconfig_spec.rb
43
+ - spec/spec_helper.rb
44
+ - History.txt
45
+ - Manifest.txt
46
+ - README.txt
47
+ has_rdoc: true
48
+ homepage: http://github.com/brendan/simpleconfig/wikis
49
+ post_install_message:
50
+ rdoc_options:
51
+ - --main
52
+ - README.txt
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: "0"
60
+ version:
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: "0"
66
+ version:
67
+ requirements: []
68
+
69
+ rubyforge_project:
70
+ rubygems_version: 1.2.0
71
+ signing_key:
72
+ specification_version: 2
73
+ summary: This is a really simple system for getting configuration data into your app. See the wiki at http://github.com/brendan/simpleconfig/wikis for usage.
74
+ test_files: []
75
+