Class: Chef::Knife::StencilCollection

Inherits:
Array
  • Object
show all
Includes:
StencilBase
Defined in:
lib/chef/knife/stencil_collection.rb

Overview

A collection of all StencilFile objects

Instance Method Summary collapse

Methods included from StencilBase

#build_plugin_klass, #explain, #invoked_as_stencil?, #locate_config_value, #normalize_path, #stencil_root

Constructor Details

#initialize(options = {}) ⇒ StencilCollection

Returns a new instance of StencilCollection.



29
30
31
32
33
# File 'lib/chef/knife/stencil_collection.rb', line 29

def initialize(options={})
  Dir.glob(File.join(stencil_root, "**/*.json")).each do |file|
    self << Knife::StencilFile.new(normalize_path(file, stencil_root))
  end
end

Instance Method Details

#best_match(name) ⇒ Object

Return stencil that best matches a given node name



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/chef/knife/stencil_collection.rb', line 53

def best_match(name)
  weight_stencil_file_map = Hash.new

  self.each do |stencil_file|
    if stencil_file.matches
      regex = Regexp.new(stencil_file.matches)
      if name.scan(regex).size > 0
        weight = ( name.scan(regex)[0].size || 0 )
 weight_stencil_file_map[weight] = stencil_file
      end
    end
  end

  unless weight_stencil_file_map.keys.size > 0
    raise ArgumentError, 'No stencil can be found to match that name'
  end

  match = weight_stencil_file_map.sort_by{|k,v| k}.reverse.first[1]	# The StencilFile with the most matched chars
  explain("decision tree: #{weight_stencil_file_map.sort_by{|k,v| k}.reverse}")

	explain("determined #{match.path} to be the best matched root stencil via #{match.matches}")
  return match
end

#for_name(name) ⇒ Object

Return stencil for a given name



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/chef/knife/stencil_collection.rb', line 36

def for_name(name)
  collection = Array.new
  collection.push(best_match(name))

  collection.each do |stencil_file|

	  stencil_file.inherits.each do |path|
	    collection << self.stencil_for_path(normalize_path(path, stencil_root))
	  end

  end

  collection.reverse.each {|t| explain("#{t.path} overrides #{t.inherits} and supplies options #{t.options}")}
  return collection.reverse
end

#stencil_for_path(path) ⇒ Object

For a given path, determine which stencil matches



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/chef/knife/stencil_collection.rb', line 78

def stencil_for_path(path)
  matched_stencil = nil

  self.each do |stencil_file|
    if stencil_file.path == path 
      matched_stencil = stencil_file
    end
  end

	if matched_stencil
	  return matched_stencil
	else
	  raise ArgumentError, "#{path} not found in StencilCollection"
	end
end