confy 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,2 @@
1
+ .bundle/**
2
+ vendor/**
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
@@ -0,0 +1,26 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ confy (0.1.0)
5
+ crack
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ crack (0.1.8)
11
+ diff-lcs (1.1.2)
12
+ rspec (2.5.0)
13
+ rspec-core (~> 2.5.0)
14
+ rspec-expectations (~> 2.5.0)
15
+ rspec-mocks (~> 2.5.0)
16
+ rspec-core (2.5.1)
17
+ rspec-expectations (2.5.0)
18
+ diff-lcs (~> 1.1.2)
19
+ rspec-mocks (2.5.0)
20
+
21
+ PLATFORMS
22
+ ruby
23
+
24
+ DEPENDENCIES
25
+ confy!
26
+ rspec
@@ -0,0 +1,24 @@
1
+ # Confy
2
+
3
+ Reads configuration-like files and makes them Object-like.
4
+
5
+ ### Backends
6
+ - xml
7
+ - json
8
+ - yaml
9
+ - 'simple' (e.g. x=1)
10
+
11
+ ### Examples
12
+
13
+
14
+ # Given an generic conf file:
15
+ # name=james\nage=42
16
+ Confy.parse("/path/to/person.xyz", :as => "SimpleAssignment").name
17
+ # => "james"
18
+
19
+ # Given an XML file:
20
+ # <person><address><city>Birmingham</city></address></perso>
21
+ Confy.parse("/path/to/person.xml").person.address.city
22
+ # => "Birmingham"
23
+
24
+
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib/', __FILE__)
3
+ $:.unshift lib unless $:.include?(lib)
4
+
5
+ require 'confy/version'
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = "confy"
9
+ s.version = Confy::VERSION
10
+ s.platform = Gem::Platform::RUBY
11
+ s.authors = ["James Cook"]
12
+ s.email = ["james@isotope11.com"]
13
+ s.summary = %q{Configuration parser}
14
+ #s.description = %q{}
15
+
16
+ s.required_rubygems_version = ">= 1.3.6"
17
+ s.rubyforge_project = "confy"
18
+
19
+ s.add_dependency "crack"
20
+ s.add_development_dependency "rspec"
21
+
22
+ s.files = `git ls-files`.split("\n")
23
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
24
+ s.require_paths = ["lib"]
25
+ end
@@ -0,0 +1,22 @@
1
+ require 'bundler/setup'
2
+ require "ostruct"
3
+
4
+ lib = File.expand_path('../', __FILE__)
5
+ $:.unshift lib unless $:.include?(lib)
6
+ require "hash_to_ostruct.rb"
7
+
8
+ module Confy
9
+ autoload :Core, "confy/core"
10
+ autoload :Backend, "confy/backend"
11
+
12
+ def parse *args
13
+ core = Core.new *args
14
+ core.parse
15
+ end
16
+
17
+ def [] *args
18
+ parse *args
19
+ end
20
+
21
+ module_function :parse, :[]
22
+ end
@@ -0,0 +1,18 @@
1
+ lib = File.expand_path('../', __FILE__)
2
+ $:.unshift lib unless $:.include?(lib)
3
+
4
+ module Confy
5
+ module Backend
6
+ require "backend/base"
7
+ autoload "Yaml", "backend/yaml"
8
+ autoload "Json", "backend/json"
9
+ autoload "Xml", "backend/xml"
10
+ autoload "SimpleAssignment","backend/simple_assignment"
11
+
12
+ # Link up the backends to matching file extensions
13
+ register :json
14
+ register :xml
15
+ register :simple_assignment
16
+ register :yaml, :yml, :as => "Yaml"
17
+ end
18
+ end
@@ -0,0 +1,28 @@
1
+ module Confy
2
+ module Backend
3
+ class Base
4
+ def self.which(path)
5
+ extension = extensions.dup.detect{|e,klass| e.to_s == File.extname(path)[1..-1] }
6
+ if extension
7
+ Backend.const_get(extension.pop)
8
+ else
9
+ raise Confy::UnsupportedFileExtensionError, "No backend available for #{path}."
10
+ end
11
+ end
12
+
13
+ def self.extensions
14
+ @extensions ||= Set.new
15
+ end
16
+ end
17
+
18
+ # backend should call this method automatically once defined to register themselves as a backend
19
+ def register *args
20
+ options = args.last.is_a?(Hash) ? args.pop : {}
21
+ extension = args.first
22
+ options[:as] = "#{extension.to_s[0].upcase}#{extension.to_s[1..-1]}" if options[:as].nil?
23
+ args.flatten.map{|ext| Base.extensions.<<([ext.to_s, options[:as].to_s]) }
24
+ end
25
+
26
+ module_function :register
27
+ end
28
+ end
@@ -0,0 +1,15 @@
1
+ module Confy
2
+ module Backend
3
+ class Json < Hash
4
+ def initialize path
5
+ require "json"
6
+ @config = ::JSON.parse(::File.read(path)).to_ostruct
7
+ end
8
+
9
+ def method_missing *args
10
+ @config.send args.shift
11
+ end
12
+ end
13
+ end
14
+ end
15
+
@@ -0,0 +1,52 @@
1
+ # Example:
2
+ # #my.conf
3
+ # x=1
4
+ # y=2
5
+ # z:3
6
+ # Confy.parse("my.conf", :as => :simple_assignment)
7
+ module Confy
8
+ module Backend
9
+
10
+ class SimpleAssignment < Hash
11
+ def initialize path
12
+ @config = __parse path
13
+ end
14
+
15
+ def self.splitter pattern=nil
16
+ if pattern
17
+ @splitter = pattern
18
+ end
19
+
20
+ @splitter ||= /=|:/
21
+ end
22
+
23
+ def self.comment_pattern pattern=nil
24
+ if pattern
25
+ @comment_pattern = pattern
26
+ end
27
+
28
+ @comment_pattern ||= /\A#/
29
+ end
30
+
31
+ def method_missing *args
32
+ @config.send args.shift
33
+ end
34
+
35
+ private
36
+ def __parse path
37
+ @config = {}
38
+ ::File.readlines(path).each do |line|
39
+ key,val = line.split(SimpleAssignment.splitter)
40
+ if key && val
41
+ key.strip!; val.strip!
42
+ next if key =~ SimpleAssignment.comment_pattern
43
+ @config[key] = val.chomp
44
+ end
45
+ end
46
+ @config.to_ostruct
47
+ end
48
+ end
49
+ register :simple_assignment
50
+ end
51
+ end
52
+
@@ -0,0 +1,17 @@
1
+ module Confy
2
+ module Backend
3
+
4
+ class Xml < Hash
5
+ def initialize path
6
+ require "crack/xml"
7
+ @config = ::Crack::XML.parse(::File.read(path)).to_ostruct
8
+ end
9
+
10
+ def method_missing *args
11
+ @config.send args.shift
12
+ end
13
+ end
14
+ register :xml
15
+ end
16
+ end
17
+
@@ -0,0 +1,16 @@
1
+ module Confy
2
+ module Backend
3
+ class Yaml < Hash
4
+ def initialize path
5
+ require "yaml"
6
+ @config = ::YAML.load_file(path).to_ostruct
7
+ end
8
+
9
+ def method_missing *args
10
+ @config.send args.shift
11
+ end
12
+ end
13
+ register :yaml, :yml, :as => "Yaml"
14
+ end
15
+ end
16
+
@@ -0,0 +1,32 @@
1
+ module Confy
2
+ class Core
3
+ attr_reader :backend, :path
4
+ def initialize *args
5
+ @path, *rest = args
6
+ tail = rest.pop
7
+ if tail.is_a?(Hash)
8
+ set_options tail
9
+ end
10
+ raise FileNotFoundError unless @path && File.exist?(@path)
11
+ end
12
+
13
+ def inspect
14
+ backend ? backend.inspect : "<Confy::Core>"
15
+ end
16
+
17
+ def parse
18
+ @backend ||= Backend::Base.which(@path)
19
+ @backend.new @path
20
+ end
21
+
22
+ private
23
+ def set_options options
24
+ if options[:as]
25
+ @backend = Backend.const_get options[:as].to_s
26
+ end
27
+ end
28
+ end
29
+
30
+ class FileNotFoundError < StandardError; end
31
+ class UnsupportedFileExtensionError < StandardError; end
32
+ end
@@ -0,0 +1,3 @@
1
+ module Confy
2
+ VERSION = "0.2.0"
3
+ end
@@ -0,0 +1,15 @@
1
+ # Allow for recursive ostruct goodness
2
+ # TODO Less monkey patching
3
+ Hash.class_eval do
4
+ def to_ostruct
5
+ open_struct = OpenStruct.new
6
+ each { | key, value | open_struct.send("#{key}=", (value.respond_to?(:to_ostruct) ? value.to_ostruct : value) )}
7
+ open_struct
8
+ end
9
+ end
10
+
11
+ Array.class_eval do
12
+ def to_ostruct
13
+ map { | element | element.to_ostruct }
14
+ end
15
+ end
@@ -0,0 +1,16 @@
1
+ require "spec_helper"
2
+
3
+ describe Confy do
4
+ context ".parse" do
5
+ context "given a json file" do
6
+ it "should parse the file" do
7
+ path = File.join(fixture_path, "sample.json")
8
+ config = Confy.parse( path )
9
+ config.should be_an_instance_of(Confy::Backend::Json)
10
+ config.name.should == "bob"
11
+ config.age.should == "42"
12
+ end
13
+ end
14
+ end
15
+ end
16
+
@@ -0,0 +1,16 @@
1
+ require "spec_helper"
2
+
3
+ describe Confy do
4
+ context ".parse" do
5
+ context "with :as => 'SimpleAssignment'" do
6
+ it "should parse the file" do
7
+ path = File.join(fixture_path, "sample.conf")
8
+ config = Confy.parse( path, :as => "SimpleAssignment")
9
+ config.should be_an_instance_of(Confy::Backend::SimpleAssignment)
10
+ config.name.should == "james"
11
+ config.age.should == "27"
12
+ config.location.should == "Birmingham"
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,32 @@
1
+ require "spec_helper"
2
+
3
+ describe Confy do
4
+ context ".parse" do
5
+ context "given a valid path" do
6
+ context "given a supported extension" do
7
+ it "should parse the file" do
8
+ path = File.join(fixture_path, "sample.yml")
9
+ config = Confy.parse( path )
10
+ config.should be_an_instance_of(Confy::Backend::Yaml)
11
+ config.one.should == "one"
12
+ config.two.should == "two"
13
+ config.three.name.should == "bob"
14
+ end
15
+ end
16
+
17
+ context "given a unsupported extension" do
18
+ it "should raise UnsupportedFileExtension" do
19
+ path = File.join(fixture_path, "invalid.wtf")
20
+ lambda{ Confy.parse( path )}.should raise_error(Confy::UnsupportedFileExtensionError)
21
+ end
22
+ end
23
+ end
24
+
25
+ context "given a invalid path" do
26
+ it "should raise FileNotFound" do
27
+ path = "/tmp/asdf/"
28
+ lambda{ Confy.parse( path )}.should raise_error(Confy::FileNotFoundError)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1 @@
1
+ E>( o )<3
@@ -0,0 +1,6 @@
1
+ # comment
2
+ name=james
3
+ age=27
4
+ location = Birmingham
5
+
6
+ # another comment
@@ -0,0 +1 @@
1
+ {"name": "bob", "age": "42"}
@@ -0,0 +1,8 @@
1
+ <person>
2
+ <name>Bob</name>
3
+ <age>200</age>
4
+ <address>
5
+ <state>AL</state>
6
+ <city>Birmingham</city>
7
+ </address>
8
+ </person>
@@ -0,0 +1,4 @@
1
+ one: "one"
2
+ two: "two"
3
+ three:
4
+ name: "bob"
@@ -0,0 +1,10 @@
1
+ lib = File.expand_path('../../', __FILE__)
2
+ $:.unshift lib unless $:.include?(lib)
3
+
4
+ require "confy"
5
+
6
+ RSpec.configure do
7
+ def fixture_path
8
+ File.join( File.dirname(__FILE__), "fixtures" )
9
+ end
10
+ end
metadata ADDED
@@ -0,0 +1,123 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: confy
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 2
8
+ - 0
9
+ version: 0.2.0
10
+ platform: ruby
11
+ authors:
12
+ - James Cook
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-04-02 00:00:00 -05:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: crack
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ version: "0"
31
+ type: :runtime
32
+ version_requirements: *id001
33
+ - !ruby/object:Gem::Dependency
34
+ name: rspec
35
+ prerelease: false
36
+ requirement: &id002 !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ version: "0"
44
+ type: :development
45
+ version_requirements: *id002
46
+ description:
47
+ email:
48
+ - james@isotope11.com
49
+ executables: []
50
+
51
+ extensions: []
52
+
53
+ extra_rdoc_files: []
54
+
55
+ files:
56
+ - .gitignore
57
+ - Gemfile
58
+ - Gemfile.lock
59
+ - README.md
60
+ - confy.gemspec
61
+ - lib/confy.rb
62
+ - lib/confy/backend.rb
63
+ - lib/confy/backend/base.rb
64
+ - lib/confy/backend/json.rb
65
+ - lib/confy/backend/simple_assignment.rb
66
+ - lib/confy/backend/xml.rb
67
+ - lib/confy/backend/yaml.rb
68
+ - lib/confy/core.rb
69
+ - lib/confy/version.rb
70
+ - lib/hash_to_ostruct.rb
71
+ - spec/backend/json_spec.rb
72
+ - spec/backend/simple_assignment_spec.rb
73
+ - spec/confy_spec.rb
74
+ - spec/fixtures/invalid.wtf
75
+ - spec/fixtures/sample.conf
76
+ - spec/fixtures/sample.json
77
+ - spec/fixtures/sample.xml
78
+ - spec/fixtures/sample.yml
79
+ - spec/spec_helper.rb
80
+ has_rdoc: true
81
+ homepage:
82
+ licenses: []
83
+
84
+ post_install_message:
85
+ rdoc_options: []
86
+
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ segments:
95
+ - 0
96
+ version: "0"
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ none: false
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ segments:
103
+ - 1
104
+ - 3
105
+ - 6
106
+ version: 1.3.6
107
+ requirements: []
108
+
109
+ rubyforge_project: confy
110
+ rubygems_version: 1.3.7
111
+ signing_key:
112
+ specification_version: 3
113
+ summary: Configuration parser
114
+ test_files:
115
+ - spec/backend/json_spec.rb
116
+ - spec/backend/simple_assignment_spec.rb
117
+ - spec/confy_spec.rb
118
+ - spec/fixtures/invalid.wtf
119
+ - spec/fixtures/sample.conf
120
+ - spec/fixtures/sample.json
121
+ - spec/fixtures/sample.xml
122
+ - spec/fixtures/sample.yml
123
+ - spec/spec_helper.rb