valise 0.8.2 → 0.9.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.
@@ -42,17 +42,18 @@ module Valise
42
42
  return definer
43
43
  end
44
44
 
45
- def from_here(rel_path)
46
- m = /(.*):\d+/.match(caller[0])
47
- dir = ::File::dirname(::File::expand_path(m[1]))
45
+ def handle(path, serialization, merge_diff = nil)
46
+ @target.add_handler(unpath(path),
47
+ serialization,
48
+ merge_diff)
49
+ end
48
50
 
49
- collapse(unpath(dir) + unpath(rel_path))
51
+ def serialize(path, serialization, options = nil)
52
+ @target.add_serialization_handler(path, serialization, options)
50
53
  end
51
54
 
52
- def handle(path, serialization, merge_diff = nil)
53
- @target.add_handler(unpath(path),
54
- Valise::Serialization[serialization],
55
- Valise::MergeDiff[merge_diff])
55
+ def merge(path, merge_diff, options = nil)
56
+ @target.add_merge_diff_handler(path, merge_diff, options)
56
57
  end
57
58
 
58
59
  def defaults(name=nil, &block)
@@ -0,0 +1,35 @@
1
+ require 'valise/set'
2
+
3
+ module Valise
4
+ class Set
5
+ class ExtensionsDecorator < Set
6
+ def initialize(set)
7
+ @set = set
8
+ @extensions = []
9
+ end
10
+ attr_accessor :extensions
11
+ attr_reader :set
12
+ protected :set
13
+
14
+ def inspect
15
+ super + "x#{extensions.inspect}"
16
+ end
17
+
18
+ def search_roots
19
+ set.search_roots
20
+ end
21
+
22
+ def merge_diff
23
+ set.merge_diff
24
+ end
25
+
26
+ def serialization
27
+ set.serialization
28
+ end
29
+
30
+ def get(path)
31
+ set.get(path).exts(*extensions)
32
+ end
33
+ end
34
+ end
35
+ end
data/lib/valise/set.rb CHANGED
@@ -6,11 +6,13 @@ require 'valise/stack'
6
6
  require 'valise/path-matcher'
7
7
  require 'valise/stem-decorator'
8
8
  require 'valise/set/definer'
9
+ require 'valise/set/extensions-decorator'
9
10
 
10
11
  module Valise
11
12
  class Set
12
13
  include Debugging
13
14
  include Enumerable
15
+ include Unpath
14
16
 
15
17
  def initialize
16
18
  @search_roots = []
@@ -19,32 +21,67 @@ module Valise
19
21
  end
20
22
 
21
23
  def inspect
22
- @search_roots.inspect
24
+ search_roots.inspect
23
25
  end
24
26
 
25
27
  def to_s
26
- @search_roots.map(&:to_s).join(":")
28
+ search_roots.map(&:to_s).join(":")
29
+ end
30
+
31
+ def exts(*extensions)
32
+ exts = ExtensionsDecorator.new(self)
33
+ exts.extensions = extensions
34
+ return exts
35
+ end
36
+
37
+ def transform
38
+ set = self.class.new
39
+ set.search_roots = yield search_roots
40
+ set.merge_diff = merge_diff.dup
41
+ set.serialization = serialization.dup
42
+ return set
27
43
  end
28
44
 
29
45
  def reverse
30
- set = Set.new
31
- set.search_roots = @search_roots.reverse
32
- set.merge_diff = @merge_diff.dup
33
- set.serialization = @serialization.dup
34
- set
46
+ transform do |roots|
47
+ roots.reverse
48
+ end
35
49
  end
36
50
 
37
51
  def sub_set(path)
38
52
  segments = unpath(path)
39
- set = Set.new
40
- set.search_roots = @search_roots.map do |root|
41
- new_root = root.dup
42
- new_root.segments += segments
43
- new_root
53
+ transform do |roots|
54
+ roots.map do |root|
55
+ new_root = root.dup
56
+ new_root.segments += segments
57
+ new_root
58
+ end
59
+ end
60
+ end
61
+
62
+ def stemmed(path)
63
+ segments = unpath(path)
64
+ transform do |roots|
65
+ roots.map do |root|
66
+ StemDecorator.new(segments, root)
67
+ end
68
+ end
69
+ end
70
+
71
+ def not_above(root)
72
+ index = search_roots.index(root)
73
+ raise Errors::RootNotInSet if index.nil?
74
+ transform do |roots|
75
+ roots[index..-1]
76
+ end
77
+ end
78
+
79
+ def below(root)
80
+ index = search_roots.index(root)
81
+ raise Errors::RootNotInSet if index.nil?
82
+ transform do |roots|
83
+ roots[(index+1)..-1]
44
84
  end
45
- set.merge_diff = @merge_diff.dup
46
- set.serialization = @serialization.dup
47
- set
48
85
  end
49
86
 
50
87
  def define(&block)
@@ -58,21 +95,33 @@ module Valise
58
95
  end
59
96
 
60
97
  def prepend_search_root(search_root)
61
- @search_roots.unshift(search_root)
98
+ search_roots.unshift(search_root)
62
99
  end
63
100
 
64
101
  def add_search_root(search_root)
65
- @search_roots << search_root
102
+ search_roots << search_root
66
103
  end
67
104
 
68
105
  def add_handler(segments, serialization_class, merge_diff_class)
69
- @merge_diff[segments] = merge_diff_class unless merge_diff_class.nil?
70
- @serialization[segments] = serialization_class unless serialization_class.nil?
106
+ add_serialization_handler(segments, serialization_class)
107
+ add_merge_handler(segments, merge_diff_class)
108
+ end
109
+
110
+ def add_serialization_handler(pattern, serializer, options = nil)
111
+ return if serializer.nil?
112
+ Strategies::Serialization.check!(serializer)
113
+ serialization[pattern] = [serializer, options]
114
+ end
115
+
116
+ def add_merge_handler(pattern, merger, options = nil)
117
+ return if merger.nil?
118
+ Strategies::MergeDiff.check!(merger)
119
+ merge_diff[pattern] = [merger, options]
71
120
  end
72
121
 
73
122
  def +(other)
74
123
  result = self.class.new
75
- result.search_roots = @search_roots + other.search_roots
124
+ result.search_roots = search_roots + other.search_roots
76
125
  result.merge_handlers(*other.handler_lists)
77
126
  result.merge_handlers(*handler_lists)
78
127
  return result
@@ -83,38 +132,36 @@ module Valise
83
132
  :merge_diff=, :merge_diff,
84
133
  :serialization=, :serialization
85
134
 
86
- include Unpath
87
- def get(path)
88
- return Stack.new(path, self,
89
- merge_diff(path),
90
- serialization(path))
135
+ def merge_diff_for(stack)
136
+ type, options = *(merge_diff[unpath(stack.segments)] || [])
137
+ options = (options || {}).merge(:stack => stack)
138
+ Strategies::MergeDiff.instance(type, options)
91
139
  end
92
140
 
93
- def merge_diff(path)
94
- @merge_diff[unpath(path)]
141
+ def serialization_for(stack)
142
+ type, options = *serialization[unpath(stack.segments)]
143
+ Strategies::Serialization.instance(type, options)
95
144
  end
96
145
 
97
- def serialization(path)
98
- @serialization[unpath(path)]
146
+ def merge_handlers(new_merge_diff, new_serialization)
147
+ merge_diff.merge!(new_merge_diff)
148
+ serialization.merge!(new_serialization)
99
149
  end
100
150
 
101
- def merge_handlers(merge_diff, serialization)
102
- @merge_diff.merge!(merge_diff)
103
- @serialization.merge!(serialization)
151
+ def handler_lists
152
+ [merge_diff, serialization]
104
153
  end
105
154
 
106
- def handler_lists
107
- [@merge_diff, @serialization]
155
+ def get(path)
156
+ Stack.new(path, self)
108
157
  end
109
158
 
110
159
  def find(path)
111
- item = get(path).present.first
112
- return item unless item.nil?
113
- raise Errors::NotFound, "#{path} not found in #{@search_roots.inspect}"
160
+ get(path).find
114
161
  end
115
162
 
116
163
  def each(&block)
117
- @search_roots.each(&block)
164
+ search_roots.each(&block)
118
165
  end
119
166
 
120
167
  def glob(path_matcher)
@@ -125,7 +172,7 @@ module Valise
125
172
  visited = {}
126
173
  path_matcher = PathMatcher.build(path_matcher)
127
174
 
128
- @search_roots.each do |root|
175
+ search_roots.each do |root|
129
176
  root.each do |segments|
130
177
  next unless path_matcher === segments
131
178
  unless visited.has_key?(segments)
@@ -143,28 +190,12 @@ module Valise
143
190
  glob(ALL_FILES, &block)
144
191
  end
145
192
 
146
- def not_above(root)
147
- index = @search_roots.index(root)
148
- raise Errors::RootNotInSet if index.nil?
149
- set = self.class.new
150
- set.search_roots = @search_roots[index..-1]
151
- set
152
- end
153
-
154
- def below(root)
155
- index = @search_roots.index(root)
156
- raise Errors::RootNotInSet if index.nil?
157
- set = self.class.new
158
- set.search_roots = @search_roots[(index+1)..-1]
159
- set
160
- end
161
-
162
193
  def depth_of(root)
163
- return @search_roots.index(root)
194
+ return search_roots.index(root)
164
195
  end
165
196
 
166
197
  def [](index)
167
- return @search_roots[index]
198
+ return search_roots[index]
168
199
  end
169
200
 
170
201
  def populate(to = self)
@@ -0,0 +1,53 @@
1
+ require 'valise/stack'
2
+
3
+ module Valise
4
+ class Stack
5
+ class ExtensionsDecorator < Stack
6
+ def initialize(stack)
7
+ @stack = stack
8
+ @extensions = []
9
+ @stacks = Hash.new{|h,segments| h[segments] = @stack.valise.get(segments) }
10
+ end
11
+
12
+ attr_accessor :extensions
13
+
14
+ def inspect
15
+ @stack.inspect + "x#{extensions.inspect}"
16
+ end
17
+
18
+ def valise
19
+ @stack.valise
20
+ end
21
+
22
+ def reget(root)
23
+ decorated = self.new(super)
24
+ decorated.extensions = self.extensions
25
+ decorated
26
+ end
27
+
28
+ def merged(item)
29
+ item.stack.merged(item)
30
+ end
31
+
32
+ def diffed(item, value)
33
+ item.stack.diffed(item, value)
34
+ end
35
+
36
+ def rel_path
37
+ @stack.rel_path
38
+ end
39
+
40
+ def each
41
+ return enum_for(:each) unless block_given?
42
+ @stack.each do |item|
43
+ @extensions.each do |ext|
44
+ dir = item.segments.dup
45
+ file = dir.pop
46
+ ext_stack = @stacks[dir + [file + ext]]
47
+ yield(ext_stack.item_for(item.root))
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
data/lib/valise/stack.rb CHANGED
@@ -1,177 +1,84 @@
1
- # New plan here: Stack is returned by "find" and responds to many of the
2
- # methods that Item current responds to. It caches results, essentially, of
3
- # the find search - maybe at creation, with possiblity for reload/update.
4
- # Also, makes possible use cases like file promotion, merging, etc.
5
- #
6
- # Still need to resolve the interface for parsing and merging files.
7
- #
8
- # * something from the Valise definition - would have to be part of defaults,
9
- # which further is a problem if a file doesn't exist in the defaults
10
- #
11
- # * a filetype mapping
12
- #
13
- # * Is it a find-time user thing
14
-
1
+ require 'valise/utils'
2
+ require 'valise/item-enum'
3
+ require 'valise/strategies/merge-diff'
4
+ require 'valise/stack/extensions-decorator'
15
5
 
16
6
  module Valise
17
- module ItemEnum
18
- include Enumerable
19
-
20
- class Enumerator
21
- include ItemEnum
22
-
23
- def initialize(list, &filter)
24
- @list = list
25
- @filter = proc(&filter)
26
- end
7
+ class Stack
8
+ include Unpath
9
+ include ItemEnum
27
10
 
28
- def each
29
- @list.each do |item|
30
- next unless @filter[item]
31
- yield(item)
32
- end
33
- end
11
+ def inspect
12
+ "<default>:#{(@segments||%w{?}).join "/"} #{@valise.inspect}"
34
13
  end
35
14
 
36
- def writable
37
- Enumerator.new(self) do |item|
38
- item.writable?
39
- end
15
+ def initialize(path, set)
16
+ @segments = collapse(unpath(path))
17
+ @valise = set
40
18
  end
41
19
 
42
- def absent
43
- Enumerator.new(self) do |item|
44
- not item.present?
45
- end
46
- end
20
+ attr_reader :segments, :valise
47
21
 
48
- def present
49
- Enumerator.new(self) do |item|
50
- item.present?
51
- end
52
- end
53
- end
54
-
55
- class MergeDiff
56
- @@classes = {}
57
- def self.[](index)
58
- @@classes[index]
22
+ def rel_path
23
+ repath(@segments)
59
24
  end
60
25
 
61
- def self.register(index)
62
- @@classes[index] = self
26
+ def merge_diff
27
+ @valise.merge_diff_for(self)
63
28
  end
64
29
 
65
- def initialize(stack)
66
- @stack = stack
30
+ def dump_load
31
+ @valise.serialization_for(self)
67
32
  end
68
33
 
69
- class TopMost < MergeDiff
70
- register :topmost
71
-
72
- def merge(item)
73
- item.load_contents
74
- end
75
-
76
- def diff(item, value)
77
- value
78
- end
34
+ def merged(item)
35
+ merge_diff.merge(item)
79
36
  end
80
37
 
81
- class HashMerge < MergeDiff
82
- register :hash_merge
83
-
84
- def merge(item)
85
- merge_stack(@stack.not_above(item).reverse)
86
- end
87
-
88
- def merge_stack(stack)
89
- stack.present.inject({}) do |hash, item|
90
- deep_merge(hash, item.load_contents)
91
- end
92
- end
93
-
94
- def deep_merge(collect, item)
95
- item.each_pair do |key, value|
96
- case value
97
- when Hash
98
- collect[key] ||= {}
99
- deep_merge(collect[key], value)
100
- else
101
- collect[key] = value
102
- end
103
- end
104
- collect
105
- end
106
-
107
- def diff(item, new_contents)
108
- diff_with = merge_stack(@stack.below(item).reverse)
109
- result = new_contents.dup
110
-
111
- diff_with.each_pair do |key, value|
112
- if result.has_key?(key)
113
- if result[key] == value
114
- result.delete(key)
115
- end
116
- else
117
- result[key] = nil
118
- end
119
- end
120
-
121
- result
122
- end
38
+ def diffed(item, value)
39
+ merge_diff.diff(item, value)
123
40
  end
124
- end
125
-
126
- class Stack
127
- include Unpath
128
- include ItemEnum
129
41
 
130
- def inspect
131
- "<default>:#{@segments.join "/"} #{@valise.inspect}"
42
+ def not_above(item)
43
+ reget(valise.not_above(item.root))
132
44
  end
133
45
 
134
- def initialize(path, set, merge_class, dump_load)
135
- @segments = collapse(unpath(path))
136
- @valise = set
137
- @merge_diff = (merge_class || MergeDiff::TopMost).new(self)
138
- @dump_load = dump_load
46
+ def below(item)
47
+ reget(valise.below(item.root))
139
48
  end
140
49
 
141
- attr_reader :segments
142
-
143
- def merged(item)
144
- @merge_diff.merge(item)
50
+ def reverse
51
+ reget(valise.reverse)
145
52
  end
146
53
 
147
- def rel_path
148
- repath(@segments)
54
+ def depth_of(item)
55
+ valise.depth_of(item.root)
149
56
  end
150
57
 
151
- def diffed(item, value)
152
- @merge_diff.diff(item, value)
58
+ def find
59
+ item = present.first
60
+ return item unless item.nil?
61
+ raise Errors::NotFound, "#{rel_path} not found in #{@valise.inspect}"
153
62
  end
154
63
 
155
- def not_above(item)
156
- Stack.new(@segments, @valise.not_above(item.root), @merge_diff.class, @dump_load)
64
+ def exts(*extensions)
65
+ exts = ExtensionsDecorator.new(self)
66
+ exts.extensions = extensions
67
+ return exts
157
68
  end
158
69
 
159
- def below(item)
160
- Stack.new(@segments, @valise.below(item.root), @merge_diff.class, @dump_load)
70
+ def reget(root)
71
+ root.get(@segments)
161
72
  end
162
73
 
163
- def depth_of(item)
164
- @valise.depth_of(item.root)
74
+ def item_for(root)
75
+ Item.new(self, root, dump_load)
165
76
  end
166
77
 
167
78
  def each
168
- @valise.each do |root|
169
- yield(Item.new(self, root, @dump_load))
79
+ valise.each do |root|
80
+ yield(item_for(root))
170
81
  end
171
82
  end
172
-
173
- def reverse
174
- Stack.new(@segments, @valise.reverse, @merge_diff.class, @dump_load)
175
- end
176
83
  end
177
84
  end
@@ -60,10 +60,6 @@ module Valise
60
60
  return false
61
61
  end
62
62
 
63
- def insert(item)
64
- @search_root.insert(item)
65
- end
66
-
67
63
  def get_from(item)
68
64
  @search_root.get_from(item)
69
65
  end
@@ -0,0 +1,68 @@
1
+ require 'valise/strategies/set'
2
+
3
+ module Valise
4
+ module Strategies
5
+ class MergeDiff < Set
6
+ def initialize(options)
7
+ @stack = options[:stack]
8
+ end
9
+
10
+ class TopMost < MergeDiff
11
+ register :topmost
12
+ default
13
+
14
+ def merge(item)
15
+ item.load_contents
16
+ end
17
+
18
+ def diff(item, value)
19
+ value
20
+ end
21
+ end
22
+
23
+ class HashMerge < MergeDiff
24
+ register :hash_merge
25
+
26
+ def merge(item)
27
+ merge_stack(@stack.not_above(item).reverse)
28
+ end
29
+
30
+ def merge_stack(stack)
31
+ stack.present.inject({}) do |hash, item|
32
+ deep_merge(hash, item.load_contents)
33
+ end
34
+ end
35
+
36
+ def deep_merge(collect, item)
37
+ item.each_pair do |key, value|
38
+ case value
39
+ when Hash
40
+ collect[key] ||= {}
41
+ deep_merge(collect[key], value)
42
+ else
43
+ collect[key] = value
44
+ end
45
+ end
46
+ collect
47
+ end
48
+
49
+ def diff(item, new_contents)
50
+ diff_with = merge_stack(@stack.below(item).reverse)
51
+ result = new_contents.dup
52
+
53
+ diff_with.each_pair do |key, value|
54
+ if result.has_key?(key)
55
+ if result[key] == value
56
+ result.delete(key)
57
+ end
58
+ else
59
+ result[key] = nil
60
+ end
61
+ end
62
+
63
+ result
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,33 @@
1
+ require 'valise/strategies/set'
2
+
3
+ module Valise
4
+ module Strategies
5
+ class Serialization < Set
6
+ register :raw
7
+ default
8
+
9
+ def initialize(options)
10
+ end
11
+
12
+ def dump(item)
13
+ item.load_contents
14
+ end
15
+
16
+ def load(item)
17
+ item.raw_contents
18
+ end
19
+
20
+ class YAML < Serialization
21
+ register :yaml
22
+
23
+ def dump(item)
24
+ ::YAML::dump(super)
25
+ end
26
+
27
+ def load(item)
28
+ ::YAML::load(super)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end