Class: Chef::Knife::SubcommandLoader::GemGlobLoader

Inherits:
Chef::Knife::SubcommandLoader show all
Defined in:
lib/chef/knife/core/gem_glob_loader.rb

Constant Summary collapse

MATCHES_CHEF_GEM =
%r{/chef-[\d]+\.[\d]+\.[\d]+}
MATCHES_THIS_CHEF_GEM =
%r{/chef-#{Chef::VERSION}(-\w+)?(-\w+)?/}

Instance Attribute Summary

Attributes inherited from Chef::Knife::SubcommandLoader

#chef_config_dir

Instance Method Summary collapse

Methods inherited from Chef::Knife::SubcommandLoader

autogenerated_manifest?, #command_class_from, #find_longest_key, for_config, #force_load, gem_glob_loader, #guess_category, #initialize, #list_commands, #load_command, #load_commands, plugin_manifest, plugin_manifest?, plugin_manifest_path, #positional_arguments, #site_subcommands

Constructor Details

This class inherits a constructor from Chef::Knife::SubcommandLoader

Instance Method Details

#find_subcommands_via_dirglobObject


48
49
50
51
52
53
54
55
56
57
# File 'lib/chef/knife/core/gem_glob_loader.rb', line 48

def find_subcommands_via_dirglob
  # The "require paths" of the core knife subcommands bundled with chef
  files = Dir[File.join(Chef::Util::PathHelper.escape_glob_dir(File.expand_path("../../../knife", __FILE__)), "*.rb")]
  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_rubygemsObject


59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/chef/knife/core/gem_glob_loader.rb', line 59

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]

    # When not installed as a gem (ChefDK/appbundler in particular), AND
    # a different version of Chef is installed via gems, `files` will
    # include some files from the 'other' Chef install. If this contains
    # a knife command that doesn't exist in this version of Chef, we will
    # get a LoadError later when we try to require it.
    next if from_different_chef_version?(file)

    subcommand_files[rel_path] = file
  end

  subcommand_files.merge(find_subcommands_via_dirglob)
end

#gem_and_builtin_subcommandsObject

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 => "/absolute/path"

Note: the "right" way to load the plugins is to require the relative path, i.e., require 'chef/knife/command' but we're getting frustrated by bugs at every turn, and it's slow besides. So subcommand loader has been modified to load the plugins by using Kernel.load with the absolute path.


41
42
43
44
45
46
# File 'lib/chef/knife/core/gem_glob_loader.rb', line 41

def gem_and_builtin_subcommands
  require "rubygems"
  find_subcommands_via_rubygems
rescue LoadError
  find_subcommands_via_dirglob
end

#subcommand_filesObject


28
29
30
# File 'lib/chef/knife/core/gem_glob_loader.rb', line 28

def subcommand_files
  @subcommand_files ||= (gem_and_builtin_subcommands.values + site_subcommands).flatten.uniq
end