yaml_pack 0.0.1.alpha
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 +6 -0
- data/Gemfile +4 -0
- data/README.md +1 -0
- data/Rakefile +5 -0
- data/lib/core_ext/hash.rb +17 -0
- data/lib/yaml_pack.rb +85 -0
- data/spec/.DS_Store +0 -0
- data/spec/fixtures/.DS_Store +0 -0
- data/spec/fixtures/yaml_pack/countries/sweden.yml +3 -0
- data/spec/fixtures/yaml_pack/empty.yml +0 -0
- data/spec/fixtures/yaml_pack/names.yml +9 -0
- data/spec/fixtures/yaml_pack/names_german.yml +3 -0
- data/spec/fixtures/yaml_pack/population.yml +9 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/yaml_pack/yaml_pack_spec.rb +82 -0
- data/yaml_pack.gemspec +25 -0
- metadata +83 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# YamlPack
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# Extend Hash with recursive merging abilities
|
2
|
+
class Hash
|
3
|
+
# Deep merge method. Silly name prevents overwriting other implementations.
|
4
|
+
#
|
5
|
+
# Inspired from:
|
6
|
+
# http://www.gemtacular.com/gemdocs/cerberus-0.2.2/doc/classes/Hash.html
|
7
|
+
# File lib/cerberus/utils.rb, line 42
|
8
|
+
def yaml_pack_deep_merge!(second)
|
9
|
+
second.each_pair do |k,v|
|
10
|
+
if self[k].is_a?(Hash) and second[k].is_a?(Hash)
|
11
|
+
self[k].yaml_pack_deep_merge!(second[k])
|
12
|
+
else
|
13
|
+
self[k] = second[k]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/yaml_pack.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'core_ext/hash'
|
2
|
+
|
3
|
+
class YamlPack
|
4
|
+
VERSION = "0.0.1.alpha"
|
5
|
+
|
6
|
+
KEY_CONVERTERS = {
|
7
|
+
:symbolize => Proc.new{|key, previous_keys| key.respond_to?(:to_sym) ? key.to_sym : key }
|
8
|
+
}.freeze
|
9
|
+
|
10
|
+
attr_reader :files, :base_dir
|
11
|
+
|
12
|
+
def self.load_deep_merged(files, opts = {})
|
13
|
+
new(files, opts).load_deep_merged
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(files, opts = {})
|
17
|
+
@files = [files].flatten
|
18
|
+
|
19
|
+
@base_dir = opts.fetch(:base_dir, nil)
|
20
|
+
@with_erb = opts.fetch(:erb, true)
|
21
|
+
@key_converter = opts.fetch(:key_converter, nil)
|
22
|
+
@header_file = opts.fetch(:header_file, nil)
|
23
|
+
|
24
|
+
if KEY_CONVERTERS.has_key?(@key_converter)
|
25
|
+
@key_converter = KEY_CONVERTERS[@key_converter]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def load_deep_merged
|
30
|
+
hsh = {}
|
31
|
+
|
32
|
+
files.select{|f| File.exists?(f) }.each do |f|
|
33
|
+
content = self.content(f)
|
34
|
+
content = ERB.new(content).result(binding) if @with_erb
|
35
|
+
|
36
|
+
result = YAML::load(content) || {}
|
37
|
+
result = prepend_subfolders(f, result) if @base_dir
|
38
|
+
result = convert_keys_recursive(result) if @key_converter
|
39
|
+
|
40
|
+
hsh.yaml_pack_deep_merge!(result)
|
41
|
+
end
|
42
|
+
|
43
|
+
hsh
|
44
|
+
end
|
45
|
+
|
46
|
+
def content(file_path)
|
47
|
+
body = File.read(file_path) || ""
|
48
|
+
header + body
|
49
|
+
end
|
50
|
+
|
51
|
+
def header
|
52
|
+
(@header_file && File.exists?(@header_file)) ? File.read(@header_file) : ""
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.subfolders(base_dir, file_path)
|
56
|
+
base_dir = "#{base_dir}/".gsub("//", '/') # hack to always have a trailing /
|
57
|
+
file_path.gsub(/^#{base_dir}/, '').split('/')[0...-1]
|
58
|
+
end
|
59
|
+
|
60
|
+
protected
|
61
|
+
|
62
|
+
|
63
|
+
def convert_keys_recursive(result, previous_keys = [])
|
64
|
+
if result.is_a?(Hash)
|
65
|
+
hsh = {}
|
66
|
+
result.each do |key, value|
|
67
|
+
converted_key = @key_converter.call(key, previous_keys)
|
68
|
+
hsh[converted_key] = convert_keys_recursive(value, [*previous_keys, key])
|
69
|
+
end
|
70
|
+
hsh
|
71
|
+
else # If it's not a hash, return the object itself (end of recursion)
|
72
|
+
result
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def prepend_subfolders(file_path, object)
|
77
|
+
subfolders(file_path).inject(object) do |object, subfolder|
|
78
|
+
{subfolder => object}
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def subfolders(file_path)
|
83
|
+
self.class.subfolders(base_dir, file_path)
|
84
|
+
end
|
85
|
+
end
|
data/spec/.DS_Store
ADDED
Binary file
|
Binary file
|
File without changes
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'yaml_pack'
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
describe YamlPack do
|
5
|
+
it "should load empty file and return empty hash" do
|
6
|
+
result = YamlPack.new('spec/fixtures/yaml_pack/empty.yml').load_deep_merged
|
7
|
+
|
8
|
+
result.should == {}
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should load one yaml file" do
|
12
|
+
result = YamlPack.new('spec/fixtures/yaml_pack/names.yml').load_deep_merged
|
13
|
+
|
14
|
+
result['countries']['ch']['name'].should == 'Switzerland'
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should convert keys" do
|
18
|
+
f = 'spec/fixtures/yaml_pack/names.yml'
|
19
|
+
toolbox = YamlPack.new(f, :key_converter => Proc.new{|k| k.to_sym})
|
20
|
+
result = toolbox.load_deep_merged
|
21
|
+
result[:countries][:ch][:name].should == 'Switzerland'
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
it "should allow for key_converters with previous keys" do
|
26
|
+
f = 'spec/fixtures/yaml_pack/names.yml'
|
27
|
+
toolbox = YamlPack.new(f, :key_converter => Proc.new{|key, previous_keys| [previous_keys, key].flatten.join("_")})
|
28
|
+
result = toolbox.load_deep_merged
|
29
|
+
result['countries']['countries_ch']['countries_ch_name'].should == 'Switzerland'
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
it "should merge two yaml files" do
|
34
|
+
files = [
|
35
|
+
'spec/fixtures/yaml_pack/names.yml',
|
36
|
+
'spec/fixtures/yaml_pack/population.yml'
|
37
|
+
]
|
38
|
+
|
39
|
+
result = YamlPack.new(files).load_deep_merged
|
40
|
+
|
41
|
+
# deep merge ch
|
42
|
+
result['countries']['ch']['name'].should == 'Switzerland'
|
43
|
+
result['countries']['ch']['population'].should == 8
|
44
|
+
# items specific to population.yml
|
45
|
+
result['countries']['it']['population'].should == 56
|
46
|
+
# items specific to names.yml
|
47
|
+
result['countries']['pl']['name'].should == 'Poland'
|
48
|
+
end
|
49
|
+
|
50
|
+
it "files should overwrite previous files" do
|
51
|
+
files = [
|
52
|
+
'spec/fixtures/yaml_pack/names.yml',
|
53
|
+
'spec/fixtures/yaml_pack/names_german.yml'
|
54
|
+
]
|
55
|
+
|
56
|
+
result = YamlPack.new(files).load_deep_merged
|
57
|
+
result['countries']['ch']['name'].should == 'Schweiz'
|
58
|
+
end
|
59
|
+
|
60
|
+
it "replicate nesting of subfolders into resulting hash" do
|
61
|
+
files = [
|
62
|
+
'spec/fixtures/yaml_pack/names.yml',
|
63
|
+
'spec/fixtures/yaml_pack/countries/sweden.yml'
|
64
|
+
]
|
65
|
+
|
66
|
+
result = YamlPack.new(files, :base_dir => 'spec/fixtures/yaml_pack').load_deep_merged
|
67
|
+
result['countries']['ch']['name'].should == 'Switzerland'
|
68
|
+
result['countries']['se']['name'].should == 'Sweden'
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
it "#subfolders" do
|
73
|
+
YamlPack.subfolders("/foo/", "/foo/baz.yml").should == []
|
74
|
+
YamlPack.subfolders("/foo/", "/foo/bar/baz.yml").should == ['bar']
|
75
|
+
YamlPack.subfolders("/foo/", "/foo/bar/baz/lorem.yml").should == ['bar', 'baz']
|
76
|
+
|
77
|
+
YamlPack.subfolders("foo/", "foo/bar/baz.yml").should == ['bar']
|
78
|
+
YamlPack.subfolders("/foo", "/foo/baz.yml").should == []
|
79
|
+
YamlPack.subfolders("", "/foo/baz.yml").should == ['foo']
|
80
|
+
YamlPack.subfolders(nil, "/foo/baz.yml").should == ['foo']
|
81
|
+
end
|
82
|
+
end
|
data/yaml_pack.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "yaml_pack"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "yaml_pack"
|
7
|
+
s.version = YamlPack::VERSION
|
8
|
+
s.authors = ["sebastian"]
|
9
|
+
s.email = ["sebastian.burkhard@gmail.com"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{Framework for complex yaml configuration file structures.}
|
12
|
+
s.description = %q{
|
13
|
+
YamlPack is a small framework for writing large and complex configuration files in yml.
|
14
|
+
It supports nesting and merging merging yaml files.
|
15
|
+
}
|
16
|
+
|
17
|
+
s.rubyforge_project = "yaml_pack"
|
18
|
+
|
19
|
+
s.files = `git ls-files`.split("\n")
|
20
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
21
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
22
|
+
s.require_paths = ["lib"]
|
23
|
+
|
24
|
+
s.add_development_dependency "rspec"
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: yaml_pack
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1.alpha
|
5
|
+
prerelease: 6
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- sebastian
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-02-23 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: &70121952134780 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70121952134780
|
25
|
+
description: ! "\n YamlPack is a small framework for writing large and complex
|
26
|
+
configuration files in yml.\n It supports nesting and merging merging yaml files.\n
|
27
|
+
\ "
|
28
|
+
email:
|
29
|
+
- sebastian.burkhard@gmail.com
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- .gitignore
|
35
|
+
- Gemfile
|
36
|
+
- README.md
|
37
|
+
- Rakefile
|
38
|
+
- lib/core_ext/hash.rb
|
39
|
+
- lib/yaml_pack.rb
|
40
|
+
- spec/.DS_Store
|
41
|
+
- spec/fixtures/.DS_Store
|
42
|
+
- spec/fixtures/yaml_pack/countries/sweden.yml
|
43
|
+
- spec/fixtures/yaml_pack/empty.yml
|
44
|
+
- spec/fixtures/yaml_pack/names.yml
|
45
|
+
- spec/fixtures/yaml_pack/names_german.yml
|
46
|
+
- spec/fixtures/yaml_pack/population.yml
|
47
|
+
- spec/spec_helper.rb
|
48
|
+
- spec/yaml_pack/yaml_pack_spec.rb
|
49
|
+
- yaml_pack.gemspec
|
50
|
+
homepage: ''
|
51
|
+
licenses: []
|
52
|
+
post_install_message:
|
53
|
+
rdoc_options: []
|
54
|
+
require_paths:
|
55
|
+
- lib
|
56
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ! '>'
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: 1.3.1
|
68
|
+
requirements: []
|
69
|
+
rubyforge_project: yaml_pack
|
70
|
+
rubygems_version: 1.8.11
|
71
|
+
signing_key:
|
72
|
+
specification_version: 3
|
73
|
+
summary: Framework for complex yaml configuration file structures.
|
74
|
+
test_files:
|
75
|
+
- spec/fixtures/.DS_Store
|
76
|
+
- spec/fixtures/yaml_pack/countries/sweden.yml
|
77
|
+
- spec/fixtures/yaml_pack/empty.yml
|
78
|
+
- spec/fixtures/yaml_pack/names.yml
|
79
|
+
- spec/fixtures/yaml_pack/names_german.yml
|
80
|
+
- spec/fixtures/yaml_pack/population.yml
|
81
|
+
- spec/spec_helper.rb
|
82
|
+
- spec/yaml_pack/yaml_pack_spec.rb
|
83
|
+
has_rdoc:
|