bosh_common 0.5.0 → 0.5.1

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.
@@ -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
@@ -0,0 +1,6 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+
3
+ require "ostruct"
4
+ require "common/properties/errors"
5
+ require "common/properties/property_helper"
6
+ require "common/properties/template_evaluation_context"
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Bosh
4
4
  module Common
5
- VERSION = "0.5.0"
5
+ VERSION = "0.5.1"
6
6
  end
7
7
  end
@@ -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.0
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-07-27 00:00:00.000000000 Z
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: 852108980354805257
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: 852108980354805257
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: