cloud-templates 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4dd48a14067126047f160caf3ffdd1c48e2ff4e7
4
- data.tar.gz: ef684b50d03d1fb6b69170b8aa10444895743c52
3
+ metadata.gz: 836e106f34778808188ac4200dd45f36a91f675d
4
+ data.tar.gz: 505466ae879f3544b9a9577e57798691c9f5131a
5
5
  SHA512:
6
- metadata.gz: c79052077800068fa8b569b2785f5ca6941a2193c23ead7f48713698a1e3443e9e735e849fec75166db08b66f5574d0e86877db0f7a0bab30fd421665be408e7
7
- data.tar.gz: be49da0fd91ad960a80cdd07f72bf7306ceee9e8ebddada8f11cada9e70ba397d296a831254af515a247d3167edcfe9c847904486299f56e8c139ee2f3f55df4
6
+ metadata.gz: ae62c2f030a6f5262f565953dd0f4329cddfe70f53e7ac882061bd6ed10074741b397325d89053f13e30b9cf73712d20e4d8b1d6878c1ca65338c5718cb56f37
7
+ data.tar.gz: c8c4f1f13b841e2d0c597875349c60d149bc1227f7a13ee838dbc263ad59226c0406843aafe4a2d60bd29dd863e999d8f604b447a8ab624b00553a2447da8a47
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'cloud-templates'
3
- s.version = '0.1.0'
3
+ s.version = '0.2.0'
4
4
  s.license = 'Apache 2.0'
5
5
  s.summary = 'Hierarchical data templates'
6
6
  s.description = 'MVC-based templating framework for hierarchical data structures. ' \
@@ -107,6 +107,20 @@ module Aws
107
107
  options[:root]
108
108
  end
109
109
 
110
+ # Artifact's look-up path through all ancestors
111
+ def lookup_path
112
+ acc = [label]
113
+ ancestor = parent
114
+
115
+ until ancestor.nil?
116
+ acc << ancestor.label
117
+ ancestor = ancestor.parent
118
+ end
119
+
120
+ acc << root
121
+ acc.reverse!
122
+ end
123
+
110
124
  ##
111
125
  # Artifact's parent
112
126
  #
@@ -132,8 +146,7 @@ module Aws
132
146
  # * +params+ - input parameters hash to be used during following
133
147
  # hash transformations and expansions.
134
148
  def initialize(params)
135
- @options = Utils::Options.new(params)
136
- process_options(params)
149
+ @options = Utils::Options.new(defaults, params)
137
150
  end
138
151
  end
139
152
  end
@@ -0,0 +1,88 @@
1
+ require 'aws/templates/render'
2
+ require 'aws/templates/utils/parametrized'
3
+ require 'aws/templates/utils/dependency'
4
+
5
+ module Aws
6
+ module Templates
7
+ module Render
8
+ module Utils
9
+ ##
10
+ # Render for object introspection
11
+ #
12
+ # Used by Inspectable to provide introspection mechanism (inspect) detached from the objects
13
+ # themselves. Standard framework rendering mechanism is used.
14
+ module Inspect
15
+ extend Aws::Templates::Render
16
+
17
+ DEFAULT_RECURSION_DEPTH = 3
18
+
19
+ def self.recursion_depth
20
+ @recursion_depth || DEFAULT_RECURSION_DEPTH
21
+ end
22
+
23
+ def self.recursion_depth=(depth)
24
+ @recursion_depth = Integer(depth)
25
+ end
26
+
27
+ ##
28
+ # Basic inspection render
29
+ #
30
+ # Defines "depth" property which is used to control recursion depth during object
31
+ # introspection.
32
+ class InspectView < BasicView
33
+ def depth
34
+ (parameters.nil? ? Inspect.recursion_depth : Integer(parameters)) - 1
35
+ end
36
+ end
37
+
38
+ define_view(::Object, InspectView) do
39
+ def to_rendered
40
+ depth > 0 ? instance.inspect : instance.to_s
41
+ end
42
+ end
43
+
44
+ define_view(::Hash, InspectView) do
45
+ def to_rendered
46
+ if depth > 0
47
+ "{#{instance.map { |k, v| render_pair(k, v) }.join(',')}}"
48
+ else
49
+ instance.empty? ? '{}' : '{...}'
50
+ end
51
+ end
52
+
53
+ def render_pair(k, v)
54
+ "#{rendered_for(k, depth)}: #{rendered_for(v, depth)}"
55
+ end
56
+ end
57
+
58
+ define_view(::Enumerable, InspectView) do
59
+ def to_rendered
60
+ if depth > 0
61
+ "#{instance.class}[#{instance.map { |elem| rendered_for(elem, depth) }.join(',')}]"
62
+ else
63
+ "#{instance.class}#{instance.empty? ? '[]' : '[...]'}"
64
+ end
65
+ end
66
+ end
67
+
68
+ define_view(Templates::Utils::Dependency, InspectView) do
69
+ def to_rendered
70
+ 'Dependency(' \
71
+ "#{rendered_for(instance.object, depth)}" \
72
+ " => #{rendered_for(instance.dependencies, depth)})"
73
+ end
74
+ end
75
+
76
+ define_view(Templates::Utils::Parametrized, InspectView) do
77
+ def to_rendered
78
+ return instance.to_s unless depth > 0
79
+ "#{instance}" \
80
+ "{parameters: #{rendered_for(instance.parameters_map, depth)}," \
81
+ " dependencies: #{rendered_for(instance.dependencies, depth)}}"
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,45 @@
1
+ require 'aws/templates/render'
2
+ require 'aws/templates/artifact'
3
+ require 'aws/templates/utils/parametrized/nested'
4
+ require 'aws/templates/utils/dependency'
5
+
6
+ module Aws
7
+ module Templates
8
+ module Render
9
+ module Utils
10
+ ##
11
+ # Stringifying render
12
+ #
13
+ # Used by Inspectable module to provide stringification mechanism (to_s) detached from
14
+ # the objects themselves. Standard framework rendering mechanism is used.
15
+ module Stringify
16
+ extend Aws::Templates::Render
17
+
18
+ define_view(::Object) do
19
+ def to_rendered
20
+ instance.to_s
21
+ end
22
+ end
23
+
24
+ define_view(::Aws::Templates::Utils::Dependency) do
25
+ def to_rendered
26
+ instance.object.to_s
27
+ end
28
+ end
29
+
30
+ define_view(Templates::Artifact) do
31
+ def to_rendered
32
+ "#{instance.class}(#{instance.lookup_path.map(&:inspect).join('/')})"
33
+ end
34
+ end
35
+
36
+ define_view(Templates::Utils::Parametrized::Nested) do
37
+ def to_rendered
38
+ "#{instance.class}(in: #{instance.parent})"
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -86,8 +86,9 @@ module Aws
86
86
  # Render the object
87
87
  #
88
88
  # Renders passed object with the view default render
89
- def rendered_for(obj)
90
- render.view_for(obj, parameters).to_rendered
89
+ def rendered_for(obj, parameters_override = nil)
90
+ render.view_for(obj, parameters_override.nil? ? parameters : parameters_override)
91
+ .to_rendered
91
92
  end
92
93
 
93
94
  ##
@@ -61,6 +61,11 @@ module Aws
61
61
  @hash.include?(k)
62
62
  end
63
63
 
64
+ # The class already supports recursive concept so return self
65
+ def to_recursive
66
+ self
67
+ end
68
+
64
69
  ##
65
70
  # Create wrapper object
66
71
  #
@@ -103,18 +108,13 @@ module Aws
103
108
  # prioritizing the ones made later in the class hierarchy. The method
104
109
  # is working correctly with both parent classes and all Default
105
110
  # mixins used in between.
106
- def process_options(params = nil)
111
+ def defaults
107
112
  # iterating through all ancestors with defaults
108
- ancestors_with_defaults.reverse_each do |mod|
109
- # ... through all defaults of particular ancestor
110
- mod.defaults.each do |defaults_definition|
111
- # merge the default definition with options
112
- options.merge!(Definition.new(defaults_definition, self))
113
+ ancestors_with_defaults.inject(Options.new) do |opts, mod|
114
+ mod.defaults.inject(opts) do |acc, defaults_definition|
115
+ acc.merge!(Definition.new(defaults_definition, self))
113
116
  end
114
117
  end
115
-
116
- # re-inforce caller-specified overrides
117
- options.merge!(params) if params
118
118
  end
119
119
 
120
120
  private
@@ -123,9 +123,8 @@ module Aws
123
123
  self
124
124
  .class
125
125
  .ancestors
126
- .select do |mod|
127
- (mod != Default) && mod.ancestors.include?(Default)
128
- end
126
+ .select { |mod| (mod != Default) && mod.ancestors.include?(Default) }
127
+ .reverse!
129
128
  end
130
129
  end
131
130
 
@@ -134,6 +133,12 @@ module Aws
134
133
  #
135
134
  # It's a DSL extension to declaratively define defaults
136
135
  class_scope do
136
+ ##
137
+ # To mark hash branch as deleted
138
+ def deleted
139
+ Aws::Templates::Utils::DELETED_MARKER
140
+ end
141
+
137
142
  ##
138
143
  # Defaults for the input hash
139
144
  #
@@ -1,6 +1,7 @@
1
1
  require 'set'
2
2
  require 'aws/templates/utils/dependency/object'
3
3
  require 'aws/templates/utils/dependency/enumerable'
4
+ require 'aws/templates/utils/inspectable'
4
5
 
5
6
  module Aws
6
7
  module Templates
@@ -15,6 +16,8 @@ module Aws
15
16
  # * Dependecy can be applied case-by-case basis whereas singleton is attached to the object
16
17
  # itself
17
18
  class Dependency < BasicObject
19
+ include Inspectable
20
+
18
21
  ##
19
22
  # Equality
20
23
  #
@@ -46,7 +49,7 @@ module Aws
46
49
  end
47
50
 
48
51
  # mark the object as dependency
49
- def as_dependency
52
+ def as_a_dependency
50
53
  self
51
54
  end
52
55
 
@@ -0,0 +1,22 @@
1
+ module Aws
2
+ module Templates
3
+ module Utils
4
+ ##
5
+ # Inspect mixin.
6
+ #
7
+ # Mixin provides means of composing inspect strings for objects through framework's rendering
8
+ # mechanism.
9
+ module Inspectable
10
+ def to_s
11
+ ::Kernel.require 'aws/templates/render/utils/stringify'
12
+ ::Aws::Templates::Render::Utils::Stringify.view_for(self).to_rendered
13
+ end
14
+
15
+ def inspect
16
+ ::Kernel.require 'aws/templates/render/utils/inspect'
17
+ ::Aws::Templates::Render::Utils::Inspect.view_for(self).to_rendered
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -137,6 +137,11 @@ module Aws
137
137
  end
138
138
  end
139
139
 
140
+ # The class already supports recursive concept so return self
141
+ def to_recursive
142
+ self
143
+ end
144
+
140
145
  ##
141
146
  # Create filter
142
147
  #
@@ -51,7 +51,11 @@ module Aws
51
51
  true
52
52
  end
53
53
 
54
- attr_reader :root
54
+ def root
55
+ parent.root
56
+ end
57
+
58
+ attr_reader :parent
55
59
 
56
60
  def dependencies
57
61
  @dependencies ||= Set.new
@@ -59,11 +63,15 @@ module Aws
59
63
 
60
64
  protected
61
65
 
62
- def initialize(root_link, obj)
63
- @root = root_link
66
+ def initialize(parent, obj)
67
+ unless obj.respond_to?(:to_recursive)
68
+ raise "Value #{obj} can't be transformed " \
69
+ 'into a recursive container'
70
+ end
71
+
72
+ @parent = parent
64
73
  depends_on(obj) if obj.dependency?
65
- @options = Options.new(obj)
66
- process_options(obj)
74
+ @options = Options.new(defaults, obj.to_recursive)
67
75
  end
68
76
  end
69
77
  end
@@ -1,7 +1,6 @@
1
1
  require 'aws/templates/exceptions'
2
2
  require 'aws/templates/utils/parametrized'
3
3
  require 'aws/templates/utils/parametrized/nested'
4
- require 'aws/templates/utils/parametrized/mapper'
5
4
  require 'singleton'
6
5
 
7
6
  module Aws
@@ -130,14 +129,7 @@ module Aws
130
129
 
131
130
  def transform(_, value, instance)
132
131
  return if value.nil?
133
- klass.new instance.root,
134
- if Utils.hashable?(value)
135
- value
136
- elsif Utils.parametrized?(value)
137
- Mapper.new(value)
138
- else
139
- raise "Value #{value} doesn't have parameters"
140
- end
132
+ klass.new(instance, value)
141
133
  end
142
134
  end
143
135
 
@@ -2,6 +2,7 @@ require 'aws/templates/exceptions'
2
2
  require 'aws/templates/utils/parametrized/guarded'
3
3
  require 'aws/templates/utils/inheritable'
4
4
  require 'aws/templates/utils/dependent'
5
+ require 'aws/templates/utils/inspectable'
5
6
  require 'set'
6
7
 
7
8
  module Aws
@@ -16,8 +17,9 @@ module Aws
16
17
  # it's domain-specific extended implementation of attr_reader.
17
18
  module Parametrized
18
19
  include Guarded
19
- include Inheritable
20
20
  include Dependent
21
+ include Inheritable
22
+ include Inspectable
21
23
 
22
24
  ##
23
25
  # Parameter object
@@ -135,6 +137,38 @@ module Aws
135
137
  end
136
138
  end
137
139
 
140
+ ##
141
+ # Makes parametrized accessible as recursive concept
142
+ class RecursiveAdapter
143
+ attr_reader :target
144
+
145
+ ##
146
+ # Defined hash keys
147
+ def keys
148
+ target.parameter_names.merge(target.options.keys)
149
+ end
150
+
151
+ ##
152
+ # Index operator
153
+ #
154
+ # Performs intermediate transformation of value if needed (if value is a lambda) and
155
+ # returns it wrapping into Definition instance with the same context if needed
156
+ # (if value is a map)
157
+ def [](k)
158
+ target.parameter_names.include?(k) ? target.send(k) : target.options[k]
159
+ end
160
+
161
+ ##
162
+ # Check if the key is present in the hash
163
+ def include?(k)
164
+ target.parameter_names.include?(k) || target.options.include?(k)
165
+ end
166
+
167
+ def initialize(target)
168
+ @target = target
169
+ end
170
+ end
171
+
138
172
  instance_scope do
139
173
  ##
140
174
  # Lazy initializer
@@ -163,6 +197,20 @@ module Aws
163
197
  parameter_names.each { |name| send(name) }
164
198
  end
165
199
 
200
+ ##
201
+ # Evaluate all parameters
202
+ #
203
+ # Return parameters as a hash
204
+ def parameters_map
205
+ parameter_names.each_with_object({}) { |name, obj| obj[name] = send(name) }
206
+ end
207
+
208
+ ##
209
+ # Transforms parametrized into an instance of recursive concept
210
+ def to_recursive
211
+ RecursiveAdapter.new(self)
212
+ end
213
+
166
214
  attr_reader :getter
167
215
  end
168
216
 
@@ -1,5 +1,13 @@
1
1
  require 'aws/templates/exceptions'
2
2
 
3
+ ##
4
+ # Hash implements resursive concept
5
+ class Hash
6
+ def to_recursive
7
+ self
8
+ end
9
+ end
10
+
3
11
  module Aws
4
12
  module Templates
5
13
  ##
@@ -134,7 +134,7 @@ describe Aws::Templates::Artifact do
134
134
  context 'instance of child class created' do
135
135
  let(:child_class) do
136
136
  Class.new(artifact_class) do
137
- default a: 'c',
137
+ default a: deleted,
138
138
  c: proc { options[:d].tr(' ', '.') }
139
139
  end
140
140
  end
@@ -147,7 +147,6 @@ describe Aws::Templates::Artifact do
147
147
  {
148
148
  root: 3,
149
149
  label: 'thing',
150
- a: 'c',
151
150
  b: 'Q.W.E',
152
151
  c: 'q.w.e',
153
152
  d: 'q w e'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cloud-templates
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ivan Matylitski
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-09-26 00:00:00.000000000 Z
12
+ date: 2017-10-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -162,6 +162,8 @@ files:
162
162
  - lib/aws/templates/render.rb
163
163
  - lib/aws/templates/render/registry.rb
164
164
  - lib/aws/templates/render/utils/base_type_views.rb
165
+ - lib/aws/templates/render/utils/inspect.rb
166
+ - lib/aws/templates/render/utils/stringify.rb
165
167
  - lib/aws/templates/render/view.rb
166
168
  - lib/aws/templates/utils.rb
167
169
  - lib/aws/templates/utils/artifact_storage.rb
@@ -176,6 +178,7 @@ files:
176
178
  - lib/aws/templates/utils/dependency/object.rb
177
179
  - lib/aws/templates/utils/dependent.rb
178
180
  - lib/aws/templates/utils/inheritable.rb
181
+ - lib/aws/templates/utils/inspectable.rb
179
182
  - lib/aws/templates/utils/late_bound.rb
180
183
  - lib/aws/templates/utils/memoized.rb
181
184
  - lib/aws/templates/utils/named.rb
@@ -184,7 +187,6 @@ files:
184
187
  - lib/aws/templates/utils/parametrized/constraints.rb
185
188
  - lib/aws/templates/utils/parametrized/getters.rb
186
189
  - lib/aws/templates/utils/parametrized/guarded.rb
187
- - lib/aws/templates/utils/parametrized/mapper.rb
188
190
  - lib/aws/templates/utils/parametrized/nested.rb
189
191
  - lib/aws/templates/utils/parametrized/transformations.rb
190
192
  - spec/aws/templates/artifact_spec.rb
@@ -1,73 +0,0 @@
1
- require 'set'
2
-
3
- module Aws
4
- module Templates
5
- module Utils
6
- module Parametrized
7
- ##
8
- # Map from "parametrized" to "recursive"
9
- #
10
- # The class is adapter used to wrap any "parametrized" object (implementing "parametrized"
11
- # concept) into an object implementing "hashable" and "recursive" concepts.
12
- class Mapper
13
- attr_reader :delegate
14
-
15
- SPECIAL_CASE = [:root].freeze
16
-
17
- def [](key)
18
- @delegate.public_send(key) if @parameter_names.include?(key)
19
- end
20
-
21
- def include?(key)
22
- @parameter_names.include?(key)
23
- end
24
-
25
- def to_hash
26
- @parameter_names.each_with_object({}) do |method_name, hsh|
27
- hsh[method_name] = @delegate.public_send(method_name)
28
- end
29
- end
30
-
31
- def keys
32
- @parameter_names.to_a
33
- end
34
-
35
- def dependency?
36
- delegate.dependency?
37
- end
38
-
39
- def dependencies
40
- delegate.dependencies
41
- end
42
-
43
- def object
44
- delegate.object
45
- end
46
-
47
- def initialize(obj)
48
- obj.parameter_names.each { |pname| _check_parameter(obj, pname) }
49
- @delegate = obj
50
- @parameter_names = Set.new(@delegate.parameter_names).merge(SPECIAL_CASE)
51
- end
52
-
53
- private
54
-
55
- PROPERTY_LIKE = /^[^_!?][^!?]*$/
56
-
57
- def _check_parameter(obj, name)
58
- _raise_misnamed(obj, name) unless name.to_s =~ PROPERTY_LIKE
59
- _raise_arity(obj, name) unless obj.public_method(name).arity.zero?
60
- end
61
-
62
- def _raise_misnamed(obj, name)
63
- raise "Parameter #{name} of #{obj} is mis-named"
64
- end
65
-
66
- def _raise_arity(obj, name)
67
- raise "Parameter #{name} of #{obj} has arity"
68
- end
69
- end
70
- end
71
- end
72
- end
73
- end