brendan-simpleconfig 0.0.1

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.
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
+