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.
@@ -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: