valise 0.8.2 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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