confy 0.2.0
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/.gitignore +2 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +26 -0
- data/README.md +24 -0
- data/confy.gemspec +25 -0
- data/lib/confy.rb +22 -0
- data/lib/confy/backend.rb +18 -0
- data/lib/confy/backend/base.rb +28 -0
- data/lib/confy/backend/json.rb +15 -0
- data/lib/confy/backend/simple_assignment.rb +52 -0
- data/lib/confy/backend/xml.rb +17 -0
- data/lib/confy/backend/yaml.rb +16 -0
- data/lib/confy/core.rb +32 -0
- data/lib/confy/version.rb +3 -0
- data/lib/hash_to_ostruct.rb +15 -0
- data/spec/backend/json_spec.rb +16 -0
- data/spec/backend/simple_assignment_spec.rb +16 -0
- data/spec/confy_spec.rb +32 -0
- data/spec/fixtures/invalid.wtf +1 -0
- data/spec/fixtures/sample.conf +6 -0
- data/spec/fixtures/sample.json +1 -0
- data/spec/fixtures/sample.xml +8 -0
- data/spec/fixtures/sample.yml +4 -0
- data/spec/spec_helper.rb +10 -0
- metadata +123 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -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
|
data/README.md
ADDED
@@ -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
|
+
|
data/confy.gemspec
ADDED
@@ -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
|
data/lib/confy.rb
ADDED
@@ -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,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
|
+
|
data/lib/confy/core.rb
ADDED
@@ -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,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
|
data/spec/confy_spec.rb
ADDED
@@ -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 @@
|
|
1
|
+
{"name": "bob", "age": "42"}
|
data/spec/spec_helper.rb
ADDED
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
|