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 ADDED
@@ -0,0 +1,6 @@
1
+ *.gem
2
+ bin/*
3
+ .rspec
4
+ .bundle
5
+ Gemfile.lock
6
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in yaml_pack.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1 @@
1
+ # YamlPack
data/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+ task default: :spec
@@ -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
@@ -0,0 +1,3 @@
1
+ se:
2
+ name: Sweden
3
+ population: 11
File without changes
@@ -0,0 +1,9 @@
1
+ countries:
2
+ ch:
3
+ name: Switzerland
4
+ de:
5
+ name: Germany
6
+ fr:
7
+ name: France
8
+ pl:
9
+ name: Poland
@@ -0,0 +1,3 @@
1
+ countries:
2
+ ch:
3
+ name: Schweiz
@@ -0,0 +1,9 @@
1
+ countries:
2
+ ch:
3
+ population: 8
4
+ de:
5
+ population: 80
6
+ fr:
7
+ population: 55
8
+ it:
9
+ population: 56
@@ -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: