lib/chef-dk/policyfile/solution_dependencies.rb in chef-dk-0.2.1 vs lib/chef-dk/policyfile/solution_dependencies.rb in chef-dk-0.3.0
- old
+ new
@@ -26,10 +26,16 @@
Cookbook = Struct.new(:name, :version)
class Cookbook
+ VALID_STRING_FORMAT = /\A[^\s]+ \([^\s]+\)\Z/
+
+ def self.valid_str?(str)
+ !!(str =~ VALID_STRING_FORMAT)
+ end
+
def self.parse(str)
name, version_w_parens = str.split(' ')
version = version_w_parens[/\(([^)]+)\)/, 1]
new(name, version)
end
@@ -76,19 +82,17 @@
@cookbook_dependencies.delete_if { |cb, _deps| cb.name == cookbook_name }
add_cookbook_dep(cookbook_name, new_version, new_dependency_list)
end
def consume_lock_data(lock_data)
- policyfile_dependencies_data = lock_data["Policyfile"] || []
- policyfile_dependencies_data.each do |cookbook_name, constraint|
- add_policyfile_dep(cookbook_name, constraint)
+ unless lock_data.key?("Policyfile") and lock_data.key?("dependencies")
+ msg = %Q|lockfile solution_dependencies must be a Hash of the form `{"Policyfile": [], "dependencies": {} }' (got: #{lock_data.inspect})|
+ raise InvalidLockfile, msg
end
- cookbook_dependencies_data = lock_data["dependencies"] || {}
- cookbook_dependencies_data.each do |name_and_version, deps_list|
- cookbook = Cookbook.parse(name_and_version)
- add_cookbook_obj_dep(cookbook, deps_list)
- end
+
+ set_policyfile_deps_from_lock_data(lock_data)
+ set_cookbook_deps_from_lock_data(lock_data)
end
def test_conflict!(cookbook_name, version)
unless have_cookbook_dep?(cookbook_name, version)
raise CookbookNotInWorkingSet, "Cookbook #{cookbook_name} (#{version}) not in the working set, cannot test for conflicts"
@@ -194,9 +198,99 @@
@cookbook_dependencies.find { |k,v| k.name == name }
end
def find_cookbook_dep_by_name_and_version(name, version)
@cookbook_dependencies[Cookbook.new(name, version)]
+ end
+
+ def set_policyfile_deps_from_lock_data(lock_data)
+ policyfile_deps_data = lock_data["Policyfile"]
+
+ unless policyfile_deps_data.kind_of?(Array)
+ msg = "lockfile solution_dependencies Policyfile dependencies must be an array of cookbooks and constraints (got: #{policyfile_deps_data.inspect})"
+ raise InvalidLockfile, msg
+ end
+
+ policyfile_deps_data.each do |entry|
+ add_policyfile_dep_from_lock_data(entry)
+ end
+ end
+
+ def add_policyfile_dep_from_lock_data(entry)
+ unless entry.kind_of?(Array) and entry.size == 2
+ msg = %Q(lockfile solution_dependencies Policyfile dependencies entry must be like [ "$COOKBOOK_NAME", "$CONSTRAINT" ] (got: #{entry.inspect}))
+ raise InvalidLockfile, msg
+ end
+
+ cookbook_name, constraint = entry
+
+ unless cookbook_name.kind_of?(String) and !cookbook_name.empty?
+ msg = "lockfile solution_dependencies Policyfile dependencies entry. Cookbook name portion must be a string (got: #{entry.inspect})"
+ raise InvalidLockfile, msg
+ end
+
+ unless constraint.kind_of?(String) and !constraint.empty?
+ msg = "malformed lockfile solution_dependencies Policyfile dependencies entry. Version constraint portion must be a string (got: #{entry.inspect})"
+ raise InvalidLockfile, msg
+ end
+ add_policyfile_dep(cookbook_name, constraint)
+ rescue Semverse::InvalidConstraintFormat
+ msg = "malformed lockfile solution_dependencies Policyfile dependencies entry. Version constraint portion must be a valid version constraint (got: #{entry.inspect})"
+ raise InvalidLockfile, msg
+ end
+
+ def set_cookbook_deps_from_lock_data(lock_data)
+ cookbook_dependencies_data = lock_data["dependencies"]
+
+ unless cookbook_dependencies_data.kind_of?(Hash)
+ msg = "lockfile solution_dependencies dependencies entry must be a Hash (JSON object) of dependencies (got: #{cookbook_dependencies_data.inspect})"
+ raise InvalidLockfile, msg
+ end
+
+ cookbook_dependencies_data.each do |name_and_version, deps_list|
+ add_cookbook_dep_from_lock_data(name_and_version, deps_list)
+ end
+ end
+
+ def add_cookbook_dep_from_lock_data(name_and_version, deps_list)
+ unless name_and_version.kind_of?(String)
+ show = "#{name_and_version.inspect} => #{deps_list.inspect}"
+ msg = %Q(lockfile cookbook_dependencies entries must be of the form "$COOKBOOK_NAME ($VERSION)" => [ $dependency, ...] (got: #{show}) )
+ raise InvalidLockfile, msg
+ end
+
+ unless Cookbook.valid_str?(name_and_version)
+ msg = %Q(lockfile cookbook_dependencies entry keys must be of the form "$COOKBOOK_NAME ($VERSION)" (got: #{name_and_version.inspect}) )
+ raise InvalidLockfile, msg
+ end
+
+ unless deps_list.kind_of?(Array)
+ msg = %Q(lockfile cookbook_dependencies entry values must be an Array like [ [ "$COOKBOOK_NAME", "$CONSTRAINT" ], ... ] (got: #{deps_list.inspect}) )
+ raise InvalidLockfile, msg
+ end
+
+ deps_list.each do |entry|
+
+ unless entry.kind_of?(Array) and entry.size == 2
+ msg = %Q(lockfile solution_dependencies dependencies entry must be like [ "$COOKBOOK_NAME", "$CONSTRAINT" ] (got: #{entry.inspect}))
+ raise InvalidLockfile, msg
+ end
+
+ dep_name, constraint = entry
+
+ unless dep_name.kind_of?(String) and !dep_name.empty?
+ msg = "malformed lockfile solution_dependencies dependencies entry. Cookbook name portion must be a string (got: #{entry.inspect})"
+ raise InvalidLockfile, msg
+ end
+
+ unless constraint.kind_of?(String) and !constraint.empty?
+ msg = "malformed lockfile solution_dependencies dependencies entry. Version constraint portion must be a string (got: #{entry.inspect})"
+ raise InvalidLockfile, msg
+ end
+ end
+
+ cookbook = Cookbook.parse(name_and_version)
+ add_cookbook_obj_dep(cookbook, deps_list)
end
end
end