From b975dce9609d74d349f6904da61541b15e43e806 Mon Sep 17 00:00:00 2001 From: Thom May Date: Wed, 30 Mar 2016 09:54:01 +0100 Subject: do legwork in preparation for ruby roles --- lib/chef/chef_fs/data_handler/data_handler_base.rb | 18 ++++++++++++------ lib/chef/chef_fs/data_handler/role_data_handler.rb | 2 +- lib/chef/chef_fs/file_system/base_fs_object.rb | 4 ++++ .../chef_fs/file_system/chef_server/rest_list_dir.rb | 4 ++-- .../file_system/chef_server/rest_list_entry.rb | 6 ++---- .../repository/chef_repository_file_system_entry.rb | 2 +- .../file_system/repository/file_system_entry.rb | 8 +++++--- spec/integration/knife/upload_spec.rb | 19 +++++++++++++++++++ 8 files changed, 46 insertions(+), 17 deletions(-) diff --git a/lib/chef/chef_fs/data_handler/data_handler_base.rb b/lib/chef/chef_fs/data_handler/data_handler_base.rb index b30ae9c708..fdedb46d9d 100644 --- a/lib/chef/chef_fs/data_handler/data_handler_base.rb +++ b/lib/chef/chef_fs/data_handler/data_handler_base.rb @@ -24,14 +24,18 @@ class Chef object end + def remove_file_extension(name, ext=".*") + File.basename(name, ext) + end + # # Takes a name like blah.json and removes the .json from it. # def remove_dot_json(name) - if name.length < 5 || name[-5, 5] != ".json" - raise "Invalid name #{path}: must end in .json" + unless File.extname(name) == ".json" + raise "Invalid name #{name}: must end in .json" end - name[0, name.length - 5] + remove_file_extension(name, ".json") end # @@ -109,8 +113,10 @@ class Chef # # Bring in an instance of this object from Ruby. (Like roles/x.rb) # - def from_ruby(ruby) - chef_class.from_file(ruby).to_hash + def from_ruby(path) + r = chef_class.new + r.from_file(path) + r.to_hash end # @@ -192,7 +198,7 @@ class Chef # @yield [s] callback to handle errors # @yieldparam [s] error message def verify_integrity(object, entry) - base_name = remove_dot_json(entry.name) + base_name = remove_file_extension(entry.name) if object["name"] != base_name yield("Name must be '#{base_name}' (is '#{object['name']}')") end diff --git a/lib/chef/chef_fs/data_handler/role_data_handler.rb b/lib/chef/chef_fs/data_handler/role_data_handler.rb index 74533cff05..b09c146a5d 100644 --- a/lib/chef/chef_fs/data_handler/role_data_handler.rb +++ b/lib/chef/chef_fs/data_handler/role_data_handler.rb @@ -7,7 +7,7 @@ class Chef class RoleDataHandler < DataHandlerBase def normalize(role, entry) result = normalize_hash(role, { - "name" => remove_dot_json(entry.name), + "name" => remove_file_extension(entry.name), "description" => "", "json_class" => "Chef::Role", "chef_type" => "role", diff --git a/lib/chef/chef_fs/file_system/base_fs_object.rb b/lib/chef/chef_fs/file_system/base_fs_object.rb index cf1aed552f..9f26099363 100644 --- a/lib/chef/chef_fs/file_system/base_fs_object.rb +++ b/lib/chef/chef_fs/file_system/base_fs_object.rb @@ -141,6 +141,10 @@ class Chef true end + def is_ruby_or_json_file?(fn) + %w{ .rb .json }.include? File.extname(fn) + end + # Printable path, generally used to distinguish paths in one root from # paths in another. def path_for_printing diff --git a/lib/chef/chef_fs/file_system/chef_server/rest_list_dir.rb b/lib/chef/chef_fs/file_system/chef_server/rest_list_dir.rb index b5b602a208..f85b9ea74e 100644 --- a/lib/chef/chef_fs/file_system/chef_server/rest_list_dir.rb +++ b/lib/chef/chef_fs/file_system/chef_server/rest_list_dir.rb @@ -35,7 +35,7 @@ class Chef attr_reader :data_handler def can_have_child?(name, is_dir) - name =~ /\.json$/ && !is_dir + is_ruby_or_json_file?(name) && !is_dir end # @@ -74,7 +74,7 @@ class Chef begin # Grab the names of the children, append json, and make child entries @children ||= root.get_json(api_path).keys.sort.map do |key| - make_child_entry("#{key}.json", true) + make_child_entry("#{key}", true) end rescue Timeout::Error => e raise Chef::ChefFS::FileSystem::OperationFailedError.new(:children, self, e, "Timeout retrieving children: #{e}") diff --git a/lib/chef/chef_fs/file_system/chef_server/rest_list_entry.rb b/lib/chef/chef_fs/file_system/chef_server/rest_list_entry.rb index 5b9252ba03..4ad3dfe5b8 100644 --- a/lib/chef/chef_fs/file_system/chef_server/rest_list_entry.rb +++ b/lib/chef/chef_fs/file_system/chef_server/rest_list_entry.rb @@ -38,10 +38,8 @@ class Chef end def api_child_name - if name.length < 5 || name[-5, 5] != ".json" - raise "Invalid name #{path}: must end in .json" - end - name[0, name.length - 5] + raise "Invalid name #{path}" unless is_ruby_or_json_file?(path) + File.basename(path, ".*") end def api_path diff --git a/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_entry.rb b/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_entry.rb index 329e2e3509..17bb383bbf 100644 --- a/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_entry.rb +++ b/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_entry.rb @@ -54,7 +54,7 @@ class Chef end def can_have_child?(name, is_dir) - !is_dir && name[-5..-1] == ".json" + !is_dir && is_ruby_or_json_file?(name) end def write(file_contents) diff --git a/lib/chef/chef_fs/file_system/repository/file_system_entry.rb b/lib/chef/chef_fs/file_system/repository/file_system_entry.rb index bee017f7a8..2db6bbabe2 100644 --- a/lib/chef/chef_fs/file_system/repository/file_system_entry.rb +++ b/lib/chef/chef_fs/file_system/repository/file_system_entry.rb @@ -92,11 +92,13 @@ class Chef end def read - begin + if File.extname(file_path) == ".rb" + data_handler.from_ruby(file_path).to_json + else File.open(file_path, "rb") { |f| f.read } - rescue Errno::ENOENT - raise Chef::ChefFS::FileSystem::NotFoundError.new(self, $!) end + rescue Errno::ENOENT + raise Chef::ChefFS::FileSystem::NotFoundError.new(self, $!) end def write(content) diff --git a/spec/integration/knife/upload_spec.rb b/spec/integration/knife/upload_spec.rb index 038bbad216..4fe67ccf7e 100644 --- a/spec/integration/knife/upload_spec.rb +++ b/spec/integration/knife/upload_spec.rb @@ -154,6 +154,25 @@ EOM end end + context 'the role is in ruby', focus: true do + before do + file "roles/x.rb", <