class Chef::Knife::SubcommandLoader
Attributes
chef_config_dir[R]
env[R]
Public Class Methods
new(chef_config_dir, env=ENV)
click to toggle source
# File lib/chef/knife/core/subcommand_loader.rb, line 27 def initialize(chef_config_dir, env=ENV) @chef_config_dir, @env = chef_config_dir, env @forced_activate = {} end
Public Instance Methods
find_subcommands_via_dirglob()
click to toggle source
# File lib/chef/knife/core/subcommand_loader.rb, line 108 def find_subcommands_via_dirglob # The "require paths" of the core knife subcommands bundled with chef files = Dir[File.expand_path('../../../knife/*.rb', __FILE__)] subcommand_files = {} files.each do |knife_file| rel_path = knife_file[/#{CHEF_ROOT}#{Regexp.escape(File::SEPARATOR)}(.*)\.rb/,1] subcommand_files[rel_path] = knife_file end subcommand_files end
find_subcommands_via_manifest()
click to toggle source
If the user has created a ~/.chef/plugin_manifest.json file, we'll use that instead of inspecting the on-system gems to find the plugins. The file format is expected to look like:
{ "plugins": { "knife-ec2": { "paths": [ "/home/alice/.rubymanagerthing/gems/knife-ec2-x.y.z/lib/chef/knife/ec2_server_create.rb", "/home/alice/.rubymanagerthing/gems/knife-ec2-x.y.z/lib/chef/knife/ec2_server_delete.rb" ] } } }
Extraneous content in this file is ignored. This intentional so that we can adapt the file format for potential behavior changes to knife in the future.
# File lib/chef/knife/core/subcommand_loader.rb, line 95 def find_subcommands_via_manifest # Format of subcommand_files is "relative_path" (something you can # Kernel.require()) => full_path. The relative path isn't used # currently, so we just map full_path => full_path. subcommand_files = {} plugin_manifest["plugins"].each do |plugin_name, plugin_manifest| plugin_manifest["paths"].each do |cmd_path| subcommand_files[cmd_path] = cmd_path end end subcommand_files.merge(find_subcommands_via_dirglob) end
find_subcommands_via_rubygems()
click to toggle source
# File lib/chef/knife/core/subcommand_loader.rb, line 119 def find_subcommands_via_rubygems files = find_files_latest_gems 'chef/knife/*.rb' subcommand_files = {} files.each do |file| rel_path = file[/(#{Regexp.escape File.join('chef', 'knife', '')}.*)\.rb/, 1] subcommand_files[rel_path] = file end subcommand_files.merge(find_subcommands_via_dirglob) end
gem_and_builtin_subcommands()
click to toggle source
Returns a Hash of paths to knife commands built-in to chef, or installed via gem. If rubygems is not installed, falls back to globbing the knife directory. The Hash is of the form {“relative/path” => “/absolute/path”}
# File lib/chef/knife/core/subcommand_loader.rb, line 62 def gem_and_builtin_subcommands if have_plugin_manifest? find_subcommands_via_manifest else # search all gems for chef/knife/*.rb require 'rubygems' find_subcommands_via_rubygems end rescue LoadError find_subcommands_via_dirglob end
have_plugin_manifest?()
click to toggle source
# File lib/chef/knife/core/subcommand_loader.rb, line 130 def have_plugin_manifest? ENV["HOME"] && File.exist?(plugin_manifest_path) end
load_commands()
click to toggle source
Load all the sub-commands
# File lib/chef/knife/core/subcommand_loader.rb, line 33 def load_commands subcommand_files.each { |subcommand| Kernel.load subcommand } true end
plugin_manifest()
click to toggle source
# File lib/chef/knife/core/subcommand_loader.rb, line 134 def plugin_manifest Chef::JSONCompat.from_json(File.read(plugin_manifest_path)) end
plugin_manifest_path()
click to toggle source
# File lib/chef/knife/core/subcommand_loader.rb, line 138 def plugin_manifest_path File.join(ENV['HOME'], '.chef', 'plugin_manifest.json') end
site_subcommands()
click to toggle source
Returns an Array of paths to knife commands located in chef_config_dir/plugins/knife/ and ~/.chef/plugins/knife/
# File lib/chef/knife/core/subcommand_loader.rb, line 40 def site_subcommands user_specific_files = [] if chef_config_dir user_specific_files.concat Dir.glob(File.expand_path("plugins/knife/*.rb", chef_config_dir)) end # finally search ~/.chef/plugins/knife/*.rb user_specific_files.concat Dir.glob(File.join(env['HOME'], '.chef', 'plugins', 'knife', '*.rb')) if env['HOME'] user_specific_files end
subcommand_files()
click to toggle source
# File lib/chef/knife/core/subcommand_loader.rb, line 74 def subcommand_files @subcommand_files ||= (gem_and_builtin_subcommands.values + site_subcommands).flatten.uniq end
Private Instance Methods
check_spec_for_glob(spec, glob)
click to toggle source
# File lib/chef/knife/core/subcommand_loader.rb, line 176 def check_spec_for_glob(spec, glob) dirs = if spec.require_paths.size > 1 then "{#{spec.require_paths.join(',')}}" else spec.require_paths.first end glob = File.join("#{spec.full_gem_path}/#{dirs}", glob) Dir[glob].map { |f| f.untaint } end
find_files_latest_gems(glob, check_load_path=true)
click to toggle source
# File lib/chef/knife/core/subcommand_loader.rb, line 144 def find_files_latest_gems(glob, check_load_path=true) files = [] if check_load_path files = $LOAD_PATH.map { |load_path| Dir["#{File.expand_path glob, load_path}#{Gem.suffix_pattern}"] }.flatten.select { |file| File.file? file.untaint } end gem_files = latest_gem_specs.map do |spec| # Gem::Specification#matches_for_glob wasn't added until RubyGems 1.8 if spec.respond_to? :matches_for_glob spec.matches_for_glob("#{glob}#{Gem.suffix_pattern}") else check_spec_for_glob(spec, glob) end end.flatten files.concat gem_files files.uniq! if check_load_path return files end
latest_gem_specs()
click to toggle source
# File lib/chef/knife/core/subcommand_loader.rb, line 168 def latest_gem_specs @latest_gem_specs ||= if Gem::Specification.respond_to? :latest_specs Gem::Specification.latest_specs(true) # find prerelease gems else Gem.source_index.latest_specs(true) end end