Skip to content

Commit c651822

Browse files
committed
Adding tag, tagged?, and untag support to recipes - closes CHEF-8
1 parent 28e0f6b commit c651822

4 files changed

Lines changed: 109 additions & 0 deletions

File tree

chef/lib/chef/client.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ def build_node(node_name=nil, solo=false)
140140
Chef::Log.debug("Platform is #{platform} version #{version}")
141141
@node[:platform] = platform
142142
@node[:platform_version] = version
143+
@node[:tags] = Array.new unless @node.attribute?(:tags)
143144
@node
144145
end
145146

chef/lib/chef/recipe.rb

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,55 @@ def search(type, query, &block)
9393
block.call(sr)
9494
end
9595
end
96+
97+
# Sets a tag, or list of tags, for this node. Syntactic sugar for
98+
# @node[:tags].
99+
#
100+
# With no arguments, returns the list of tags.
101+
#
102+
# === Parameters
103+
# tags<Array>:: A list of tags to add - can be a single string
104+
#
105+
# === Returns
106+
# tags<Array>:: The contents of @node[:tags]
107+
def tag(*args)
108+
if args.length > 0
109+
args.each do |tag|
110+
@node[:tags] << tag unless @node[:tags].include?(tag)
111+
end
112+
@node[:tags]
113+
else
114+
@node[:tags]
115+
end
116+
end
117+
118+
# Returns true if the node is tagged with the supplied list of tags.
119+
#
120+
# === Parameters
121+
# tags<Array>:: A list of tags
122+
#
123+
# === Returns
124+
# true<TrueClass>:: If all the parameters are present
125+
# false<FalseClass>:: If any of the parameters are missing
126+
def tagged?(*args)
127+
args.each do |tag|
128+
return false unless @node[:tags].include?(tag)
129+
end
130+
true
131+
end
132+
133+
# Removes the list of tags from the node.
134+
#
135+
# === Parameters
136+
# tags<Array>:: A list of tags
137+
#
138+
# === Returns
139+
# tags<Array>:: The current list of @node[:tags]
140+
def untag(*args)
141+
args.each do |tag|
142+
@node[:tags].delete(tag)
143+
end
144+
end
96145

97146
def method_missing(method_symbol, *args, &block)
98147
resource = nil

chef/spec/unit/client_spec.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,18 @@
174174
@client.build_node
175175
@client.node.recipes.should eql([ "one", "two", "three" ])
176176
end
177+
178+
it "should set the tags attribute to an empty array if it is not already defined" do
179+
@client.build_node
180+
@client.node.tags.should eql([])
181+
end
182+
183+
it "should not set the tags attribute to an empty array if it is already defined" do
184+
@client.node = @node
185+
@client.node[:tags] = [ "radiohead" ]
186+
@client.build_node
187+
@client.node.tags.should eql([ "radiohead" ])
188+
end
177189
end
178190

179191
describe Chef::Client, "register" do

chef/spec/unit/recipe_spec.rb

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
describe Chef::Recipe do
2222
before(:each) do
2323
@recipe = Chef::Recipe.new("hjk", "test", Chef::Node.new)
24+
@recipe.node[:tags] = Array.new
2425
end
2526

2627
it "should load a two word (zen_master) resource" do
@@ -140,4 +141,50 @@
140141
res.pretty_kitty.should eql(true)
141142
end
142143

144+
it "should set tags via tag" do
145+
@recipe.tag "foo"
146+
@recipe.node[:tags].should include("foo")
147+
end
148+
149+
it "should set multiple tags via tag" do
150+
@recipe.tag "foo", "bar"
151+
@recipe.node[:tags].should include("foo")
152+
@recipe.node[:tags].should include("bar")
153+
end
154+
155+
it "should not set the same tag twice via tag" do
156+
@recipe.tag "foo"
157+
@recipe.tag "foo"
158+
@recipe.node[:tags].should eql([ "foo" ])
159+
end
160+
161+
it "should return the current list of tags from tag with no arguments" do
162+
@recipe.tag "foo"
163+
@recipe.tag.should eql([ "foo" ])
164+
end
165+
166+
it "should return true from tagged? if node is tagged" do
167+
@recipe.tag "foo"
168+
@recipe.tagged?("foo").should be(true)
169+
end
170+
171+
it "should return false from tagged? if node is not tagged" do
172+
@recipe.tagged?("foo").should be(false)
173+
end
174+
175+
it "should return false from tagged? if node is not tagged" do
176+
@recipe.tagged?("foo").should be(false)
177+
end
178+
179+
it "should remove a tag from the tag list via untag" do
180+
@recipe.tag "foo"
181+
@recipe.untag "foo"
182+
@recipe.node[:tags].should eql([])
183+
end
184+
185+
it "should remove multiple tags from the tag list via untag" do
186+
@recipe.tag "foo", "bar"
187+
@recipe.untag "bar", "foo"
188+
@recipe.node[:tags].should eql([])
189+
end
143190
end

0 commit comments

Comments
 (0)