summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Somers <somers.ben@gmail.com>2013-05-16 13:53:34 -0700
committerBen Somers <somers.ben@gmail.com>2013-05-16 13:53:34 -0700
commit6fe76701baa77758a8f5a80d2cc1fab846a07dcb (patch)
tree2bf59dce20268eaf3821c004d8e8e6ec0d21b2e5
parent437ca9a3ba08f3b4288303db1d1ed7c53b452ffb (diff)
downloadchef-6fe76701baa77758a8f5a80d2cc1fab846a07dcb.tar.gz
Added duplicate role detection for Role.from_disk
Now Role.from_disk raises an error when it detects two roles of the same type (.rb or .json) exist anywhere in the roles directory or subdirectories.
-rw-r--r--lib/chef/exceptions.rb1
-rw-r--r--lib/chef/role.rb8
-rw-r--r--spec/unit/role_spec.rb6
3 files changed, 13 insertions, 2 deletions
diff --git a/lib/chef/exceptions.rb b/lib/chef/exceptions.rb
index 8d6eac7839..c106b8e1d0 100644
--- a/lib/chef/exceptions.rb
+++ b/lib/chef/exceptions.rb
@@ -57,6 +57,7 @@ class Chef
class PrivateKeyMissing < RuntimeError; end
class CannotWritePrivateKey < RuntimeError; end
class RoleNotFound < RuntimeError; end
+ class DuplicateRole < RuntimeError; end
class ValidationFailed < ArgumentError; end
class InvalidPrivateKey < ArgumentError; end
class ConfigurationError < ArgumentError; end
diff --git a/lib/chef/role.rb b/lib/chef/role.rb
index a7e3f657a7..57babab462 100644
--- a/lib/chef/role.rb
+++ b/lib/chef/role.rb
@@ -234,8 +234,12 @@ class Chef
# the raw rb files as well. Can search within directories in the role_path.
def self.from_disk(name, force=nil)
roles_files = Dir.glob(File.join(Chef::Config[:role_path], "**", "**"))
- js_path = roles_files.detect { |file| file.match /#{name}\.json$/ }
- rb_path = roles_files.detect { |file| file.match /#{name}\.rb$/ }
+ js_files = roles_files.select { |file| file.match /#{name}\.json$/ }
+ rb_files = roles_files.select { |file| file.match /#{name}\.rb$/ }
+ if js_files.count > 1 or rb_files.count > 1
+ raise Chef::Exceptions::DuplicateRole, "Multiple roles of same type found named #{name}"
+ end
+ js_path, rb_path = js_files.first, rb_files.first
if js_path && (File.exists?(js_path) || force == "json")
# from_json returns object.class => json_class in the JSON.
diff --git a/spec/unit/role_spec.rb b/spec/unit/role_spec.rb
index 77a47ee6fd..b96f8500d7 100644
--- a/spec/unit/role_spec.rb
+++ b/spec/unit/role_spec.rb
@@ -285,6 +285,12 @@ EOR
File.should_not_receive(:exists?)
lambda {@role.class.from_disk("lolcat")}.should raise_error(Chef::Exceptions::RoleNotFound)
end
+
+ it "should raise an exception if two files exist with the same name" do
+ Dir.should_receive(:glob).and_return(["#{Chef::Config[:role_path]}/memes/lolcat.rb", "#{Chef::Config[:role_path]}/lolcat.rb"])
+ File.should_not_receive(:exists?)
+ lambda {@role.class.from_disk("lolcat")}.should raise_error(Chef::Exceptions::DuplicateRole)
+ end
end
end