bosh_common 0.5.0 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/common/properties/errors.rb +16 -0
- data/lib/common/properties/property_helper.rb +43 -0
- data/lib/common/properties/template_evaluation_context.rb +86 -0
- data/lib/common/properties.rb +6 -0
- data/lib/common/version.rb +1 -1
- data/spec/unit/properties/property_helper_spec.rb +39 -0
- data/spec/unit/properties/template_evaluation_context_spec.rb +74 -0
- metadata +12 -4
@@ -0,0 +1,16 @@
|
|
1
|
+
# Copyright (c) 2009-2012 VMware, Inc.
|
2
|
+
|
3
|
+
module Bosh::Common
|
4
|
+
|
5
|
+
class TemplateEvaluationFailed < StandardError; end
|
6
|
+
|
7
|
+
class UnknownProperty < StandardError
|
8
|
+
attr_reader :name
|
9
|
+
|
10
|
+
def initialize(name)
|
11
|
+
@name = name
|
12
|
+
super("Can't find property `#{name}'")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# Copyright (c) 2009-2012 VMware, Inc.
|
2
|
+
|
3
|
+
module Bosh::Common
|
4
|
+
module PropertyHelper
|
5
|
+
# Copies property with a given name from src to dst.
|
6
|
+
# @param [Hash] dst Property destination
|
7
|
+
# @param [Hash] src Property source
|
8
|
+
# @param [String] name Property name (dot-separated)
|
9
|
+
# @param [Object] default Default value (if property is not in src)
|
10
|
+
def copy_property(dst, src, name, default = nil)
|
11
|
+
keys = name.split(".")
|
12
|
+
src_ref = src
|
13
|
+
dst_ref = dst
|
14
|
+
|
15
|
+
keys.each do |key|
|
16
|
+
src_ref = src_ref[key]
|
17
|
+
break if src_ref.nil? # no property with this name is src
|
18
|
+
end
|
19
|
+
|
20
|
+
keys[0..-2].each do |key|
|
21
|
+
dst_ref[key] ||= {}
|
22
|
+
dst_ref = dst_ref[key]
|
23
|
+
end
|
24
|
+
|
25
|
+
dst_ref[keys[-1]] ||= {}
|
26
|
+
dst_ref[keys[-1]] = src_ref || default
|
27
|
+
end
|
28
|
+
|
29
|
+
# @param [Hash] collection Property collection
|
30
|
+
# @param [String] name Dot-separated property name
|
31
|
+
def lookup_property(collection, name)
|
32
|
+
keys = name.split(".")
|
33
|
+
ref = collection
|
34
|
+
|
35
|
+
keys.each do |key|
|
36
|
+
ref = ref[key]
|
37
|
+
return nil if ref.nil?
|
38
|
+
end
|
39
|
+
|
40
|
+
ref
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# Copyright (c) 2009-2012 VMware, Inc.
|
2
|
+
|
3
|
+
module Bosh::Common
|
4
|
+
# Helper class to evaluate templates. Used by Director, CLI and Agent.
|
5
|
+
class TemplateEvaluationContext
|
6
|
+
include PropertyHelper
|
7
|
+
|
8
|
+
# @return [String] Template name
|
9
|
+
attr_reader :name
|
10
|
+
|
11
|
+
# @return [Integer] Template instance index
|
12
|
+
attr_reader :index
|
13
|
+
|
14
|
+
# @return [Hash] Template properties
|
15
|
+
attr_reader :properties
|
16
|
+
|
17
|
+
# @return [Hash] Template spec
|
18
|
+
attr_reader :spec
|
19
|
+
|
20
|
+
# @param [Hash] spec Template spec
|
21
|
+
def initialize(spec)
|
22
|
+
unless spec.is_a?(Hash)
|
23
|
+
raise TemplateEvaluationFailed,
|
24
|
+
"Invalid spec provided for template evaluation context, " +
|
25
|
+
"Hash expected, #{spec.class} given"
|
26
|
+
end
|
27
|
+
|
28
|
+
if spec["job"].is_a?(Hash)
|
29
|
+
@name = spec["job"]["name"]
|
30
|
+
else
|
31
|
+
@name = nil
|
32
|
+
end
|
33
|
+
|
34
|
+
@index = spec["index"]
|
35
|
+
@spec = openstruct(spec)
|
36
|
+
@raw_properties = spec["properties"] || {}
|
37
|
+
@properties = openstruct(@raw_properties)
|
38
|
+
end
|
39
|
+
|
40
|
+
# @return [Binding] Template binding
|
41
|
+
def get_binding
|
42
|
+
binding.taint
|
43
|
+
end
|
44
|
+
|
45
|
+
# Property lookup helper
|
46
|
+
# @param [String] name Property name
|
47
|
+
# @param [optional, Object] default Default value
|
48
|
+
# @return [Object] Property value
|
49
|
+
def p(name, default = nil)
|
50
|
+
result = lookup_property(@raw_properties, name)
|
51
|
+
if result.nil?
|
52
|
+
return default if default
|
53
|
+
raise UnknownProperty.new(name)
|
54
|
+
end
|
55
|
+
result
|
56
|
+
end
|
57
|
+
|
58
|
+
# Run a block of code if all given properties are defined
|
59
|
+
# @param [Array<String>] names Property names
|
60
|
+
# @yield [Object] property values
|
61
|
+
def if_p(*names)
|
62
|
+
values = names.map do |name|
|
63
|
+
value = lookup_property(@raw_properties, name)
|
64
|
+
return if value.nil?
|
65
|
+
value
|
66
|
+
end
|
67
|
+
|
68
|
+
yield *values
|
69
|
+
end
|
70
|
+
|
71
|
+
# @return [Object] Object representation where all hashes are unrolled
|
72
|
+
# into OpenStruct objects. This exists mostly for backward
|
73
|
+
# compatibility, as it doesn't provide good error reporting.
|
74
|
+
def openstruct(object)
|
75
|
+
case object
|
76
|
+
when Hash
|
77
|
+
mapped = object.inject({}) { |h, (k,v)| h[k] = openstruct(v); h }
|
78
|
+
OpenStruct.new(mapped)
|
79
|
+
when Array
|
80
|
+
object.map { |item| openstruct(item) }
|
81
|
+
else
|
82
|
+
object
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/lib/common/version.rb
CHANGED
@@ -0,0 +1,39 @@
|
|
1
|
+
# Copyright (c) 2012 VMware, Inc.
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
require "common/properties"
|
5
|
+
|
6
|
+
describe Bosh::Common::PropertyHelper do
|
7
|
+
|
8
|
+
before(:each) do
|
9
|
+
@helper = Object.new
|
10
|
+
@helper.extend(Bosh::Common::PropertyHelper)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "can copy named property from one collection to another" do
|
14
|
+
dst = {}
|
15
|
+
src = {"foo" => {"bar" => "baz", "secret" => "zazzle"}}
|
16
|
+
|
17
|
+
@helper.copy_property(dst, src, "foo.bar")
|
18
|
+
dst.should == {"foo" => {"bar" => "baz"}}
|
19
|
+
|
20
|
+
@helper.copy_property(dst, src, "no.such.prop", "default")
|
21
|
+
dst.should == {
|
22
|
+
"foo" => {"bar" => "baz"},
|
23
|
+
"no" => {
|
24
|
+
"such" => {"prop" => "default"}
|
25
|
+
}
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
it "can lookup the property in a Hash using dot-syntax" do
|
30
|
+
properties = {
|
31
|
+
"foo" => {"bar" => "baz"},
|
32
|
+
"router" => {"token" => "foo"}
|
33
|
+
}
|
34
|
+
|
35
|
+
@helper.lookup_property(properties, "foo.bar").should == "baz"
|
36
|
+
@helper.lookup_property(properties, "router").should == {"token" => "foo"}
|
37
|
+
@helper.lookup_property(properties, "no.prop").should be_nil
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# Copyright (c) 2012 VMware, Inc.
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
require "common/properties"
|
5
|
+
|
6
|
+
describe Bosh::Common::TemplateEvaluationContext do
|
7
|
+
|
8
|
+
def eval_template(erb, context)
|
9
|
+
ERB.new(erb).result(context.get_binding)
|
10
|
+
end
|
11
|
+
|
12
|
+
def make(spec)
|
13
|
+
Bosh::Common::TemplateEvaluationContext.new(spec)
|
14
|
+
end
|
15
|
+
|
16
|
+
before(:each) do
|
17
|
+
@spec = {
|
18
|
+
"job" => {
|
19
|
+
"name" => "foobar"
|
20
|
+
},
|
21
|
+
"properties" => {
|
22
|
+
"foo" => "bar",
|
23
|
+
"router" => {"token" => "zbb"}
|
24
|
+
},
|
25
|
+
"index" => 0,
|
26
|
+
}
|
27
|
+
|
28
|
+
@context = make(@spec)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "unrolls properties into OpenStruct" do
|
32
|
+
eval_template("<%= properties.foo %>", @context).should == "bar"
|
33
|
+
end
|
34
|
+
|
35
|
+
it "supports looking up template index" do
|
36
|
+
eval_template("<%= spec.index %>", @context).should == "0"
|
37
|
+
end
|
38
|
+
|
39
|
+
it "supports 'p' helper" do
|
40
|
+
eval_template("<%= p('router.token') %>", @context).should == "zbb"
|
41
|
+
expect {
|
42
|
+
eval_template("<%= p('bar.baz') %>", @context)
|
43
|
+
}.to raise_error(Bosh::Common::UnknownProperty)
|
44
|
+
|
45
|
+
eval_template("<%= p('bar.baz', 22) %>", @context).should == "22"
|
46
|
+
end
|
47
|
+
|
48
|
+
it "supports 'if_p' helper" do
|
49
|
+
template = <<-TMPL
|
50
|
+
<% if_p("router.token") do |token| %>
|
51
|
+
<%= token %>
|
52
|
+
<% end %>
|
53
|
+
TMPL
|
54
|
+
|
55
|
+
eval_template(template, @context).strip.should == "zbb"
|
56
|
+
|
57
|
+
template = <<-TMPL
|
58
|
+
<% if_p("router.token", "foo") do |token, foo| %>
|
59
|
+
<%= token %>, <%= foo %>
|
60
|
+
<% end %>
|
61
|
+
TMPL
|
62
|
+
|
63
|
+
eval_template(template, @context).strip.should == "zbb, bar"
|
64
|
+
|
65
|
+
template = <<-TMPL
|
66
|
+
<% if_p("router.token", "no.such.prop") do |token, none| %>
|
67
|
+
test output
|
68
|
+
<% end %>
|
69
|
+
TMPL
|
70
|
+
|
71
|
+
eval_template(template, @context).strip.should == ""
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bosh_common
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-10-05 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: BOSH common
|
15
15
|
email: support@vmware.com
|
@@ -21,6 +21,10 @@ files:
|
|
21
21
|
- lib/common/exec.rb
|
22
22
|
- lib/common/exec/error.rb
|
23
23
|
- lib/common/exec/result.rb
|
24
|
+
- lib/common/properties.rb
|
25
|
+
- lib/common/properties/errors.rb
|
26
|
+
- lib/common/properties/property_helper.rb
|
27
|
+
- lib/common/properties/template_evaluation_context.rb
|
24
28
|
- lib/common/thread_formatter.rb
|
25
29
|
- lib/common/thread_pool.rb
|
26
30
|
- lib/common/version.rb
|
@@ -31,6 +35,8 @@ files:
|
|
31
35
|
- spec/spec_helper.rb
|
32
36
|
- spec/unit/common_spec.rb
|
33
37
|
- spec/unit/exec_spec.rb
|
38
|
+
- spec/unit/properties/property_helper_spec.rb
|
39
|
+
- spec/unit/properties/template_evaluation_context_spec.rb
|
34
40
|
- spec/unit/thread_pool_spec.rb
|
35
41
|
homepage: http://www.vmware.com
|
36
42
|
licenses: []
|
@@ -46,7 +52,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
46
52
|
version: '0'
|
47
53
|
segments:
|
48
54
|
- 0
|
49
|
-
hash:
|
55
|
+
hash: -411355085407901587
|
50
56
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
57
|
none: false
|
52
58
|
requirements:
|
@@ -55,7 +61,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
55
61
|
version: '0'
|
56
62
|
segments:
|
57
63
|
- 0
|
58
|
-
hash:
|
64
|
+
hash: -411355085407901587
|
59
65
|
requirements: []
|
60
66
|
rubyforge_project:
|
61
67
|
rubygems_version: 1.8.24
|
@@ -68,5 +74,7 @@ test_files:
|
|
68
74
|
- spec/spec_helper.rb
|
69
75
|
- spec/unit/common_spec.rb
|
70
76
|
- spec/unit/exec_spec.rb
|
77
|
+
- spec/unit/properties/property_helper_spec.rb
|
78
|
+
- spec/unit/properties/template_evaluation_context_spec.rb
|
71
79
|
- spec/unit/thread_pool_spec.rb
|
72
80
|
has_rdoc:
|