cloud-templates 0.1.0 → 0.2.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.
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